/*=========================================================================
* Memory.h : Contain the memory's functions.
*            (based on CAP memory (see Pierrick))
* This is a part of the Game project.
*
* To use memory, use M_p_GameMalloc and M_GameFree macros
*
* Version              1.0
* Creation date        30/08/96
* Revision date
*
* That file needs to be compatible for all platforms.
*
* (c) Ubi Studios 1996
*=======================================================================*/
 
/*#define GAM_D_DebugMalloc*/
/*#define GAM_D_DebugStatistic*/
 
#include "ToolsCPA.h"
 
#include "Structur/ErrGame.h"
#include "Structur/MemGame.h"
#include "Structur/GameScpt.h"
#include "Structur/EngMode.h"
 
#include "Options/ActBlMal.h"
#include "LSMem.h"
 
#include "Basic.h"
#include "ZeMem.h"
 
/* XB 05/05/99 */
#include "TEX.H"
extern void INO_PrintUsedStaticMemory(void);
/* End XB 05/05/99 */

#ifdef GAM_USE_SNA
#include "sna.h"
#endif /* GAM_USE_SNA */
 
/*XB980825*/
#ifdef U64
extern unsigned long g_ulTotalMemoryUsed;
extern unsigned long g_ulTotalMemoryAllocated;
#endif /* U64 */
/*End XB*/
 
/**************************************************************************/
void fn_vFirstInitGameMemory(void)
{
	/**** Check the ACP memory module ****/
	Mmg_M_InitMmg(Game);
	Mmg_fn_cCheckAlignmentValidity();
}
/**************************************************************************/

