reman3/Rayman_X/cpa/tempgrp/SAI/P5/SAI_Save.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;
}
}
/**************************************************************************/