#include "CMP.h"
#include "Options\specif\SubMapPs.h"
 
#include "ago.h"
 
extern POS_tdstCompletePosition	*POS_g_p_stIdentityMatrix;
 
#if defined (ACTIVE_EDITOR)
BOOL g_bSectionSoundFoundInLevelDSC;
#endif /*ACTIVE_EDITOR*/

/* ANNECY MT - 30/03/99 { PC Protection */
#ifndef U64 
void fn_vCopyProtectKeyToModels();
void fn_vCopyChecksumToModels();

#ifndef ACTIVE_EDITOR
#ifdef _DEBUG
EXTERN ACP_tdxBool	g_bDreamcast;
EXTERN void MDS_fn_vGenerateDCData(char, char);
#endif /* _DEBUG */
#endif /* ACTIVE_EDITOR */

EXTERN	ACP_tdxBool	g_bDumpMemory;
#endif /* U64 */
/* END ANNECY MT } */

extern tdstEngineObject *g_AlphabetCharacterPointer;
extern ACP_tdxBool  g_bInGameMenu;


/* Modif 03/07/98 : init interpolation and keep anim of char. in the fix - Carlos Torres*/
void fn_vFirstInitEngine( void )
{
	SndBool				bRet;
	BOOL				bHasSwapped=FALSE;
	SND_tdstInitStruct	SndInit;
	char				a256_cName[256];	
	
	strcpy(a256_cName, fn_szGetGameDataPath());
	strcat(a256_cName, "\\world\\levels\\fix.ptx");
	TEX_SetNameOfBinaryFile((unsigned char *)a256_cName);
	
	g_stEngineStructure.hGLDDevice   = fn_hGetGLDDevice(0);
	g_stEngineStructure.hGLDViewport = fn_hGetGLDViewport(0);
	g_stEngineStructure.hDrawSem     = fn_hGetDrawSemaphore();
	
	g_stEngineStructure.eInputMode  = IM_Normal;
	g_stEngineStructure.eDisplayFixMode = DFM_DisplayAll;
	
	LST2_M_DynamicInitAnchor(&g_stEngineStructure.hCameraList);
	LST2_M_DynamicInitAnchor(&g_stEngineStructure.hMainCharacterList);
	LST2_M_DynamicInitAnchor(&g_stEngineStructure.hAlwaysActiveCharactersList);
 
	g_stEngineStructure.ucPreviousLevel = 0;
	g_stEngineStructure.ucExitIdToQuitPrevLevel = 0;
	g_stEngineStructure.ucLevelGlobalCounter = 0;
 
 
	/*fn_vFreeNextLevelPositionName();*/
	
	MTH_M_vInit();
	
	/*g_b_lSurfacesOn = TRUE;*/
	g_ucIsEdInGhostMode = 0;

/* ANNECY MT - 25/06/99 { */
#if !defined(U64) && defined(_DEBUG)
	g_ucSlowDownEngine = 0;
	g_ucSlowDownTime = 0;
#endif	
/* END ANNECY MT } */

	/**** Initialize the engine clock ****/
	fn_vFirstInitEngineClock();
	
	/**** Verify some program's variable ****/
	fn_vVerifySomeProgramVariables();
	
	GLI_xInitGli();

	fn_vInitFrameLenght ();
	
	GAM_fn_vCreateGameDeviceAndViewPorts();
	
#ifdef ACTIVE_EDITOR
//	fn_vSwapDeviceToFullScreen();
#endif
	
	VIG_fn_vInitDeviceVignette(g_stEngineStructure.hGLDDevice,g_stEngineStructure.hGLDFixViewport,g_stEngineStructure.hDrawSem);
	VIG_fn_vInitVignette();
	
	FON_fn_vInitFonts();

/* ANNECY AV DEMO {*/
    DEMO_fn_vAllocateMemory ();
/* END ANNECY AV }*/
 
    /* GuS 98/08/11*/
    if ( SNA_fn_ucGetLoadDscType() == SNA_C_LoadBinaryDsc )
    {
        /* read Directories Description*/
        SNA_M_ReadSingleSectionFromDscFile();
	}
	/* if we are not going to load binary data, then the game script is parsed normally*/
	if ( 
			(SNA_fn_ucGetLoadType()!=SNA_LOAD_SNAPSHOT)
			&& (SNA_fn_ucGetLoadDscType()!=SNA_C_LoadBinaryDsc)
		)
		fn_vLoadGameScript();
	else
		/* Else, we compute witch part of the game desc are to be loaded.*/
		fn_vLoadReducedGameScript();
 
	/* init interpol module*/
	fn_v_InitInterpol();
 
	if (SNA_fn_ucGetLoadType()!=SNA_LOAD_SNAPSHOT)
	{
		fn_vInitAI(FALSE);
#ifndef U64
	    DEMO_fn_vInitGMTFixList ();
#endif /* U64 */
	}
#ifndef RETAIL /* { */
	else
		fn_vInitAI(TRUE);
#endif /* RETAIL } */
 
	/* SOUND: After fn_vLoadGameScript/ Before fn_bLoadCurrentGameOptions(for fn_lInitSoundForAnim)*/
	/***** Init sound engine:*/
	SND_fn_vSetSoftDirectory(fn_szGetEngineDLLPath());
	fn_vInitSoundStruct((void*)&SndInit); /*fct defined by GameITF*/
	SND_fn_iInitSound(&SndInit);
	bRet=SIF_fn_bInitSoundInfos();
	SND_fn_vSetDopplerFactorSound(SND_C_NO_DOPPLER);
	/**** fin int sound*/
	
	bRet=SND_fn_bInitDataLoadSnd("Rayman2");
 
    if ( SNA_fn_ucGetLoadDscType() == SNA_C_LoadBinaryDsc )
    {
 
        /* Read all sections from the binarized game.dsc.*/
        SNA_M_ReadAllRemainingSectionsFromDscFile();
        /* Then close it*/
        SNA_M_EndReadFromCurrentDscFile();
 
	}
	
	/**** init sound objects*/
	fn_lInitSoundForAnim();
	fn_vInitMicrosFunction();
	/* fin magouille son*/
	/* SOUND fin*/
	
	/*Init VDO lib*/
#if defined(GAM_VIDEO)
	VDO_fn_xInitAVI(fn_hGetApplicationInstance(),g_stEngineStructure.hDrawSem);
#endif /* GAM_VIDEO*/
	
	fn_bDestroySavedGame(0); /* destroy the temporary save  slot if it exists*/
	
	fn_vInitAllLinkTables(); /* initialise link tables before loading menus*/
	
	/*** Initialize the collision object used for acceleration ***/
#ifndef RETAIL /* { */
	if ((SNA_fn_ucGetLoadType()==SNA_SAVE_SNAPSHOT))	
	{
		char szFileName[_MAX_PATH];
/*
		sprintf(szFileName,"%s\\Fix.vgm",fn_szGetLevelsDataPath());
		SNA_fn_xWriteOpenVignetteTableFile(szFileName);
*/		
		sprintf(szFileName,"%s\\Fix.snd",fn_szGetLevelsDataPath());
		SNA_fn_xWriteOpenSoundTableFile(szFileName);
	}
#endif /* RETAIL } */
	
 
	GAM_fn_vCreateListOfLevel();
	
	/**** Init all object's type structures ****/
	fn_vFirstInitObjectTypeStructure();
	
	
#ifndef RETAIL /* { */
	if (SNA_fn_ucGetLoadType()!=SNA_LOAD_SNAPSHOT)
	{
		unsigned char ucOldACPModeMalloc;
 
		ucOldACPModeMalloc = GEO_M_ucGetMemMallocMode();
		GEO_xSelectMemoryChannel(ACP_FixMemoryChannel);
		POS_fn_vInitPos();
		GEO_xSelectMemoryChannel(ucOldACPModeMalloc);
 
		fn_vLoadGameFixScript();
		fn_vInitObjectsInTheFix();
	}
#endif /* RETAIL } */
 
	
	/* keep the anim load in the fix*/
	fn_v_UnclearPreviousLoadedAnims();
	
#ifndef RETAIL /* { */
	if ((SNA_fn_ucGetLoadType()==SNA_SAVE_SNAPSHOT))
	{
		char szFileName[_MAX_PATH];
		sprintf(szFileName,"%s\\Fix.snd",fn_szGetLevelsDataPath());
	}
	else if (SNA_fn_ucGetLoadType()==SNA_LOAD_SNAPSHOT)
#endif /* RETAIL } */
		fn_vLoadFix();
 
/*
	if (SNA_fn_ucGetLoadType()==SNA_LOAD_SNAPSHOT)
	{
		char szFileName[_MAX_PATH];
 
		sprintf(szFileName,"%s\\world\\levels\\Fix.gpt",fn_szGetGameDataPath());
		SNA_fn_xReadOpenGlobalPointersFile(szFileName);
		POS_g_p_stIdentityMatrix=(POS_tdstCompletePosition *)SNA_fn_vReadPointerFromGlobalPointersFile();
		SNA_fn_vCloseGlobalPointersFile();
		POS_g_p_stIdentityMatrix->ulType = POS_C_ulIdentityMatrixFlag;
		MTH3D_M_vNullVector(&(POS_g_p_stIdentityMatrix->stTranslationVector));
		MTH3D_M_vSetIdentityMatrix(&(POS_g_p_stIdentityMatrix->stRotationMatrix));
		MTH3D_M_vSetIdentityMatrix(&(POS_g_p_stIdentityMatrix->stTransformMatrix));
	}
*/
 
	fn_bLoadCurrentGameOptions();
	
	PLA_fn_vCreateAndInitHeaps();
	/*** Initialize the collision object used for acceleration ***/
	fn_vFirstTimeInitCollisionGeometricObject();
	
/* ANNECY MT - 28/08/98 {*/
	POS_fn_vSetIdentityMatrix(&g_stEngineStructure.stMainCharacterPosition);
	POS_fn_vSetIdentityMatrix(&g_stEngineStructure.stMainCameraPosition);
	g_stEngineStructure.bResurection = FALSE;	
/* END ANNECY MT }*/
 
	/* Init water streak and bubble effects */
	/* Do not delete*/
	fn_vInitBubbleEffect();
	fn_vInitWaterStreakEffect();
	SHW_fn_vInitShadow(g_stEngineStructure.hGLDDevice);
 
	HIE_fn_vCreateMatrixStack();
 
#ifndef U64
#ifndef ACTIVE_EDITOR
#ifdef _DEBUG
	if (g_bDreamcast)
		MDS_fn_vGenerateDCData(1, 1);
#endif /* _DEBUG */
#endif /* ACTIVE_EDITOR */
#endif /* U64 */

#ifndef RETAIL /* } */
	if (SNA_fn_ucGetLoadType()==SNA_SAVE_SNAPSHOT)
	{
		fn_vSaveFix(TRUE);
		SNA_fn_vCloseSoundTableFile();
	}
	if (SNA_fn_ucGetLoadType()==SNA_LOAD_SCRIPT)
		GLI_vEndofGeometricLoad();
#endif /* RETAIL */
	
	GEO_fn_vInitBoundingVolumeMaterial();
	SNA_fn_vSetSaveLoadLevel();
 
	TFMT_vSetDefaultValuesCharacter(MTH_C_ONE, MTH_C_2, MTH_C_ZERO);
}
 
 
/*-----------------------------------------------------------------------------
*  Description : Init engine when the application just run
*-----------------------------------------------------------------------------
*  Input :
*  Output :
*-----------------------------------------------------------------------------
*  Creation date : 25/04/97            Author : Francois
*-----------------------------------------------------------------------------
*  Modification date :                 Modification Author :
*  Modifications :
*---------------------------------------------------------------------------*/
void fn_vInitEngineWhenInitApplication(void)
{
	Erm_M_InitErrMsg(Game);
	fn_vComputeTempDataPath();
	
	GAM_fn_vReadUbiIniFileForGame();
	GAM_fn_vTreatExeParameters();
	
	g_stEngineStructure.eEngineMode = EM_ModeStartingProgram;
	
	
	SCR_fn_v_Mem_InitWithMemLevel(g_SCR_a9MemTable);
	
	
	GEO_xInitGEOError();
	IPT_fn_vFirstInitInput();
	RND_fn_vFirstInitRandom();
	CMP_fn_vFirstInit();
	SAI_fn_vFirstInit();
	TMP_fn_vFirstInit();
	FIL_fn_vFirstInit();
	
	VIG_fn_vFirstInit();
	PO_fn_vFirstInit();
	fn_vFirstInitAIMemory();
	fn_vFirstInitGameMemory();
	POS_fn_vFirstInit();
	fn_vInitAndRegisterAllScriptSections();
	SCR_fn_v_Mem_SetCurrentLevel(GAM_C_FixScriptPriority);
	SCR_fn_v_Mem_SetCurrentLinkLevel(GAM_C_FixScriptPriority);
	
	SNA_fn_vSetSaveLoadFix();
	/* GuS 98/08/06*/
	if ( SNA_fn_ucGetLoadDscType() == SNA_C_LoadBinaryDsc )
	{
		/* Load game.dsb that is obtained by binarization of some files (Game.dsc, Game.mem, Game.rnd & Game.pgb)*/
		/* Here is the first time the GameDsc File is used, so prepare it for reading.*/
		SNA_M_BeginReadFromDscFile( SNA_C_GameDscFile );
		/* Read the memory description from the file.*/
		SNA_M_ReadSingleSectionFromDscFile();
	}
	else
	{
		/* If we are goind to create the .dsb, open the game.dsb for writing.*/
#ifndef RETAIL
		if( SNA_fn_ucGetLoadDscType() == SNA_C_SaveBinaryDsc )
			SNA_M_BeginWriteToDscFile( SNA_C_GameDscFile );
#endif
		SNA_fn_vSetLoadType(SNA_LOAD_SCRIPT);
		fn_vLoadGameMemoryScript();
	}
	GAM_fn_vSetEngineInFixMode();
}
 
 
/*-----------------------------------------------------------------------------
*  Description : Load one level
*-----------------------------------------------------------------------------
*  Input :
*  Output :
*-----------------------------------------------------------------------------
*  Creation date : 
*-----------------------------------------------------------------------------
*  Modification date :                 Modification Author :
*  Modifications :
*---------------------------------------------------------------------------*/
void fn_vInitLevelLoop()
{
	char						szLevelSnapshotFilename[_MAX_PATH],szFileName[_MAX_PATH];
	static						HIE_tdxHandleToSuperObject hPreviousWorld=NULL;
	FIL_tdxHandleToFileNameList hLevelNameList;
	
	SCT_fn_vInitMaterialForGoThrough();
	
	/* Clear Anim of a previous level and keep the fix*/
	fn_v_ClearLoadedAnims(FALSE);
 
	/* Init for the save of global fog*/
	GLI_g_bSaveFog = FALSE;
	GLD_bSetBackgroundColorForDevice(fn_hGetGLDDevice(0), RGB(0,0,0));
 
	g_AlphabetCharacterPointer = NULL;
	g_bInGameMenu = FALSE;
 
	SCR_fn_v_Mem_SetCurrentLevel(GAM_C_LevelDynamicScriptPriority);
	SCR_fn_v_Mem_SetCurrentLinkLevel(GAM_C_LevelDynamicScriptPriority);
 
#ifndef RETAIL
	if ( SNA_fn_ucGetLoadDscType() == SNA_C_SaveBinaryDsc )
	{
		/* Binarization of some game infos.*/
		SNA_M_BeginWriteToDscFile( SNA_C_LevelDscFile );
	}
	else 
#endif
if ( SNA_fn_ucGetLoadDscType() == SNA_C_LoadBinaryDsc )
	{
		/* Load level.dsb that is obtained by binarization of some files (Level.dsc & Level.pgb)*/
		/* Here is the first time the Level Dsc File is used, so prepare it for reading.*/
		SNA_M_BeginReadFromDscFile( SNA_C_LevelDscFile );
 
		/* Read the level memory desc.*/
		SNA_M_ReadSingleSectionFromDscFile();
		/* Keep the file opened for further reading.*/
	}
#ifndef RETAIL /* { */
	if ( SNA_fn_ucGetLoadDscType() != SNA_C_LoadBinaryDsc )
	{
		if (g_cMemMode)
			/* For binarization, we read Level.mem and not LevelName\levelName.mem*/
			SCR_fnp_st_RdL0_AnalyseSection("level.mem", SCR_CDF_uw_Anl_Normal);
		else
		{
			sprintf(szFileName,"%s\\%s.%s",fn_p_szGetLevelName(),fn_p_szGetLevelName(),C_MemoryDescriptionSuffixe);
			SCR_fnp_st_RdL0_AnalyseSection(szFileName, SCR_CDF_uw_Anl_Normal);
		}
	}
#endif /* RETAIL } */
 
	SCR_fn_v_Mem_SetCurrentLevel(GAM_C_LevelScriptPriority);
	SCR_fn_v_Mem_SetCurrentLinkLevel(GAM_C_LevelScriptPriority);
	
    if ( SNA_fn_ucGetLoadDscType() == SNA_C_LoadBinaryDsc )
    {
        /* Read the vignette desc*/
        SNA_M_ReadSingleSectionFromDscFile();
 
#if defined(_DEBUG)
        fn_vChangeWindowTitle("Chargement de la map");
#endif /* _DEBUG */
 
        /* Read level desc*/
		SNA_M_ReadAllRemainingSectionsFromDscFile();
 
        /* For the moment, no other information is stored in this file, so :*/
        SNA_M_EndReadFromCurrentDscFile();
    }
    else
    {
	    sprintf(szFileName,"%s\\%s.%s",fn_p_szGetLevelName(),fn_p_szGetLevelName(),VIG_C_ScriptPgbSuffixe);
	    if (!SCR_fn_c_RdL0_IsSectionExists(szFileName))
		    sprintf(szFileName,"default.%s",VIG_C_ScriptPgbSuffixe);
	    SCR_fnp_st_RdL0_AnalyseSection(szFileName, SCR_CDF_uw_Anl_Normal);
 
        fn_vChangeWindowTitle("Chargement de la map");
    	sprintf(szFileName,"%s\\%s.%s",fn_p_szGetLevelName(),fn_p_szGetLevelName(),C_ScriptDescriptionSuffixe);

#if defined (ACTIVE_EDITOR)
		g_bSectionSoundFoundInLevelDSC = FALSE;
#endif /*ACTIVE_EDITOR*/

    	SCR_fnp_st_RdL0_AnalyseSection(szFileName, SCR_CDF_uw_Anl_Normal);

#if defined (ACTIVE_EDITOR)
		if (!g_bSectionSoundFoundInLevelDSC)
			MessageBox(NULL,"Add section {LevelSoundBanks:}", "Missing information in *.dsc in the current level", MB_OK);
#endif /*ACTIVE_EDITOR*/

#ifndef RETAIL /* { */
        if ( SNA_fn_ucGetLoadDscType() == SNA_C_SaveBinaryDsc )
            SNA_M_EndWriteToCurrentDscFile();
#endif /* RETAIL } */
    }
	
 
#ifndef RETAIL /* { */
    if (SNA_fn_ucGetLoadType()==SNA_LOAD_SCRIPT)
	{
		fn_vStandardInitLevelLoop();
		GLI_vEndofGeometricLoad();
		fn_vCopyChecksumToModels();		  
	}
	else/* Load or Save binary data for a level*/
#endif /* RETAIL } */
	{
#ifdef D_USE_LIPSYNC
		ACP_tdxBool bLipsSynchPresent;
#endif /*  D_USE_LIPSYNC*/
		
		sprintf(szFileName,"%s\\%s\\%s.ptx",fn_szGetLevelsDataPath(),fn_p_szGetLevelName(),fn_p_szGetLevelName());
		TEX_SetNameOfBinaryFile((unsigned char *)szFileName);
		sprintf(szLevelSnapshotFilename,"%s\\%s\\%s.sna",fn_szGetLevelsDataPath(),fn_p_szGetLevelName(),fn_p_szGetLevelName());
		
		if (SNA_fn_ucGetLoadType()==SNA_LOAD_SNAPSHOT)
		{
			/* Load Binary data for the level*/
			MC_tdxHandleToMainCharacterNode hMainCharNode;
			unsigned long					i;
			unsigned char					ucDummy;
			float							xDumpNear;
			char							p_cDummy[_MAX_PATH];
			char							szTrueFirstLevelNameInBin[_MAX_PATH];
			short							wDummy;
			void							*vDummy;
			tdeEngineMode				eLocalEngineMode;
			unsigned char ucDummyPrevLevel, ucDummyExit;
#ifndef RETAIL
			char              a_szLevelName[80][_MAX_NAME_LEVEL];
			unsigned char     ucNumberOfLevels;
#endif
			tdstEngineTimerStructure  stSaveTimer;
			struct GLI_tdstCamera_			*p_stCamera;
			/* ID of levels : for loading relocation tables. */
			unsigned char ucIDOfLevelToLoad = SNA_fn_ucGetLevelID( fn_p_szGetLevelName() );
 
			GLI_xGetViewportCamera ( g_stEngineStructure.hGLDDevice,g_stEngineStructure.hGLDViewport,&p_stCamera);
			if(!p_stCamera)
			{
				GLI_xCreateCamera (&(p_stCamera),GLI_C_lPersCamWithoutDistorsion);
				GLI_xSetCameraAspectAndRatio (p_stCamera,1.5, 0.75);
				GLI_xSetViewportCamera( g_stEngineStructure.hGLDDevice,
					g_stEngineStructure.hGLDViewport,
					p_stCamera ) ;
			}
			
			SNA_fn_vSetSaveLoadLevel();
					
			SNA_M_ReInitLoadRelocationTable();

#ifdef D_USE_LIPSYNC
			sprintf(szFileName,"%s\\%s\\%s.lsy",fn_szGetLevelsDataPath(),fn_p_szGetLevelName(),fn_p_szGetLevelName());
			SNA_M_vSetNextRelocationFileToLoad( ucIDOfLevelToLoad, SNA_C_ucLipsSyncRelocationTable );
			bLipsSynchPresent=SNA_fn_xReadOpenLipsSynchTableFile(szFileName);
			/* Version hybride*/
			if (bLipsSynchPresent)
			{	
				sprintf(szFileName,"%s\\%s\\%s.bls",fn_szGetLevelsDataPath(),fn_p_szGetLevelName(),fn_p_szGetLevelName());
				fn_vReadAllLipsSynchroBlocs(szFileName);
			}
#endif /* D_USE_LIPSYNC*/
 
/* ANNECY OA - 12/07/99 { */
	/* Load dummy datas : for protections */
	SNA_M_LoadUnusedRelocationTable();	
/* END ANNECY OA } */
 
			/* read level.sna*/
			SNA_M_vSetNextRelocationFileToLoad( ucIDOfLevelToLoad, SNA_C_ucSNARelocationTable );
			SNA_fn_bReadAllMemoryBlocks(szLevelSnapshotFilename);
	
/* ANNECY OA - 12/07/99 { */
	/* Load dummy datas : for protections */
	SNA_M_LoadUnusedRelocationTable();	
/* END ANNECY OA } */

			SNA_M_vSetNextRelocationFileToLoad( ucIDOfLevelToLoad, SNA_C_ucGlobalPointersRelocationTable );
			sprintf(szFileName,"%s\\%s\\%s.gpt",fn_szGetLevelsDataPath(),fn_p_szGetLevelName(),fn_p_szGetLevelName());
			SNA_fn_xReadOpenGlobalPointersFile(szFileName);

			
			/*//////*/
			/* read all global pointers and structures saved during the binarization */
			/*//////*/
 
			/* Init Position of perso in Fix*/
			{
				unsigned long i;
				POS_tdstCompletePosition *p_stMatrix;
				tdstEngineObject *p_stEngine;
				static char cFirst=0;
				HIE_tdxHandleToSuperObject h_SupObject;
				float fTransparenceLevel;
				
				SNA_g_stFixInfo.ulNbObject = SNA_fn_vReadPointerFromGlobalPointersFile();
				for(i=0;i<SNA_g_stFixInfo.ulNbObject;i++)
				{
					SNA_g_stFixInfo.a20_stObjects[i]=(tdstEngineObject*)SNA_fn_vReadPointerFromGlobalPointersFile();
 
					if( fn_h_StandardGameGetSuperObject(SNA_g_stFixInfo.a20_stObjects[i]->h_StandardGame) !=NULL )
					{
						h_SupObject = (struct HIE_tdstSuperObject_ *)SNA_fn_vReadPointerFromGlobalPointersFile();	
 
						p_stEngine=M_GetEngineObject(h_SupObject);
 
						fn_vStandardGameSetSuperObject(p_stEngine->h_StandardGame, h_SupObject );
						SNA_g_stFixInfo.a20_stObjects[i]=p_stEngine;
 
						p_stMatrix=fn_p_st3dDataGetMatrix(p_stEngine->h_3dData);
 
						SNA_fn_vReadStructureFromGlobalPointersFile((unsigned long *)p_stMatrix,sizeof(POS_tdstCompletePosition));
						HIE_fn_SO_vSetFlags(h_SupObject, (unsigned long)SNA_fn_vReadPointerFromGlobalPointersFile() );
						SNA_fn_vReadStructureFromGlobalPointersFile( (unsigned long *)&fTransparenceLevel, sizeof(float) );
						LST2_M_DynamicSetNextElement( h_SupObject, (HIE_tdxHandleToSuperObject)SNA_fn_vReadPointerFromGlobalPointersFile() );
						LST2_M_DynamicSetPrevElement( h_SupObject, (HIE_tdxHandleToSuperObject)SNA_fn_vReadPointerFromGlobalPointersFile() );
						LST2_M_DynamicSetFather( h_SupObject, (HIE_tdxHandleToSuperObject)SNA_fn_vReadPointerFromGlobalPointersFile() );
 
						HIE_fn_vSetSuperObjectTransparenceLevel( h_SupObject, fTransparenceLevel );
 
						if(cFirst==0)
						{
							p_stEngine->h_StandardGame->ucMiscFlags &= ~GAM_C_AllSecondPassDone;
						}
					
						else
						{
							/* Init dynam MS for perso in the fix (and not for always !)*/
							if(M_GetMSHandle(h_SupObject,Dynam)!=NULL)
								fn_vDynamInit(p_stEngine,OTI_WhenGameStart);
						}
					}
				}
				cFirst=1;
			}

			gp_stActualWorld=(HIE_tdxHandleToSuperObject)SNA_fn_vReadPointerFromGlobalPointersFile();
			gp_stDynamicWorld=(HIE_tdxHandleToSuperObject)SNA_fn_vReadPointerFromGlobalPointersFile();
			gp_stInactiveDynamicWorld=(HIE_tdxHandleToSuperObject)SNA_fn_vReadPointerFromGlobalPointersFile();
			SECT_hFatherSector=(HIE_tdxHandleToSuperObject)SNA_fn_vReadPointerFromGlobalPointersFile();
 
			g_hLoadedSuperObjectRoot = SECT_hFatherSector;
 
			gs_hFirstSubMapPosition=(tdstSubMapPosition *)SNA_fn_vReadPointerFromGlobalPointersFile();
	
			SNA_fn_vReadStructureFromGlobalPointersFile((unsigned long *)&g_stAlways,sizeof(tdstAlways));
 
			LST2_M_DynamicSetFirstElement( &(g_stAlways.ALW_h_LstAlwaysModel), (ALW_tdxHandleToModelList)SNA_fn_vReadPointerFromGlobalPointersFile() );
			LST2_M_DynamicSetLastElement( &(g_stAlways.ALW_h_LstAlwaysModel), (ALW_tdxHandleToModelList)SNA_fn_vReadPointerFromGlobalPointersFile() );
 
			{
				ALW_tdxHandleToModelList h_FirstAlwaysInLevel;
				ALW_tdxHandleToModelList hCurrent, hNext;

				/* The always list model is both in fix memory and level memory,*/
				/* so we read the pointer that goes from fix to level...*/
				h_FirstAlwaysInLevel = (ALW_tdxHandleToModelList)SNA_fn_vReadPointerFromGlobalPointersFile();
				if( SNA_g_stFixInfo.h_LastAlwaysInTheFix != NULL )
				{
					LST2_M_DynamicSetNextElement( SNA_g_stFixInfo.h_LastAlwaysInTheFix, h_FirstAlwaysInLevel );
					if( h_FirstAlwaysInLevel )
						LST2_M_DynamicSetPrevElement( h_FirstAlwaysInLevel, SNA_g_stFixInfo.h_LastAlwaysInTheFix );
				}

				/* Validate the list to restore father link */
				SNA_M_vValidateLst(&g_stAlways.ALW_h_LstAlwaysModel, (LST2_M_DynamicGetLastElement(&g_stAlways.ALW_h_LstAlwaysModel)), hCurrent, hNext);
			}

			{
				tdhHandleToObjectTypeElement hElement;

				hElement = (tdhHandleToObjectTypeElement) SNA_fn_vReadPointerFromGlobalPointersFile();
				if( SNA_g_stFixInfo.hLastFamilyTypeInTheFix != NULL && hElement != NULL )
					LST2_M_DynamicSetPrevElement( hElement, SNA_g_stFixInfo.hLastFamilyTypeInTheFix);
 
				hElement = (tdhHandleToObjectTypeElement) SNA_fn_vReadPointerFromGlobalPointersFile();
				if( SNA_g_stFixInfo.hLastModelTypeInTheFix != NULL && hElement != NULL )
					LST2_M_DynamicSetPrevElement( hElement, SNA_g_stFixInfo.hLastModelTypeInTheFix);
 
				hElement = (tdhHandleToObjectTypeElement) SNA_fn_vReadPointerFromGlobalPointersFile();
				if( SNA_g_stFixInfo.hLastPersonalTypeInTheFix != NULL && hElement != NULL )
					LST2_M_DynamicSetPrevElement( hElement, SNA_g_stFixInfo.hLastPersonalTypeInTheFix);
			}
 
			SNA_fn_vReadStructureFromGlobalPointersFile((unsigned long *)&g_stObjectTypes,sizeof(tdstObjectType));
			/* Correct the list*/
			{
				tdhHandleToObjectTypeElement hCurrent,hNext,hLastElement;
				
				hLastElement=LST2_M_DynamicGetLastElement(&g_stObjectTypes.hFamilyType);
				SNA_M_vValidateLst(&g_stObjectTypes.hFamilyType, hLastElement, hCurrent, hNext);
				
				hLastElement=LST2_M_DynamicGetLastElement(&g_stObjectTypes.hModelType);
				SNA_M_vValidateLst(&g_stObjectTypes.hModelType, hLastElement, hCurrent, hNext);
				
				hLastElement=LST2_M_DynamicGetLastElement(&g_stObjectTypes.hPersonalType);
				SNA_M_vValidateLst(&g_stObjectTypes.hPersonalType, hLastElement, hCurrent, hNext);
			}
			
			/* save some values that should not be replaced when reading the whole structure from the file*/
			hLevelNameList = g_stEngineStructure.hLevelNameList;
			eLocalEngineMode = g_stEngineStructure.eEngineMode;
			strcpy(szTrueFirstLevelNameInBin,g_stEngineStructure.szFirstLevelName);
			strcpy(p_cDummy,g_stEngineStructure.szNextLevelName);
			vDummy = g_stEngineStructure.hDrawSem;
			wDummy = g_stEngineStructure.stEngineTimer.sTimerHandle;
			ucDummyPrevLevel = g_stEngineStructure.ucPreviousLevel;
			ucDummyExit = g_stEngineStructure.ucExitIdToQuitPrevLevel;
			xDumpNear = ((GLI_tdstSpecificAttributesFor3D *)g_stEngineStructure.stFixViewportAttr.p_vSpecificToXD)->xNear;
			memcpy( &stSaveTimer, &g_stEngineStructure.stEngineTimer, sizeof(tdstEngineTimerStructure) );
#ifndef RETAIL
			memcpy( a_szLevelName, g_stEngineStructure.a_szLevelName, sizeof(a_szLevelName) );
			ucNumberOfLevels = g_stEngineStructure.ucNumberOfLevels;
#endif
 
			/* read the structure from the file*/
			SNA_fn_vReadStructureFromGlobalPointersFile((unsigned long *)&g_stEngineStructure,sizeof(tdstEngineStructure));

			/* restore the values that were changed when the structure was filled from the data file */
#ifndef RETAIL
			memcpy( g_stEngineStructure.a_szLevelName, a_szLevelName, sizeof(a_szLevelName) );
			g_stEngineStructure.ucNumberOfLevels = ucNumberOfLevels;
#endif
 
			((GLI_tdstSpecificAttributesFor3D *)g_stEngineStructure.stFixViewportAttr.p_vSpecificToXD)->p_stCam = g_stEngineStructure.p_stFixCamera;
			((GLI_tdstSpecificAttributesFor3D *)g_stEngineStructure.stFixViewportAttr.p_vSpecificToXD)->xNear = xDumpNear;
			strcpy(g_stEngineStructure.szFirstLevelName,szTrueFirstLevelNameInBin);
			strcpy(g_stEngineStructure.szNextLevelName,p_cDummy);
			g_stEngineStructure.stEngineTimer.sTimerHandle=wDummy;
			g_stEngineStructure.ucPreviousLevel = ucDummyPrevLevel;
			g_stEngineStructure.ucExitIdToQuitPrevLevel = ucDummyExit;
			g_stEngineStructure.hDrawSem=vDummy;
			memcpy( &g_stEngineStructure.stEngineTimer, &stSaveTimer,  sizeof(tdstEngineTimerStructure) );
			g_stEngineStructure.hLevelNameList=hLevelNameList;
			g_stEngineStructure.eEngineMode = eLocalEngineMode;
			
			{
				tdxHandleToFamilyList hCurrentFamily,hNextFamily,hLastElementFamily;
				
				hLastElementFamily=LST2_M_DynamicGetLastElement(&g_stEngineStructure.hFamilyList);
				SNA_M_vValidateLst(&g_stEngineStructure.hFamilyList, hLastElementFamily, hCurrentFamily, hNextFamily);
			}
			
			gp_stLight=(struct GLI_tdstLight_ *)SNA_fn_vReadPointerFromGlobalPointersFile();
			
			hMainCharNode=(MC_tdxHandleToMainCharacterNode)SNA_fn_vReadPointerFromGlobalPointersFile();
			LST2_M_DynamicSetFirstElement(&g_stEngineStructure.hMainCharacterList, hMainCharNode);

			g_hCharacterLauchingSoundEvents=(HIE_tdxHandleToSuperObject)SNA_fn_vReadPointerFromGlobalPointersFile();
			
			g_hShadowPolygonVisualMaterial=(ACP_tdxHandleOfMaterial)SNA_fn_vReadPointerFromGlobalPointersFile();
			g_hShadowPolygonGameMaterialInit=(GMT_tdxHandleToGameMaterial)SNA_fn_vReadPointerFromGlobalPointersFile();
			g_hShadowPolygonGameMaterial=(GMT_tdxHandleToGameMaterial)SNA_fn_vReadPointerFromGlobalPointersFile();
			g_p_stTextureOfTextureShadow=(GLI_tdstTexture *)SNA_fn_vReadPointerFromGlobalPointersFile();
			COL_g_d_lTaggedFacesTable = (long *)SNA_fn_vReadPointerFromGlobalPointersFile();
			for (i=0;i<SHW_C_xNbMaxOfShadows;i++)
			{
				g_p_hHandleOfElementForShadow[i]=(ACP_tdxHandleOfElement)SNA_fn_vReadPointerFromGlobalPointersFile();
				p_hHandleOfGeometricShadowObject[i]=(ACP_tdxHandleOfObject)SNA_fn_vReadPointerFromGlobalPointersFile();
			}
 
 
			g_hDemoSOList=(DEMO_tdxHandleToDemoSOList)SNA_fn_vReadPointerFromGlobalPointersFile();
			g_hDemoGMTLevelList=(DEMO_tdxHandleToDemoGMTList)SNA_fn_vReadPointerFromGlobalPointersFile();

			/* Retrieve stack infos for all stacks in anim player.*/
			SNA_fn_vReadArrayWithoutPointerFromGlobalPointersFile( tdstStacks, eStackNbMax, sizeof(tdstStackInfos) );
 
			{
				/**
				 * Now, load the LEVEL part of each stack. (from reset position to end of the stack)
				 * Stacks are retrieved with SNA_fn_vReadArrayWithoutPointerFromGlobalPointersFile
				 * except the Event stack, witch uses SNA_fn_vReadArrayFromGlobalPointersFile
				 */
				unsigned long ulResetPos;
 
				ulResetPos = tdstStacks[eStackA3dGENERAL].ulResetPos;
				SNA_fn_vReadArrayWithoutPointerFromGlobalPointersFile( (p_stA3dGENERAL+ulResetPos), (tdstStacks[eStackA3dGENERAL].ulStackPos-ulResetPos), sizeof(tdstA3dGENERAL) );
 
				ulResetPos = tdstStacks[eStackVertexes].ulResetPos;
				SNA_fn_vReadArrayWithoutPointerFromGlobalPointersFile( (p_a3_xVectors+ulResetPos), (tdstStacks[eStackVertexes].ulStackPos-ulResetPos), sizeof(tdxVector3) );
 
				ulResetPos = tdstStacks[eStackQuaternions].ulResetPos;
				SNA_fn_vReadArrayWithoutPointerFromGlobalPointersFile( (p_a4_xQuaternions+ulResetPos), (tdstStacks[eStackQuaternions].ulStackPos-ulResetPos), sizeof(tdxSShortQuater4) );
 
				ulResetPos = tdstStacks[eStackHierarchies].ulResetPos;
				SNA_fn_vReadArrayWithoutPointerFromGlobalPointersFile( (p_stHierarchies+ulResetPos), (tdstStacks[eStackHierarchies].ulStackPos-ulResetPos), sizeof(tdstHierarchy) );
 
				ulResetPos = tdstStacks[eStackNTTO].ulResetPos;
				SNA_fn_vReadArrayWithoutPointerFromGlobalPointersFile( (p_stNTTO+ulResetPos), (tdstStacks[eStackNTTO].ulStackPos-ulResetPos), sizeof(tdstNTTO) );
 
				ulResetPos = tdstStacks[eStackOnlyFrames].ulResetPos;
				SNA_fn_vReadArrayWithoutPointerFromGlobalPointersFile( (p_stOnlyFrames+ulResetPos), (tdstStacks[eStackOnlyFrames].ulStackPos-ulResetPos), sizeof(tdstOnlyFrame) );
 
				ulResetPos = tdstStacks[eStackChannels].ulResetPos;
				SNA_fn_vReadArrayWithoutPointerFromGlobalPointersFile( (p_stChannels+ulResetPos), (tdstStacks[eStackChannels].ulStackPos-ulResetPos), sizeof(tdstChannel) );
 
				ulResetPos = tdstStacks[eStackFrames].ulResetPos;
				SNA_fn_vReadArrayWithoutPointerFromGlobalPointersFile( (p_stFrames+ulResetPos), (tdstStacks[eStackFrames].ulStackPos-ulResetPos), sizeof(tdstFrame) );
 
				ulResetPos = tdstStacks[eStackFramesKF].ulResetPos;
				SNA_fn_vReadArrayWithoutPointerFromGlobalPointersFile( (p_stFramesKF+ulResetPos), (tdstStacks[eStackFramesKF].ulStackPos-ulResetPos), sizeof(tdstFrameKF) );
 
				ulResetPos = tdstStacks[eStackKeyFrames].ulResetPos;
				SNA_fn_vReadArrayWithoutPointerFromGlobalPointersFile( (p_stKeyFrames+ulResetPos), (tdstStacks[eStackKeyFrames].ulStackPos-ulResetPos), sizeof(tdstKeyFrame) );
 
				ulResetPos = tdstStacks[eStackEvents].ulResetPos;
				SNA_fn_vReadArrayFromGlobalPointersFile( (p_stEvents+ulResetPos), (tdstStacks[eStackEvents].ulStackPos-ulResetPos), sizeof(tdstEvent) );
 
				ulResetPos = tdstStacks[eStackMorphData].ulResetPos;
				SNA_fn_vReadArrayWithoutPointerFromGlobalPointersFile( (p_stMorphData+ulResetPos), (tdstStacks[eStackMorphData].ulStackPos-ulResetPos), sizeof(tdstMorphData) );
 
			} /* End of stack loading */

			g_AlphabetCharacterPointer = (tdstEngineObject *)SNA_fn_vReadPointerFromGlobalPointersFile();
 
			SNA_fn_vCloseGlobalPointersFile();
 
			LST2_M_DynamicInitAnchor(&g_stEngineStructure.hCameraList);
 
			SNA_M_vSetNextRelocationFileToLoad( ucIDOfLevelToLoad, SNA_C_ucTexturesRelocationTable );
			GLI_vEndofGeometricLoad();
 
			/* Take care of the progress bar*/
			VIG_fn_vAddToProgressBar(1);

/* ANNECY OA - 12/07/99 { */
	/* Load dummy datas : for protections */
	SNA_M_LoadUnusedRelocationTable();	
/* END ANNECY OA } */
 
			SNA_M_vSetNextRelocationFileToLoad( ucIDOfLevelToLoad, SNA_C_ucSoundRelocationTable );
			sprintf(szFileName,"%s\\%s\\%s.snd",fn_szGetLevelsDataPath(),fn_p_szGetLevelName(),fn_p_szGetLevelName());
			SNA_fn_xReadOpenSoundTableFile(szFileName);
			SNA_fn_vReadAndUpdateSoundPointers(szFileName);

/* ANNECY OA - 12/07/99 { */
	/* Load dummy datas : for protections */
	SNA_M_LoadUnusedRelocationTable();	
/* END ANNECY OA } */
			
#ifdef D_USE_LIPSYNC
			if (bLipsSynchPresent)
				SNA_fn_vReadAndUpdateLipsSynchPointers();
#endif /* D_USE_LIPSYNC*/
 
 
			/**** Init all object when the player enter the map ****/
			SNA_fn_vSetLoadType(4);
			
#if (defined(USE_PROFILER) && !defined(PRESS_DEMO) && !defined(U64))
			GAM_fn_vRasterDumpInit ();
#endif

/* ANNECY MT - 30/03/99 { PC Protection */
#ifndef U64
			fn_vCopyProtectKeyToModels ();
#endif
/* END ANNECY MT } */

			fn_vInitAllObjectsWhenMapJustLoaded();
			
			/* Take care of the progress bar*/
			VIG_fn_vAddToProgressBar(1);
 
			CAM_fn_vInitCameras();

/* ANNECY OA - 16/07/99 { */
			SNA_g_dwNumberOfRelocationTableLoaded = PTC_fn_lGetRandom();
/* END ANNECY OA } */

/* ANNECY MT - 28/06/99 { */
			/* fn_vStartEngineClock(); */
/* END ANNECY MT } */
			
			fn_vInitDeadLoop();
			
			if ( g_stEngineStructure.eEngineMode==EM_ModeEnterLevel )
			{
				char cDoInit = 0;
				if( fn_bLoadLevelSaveGameAfterLoadLevel() )
				{
					SAI_fn_bInitAllWhen(SAI_eInitWhenLevelGameSavedLoaded);
					cDoInit = 1;
				}
				if( fn_bLoadPlayerSaveGameAfterLoadLevel() )
				{
					SAI_fn_bInitAllWhen(SAI_eInitWhenPlayerGameSavedLoaded);
					cDoInit = 1;
				}
 
				if( cDoInit )
					fn_vInitAllObjectsWhenSavedGameJustLoaded();
			}
			
			/*bart990105 :*/
			if (fn_bIsEngineInPause())
				fn_vChangeWindowTitle("Rayman II - pause");
			else
				fn_vChangeWindowTitle("Rayman II");
			SNA_fn_vSetLoadType(SNA_LOAD_SNAPSHOT);
		}
#ifndef RETAIL /* { */
		else if (SNA_fn_ucGetLoadType()==SNA_SAVE_SNAPSHOT)
		{
			/* Binarization of a level*/
			MC_tdxHandleToMainCharacterNode hMainCharNode;
			unsigned long i;
				
			SNA_fn_vSetSaveLoadLevel();
			
			/* Write level.snd*/
			sprintf(szFileName,"%s\\%s\\%s.snd",fn_szGetLevelsDataPath(),fn_p_szGetLevelName(),fn_p_szGetLevelName());
			SNA_fn_xWriteOpenSoundTableFile(szFileName);
			
#ifdef D_USE_LIPSYNC
			/* MR0912*/
			sprintf(szFileName,"%s\\%s\\%s.lsy",fn_szGetLevelsDataPath(),fn_p_szGetLevelName(),fn_p_szGetLevelName());
			SNA_fn_xWriteOpenLipsSynchTableFile(szFileName);
			/* Version hybride*/
			sprintf(szFileName,"%s\\%s\\%s.bls",fn_szGetLevelsDataPath(),fn_p_szGetLevelName(),fn_p_szGetLevelName());
			fn_vOpenWriteLipsSynchroBloc(szFileName);
#endif /*  D_USE_LIPSYNC*/
			
			fn_vStandardInitLevelLoop();
			GLI_vEndofGeometricLoad();
/* ANNECY OA - 04/08/99 { */
			fn_vCopyChecksumToModels();		  
/* END ANNECY OA } */
	
			/* Write level.sna*/
			SNA_fn_vWriteAllMemoryBlocks(szLevelSnapshotFilename);
			
			sprintf(szFileName,"%s\\%s\\%s.ptx",fn_szGetLevelsDataPath(),fn_p_szGetLevelName(),fn_p_szGetLevelName());
			TEX_SetNameOfBinaryFile((unsigned char *)szFileName);
			
			SNA_fn_vSetSaveLoadLevel();
	
			/* Open level.gpt*/
			sprintf(szFileName,"%s\\%s\\%s.gpt",fn_szGetLevelsDataPath(),fn_p_szGetLevelName(),fn_p_szGetLevelName());
			SNA_fn_xWriteOpenGlobalPointersFile(szFileName);
			
			/*//////*/
			/* Save some global pointers and structures*/
			/*//////*/
 
			/* Save Position of perso in Fix*/
			{
				unsigned long i;
				POS_tdstCompletePosition *p_stMatrix;
				HIE_tdxHandleToSuperObject h_SupObject;
				float fTransparenceLevel;
 
				SNA_fn_vWritePointerInGlobalPointersFile((unsigned long) SNA_g_stFixInfo.ulNbObject);
				
				for(i=0;i<SNA_g_stFixInfo.ulNbObject;i++)
				{
					SNA_fn_vWritePointerInGlobalPointersFile((unsigned long) SNA_g_stFixInfo.a20_stObjects[i]);
 
					if(!fn_ucIsAnAlwaysModel(SNA_g_stFixInfo.a20_stObjects[i]))
					{
						h_SupObject = fn_h_StandardGameGetSuperObject(SNA_g_stFixInfo.a20_stObjects[i]->h_StandardGame);
 
						SNA_fn_vWritePointerInGlobalPointersFile((unsigned long)h_SupObject);
 
						fTransparenceLevel = HIE_fn_fGetSuperObjectTransparenceLevel( h_SupObject );
						p_stMatrix=fn_p_st3dDataGetMatrix(SNA_g_stFixInfo.a20_stObjects[i]->h_3dData);
 
						SNA_fn_vWriteStructureInGlobalPointersFile((unsigned long *)p_stMatrix,sizeof(POS_tdstCompletePosition ));
						SNA_fn_vWritePointerInGlobalPointersFile( HIE_fn_SO_ulGetFlags(h_SupObject) );
						SNA_fn_vWriteStructureInGlobalPointersFile( &fTransparenceLevel, sizeof(float) );
						SNA_fn_vWritePointerInGlobalPointersFile( (unsigned long)LST2_M_DynamicGetNextElement( h_SupObject ) );
						SNA_fn_vWritePointerInGlobalPointersFile( (unsigned long)LST2_M_DynamicGetPrevElement( h_SupObject ) );
						SNA_fn_vWritePointerInGlobalPointersFile( (unsigned long)LST2_M_DynamicGetFather( h_SupObject ) );
					}
				}
			}	
			
			SNA_fn_vWritePointerInGlobalPointersFile((unsigned long) gp_stActualWorld);
			SNA_fn_vWritePointerInGlobalPointersFile((unsigned long) gp_stDynamicWorld);
			SNA_fn_vWritePointerInGlobalPointersFile((unsigned long) gp_stInactiveDynamicWorld);
			SNA_fn_vWritePointerInGlobalPointersFile((unsigned long) SECT_hFatherSector);
 
			SNA_fn_vWritePointerInGlobalPointersFile((unsigned long) gs_hFirstSubMapPosition);
 
			/* Always */
			/* Write global structure*/
			SNA_fn_vWriteStructureInGlobalPointersFile(&g_stAlways,sizeof(tdstAlways));
 
			SNA_fn_vWritePointerInGlobalPointersFile((unsigned long)HIE_M_hFirstChild( &(g_stAlways.ALW_h_LstAlwaysModel)));
			SNA_fn_vWritePointerInGlobalPointersFile((unsigned long)HIE_M_hLastChild( &(g_stAlways.ALW_h_LstAlwaysModel)));
 
			/* The always list model is both in fix memory and level memory,*/
			/* so we save the pointer that goes from fix to level...*/
			if( SNA_g_stFixInfo.h_LastAlwaysInTheFix != NULL )
			{
				SNA_fn_vWritePointerInGlobalPointersFile( (unsigned long) LST2_M_DynamicGetNextElement( SNA_g_stFixInfo.h_LastAlwaysInTheFix ));
			}
			else
			{
				SNA_fn_vWritePointerInGlobalPointersFile( (unsigned long) NULL );
			}
 
			if( SNA_g_stFixInfo.hLastFamilyTypeInTheFix != NULL )
				SNA_fn_vWritePointerInGlobalPointersFile( (unsigned long) LST2_M_DynamicGetNextElement( SNA_g_stFixInfo.hLastFamilyTypeInTheFix ));
			else
				SNA_fn_vWritePointerInGlobalPointersFile( (unsigned long) NULL );
 
			if( SNA_g_stFixInfo.hLastModelTypeInTheFix != NULL )
				SNA_fn_vWritePointerInGlobalPointersFile( (unsigned long) LST2_M_DynamicGetNextElement( SNA_g_stFixInfo.hLastModelTypeInTheFix ));
			else
				SNA_fn_vWritePointerInGlobalPointersFile( (unsigned long) NULL );
 
			if( SNA_g_stFixInfo.hLastPersonalTypeInTheFix != NULL )
				SNA_fn_vWritePointerInGlobalPointersFile( (unsigned long) LST2_M_DynamicGetNextElement( SNA_g_stFixInfo.hLastPersonalTypeInTheFix ));
			else
				SNA_fn_vWritePointerInGlobalPointersFile( (unsigned long) NULL );
 
			SNA_fn_vWriteStructureInGlobalPointersFile(&g_stObjectTypes,sizeof(tdstObjectType));
			
			SNA_fn_vWriteStructureInGlobalPointersFile(&g_stEngineStructure,sizeof(tdstEngineStructure));
			
			SNA_fn_vWritePointerInGlobalPointersFile((unsigned long) gp_stLight);
			
			hMainCharNode=LST2_M_DynamicGetFirstElement(&g_stEngineStructure.hMainCharacterList);
			SNA_fn_vWritePointerInGlobalPointersFile((unsigned long) hMainCharNode);
			
			SNA_fn_vWritePointerInGlobalPointersFile((unsigned long) g_hCharacterLauchingSoundEvents);
			
			SNA_fn_vWritePointerInGlobalPointersFile((unsigned long) g_hShadowPolygonVisualMaterial);
			SNA_fn_vWritePointerInGlobalPointersFile((unsigned long) g_hShadowPolygonGameMaterialInit);
			SNA_fn_vWritePointerInGlobalPointersFile((unsigned long) g_hShadowPolygonGameMaterial);
			SNA_fn_vWritePointerInGlobalPointersFile((unsigned long) g_p_stTextureOfTextureShadow);
			SNA_fn_vWritePointerInGlobalPointersFile((unsigned long) COL_g_d_lTaggedFacesTable);
			for (i=0;i<SHW_C_xNbMaxOfShadows;i++)
			{
				SNA_fn_vWritePointerInGlobalPointersFile((unsigned long) g_p_hHandleOfElementForShadow[i]);
				SNA_fn_vWritePointerInGlobalPointersFile((unsigned long) p_hHandleOfGeometricShadowObject[i]);
			}
 
	        SNA_fn_vWritePointerInGlobalPointersFile((unsigned long) g_hDemoSOList);
			SNA_fn_vWritePointerInGlobalPointersFile((unsigned long) g_hDemoGMTLevelList);
			/* Save stack infos for all stacks in anim player.*/
			SNA_fn_vWriteArrayWithoutPointerInGlobalPointersFile( tdstStacks, eStackNbMax, sizeof(tdstStackInfos) );
 
			{ 
				/**
				 * Now, save the LEVEL part of each stack. (from reset position to end of the stack)
				 *
				 * Most of these stacks are just datas (no pointer).
				 * BUT :
				 *  - They contains datas for both Fix and Level. 
				 *  - They are located in a block of the Fix
				 *  - We need to save their "Level part" in the Level.
				 * So they are saved in the global pointer file...
				 * 
				 * All the stacks are saved using SNA_fn_vWriteArrayWithoutPointerInGlobalPointersFile,
				 * except the one for Events that is saved using SNA_fn_vWriteArrayInGlobalPointersFile.
				 */
				unsigned long ulResetPos;
 
				ulResetPos = tdstStacks[eStackA3dGENERAL].ulResetPos;
				SNA_fn_vWriteArrayWithoutPointerInGlobalPointersFile( p_stA3dGENERAL+ulResetPos, (tdstStacks[eStackA3dGENERAL].ulStackPos-ulResetPos), sizeof(tdstA3dGENERAL) );
 
				ulResetPos = tdstStacks[eStackVertexes].ulResetPos;
				SNA_fn_vWriteArrayWithoutPointerInGlobalPointersFile( p_a3_xVectors+ulResetPos, (tdstStacks[eStackVertexes].ulStackPos-ulResetPos), sizeof(tdxVector3) );
 
				ulResetPos = tdstStacks[eStackQuaternions].ulResetPos;
				SNA_fn_vWriteArrayWithoutPointerInGlobalPointersFile( p_a4_xQuaternions+ulResetPos, (tdstStacks[eStackQuaternions].ulStackPos-ulResetPos), sizeof(tdxSShortQuater4) );
 
				ulResetPos = tdstStacks[eStackHierarchies].ulResetPos;
				SNA_fn_vWriteArrayWithoutPointerInGlobalPointersFile( p_stHierarchies+ulResetPos, (tdstStacks[eStackHierarchies].ulStackPos-ulResetPos), sizeof(tdstHierarchy) );
 
				ulResetPos = tdstStacks[eStackNTTO].ulResetPos;
				SNA_fn_vWriteArrayWithoutPointerInGlobalPointersFile( p_stNTTO+ulResetPos, (tdstStacks[eStackNTTO].ulStackPos-ulResetPos), sizeof(tdstNTTO) );
 
				ulResetPos = tdstStacks[eStackOnlyFrames].ulResetPos;
				SNA_fn_vWriteArrayWithoutPointerInGlobalPointersFile( p_stOnlyFrames+ulResetPos, (tdstStacks[eStackOnlyFrames].ulStackPos-ulResetPos), sizeof(tdstOnlyFrame) );
 
				ulResetPos = tdstStacks[eStackChannels].ulResetPos;
				SNA_fn_vWriteArrayWithoutPointerInGlobalPointersFile( p_stChannels+ulResetPos, (tdstStacks[eStackChannels].ulStackPos-ulResetPos), sizeof(tdstChannel) );
 
				ulResetPos = tdstStacks[eStackFrames].ulResetPos;
				SNA_fn_vWriteArrayWithoutPointerInGlobalPointersFile( p_stFrames+ulResetPos, (tdstStacks[eStackFrames].ulStackPos-ulResetPos), sizeof(tdstFrame) );
 
				ulResetPos = tdstStacks[eStackFramesKF].ulResetPos;
				SNA_fn_vWriteArrayWithoutPointerInGlobalPointersFile( p_stFramesKF+ulResetPos, (tdstStacks[eStackFramesKF].ulStackPos-ulResetPos), sizeof(tdstFrameKF) );
 
				ulResetPos = tdstStacks[eStackKeyFrames].ulResetPos;
				SNA_fn_vWriteArrayWithoutPointerInGlobalPointersFile( p_stKeyFrames+ulResetPos, (tdstStacks[eStackKeyFrames].ulStackPos-ulResetPos), sizeof(tdstKeyFrame) );
 
				ulResetPos = tdstStacks[eStackEvents].ulResetPos;
				SNA_fn_vWriteArrayInGlobalPointersFile( p_stEvents+ulResetPos, (tdstStacks[eStackEvents].ulStackPos-ulResetPos), sizeof(tdstEvent) );
 
				ulResetPos = tdstStacks[eStackMorphData].ulResetPos;
				SNA_fn_vWriteArrayWithoutPointerInGlobalPointersFile( p_stMorphData+ulResetPos, (tdstStacks[eStackMorphData].ulStackPos-ulResetPos), sizeof(tdstMorphData) );
 
			} /* End of stack save */
 
			SNA_fn_vWritePointerInGlobalPointersFile( (unsigned long)g_AlphabetCharacterPointer);

			SNA_fn_vCloseSoundTableFile();
#ifdef D_USE_LIPSYNC
			SNA_fn_vCloseLipsSynchTableFile();
			fn_vCloseWriteLipsSynchroBloc();
#endif /*  D_USE_LIPSYNC*/
			SNA_fn_vCloseGlobalPointersFile();
		}
#endif /* RETAIL } */

	}
	
#ifndef U64
#ifndef ACTIVE_EDITOR
	if (g_bDumpMemory)
		MMG_fn_vDumpMemory();
#ifdef _DEBUG
	if (g_bDreamcast)
		MDS_fn_vGenerateDCData(0, 1);
#endif /* _DEBUG */
#endif /* ACTIVE_EDITOR */
#endif /* U64 */

	if
		(
		g_stEngineStructure.eEngineMode==EM_ModeEnterLevel ||
		g_stEngineStructure.eEngineMode==EM_ModeEnterGame
		)
	{
		if( g_bBeginMapSoundEventFlag )
		{
			GAM_fn_lSaveBlockEventSlotMemory(g_stBeginMapSoundEvent.pstPtr,0);
			SND_fn_lSendRequestSound(SND_C_OBJET_FANTOME,g_lSoundObjectTypeMusic,g_stBeginMapSoundEvent,0,NULL);
		}
	}
	
	InitArrayOfDynamicFunction ( g_a_pfnDynamicFunction );
	
	IPT_fn_vResetInputEntry();
	
	PLA_fn_vInitHeaps();
 
	bFirst=FALSE;
	{
		char szFileName[_MAX_PATH];
		fn_zsGetActualLevelFilename(szFileName,VIG_C_ScriptPgbSuffixe);
		VIG_fn_vSaveProgressBarLevelInfo(&VIG_g_stActualVignette,szFileName);
		VIG_fn_vAddToProgressBar(1);
		VIG_fn_vRefreshActualVignette();
		VIG_fn_vFreeVignette(&VIG_g_stActualVignette);
	}
	
	/*
	* initialisation variable pour WaterPlane + sinus effect + global fog
	*/
	GLI_cGlobalFogIsOn = 0;
	GLI_vInitWaterplaneModule();
 
#ifndef U64
#ifndef RETAIL /* { */
	/* set mirror flag only in script*/
	if( SNA_fn_ucGetLoadType() != SNA_LOAD_SNAPSHOT )
		SCT_fn_vInitMirrorFlagForAllSectors(SECT_hFatherSector);
#endif /* RETAIL } */
#endif
 
	/* 
	 * when this is not the first level we loaded, some IPT actions might have been deactivated by the AIs of
	 * instances in the previous level -> we have to restore them.
	 */
	IPT_fn_vActivateAllEntryElements ( ) ;
	/* make sure that no button that the player keeps pressed right now will be marked as "Just Pressed" */
	IPT_fn_vReadInput ( ) ;
	IPT_fn_vReadInput ( ) ;

	g_hSOCurrentMainSector = NULL;
	g_hSOPreviousMainSector = NULL;
 
  AGO_vInit() ;

	/* once the level is loaded, the language definitions are known, hance we can select the current language from the ubi.ini file */
	{
		char szBuffer [ _MAX_PATH ] ;
		int j ;
		szBuffer [ 0 ] = 0 ;
		GAM_fn_vReadStringInUbiIniFile ( "RAYMAN2" , "Language" , _MAX_PATH, szBuffer ) ;
		j = 0 ;
		g_stEngineStructure . ucCurrentLanguage = 0 ;
		while ( j < g_stEngineStructure . ucNbLanguages ) 
		{
			if ( stricmp ( szBuffer , g_stEngineStructure . p_stLanguageTable [ j ] . szLanguageCode ) == 0 )
			{
				g_stEngineStructure . ucCurrentLanguage = ( unsigned char ) j ;
				break ;
			}
			j ++ ;
		}
	}
}
 
 
 