#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC 04/06/99 */
void fn_vLastDesinitGameMemory(void)
{
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC 04/06/99 */

/**************************************************************************/
void GAM_fn_vSetGameMemoryInFix(void)
{
	GAM_g_ucHLMMemoryBlock  = (unsigned char)E_ucGameFixMemory;
}
/**************************************************************************/
void GAM_fn_vSetGameMemoryInLevel(void)
{
	GAM_g_ucHLMMemoryBlock  = (unsigned char)E_ucGameLevelMemory;
}
/**************************************************************************/
#if defined (GAM_D_DebugMalloc)
/*unsigned long g_ulNumberOfAllocation;*/
#endif /* GAM_D_DebugMalloc */
 
#define GAM_C_NumberOfSource 200
 
#if defined(_DEBUG)&&(defined(GAM_D_DebugStatistic)||defined(GAM_D_DebugMalloc))
unsigned long GAM_g_ulNumberOfAllocation = 0;
#endif /* _DEBUG&&(GAM_D_DebugStatistic||GAM_D_DebugMalloc) */
 
#if defined(_DEBUG)&&defined(GAM_D_DebugStatistic)
unsigned long GAM_g_ulMaxSources = 0;
struct GAM_tdstAllocInformation_
{
	char szSourceName[_MAX_PATH];
	unsigned long ulSourceLine;
	unsigned short usSourceBloc;
	unsigned long ulSourceSize;
	unsigned long ulSourceNumberOfAlloc;
	unsigned long ulSourceNumberOfRealloc;
	unsigned long ulSourceNumberOfFree;
} GAM_g_a_stAllocInformation[GAM_C_NumberOfSource];
#endif /*_DEBUG&&GAM_D_DebugStatistic*/
 
void GAM_fn_vMemoryLogFile(void *p_vPointer,unsigned char ucAction,char *szFile,unsigned long ulLine,unsigned long ulSize)
{
#if defined(_DEBUG)&&(defined(GAM_D_DebugStatistic)||defined(GAM_D_DebugMalloc))
	/* static unsigned long GAM_s_ulNumberOfAllocation = 0;*/
	unsigned short uwBlocId;
	void *p_vBeginBloc;
#endif /* _DEBUG&&(GAM_D_DebugStatistic||GAM_D_DebugMalloc) */
	
#if defined(_DEBUG)&&defined(GAM_D_DebugStatistic)
	unsigned long i;
#endif /*_DEBUG&&GAM_D_DebugStatistic*/
	
#if defined(_DEBUG)&& defined(GAM_D_DebugMalloc)
	/* static unsigned long AI_s_ulNumberOfAllocation = 0;*/
	FILE *p_stFile;
	char szFileName[30];
#endif /* _DEBUG && GAM_D_DebugMalloc */
	
#if defined(_DEBUG)&&(defined(GAM_D_DebugStatistic)||defined(GAM_D_DebugMalloc))
	Mmg_fn_vWhereIs((void*)p_vPointer,&uwBlocId,&p_vBeginBloc);
	
	if (ucAction==GAM_C_ActionMalloc) 
		GAM_g_ulNumberOfAllocation++;
	else if (ucAction==GAM_C_ActionFree) 
		GAM_g_ulNumberOfAllocation--;
#endif /* _DEBUG&&(GAM_D_DebugStatistic||GAM_D_DebugMalloc) */
	
#if defined(_DEBUG)&&defined(GAM_D_DebugStatistic)
	for (i=0;i<GAM_g_ulMaxSources&&(stricmp(szFile,GAM_g_a_stAllocInformation[i].szSourceName)||GAM_g_a_stAllocInformation[i].ulSourceLine!=ulLine||GAM_g_a_stAllocInformation[i].usSourceBloc!=uwBlocId);i++);
	if (i==GAM_g_ulMaxSources)
	{
		strcpy(GAM_g_a_stAllocInformation[i].szSourceName,szFile);
		GAM_g_a_stAllocInformation[i].ulSourceLine=ulLine;
		GAM_g_a_stAllocInformation[i].usSourceBloc = uwBlocId;
		GAM_g_a_stAllocInformation[i].ulSourceSize=0;
		GAM_g_a_stAllocInformation[i].ulSourceNumberOfAlloc=0;
		GAM_g_a_stAllocInformation[i].ulSourceNumberOfRealloc=0;
		GAM_g_a_stAllocInformation[i].ulSourceNumberOfFree=0;
		GAM_g_ulMaxSources++;
		if (GAM_g_ulMaxSources>=GAM_C_NumberOfSource)
			M_GameFatalError(E_uwGameIncreaseNumberOfSource);
	}
	
	if (ucAction==GAM_C_ActionMalloc)
	{
		GAM_g_a_stAllocInformation[i].ulSourceSize+=ulSize;
		GAM_g_a_stAllocInformation[i].ulSourceNumberOfAlloc++;
	}
	else if (ucAction==GAM_C_ActionRealloc)
	{
		GAM_g_a_stAllocInformation[i].ulSourceSize+=ulSize;
		GAM_g_a_stAllocInformation[i].ulSourceNumberOfRealloc++;
	}
	else if (ucAction==GAM_C_ActionFree)
	{
		GAM_g_a_stAllocInformation[i].ulSourceNumberOfFree++;
	}
#endif /*_DEBUG&&GAM_D_DebugStatistic*/
	
#if defined(_DEBUG)&&defined(GAM_D_DebugMalloc)
	sprintf(szFileName,"Mem%04x.log",uwBlocId);
	if ((p_stFile = fopen(szFileName,"rt"))!=NULL) 
		fclose(p_stFile);
	else
		GAM_g_ulNumberOfAllocation = 0;
	p_stFile = fopen(szFileName,"at");
	if (p_stFile!=NULL)
	{
		if (ucAction==GAM_C_ActionMalloc) 
			fprintf(p_stFile,"Malloc  : Number=#%010d, Block=#%04x, Offset=%p (%20s,%10d)\n",GAM_g_ulNumberOfAllocation,uwBlocId,(long)p_vPointer-(long)p_vBeginBloc,szFile,ulLine);
		else if (ucAction==GAM_C_ActionRealloc) 
			fprintf(p_stFile,"Realloc : Number=#%010d, Block=#%04x, Offset=%p (%20s,%10d)\n",GAM_g_ulNumberOfAllocation,uwBlocId,(long)p_vPointer-(long)p_vBeginBloc,szFile,ulLine);
		else if (ucAction==GAM_C_ActionFree) 
			fprintf(p_stFile,"Free    : Number=#%010d, Block=#%04x, Offset=%p (%20s,%10d)\n",GAM_g_ulNumberOfAllocation,uwBlocId,(long)p_vPointer-(long)p_vBeginBloc,szFile,ulLine);
		fclose(p_stFile);
	}
#endif /* _DEBUG && GAM_D_DebugMalloc */
}
/**************************************************************************/
#ifndef _FIRE_DEADCODE_U64_
int GAM_fn_vMemorySort(const void *elem1, const void *elem2)
{
#if defined(_DEBUG)&&defined(GAM_D_DebugStatistic)
	return(((struct GAM_tdstAllocInformation_*)elem2)->ulSourceSize-((struct GAM_tdstAllocInformation_*)elem1)->ulSourceSize);
#else 
	return(0);
#endif /*_DEBUG&&GAM_D_DebugStatistic*/
}
/**************************************************************************/
void GAM_fn_vPrintMemoryInformation(void)
{
#if defined(_DEBUG)&&defined(GAM_D_DebugStatistic)
	FILE *p_stFile;
	unsigned long i;
	
	qsort(GAM_g_a_stAllocInformation,GAM_g_ulMaxSources, sizeof(struct GAM_tdstAllocInformation_),GAM_fn_vMemorySort);
	
	if ((p_stFile = fopen("GamMemInfo.log","wt"))!=NULL)
	{
		for (i=0;i<GAM_g_ulMaxSources;i++)
		{
			fprintf(p_stFile,"%s (line %d, bloc %04x) :\n",GAM_g_a_stAllocInformation[i].szSourceName,GAM_g_a_stAllocInformation[i].ulSourceLine,GAM_g_a_stAllocInformation[i].usSourceBloc);
			fprintf(p_stFile,"   Number of allocations    : %d\n",GAM_g_a_stAllocInformation[i].ulSourceNumberOfAlloc);
			fprintf(p_stFile,"   Number of reallocations  : %d\n",GAM_g_a_stAllocInformation[i].ulSourceNumberOfRealloc);
			fprintf(p_stFile,"   Number of free           : %d\n",GAM_g_a_stAllocInformation[i].ulSourceNumberOfFree);
			fprintf(p_stFile,"   Total size of allocation : %d\n",GAM_g_a_stAllocInformation[i].ulSourceSize);
		}
		fprintf(p_stFile,"\nTotal number of allocation : %d\n",GAM_g_ulNumberOfAllocation);
	}
	fclose(p_stFile);
#endif /*_DEBUG&&GEO_D_DebugStatistic*/
}
#endif /* _FIRE_DEADCODE_U64_ */
/**************************************************************************/

#ifndef RETAIL
void *fnp_vGameDebugMallocInHLM(unsigned long ulSize,char *szFile,unsigned long ulLine)
{
	void *Var;
	Var = fnp_vGameMallocInHLM(ulSize);
	GAM_fn_vMemoryLogFile(Var,GAM_C_ActionMalloc,szFile,ulLine,ulSize);
	return(Var);
}
#endif

/**************************************************************************/
void *fnp_vGameMallocInHLM(unsigned long ulSize)
{
	void *p_vPointer = NULL;
#if defined(_DEBUG)
	static unsigned char HLM_ucDynamicAlloc = FALSE;
#endif
	
	/**** Check parameters ****/
	if (ulSize==0)
	{
		M_GameFatalError(E_uwGameGameMallocBadSize);
	}
	
	if (GAM_g_ucHLMMemoryBlock<E_ucFirstMemoryBlock||GAM_g_ucHLMMemoryBlock>E_ucLastMemoryBlock)
	{
		M_GameFatalError(E_uwGameGameMallocBadBlock);
	}
	
	Mmg_M_SetModeAlloc4Ch(Game,(unsigned char)GAM_g_ucHLMMemoryBlock,C_ucMmgDefaultChannel);
 
#if defined(U64) && !defined(FINAL_VERSION)
	g_ucModuleIdForDebug=2;
#endif
 
#if defined(_DEBUG)
	if (HLM_ucDynamicAlloc||(p_vPointer = Mmg_fn_p_vAlloc4Ch(ulSize,C_ucMmgDefaultChannel))==NULL)
	{
		if (!HLM_ucDynamicAlloc)
		{
			Erm_M_ClearLastError(C_ucErmDefaultChannel);
			M_GameWarningError(E_uwGameDebugDynamicAllocation);
			Erm_M_ClearLastError(C_ucErmDefaultChannel);
			HLM_ucDynamicAlloc = TRUE;
		}
		Mmg_M_SetModeAlloc4Ch(Game,E_ucDynamic,C_ucMmgDefaultChannel);
		if ((p_vPointer = Mmg_fn_p_vAlloc4Ch(ulSize,C_ucMmgDefaultChannel))==NULL)
		{
			M_GameFatalError(E_uwGameGameMallocAlloc);
		}
	}
#else /* _DEBUG */
	if( (p_vPointer = Mmg_fn_p_vAlloc4Ch(ulSize,C_ucMmgDefaultChannel)) == NULL )
		M_GameFatalError(E_uwGameGameMallocAlloc);
#endif /* _DEBUG */
 
#if defined(U64) && !defined(FINAL_VERSION)
	g_ucModuleIdForDebug=0xff;
#endif
	memset(p_vPointer,0,ulSize);
	
	return (p_vPointer);
}
/**************************************************************************/
void fn_vGameFreeInHLM(void *p_vPointer)
{
#if defined(_DEBUG)
	struct tdstBlockInfo_ stMyBlockInfo;
#endif /* _DEBUG */
	
	if (p_vPointer==NULL)
	{
		M_GameInformationError(E_uwGameGameFreeNullPointer);
		/*ANNECY CT 20/02/98{*/
		return;
		/*ENDANNECY CT}*/
	}
	
#if defined(_DEBUG)
/*	Mmg_fn_vTestMallocIntegrityAt(p_vPointer);*/
#endif /*_DEBUG*/
	
	Mmg_M_SetModeAlloc4Ch(Game,(unsigned char)GAM_g_ucHLMMemoryBlock,C_ucMmgDefaultChannel);
#if defined(_DEBUG)
	Mmg_fn_vGiveInformationBlock(Erm_M_ucGiveModuleId(Game),(unsigned char)GAM_g_ucHLMMemoryBlock,&stMyBlockInfo);
	if (p_vPointer<(void*)stMyBlockInfo.p_cBeginBlock||p_vPointer>(void*)stMyBlockInfo.p_cEndBlock) 
		Mmg_M_SetModeAlloc4Ch(Game,E_ucDynamic,C_ucMmgDefaultChannel);
#endif /* _DEBUG */
	Mmg_fn_vFree4Ch(p_vPointer,C_ucMmgDefaultChannel);
}
/**************************************************************************/
#ifndef _FIRE_DEADCODE_U64_
void fn_vFreeFixAllowedMemory(void)
{
	unsigned char i;
	
	for (i=E_ucFirstFixMemoryBlock;i<=E_ucLastFixMemoryBlock;i++)
	{
		Mmg_M_FreeBlock(Game,i);
		Mmg_M_DeleteBlock(Game,i);
	}
	GEO_xDeleteMemoryChannel(ACP_FixMemoryChannel);
	fn_vFreeAIFixMemory();
	fn_vDeleteAIFixMemory();
	TMP_fn_vFreeFixMemory();
	SAI_fn_vDeleteFixMemory();
}
#endif   /* _FIRE_DEADCODE_U64_ */
/**************************************************************************/
extern void SAI_fn_vFreeLevelMemory();
void fn_vFreeLevelAllowedMemory(void)
{
	
	unsigned char i;
	
/* XB 22/06/99 */
#ifndef U64
	GLI_TEX_vKillMemoryChannel(ACP_LevelMemoryChannel);
#endif /* U64 */
/* End XB 22/06/99 */

#if !defined(U64)
 
	if (SNA_fn_ucGetLoadType()==SNA_LOAD_SCRIPT)
	{
#endif /* U64 */
		for (i=E_ucFirstLevelMemoryBlock;i<=E_ucLastLevelMemoryBlock;i++)
		{
			Mmg_M_FreeBlock(Game,i);
			Mmg_M_DeleteBlock(Game,i);
		}
		GEO_xDeleteMemoryChannel(ACP_LevelMemoryChannel);
#if defined(U64)
		GEO_xDeleteMemoryChannel(ACP_U64_LevelMemoryChannel);
#endif /* U64 */
		
		fn_vFreeAILevelMemory();
		fn_vDeleteAILevelMemory();
 
		/* Free level saved values list and delete SAI level memory block*/
		SAI_fn_vDeleteLevelMemory();

#ifdef U64
		//XB 21 April 1999
		TMP_fn_vFreeLevelMemory();
#endif
		//End XB
#if !defined(U64)
	}
	else if( SNA_fn_ucGetLoadType() == SNA_LOAD_SNAPSHOT ) 
	{
		/* Here, we free the list of saved value for the level WITHOUT deleting SAI level memory block.*/
		SAI_fn_vFreeLevelMemory();
	}
/*
	else if (SNA_fn_ucGetLoadType()==SNA_LOAD_SNAPSHOT)
	{
		for (i=E_ucFirstLevelMemoryBlock;i<=E_ucLastLevelMemoryBlock;i++)
		{
			Mmg_M_FreeBlock(Game,i);
		}
		Mmg_M_FreeBlock(GEO,2);
		fn_vFreeAILevelMemory();
	}
*/
#endif /* U64 */
	
	/* MR0310*/
	/* else
	{
	for (i=E_ucFirstLevelMemoryBlock;i<=E_ucLastLevelMemoryBlock;i++)
	{
	if(i%2==1)
	Mmg_M_DeleteBlock(Game,i);
	}
}*/
 
	GEO_xSelectMemoryChannel(ACP_FixMemoryChannel);
	AI_fn_vAIUseFixMemory();
	GAM_fn_vSetGameMemoryInFix();
	
}
 
/**************************************************************************/
void fn_vGameTestMemory(void)
{
	/**** Test the integrity of all memory already allocated ****/
	Mmg_fn_vTestMalloc();
}
/**************************************************************************/
#if !defined(RETAIL) || defined(FINAL_VERSION_FOR_TESTERS)
void GAM_PrintUsedStaticMemory(void)
{
	Mmg_M_PrintUsedStaticMemoryInModule(Game);
}
#endif /* !defined(RETAIL) || defined(FINAL_VERSION_FOR_TESTERS) */
/**************************************************************************/
/*XB*/
#ifdef CHECK_MEMORY
void GAM_CheckMemory(void)
{
	Mmg_M_CheckMemory(Game);
}
#endif /* CHECK_MEMORY */
/*End XB*/
/**************************************************************************/
/* XB 02/06/99 */
#ifndef FINAL_VERSION
unsigned long GAM_fn_ulGetUsedStaticMemory(void)
{
	return Mmg_M_GetUsedStaticMemory(Game);
}
#endif /* FINAL_VERSION */
/* End XB 02/06/99 */
/**************************************************************************/
#if !defined(RETAIL) || defined(FINAL_VERSION_FOR_TESTERS)
void GAM_PrintAllUsedStaticMemory(void)
{
	/* MR0310 (anti-bug...)*/
#if !defined(U64)
/*	if (SNA_fn_ucGetLoadType()!=SNA_LOAD_SNAPSHOT)*/
	{
		AI_PrintUsedStaticMemory();
		/*BIN_fn_vPrintUsedStaticMemory();*/
#ifndef U64
		FON_PrintUsedStaticMemory();
#endif
		GAM_PrintUsedStaticMemory();
		GEO_PrintUsedStaticMemory();
		GLD_PrintUsedStaticMemory();
		IPT_PrintUsedStaticMemory();
		/* FBF {*/
		/* MNU_PrintUsedStaticMemory();*/
		/* FBF }*/
		POS_fn_vPrintUsedStaticMemory();
		RND_PrintUsedStaticMemory();
		SAI_PrintUsedStaticMemory();
		Scr_PrintUsedStaticMemory();
		SND_PrintUsedStaticMemory();
		TMP_PrintUsedStaticMemory();
	}
#else  /* U64 */
	g_ulTotalMemoryUsed=0;
	g_ulTotalMemoryAllocated=0;
	osSyncPrintf(("------------> GAM <------------\n"));
	GAM_PrintUsedStaticMemory();
	osSyncPrintf(("------------> GEO <------------\n"));
	GEO_PrintUsedStaticMemory();
	osSyncPrintf(("------------> AI  <------------\n"));
	AI_PrintUsedStaticMemory();
	osSyncPrintf(("------------> INO <------------\n"));
	INO_PrintUsedStaticMemory();
	osSyncPrintf(("------------> IPT <------------\n"));
	IPT_PrintUsedStaticMemory();
	osSyncPrintf(("------------> FON <------------\n"));
	FON_PrintUsedStaticMemory();
	osSyncPrintf(("------------> SAI <------------\n"));
	SAI_PrintUsedStaticMemory();
	osSyncPrintf(("------------> RND <------------\n"));
	RND_PrintUsedStaticMemory();
	osSyncPrintf(("------------> TMP <------------\n"));
	TMP_PrintUsedStaticMemory();
	osSyncPrintf(("------------> SND <------------\n"));
	SND_PrintUsedStaticMemory();
	osSyncPrintf("--> Total = %ld bytes used / %ld bytes allocated (lost %ld bytes)\n",
								g_ulTotalMemoryUsed,
								g_ulTotalMemoryAllocated,
								g_ulTotalMemoryAllocated-g_ulTotalMemoryUsed);
	LDR_fn_vPrintMemoryMapping();
#endif /*U64 */
}
#endif /* !defined(RETAIL) || defined(FINAL_VERSION_FOR_TESTERS) */
/**************************************************************************/
#if !defined(U64) && !defined(RETAIL)
/* Modif GuS 08/08/98 : binarisation des scripts.*/
SCR_tde_Anl_ReturnValue fn_eScriptCallBackMemoryDescription(SCR_tdst_File_Description *_p_stFile,char *_p_szName,char *_ap_szParams[],SCR_tde_Anl_Action	_eAction)
{
	SCR_tde_Anl_ReturnValue eReturnValue = SCR_ERV_Anl_NormalReturn;
	static int iFirst=0;
	static void *vTab[50];
	static short wNbMalloc=0;
	_p_stFile=_p_stFile;
	
    if ( M_IsTitle )
        if ( SNA_M_bTestSaveGameMemDesc() )
            SNA_fn_vWriteNoParamEntryToCurrentDscFile( SNA_C_ul_MemoryDescTitle );
 
	if (M_IsEntry)
	{
		if (M_ActionIs(C_Entry_GAM_FixMemory))
		{
			Mmg_M_InitBlock(Game,E_ucGameFixMemory,(unsigned long)fn_lAToI(_ap_szParams[0]));
			GAM_fn_vSetGameMemoryInFix();
 
            if ( SNA_M_bTestSaveGameMemDesc() )
                SNA_fn_vWriteLongEntryToCurrentDscFile ( SNA_C_ul_GAMFixMemory, (unsigned long)fn_lAToI(_ap_szParams[0]) );
		}
		else if (M_ActionIs(C_Entry_GAM_LevelMemory))
		{
			if((iFirst<2)||(SNA_fn_ucGetLoadType()==SNA_LOAD_SCRIPT))
				Mmg_M_InitBlock(Game,E_ucGameLevelMemory,(unsigned long)fn_lAToI(_ap_szParams[0]));
			if(iFirst>0)
				GAM_fn_vSetGameMemoryInLevel();
 
            if ( SNA_M_bTestSaveGameMemDesc() )
                SNA_fn_vWriteLongEntryToCurrentDscFile ( SNA_C_ul_GAMLevelMemory, (unsigned long)fn_lAToI(_ap_szParams[0]) );
		}
		else if (M_ActionIs(C_Entry_FontMemory))
		{
		 M_CheckScriptParamNumber(1);
			FON_fn_vFirstInitFONMemory((unsigned long)fn_lAToI(_ap_szParams[0]));
 
            if ( SNA_M_bTestSaveGameMemDesc() )
                SNA_fn_vWriteLongEntryToCurrentDscFile ( SNA_C_ul_FontMemory, (unsigned long)fn_lAToI(_ap_szParams[0]) );
		}
		else if (M_ActionIs(C_Entry_SAIFixMemory))
		{
			SAI_fn_vInitFixMemory((unsigned long)fn_lAToI(_ap_szParams[0]));
			SAI_fn_vSAIUseFixMemory();
 
            if ( SNA_M_bTestSaveGameMemDesc() )
                SNA_fn_vWriteLongEntryToCurrentDscFile ( SNA_C_ul_SAIFixMemory, (unsigned long)fn_lAToI(_ap_szParams[0]) );
		}
		else if (M_ActionIs(C_Entry_SAILevelMemory))
		{
			SAI_fn_vInitLevelMemory((unsigned long)fn_lAToI(_ap_szParams[0]));
			SAI_fn_vSAIUseLevelMemory();
 
            if ( SNA_M_bTestSaveGameMemDesc() )
                SNA_fn_vWriteLongEntryToCurrentDscFile ( SNA_C_ul_SAILevelMemory, (unsigned long)fn_lAToI(_ap_szParams[0]) );
		}
		else if (M_ActionIs(C_Entry_TMPFixMemory))
		{
			TMP_fn_vCreateFixMemory((unsigned long)fn_lAToI(_ap_szParams[0]));
            if ( SNA_M_bTestSaveGameMemDesc() )
                SNA_fn_vWriteLongEntryToCurrentDscFile ( SNA_C_ul_TMPFixMemory, (unsigned long)fn_lAToI(_ap_szParams[0]) );
		}
		else if (M_ActionIs(C_Entry_AIFixMemory))
		{
			fn_vInitAIFixMemory((unsigned long)fn_lAToI(_ap_szParams[0]));
			AI_fn_vAIUseFixMemory();
 
            if ( SNA_M_bTestSaveGameMemDesc() )
                SNA_fn_vWriteLongEntryToCurrentDscFile ( SNA_C_ul_AIFixMemory, (unsigned long)fn_lAToI(_ap_szParams[0]) );
		}
		else if (M_ActionIs(C_Entry_AIMemory))
		{
			if((iFirst<2)||(SNA_fn_ucGetLoadType()==SNA_LOAD_SCRIPT))
				fn_vInitAILevelMemory((unsigned long)fn_lAToI(_ap_szParams[0]));
			AI_fn_vAIUseLevelMemory();
 
            if ( SNA_M_bTestSaveGameMemDesc() )
                SNA_fn_vWriteLongEntryToCurrentDscFile ( SNA_C_ul_AILevelMemory, (unsigned long)fn_lAToI(_ap_szParams[0]) );
		}
		else if (M_ActionIs(C_Entry_ACPTextMemory))
		{
			GEO_xCreateMemoryChannel(0,(unsigned long)fn_lAToI(_ap_szParams[0]));
 
            if ( SNA_M_bTestSaveGameMemDesc() )
                SNA_fn_vWriteLongEntryToCurrentDscFile ( SNA_C_ul_ACPTextMemory, (unsigned long)fn_lAToI(_ap_szParams[0]) );
		}
		else if (M_ActionIs(C_Entry_ACPFixMemory))
		{
			GEO_xCreateMemoryChannel(ACP_FixMemoryChannel,(unsigned long)fn_lAToI(_ap_szParams[0]));
			GEO_xSelectMemoryChannel(ACP_FixMemoryChannel);
 
            if ( SNA_M_bTestSaveGameMemDesc() )
                SNA_fn_vWriteLongEntryToCurrentDscFile ( SNA_C_ul_ACPFixMemory, (unsigned long)fn_lAToI(_ap_szParams[0]) );
		}
		else if (M_ActionIs(C_Entry_ACPLevelMemory))
		{
			if((iFirst<2)||(SNA_fn_ucGetLoadType()==SNA_LOAD_SCRIPT))
				GEO_xCreateMemoryChannel(ACP_LevelMemoryChannel,(unsigned long)fn_lAToI(_ap_szParams[0]));
			if(iFirst>0)
				GEO_xSelectMemoryChannel(ACP_LevelMemoryChannel);
 
            if ( SNA_M_bTestSaveGameMemDesc() )
                SNA_fn_vWriteLongEntryToCurrentDscFile ( SNA_C_ul_ACPLevelMemory, (unsigned long)fn_lAToI(_ap_szParams[0]) );
		}
		else if (M_ActionIs(C_Entry_POSMemory))
		{
			POS_fn_vInitPosMemory((unsigned long)fn_lAToI(_ap_szParams[0]));
 
            if ( SNA_M_bTestSaveGameMemDesc() )
                SNA_fn_vWriteLongEntryToCurrentDscFile ( SNA_C_ul_PositionMemory, (unsigned long)fn_lAToI(_ap_szParams[0]) );
		}
		else if (M_ActionIs(C_Entry_ScriptMemory))
		{
			g_SCR_a9MemTable[fn_lAToI(_ap_szParams[0])] = fn_lAToI(_ap_szParams[1]);
			SCR_fn_v_Mem_InitWithMemLevel(g_SCR_a9MemTable);
 
            if ( SNA_M_bTestSaveGameMemDesc() )
            {
                SNA_fn_vWrite2LongEntryToCurrentDscFile
                 ( 
                    SNA_C_ul_ScriptMemory, 
                    (unsigned long)fn_lAToI(_ap_szParams[0]),
                    (unsigned long)fn_lAToI(_ap_szParams[1])
                 );
            }
		}
#ifdef D_USE_LIPSYNC
		else if (M_ActionIs(C_Entry_LipsSynchMemory))		/* MR0912*/
		{
			LSY_fn_vFirstInitLSYMemory((unsigned long)fn_lAToI(_ap_szParams[0]));
		}
#endif /*  D_USE_LIPSYNC*/
		else if (M_ActionIs(C_Entry_IPTMemory))
		{
			IPT_fn_vInitMemory((unsigned long)fn_lAToI(_ap_szParams[0]));
 
            if ( SNA_M_bTestSaveGameMemDesc() )
                SNA_fn_vWriteLongEntryToCurrentDscFile ( SNA_C_ul_IPTMemory, (unsigned long)fn_lAToI(_ap_szParams[0]) );
		}
		/* For BIN*/
		else if (M_ActionIs(C_Entry_UseMemorySnapshot))	/* MR0309*/
		{
			/*g_bMemorySnapshot=TRUE;*/
			/*SNA_fn_vSetLoadType(SNA_LOAD_SNAPSHOT);*/
			SNA_fn_vSetLoadType((unsigned char)fn_lAToI(_ap_szParams[0]));
		}  
		else if (M_ActionIs("Gap"))	/* MR0309*/
		{
			vTab[wNbMalloc]=malloc((unsigned long)atol(_ap_szParams[0]));
			wNbMalloc++;
		}
		/* For BIN End*/
		else
			M_GameInformationError(E_uwGameScriptCallBackDescriptionUnknownAction);
	}
	else if ( M_IsEnd )
	{
		int i;
		for(i=0;i<wNbMalloc;i++)
		{
			free(vTab[i]);
		}
		wNbMalloc=0;
		iFirst++;
		if( (iFirst>1)&&(SNA_fn_ucGetLoadType()==SNA_LOAD_SNAPSHOT) )
		{
			AI_fn_vAIUseLevelMemory();
			GEO_xSelectMemoryChannel(ACP_LevelMemoryChannel);
			GAM_fn_vSetGameMemoryInLevel();
		}
		
        if ( SNA_M_bTestSaveGameMemDesc() )
            SNA_fn_vWriteNoParamEntryToCurrentDscFile ( SNA_C_ulEndOfDescSection );
	}
	
	return(eReturnValue);
}
#endif /* U64 */
 
/**************************************************************************/
