304 lines
10 KiB
C
304 lines
10 KiB
C
#include "SaiCPA.h"
|
|
#include "MmgSai.h"
|
|
#include "ErmSai.h"
|
|
#include "Sai_Enum.h"
|
|
#include "Sai_Pub.h"
|
|
#include "Sai_str.h"
|
|
#include "Sai_Priv.h"
|
|
#include "Sai_Save.h"
|
|
#include "cmp.h"
|
|
|
|
|
|
/* To avoid using compressed file in debug mode */
|
|
/* (uncompressed files are easier to view :-)*/
|
|
#ifdef _DEBUG
|
|
#undef SAVEGAME_COMPRESSION
|
|
#else
|
|
#define SAVEGAME_COMPRESSION
|
|
#endif
|
|
|
|
/**************************************************************************/
|
|
unsigned char SAI_fn_ucSaveAllGameTableValues(struct SAI_tdstInternalStructure_ *p_stInternalStructure,char *_szFileName,SAI_tdeFlags _eFlags)
|
|
{
|
|
unsigned char bReturn = SAI_TRUE;
|
|
SAI_tdxHandleToListEntry hListEntry = p_stInternalStructure -> p_stFirstEntry;
|
|
FILE *p_stTempFile;
|
|
|
|
#ifdef SAVEGAME_COMPRESSION
|
|
char szTempFile[_MAX_PATH];
|
|
|
|
sprintf(szTempFile,"%s/TT.tmp",fn_szGetTempDataPath());
|
|
|
|
DeleteFile(szTempFile);
|
|
FIL_fn_bValidatePath(".",_szFileName);
|
|
p_stTempFile = fopen(szTempFile,"wb");
|
|
#else /* SAVEGAME_COMPRESSION */
|
|
FIL_fn_bValidatePath(".",_szFileName);
|
|
p_stTempFile = fopen(_szFileName,"wb");
|
|
#endif /* SAVEGAME_COMPRESSION */
|
|
|
|
if (p_stTempFile!=NULL)
|
|
{
|
|
SAI_fn_vClearBooleanBuffer();
|
|
while (hListEntry)
|
|
{
|
|
if ((hListEntry->eFlags&(_eFlags)))
|
|
SAI_fn_ucSaveGameTableValue(hListEntry,p_stTempFile);
|
|
hListEntry = hListEntry -> p_stNextEntry;
|
|
}
|
|
SAI_fn_vFlushBooleanBuffer( p_stTempFile );
|
|
fclose(p_stTempFile);
|
|
|
|
#ifndef _DEBUG
|
|
CMP_fn_vCompressFileIn(szTempFile,_szFileName,D_CMP_DIFF);
|
|
#endif
|
|
|
|
}
|
|
else
|
|
bReturn = SAI_FALSE;
|
|
|
|
#ifdef SAVEGAME_COMPRESSION
|
|
DeleteFile(szTempFile);
|
|
#endif /* SAVEGAME_COMPRESSION */
|
|
|
|
return(bReturn);
|
|
}
|
|
/**************************************************************************/
|
|
unsigned char SAI_fn_ucSaveGameTableValue(SAI_tdxHandleToListEntry hListEntry,FILE *_p_stFile)
|
|
{
|
|
unsigned char bReturn = SAI_TRUE;
|
|
|
|
switch( hListEntry->eFlags & C_TypesFlags )
|
|
{
|
|
/* GuS : Save a boolean */
|
|
/* (WARNING: all boolean entries must be at the end of the list, no other data should be saved AFTER booleans,*/
|
|
/* More over, the list must be saved from the first element to the last one.)*/
|
|
case SAI_eType1:
|
|
if (hListEntry->eFlags&SAI_ePlayerSaveTableValue||hListEntry->eFlags&SAI_eLevelSaveTableValue)
|
|
SAI_fn_vSaveBoolean(
|
|
hListEntry->uData.stBooleanData.ucCharData,
|
|
hListEntry->uData.stBooleanData.ucBitPosition,
|
|
_p_stFile );
|
|
else if(hListEntry->eFlags&SAI_ePlayerSaveCurrentValue||hListEntry->eFlags&SAI_eLevelSaveCurrentValue)
|
|
SAI_fn_vSaveBoolean(
|
|
*(unsigned char *)hListEntry->p_vDataPointer,
|
|
hListEntry->uData.stBooleanData.ucBitPosition,
|
|
_p_stFile );
|
|
else
|
|
M_SAIFatalError(E_uwSAI_InvalidSaveMode);
|
|
break;
|
|
|
|
case SAI_eType8:
|
|
if (hListEntry->eFlags&SAI_ePlayerSaveTableValue||hListEntry->eFlags&SAI_eLevelSaveTableValue)
|
|
fwrite(&hListEntry->uData.ucCharData,1,sizeof(unsigned char),_p_stFile);
|
|
else if(hListEntry->eFlags&SAI_ePlayerSaveCurrentValue||hListEntry->eFlags&SAI_eLevelSaveCurrentValue)
|
|
fwrite(hListEntry->p_vDataPointer,1,sizeof(unsigned char),_p_stFile);
|
|
else
|
|
M_SAIFatalError(E_uwSAI_InvalidSaveMode);
|
|
break;
|
|
case SAI_eType16:
|
|
if (hListEntry->eFlags&SAI_ePlayerSaveTableValue||hListEntry->eFlags&SAI_eLevelSaveTableValue)
|
|
fwrite(&hListEntry->uData.uwShortData,1,sizeof(unsigned short),_p_stFile);
|
|
else if(hListEntry->eFlags&SAI_ePlayerSaveCurrentValue||hListEntry->eFlags&SAI_eLevelSaveCurrentValue)
|
|
fwrite(hListEntry->p_vDataPointer,1,sizeof(unsigned short),_p_stFile);
|
|
else
|
|
M_SAIFatalError(E_uwSAI_InvalidSaveMode);
|
|
break;
|
|
case SAI_eType32:
|
|
if (hListEntry->eFlags&SAI_ePlayerSaveTableValue||hListEntry->eFlags&SAI_eLevelSaveTableValue)
|
|
fwrite(&hListEntry->uData.ulLongData,1,sizeof(unsigned long),_p_stFile);
|
|
else if(hListEntry->eFlags&SAI_ePlayerSaveCurrentValue||hListEntry->eFlags&SAI_eLevelSaveCurrentValue)
|
|
fwrite(hListEntry->p_vDataPointer,1,sizeof(unsigned long),_p_stFile);
|
|
else
|
|
M_SAIFatalError(E_uwSAI_InvalidSaveMode);
|
|
break;
|
|
case SAI_eType64:
|
|
if (hListEntry->eFlags&SAI_ePlayerSaveTableValue||hListEntry->eFlags&SAI_eLevelSaveTableValue)
|
|
fwrite(&hListEntry->uData.i64Long64Data,1,sizeof(tdLong64),_p_stFile);
|
|
else if(hListEntry->eFlags&SAI_ePlayerSaveCurrentValue||hListEntry->eFlags&SAI_eLevelSaveCurrentValue)
|
|
fwrite(hListEntry->p_vDataPointer,1,sizeof(tdLong64),_p_stFile);
|
|
else
|
|
M_SAIFatalError(E_uwSAI_InvalidSaveMode);
|
|
break;
|
|
case SAI_eTypePointer:
|
|
if (hListEntry->eFlags&SAI_ePlayerSaveTableValue||hListEntry->eFlags&SAI_eLevelSaveTableValue)
|
|
{
|
|
fwrite(&hListEntry->uData.stPointerData.uwBlocAndModuleID,1,sizeof(unsigned short),_p_stFile);
|
|
fwrite(&hListEntry->uData.stPointerData.p_vPointer,1,sizeof(void *),_p_stFile);
|
|
}
|
|
else if(hListEntry->eFlags&SAI_ePlayerSaveCurrentValue||hListEntry->eFlags&SAI_eLevelSaveCurrentValue)
|
|
{
|
|
void *p_vBeginBloc;
|
|
unsigned short uwBlocId;
|
|
void *p_vPointer = (void*)(*((void**)hListEntry->p_vDataPointer));
|
|
if (p_vPointer!=NULL)
|
|
{
|
|
Mmg_fn_vWhereIs((void*)p_vPointer,&uwBlocId,&p_vBeginBloc);
|
|
if (uwBlocId==0xffff)
|
|
p_vPointer = (void*)p_vPointer;
|
|
else
|
|
p_vPointer = (void*)(((long)p_vPointer)-(long)p_vBeginBloc);
|
|
}
|
|
else
|
|
uwBlocId = 0xffff;
|
|
|
|
fwrite(&uwBlocId,1,sizeof(unsigned short),_p_stFile);
|
|
fwrite(&p_vPointer,1,sizeof(void *),_p_stFile);
|
|
}
|
|
else
|
|
M_SAIFatalError(E_uwSAI_InvalidSaveMode);
|
|
break;
|
|
case SAI_eTypeXX:
|
|
if (hListEntry->eFlags&SAI_ePlayerSaveTableValue||hListEntry->eFlags&SAI_eLevelSaveTableValue)
|
|
fwrite(hListEntry->uData.stArrayData.p_ucPointer,hListEntry->uData.stArrayData.ulArraySize,sizeof(unsigned char),_p_stFile);
|
|
else if(hListEntry->eFlags&SAI_ePlayerSaveCurrentValue||hListEntry->eFlags&SAI_eLevelSaveCurrentValue)
|
|
fwrite(hListEntry->p_vDataPointer,hListEntry->uData.stArrayData.ulArraySize,sizeof(unsigned char),_p_stFile);
|
|
else
|
|
M_SAIFatalError(E_uwSAI_InvalidSaveMode);
|
|
break;
|
|
default:
|
|
bReturn = SAI_FALSE;
|
|
break;
|
|
}
|
|
|
|
return(bReturn);
|
|
}
|
|
/**************************************************************************/
|
|
|
|
unsigned char SAI_fn_ucLoadGameTableValue( SAI_tdxHandleToListEntry hListEntry, FILE *_p_stFile )
|
|
{
|
|
unsigned char bReturn = SAI_TRUE;
|
|
if (!feof(_p_stFile))
|
|
{
|
|
switch( hListEntry->eFlags & C_TypesFlags )
|
|
{
|
|
case SAI_eType1:
|
|
hListEntry->uData.stBooleanData.ucCharData =
|
|
(unsigned char)(SAI_fn_cLoadBoolean( _p_stFile ) << hListEntry->uData.stBooleanData.ucBitPosition);
|
|
break;
|
|
case SAI_eType8:
|
|
fread(&hListEntry->uData.ucCharData,1,sizeof(hListEntry->uData.ucCharData),_p_stFile);
|
|
break;
|
|
case SAI_eType16:
|
|
fread(&hListEntry->uData.uwShortData,1,sizeof(hListEntry->uData.uwShortData),_p_stFile);
|
|
break;
|
|
case SAI_eType32:
|
|
fread(&hListEntry->uData.ulLongData,1,sizeof(hListEntry->uData.ulLongData),_p_stFile);
|
|
break;
|
|
case SAI_eType64:
|
|
fread(&hListEntry->uData.i64Long64Data,1,sizeof(hListEntry->uData.i64Long64Data),_p_stFile);
|
|
break;
|
|
case SAI_eTypePointer:
|
|
fread(&hListEntry->uData.stPointerData.uwBlocAndModuleID,1,sizeof(hListEntry->uData.stPointerData.uwBlocAndModuleID),_p_stFile);
|
|
fread(&hListEntry->uData.stPointerData.p_vPointer,1,sizeof(hListEntry->uData.stPointerData.p_vPointer),_p_stFile);
|
|
break;
|
|
case SAI_eTypeXX:
|
|
fread(hListEntry->uData.stArrayData.p_ucPointer,hListEntry->uData.stArrayData.ulArraySize,sizeof(*hListEntry->uData.stArrayData.p_ucPointer),_p_stFile);
|
|
break;
|
|
default:
|
|
bReturn = SAI_FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return(bReturn);
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
unsigned char SAI_fn_ucLoadAllGameTableValues(
|
|
struct SAI_tdstInternalStructure_ *p_stInternalStructure,
|
|
char *_szFileName,
|
|
SAI_tdeFlags _eFlags )
|
|
{
|
|
unsigned char bReturn = SAI_FALSE;
|
|
SAI_tdxHandleToListEntry hListEntry = p_stInternalStructure -> p_stFirstEntry;
|
|
FILE *p_stTempFile;
|
|
#ifdef SAVEGAME_COMPRESSION
|
|
char szTempFile[_MAX_PATH];
|
|
|
|
sprintf(szTempFile,"%s/TT.tmp",fn_szGetTempDataPath());
|
|
DeleteFile(szTempFile);
|
|
|
|
if (CMP_fn_bExpandFileIn(_szFileName,szTempFile,D_CMP_DIFF))
|
|
{
|
|
p_stTempFile = fopen(szTempFile,"rb");
|
|
#else /* SAVEGAME_COMPRESSION */
|
|
p_stTempFile = fopen(_szFileName,"rb");
|
|
#endif /* SAVEGAME_COMPRESSION */
|
|
if (p_stTempFile!=NULL)
|
|
{
|
|
SAI_fn_vClearBooleanBuffer();
|
|
while (hListEntry)
|
|
{
|
|
if( hListEntry->eFlags & _eFlags )
|
|
SAI_fn_ucLoadGameTableValue( hListEntry, p_stTempFile );
|
|
hListEntry = hListEntry -> p_stNextEntry;
|
|
}
|
|
fclose(p_stTempFile);
|
|
bReturn = SAI_TRUE;
|
|
}
|
|
|
|
#ifdef SAVEGAME_COMPRESSION
|
|
}
|
|
DeleteFile(szTempFile);
|
|
#endif
|
|
|
|
return(bReturn);
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/* GuS*/
|
|
/* To optimize saving of boolean data, all booleans are grouped by 8 in a char.*/
|
|
/* To achieve this, saving is bufferised into one char witch is written to file*/
|
|
/* only when it is full.*/
|
|
static unsigned char g_ucBooleanBuffer = 0;
|
|
static unsigned char g_ucCurrentPosition = 0; /* Next bit to be read or set (0..7)*/
|
|
|
|
void SAI_fn_vSaveBoolean( unsigned char _ucData, unsigned char _ucBitPosition, FILE *_p_stFile )
|
|
{
|
|
g_ucBooleanBuffer |= ((_ucData >> _ucBitPosition) & (unsigned char)1 ) << g_ucCurrentPosition;
|
|
g_ucCurrentPosition++;
|
|
|
|
if( g_ucCurrentPosition > 7 )
|
|
SAI_fn_vFlushBooleanBuffer( _p_stFile );
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
/* GuS*/
|
|
/* Function for reading boolean previously saved with SAI_fn_vSaveBoolean.*/
|
|
/* Return one boolean in the first (lowest) bit of a char.*/
|
|
/* Return -1 if end of file is reached.*/
|
|
char SAI_fn_cLoadBoolean( FILE *_p_stFile )
|
|
{
|
|
if( g_ucCurrentPosition == 0 || g_ucCurrentPosition > 7 )
|
|
{
|
|
if( fread( &g_ucBooleanBuffer, 1, sizeof(unsigned char), _p_stFile ) == 0 ) return -1;
|
|
g_ucCurrentPosition = 0;
|
|
}
|
|
|
|
return (unsigned char)((g_ucBooleanBuffer >> (g_ucCurrentPosition++)) & 1);
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
void SAI_fn_vClearBooleanBuffer()
|
|
{
|
|
g_ucBooleanBuffer = 0;
|
|
g_ucCurrentPosition = 0;
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
void SAI_fn_vFlushBooleanBuffer( FILE *_p_stFile )
|
|
{
|
|
if( g_ucCurrentPosition )
|
|
{
|
|
fwrite( &g_ucBooleanBuffer, 1, sizeof(unsigned char), _p_stFile );
|
|
g_ucBooleanBuffer = 0;
|
|
g_ucCurrentPosition = 0;
|
|
}
|
|
}
|
|
/**************************************************************************/
|