/*-----------------------------------------------------------------------------
 *  Description :   It is the desinitialization of the engine when map just ended
 *-----------------------------------------------------------------------------
 *  Input :
 *  Output :
 *-----------------------------------------------------------------------------
 *  Creation date : 27/08/96            Author : Francois
 *-----------------------------------------------------------------------------
 *  Modification date :                 Modification Author :
 *  Modifications : 03/04/98 Carlos Torres RAZ g_hLoadedSuperObjectRoot
 *  Modifications :
 *---------------------------------------------------------------------------*/
extern void fn_vLastDeinitMorphTaskList();
extern void GAM_fn_vRasterDumpDesInit ();
 
 void fn_vDesInitLevelLoop()
 {
 
	 /**** Initialize the Dead loop members ****/
	 fn_vDesInitDeadLoop();
 
	 /**** Stop the timer ****/
	 fn_vStopEngineClock();
 
	 SPO_ReinitSuperimposedArray();
 
	/**** Kill all level always ****/
	 fn_vKillAllAlwaysModel();
	 fn_vLastDesinitAlwaysStructure();
 
	 MGT_fn_vLastDesInitMagnet();
 
 	 PRF_fn_vReinitAllChrono ();
 
	 /* Stop the music:*/
	 SND_fn_vKillObjectSound2(SND_C_OBJET_FANTOME,g_lSoundObjectTypeMusic);
	 /* Reinit Doppler effect*/
	 SND_fn_vSetDopplerFactorSound(SND_C_NO_DOPPLER);
 
	 /**** Desinit all object's type structure ****/
#ifndef RETAIL /* { */
	 if (SNA_fn_ucGetLoadType()==SNA_LOAD_SCRIPT)
		 fn_vFreeAllObjectTypeForPriority(E_ucGameLevelMemory);
#endif /* RETAIL } */
 
	 fn_vDesinitFamilyStructureForPriority(E_ucGameLevelMemory);
 
	 /**** Free all super engine's objects ****/
	 fn_vDestroyAllHierarchy(gp_stActualWorld);
 
	 /* Erase the MorphList array. */
	 /* Have to do do it AFTER char desinit that can free some elements of the array.*/
	 fn_vLastDeinitMorphTaskList();
 
	 g_hLoadedSuperObjectRoot=NULL;
 
	 SND_fn_vKillAllObjectSound();
	 
#ifndef U64
	DEMO_fn_vDesInitLevel ();
#endif
	 /**** Free and delete non fixed memory*/
	 fn_vRemoveAllMicros();
	 fn_vFreeLevelAllowedMemory();
 
	 fn_vDeleteAllLevelReUsableSections();
 
	 LST2_M_DynamicInitAnchor(&g_stEngineStructure.hCameraList);
	 LST2_M_DynamicInitAnchor(&g_stEngineStructure.hMainCharacterList);
	 LST2_M_DynamicInitAnchor(&g_stEngineStructure.hAlwaysActiveCharactersList);
 
	 fn_vReputGameViewportCamera();
 
/* GuS : We don't use FixLvl pointers anymore...
	 if(SNA_fn_ucGetLoadType()==SNA_LOAD_SNAPSHOT)
	 {
		 SNA_fn_bDelocateMemoryBlocks();
	 }
*/
 
#if (defined(USE_PROFILER) && !defined(PRESS_DEMO) && !defined(U64))
	 GAM_fn_vRasterDumpDesInit ();
#endif
 }
 
 
void fn_vDesinitEngineWhenLeaveApplication(void)
{
	Mmg_fn_vStopMmgModule();
	MMG_fn_vDesinitMemoryRasterDeclaration ();
}


/* ANNECY MT - 30/03/99 { Pc Protection */

void fn_vInitAlwaysModelToProtection(long _lType)
{
	#if !defined(PRESS_DEMO)
	unsigned long i;
	ALW_tdxHandleToModelList   h_AlwaysModelChild;
/* ANNECY OA - 04/08/99 { */
	HIE_tdxHandleToSuperObject hCharacter;
/* END ANNECY OA } */
 

	LST2_M_DynamicForEachElementOf(&(g_stAlways.ALW_h_LstAlwaysModel),h_AlwaysModelChild,i)
	{
		tdstEngineObject *p_stObject = h_AlwaysModelChild->p_stAlwaysObject;
		MS_tdxHandleToStandardGame h_StdGame = p_stObject -> h_StandardGame;

		if (h_StdGame && (h_StdGame -> ulCustomBits & GAM_C_CustBitProtection))
		{
			AI_tdstMind *p_stMind;
			MS_tdxHandleToBrain h_Brain;
			static char cFastC = 1;
			struct AI_tdstAIModel_ *p_stAIModel;

			if((h_Brain = p_stObject -> h_Brain) == NULL )
				continue;
			if((p_stMind = M_pstGetMindOfBrain(h_Brain)) == NULL)
				continue;
			
			p_stAIModel = p_stMind->p_stAIModel;

/* ANNECY OA - 22/07/99 { */
//			if (p_stAIModel -> CFast_lFunction >= 0) // ASK: ???
			{				
				if (_lType == 0)
				{
					/* init values after binary loading */
					fn_vInitDesignerVariablesWithProtectKeyInModel (p_stMind);
					fn_vInitDesignerVariablesWithComputedDatas (p_stMind);
				}

#if defined(PTC_SYSTEM_ACTIVED) && !defined(RETAIL)
				else if (_lType == 1)
				{
					/* init values after script loading */
					fn_vInitDesignerVariablesWithChecksumInModel (p_stObject, p_stMind);
					fn_vInitDesignerVariablesWithCode (p_stObject, p_stMind);
				}
#endif	/* PTC_SYSTEM_ACTIVED && !RETAIL */
/* END ANNECY OA } */
			}
//			p_stAIModel -> CFast_lFunction = -1;
		}
	}

/* ANNECY OA - 30/07/99 { */
	HIE_M_ForEachChildOf(gp_stDynamicWorld,hCharacter,i)
	{
		tdstEngineObject *p_stObject = (tdstEngineObject *)HIE_fn_hGetSuperObjectObject(hCharacter);
		MS_tdxHandleToStandardGame h_StdGame = p_stObject -> h_StandardGame;

		if (h_StdGame && (h_StdGame -> ulCustomBits & GAM_C_CustBitProtection))
		{
			AI_tdstMind *p_stMind;
			MS_tdxHandleToBrain h_Brain;
			static char cFastC = 1;
			struct AI_tdstAIModel_ *p_stAIModel;

			if((h_Brain = p_stObject -> h_Brain) == NULL )
				continue;
			if((p_stMind = M_pstGetMindOfBrain(h_Brain)) == NULL)
				continue;
			
			p_stAIModel = p_stMind->p_stAIModel;

			{				
				if (_lType == 0)
				{
					/* Init values after binary loading */
					fn_vInitDesignerVariablesWithProtectKeyInModel (p_stMind);
					fn_vInitDesignerVariablesWithComputedDatas (p_stMind);
				}

#if defined(PTC_SYSTEM_ACTIVED) && !defined(RETAIL)
				else if (_lType == 1)
				{
					/* Init values after script loading */
					fn_vInitDesignerVariablesWithChecksumInModel (p_stObject, p_stMind);
					fn_vInitDesignerVariablesWithCode (p_stObject, p_stMind);
				}
#endif	/* PTC_SYSTEM_ACTIVED && !RETAIL */
			}
		}
	}
/* END ANNECY OA } */
#endif /* PRESS_DEMO */
}


void fn_vCopyProtectKeyToModels()
{
	#if !defined(PRESS_DEMO)
	DWORD i;

/* ANNECY OA - 04/08/99 { */
//	if (SNA_fn_bBigFileUsed ())
/* END ANNECY OA } */
	{
		fn_vInitAlwaysModelToProtection (0);
	}

/* ANNECY OA - 16/07/99 { */
	for(i = 0; i < SNA_g_dwNumberOfRelocationTableLoaded; ++i)
	{
		SNA_g_a_dwInitKeyRelocationTableLoaded[i] = PTC_fn_lGetRandom();
		SNA_g_a_dwProtectKeyRelocationTableLoaded[i] = PTC_fn_lGetRandom();
	}
/* END ANNECY OA } */
	#endif /* PRESS_DEMO */
}

void fn_vCopyChecksumToModels()
{
	#if !defined(PRESS_DEMO)
	fn_vInitAlwaysModelToProtection (1);
	#endif /* PRESS_DEMO */
}

/* END ANNECY MT } */

