/*++ Read global game data from data files. --*/ static VOID PAL_ReadGlobalGameData(void) { const GAMEDATA *p = &gpGlobals->g; unsigned int i; LOAD_DATA(p->lprgScriptEntry, p->nScriptEntry * sizeof(SCRIPTENTRY), 4, gpGlobals->f.fpSSS); LOAD_DATA(p->lprgStore, p->nStore * sizeof(STORE), 0, gpGlobals->f.fpDATA); LOAD_DATA(p->lprgEnemy, p->nEnemy * sizeof(ENEMY), 1, gpGlobals->f.fpDATA); LOAD_DATA(p->lprgEnemyTeam, p->nEnemyTeam * sizeof(ENEMYTEAM), 2, gpGlobals->f.fpDATA); LOAD_DATA(p->lprgMagic, p->nMagic * sizeof(MAGIC), 4, gpGlobals->f.fpDATA); LOAD_DATA(p->lprgBattleField, p->nBattleField * sizeof(BATTLEFIELD), 5, gpGlobals->f.fpDATA); LOAD_DATA(p->lprgLevelUpMagic, p->nLevelUpMagic * sizeof(LEVELUPMAGIC_ALL), 6, gpGlobals->f.fpDATA); LOAD_DATA(p->rgwBattleEffectIndex, sizeof(p->rgwBattleEffectIndex), 11, gpGlobals->f.fpDATA); PAL_MKFReadChunk((LPBYTE)&(p->EnemyPos), sizeof(p->EnemyPos), 13, gpGlobals->f.fpDATA); DO_BYTESWAP(&(p->EnemyPos), sizeof(p->EnemyPos)); PAL_MKFReadChunk((LPBYTE)(p->rgLevelUpExp), sizeof(p->rgLevelUpExp), 14, gpGlobals->f.fpDATA); DO_BYTESWAP(p->rgLevelUpExp, sizeof(p->rgLevelUpExp)); }
/*++ Load the default game data. --*/ static VOID PAL_LoadDefaultGame(void) { const GAMEDATA *p = &gpGlobals->g; UINT32 i; // // Load the default data from the game data files. // LOAD_DATA(p->lprgEventObject, p->nEventObject * sizeof(EVENTOBJECT), 0, gpGlobals->f.fpSSS); PAL_MKFReadChunk((LPBYTE)(p->rgScene), sizeof(p->rgScene), 1, gpGlobals->f.fpSSS); DO_BYTESWAP(p->rgScene, sizeof(p->rgScene)); PAL_MKFReadChunk((LPBYTE)(p->rgObject), sizeof(p->rgObject), 2, gpGlobals->f.fpSSS); DO_BYTESWAP(p->rgObject, sizeof(p->rgObject)); PAL_MKFReadChunk((LPBYTE)(&(p->PlayerRoles)), sizeof(PLAYERROLES), 3, gpGlobals->f.fpDATA); DO_BYTESWAP(&(p->PlayerRoles), sizeof(PLAYERROLES)); // // Set some other default data. // gpGlobals->dwCash = 0; gpGlobals->wNumMusic = 0; gpGlobals->wNumPalette = 0; gpGlobals->wNumScene = 1; gpGlobals->wCollectValue = 0; gpGlobals->fNightPalette = FALSE; gpGlobals->wMaxPartyMemberIndex = 0; gpGlobals->viewport = PAL_XY(0, 0); gpGlobals->wLayer = 0; gpGlobals->wChaseRange = 1; #ifndef PAL_CLASSIC gpGlobals->bBattleSpeed = 2; #endif memset(gpGlobals->rgInventory, 0, sizeof(gpGlobals->rgInventory)); memset(gpGlobals->rgPoisonStatus, 0, sizeof(gpGlobals->rgPoisonStatus)); memset(gpGlobals->rgParty, 0, sizeof(gpGlobals->rgParty)); memset(gpGlobals->rgTrail, 0, sizeof(gpGlobals->rgTrail)); memset(&(gpGlobals->Exp), 0, sizeof(gpGlobals->Exp)); for (i = 0; i < MAX_PLAYER_ROLES; i++) { gpGlobals->Exp.rgPrimaryExp[i].wLevel = p->PlayerRoles.rgwLevel[i]; gpGlobals->Exp.rgHealthExp[i].wLevel = p->PlayerRoles.rgwLevel[i]; gpGlobals->Exp.rgMagicExp[i].wLevel = p->PlayerRoles.rgwLevel[i]; gpGlobals->Exp.rgAttackExp[i].wLevel = p->PlayerRoles.rgwLevel[i]; gpGlobals->Exp.rgMagicPowerExp[i].wLevel = p->PlayerRoles.rgwLevel[i]; gpGlobals->Exp.rgDefenseExp[i].wLevel = p->PlayerRoles.rgwLevel[i]; gpGlobals->Exp.rgDexterityExp[i].wLevel = p->PlayerRoles.rgwLevel[i]; gpGlobals->Exp.rgFleeExp[i].wLevel = p->PlayerRoles.rgwLevel[i]; } gpGlobals->fEnteringScene = TRUE; }
VOID PAL_SaveGame( LPCSTR szFileName, WORD wSavedTimes ) /*++ Purpose: Save the current game state to file. Parameters: [IN] szFileName - file name of saved game. Return value: None. --*/ { FILE *fp; static SAVEDGAME s; UINT32 i; // // Put all the data to the saved game struct. // s.wViewportX = PAL_X(gpGlobals->viewport); s.wViewportY = PAL_Y(gpGlobals->viewport); s.nPartyMember = gpGlobals->wMaxPartyMemberIndex; s.wNumScene = gpGlobals->wNumScene; s.wPaletteOffset = (gpGlobals->fNightPalette ? 0x180 : 0); s.wPartyDirection = gpGlobals->wPartyDirection; s.wNumMusic = gpGlobals->wNumMusic; s.wNumBattleMusic = gpGlobals->wNumBattleMusic; s.wNumBattleField = gpGlobals->wNumBattleField; s.wScreenWave = gpGlobals->wScreenWave; s.wCollectValue = gpGlobals->wCollectValue; s.wLayer = gpGlobals->wLayer; s.wChaseRange = gpGlobals->wChaseRange; s.wChasespeedChangeCycles = gpGlobals->wChasespeedChangeCycles; s.nFollower = gpGlobals->nFollower; s.dwCash = gpGlobals->dwCash; #ifndef PAL_CLASSIC s.wBattleSpeed = gpGlobals->bBattleSpeed; #else s.wBattleSpeed = 2; #endif memcpy(s.rgParty, gpGlobals->rgParty, sizeof(gpGlobals->rgParty)); memcpy(s.rgTrail, gpGlobals->rgTrail, sizeof(gpGlobals->rgTrail)); s.Exp = gpGlobals->Exp; s.PlayerRoles = gpGlobals->g.PlayerRoles; memcpy(s.rgPoisonStatus, gpGlobals->rgPoisonStatus, sizeof(gpGlobals->rgPoisonStatus)); memcpy(s.rgInventory, gpGlobals->rgInventory, sizeof(gpGlobals->rgInventory)); memcpy(s.rgScene, gpGlobals->g.rgScene, sizeof(gpGlobals->g.rgScene)); memcpy(s.rgObject, gpGlobals->g.rgObject, sizeof(gpGlobals->g.rgObject)); memcpy(s.rgEventObject, gpGlobals->g.lprgEventObject, sizeof(EVENTOBJECT) * gpGlobals->g.nEventObject); s.wSavedTimes = wSavedTimes; // // Adjust endianness // DO_BYTESWAP(&s, sizeof(SAVEDGAME)); // // Cash amount is in DWORD, so do a wordswap in Big-Endian. // #if SDL_BYTEORDER == SDL_BIG_ENDIAN s.dwCash = ((s.dwCash >> 16) | (s.dwCash << 16)); #endif // // Try writing to file // fp = fopen(szFileName, "wb"); if (fp == NULL) { return; } i = PAL_MKFGetChunkSize(0, gpGlobals->f.fpSSS); i += sizeof(SAVEDGAME) - sizeof(EVENTOBJECT) * MAX_EVENT_OBJECTS; fwrite(&s, i, 1, fp); fclose(fp); }
INT PAL_LoadSavedGame( LPCSTR szFileName ) /*++ Purpose: Load a saved game. Parameters: [IN] szFileName - file name of saved game. Return value: 0 if success, -1 if failed. --*/ { FILE *fp; static SAVEDGAME s; UINT32 i; // // Try to open the specified file // fp = fopen(szFileName, "rb"); if (fp == NULL) { return -1; } // // Read all data from the file and close. // fread(&s, sizeof(SAVEDGAME), 1, fp); fclose(fp); // // Adjust endianness // DO_BYTESWAP(&s, sizeof(SAVEDGAME)); // // Cash amount is in DWORD, so do a wordswap in Big-Endian. // #if SDL_BYTEORDER == SDL_BIG_ENDIAN s.dwCash = ((s.dwCash >> 16) | (s.dwCash << 16)); #endif // // Get all the data from the saved game struct. // gpGlobals->viewport = PAL_XY(s.wViewportX, s.wViewportY); gpGlobals->wMaxPartyMemberIndex = s.nPartyMember; gpGlobals->wNumScene = s.wNumScene; gpGlobals->fNightPalette = (s.wPaletteOffset != 0); gpGlobals->wPartyDirection = s.wPartyDirection; gpGlobals->wNumMusic = s.wNumMusic; gpGlobals->wNumBattleMusic = s.wNumBattleMusic; gpGlobals->wNumBattleField = s.wNumBattleField; gpGlobals->wScreenWave = s.wScreenWave; gpGlobals->sWaveProgression = 0; gpGlobals->wCollectValue = s.wCollectValue; gpGlobals->wLayer = s.wLayer; gpGlobals->wChaseRange = s.wChaseRange; gpGlobals->wChasespeedChangeCycles = s.wChasespeedChangeCycles; gpGlobals->nFollower = s.nFollower; gpGlobals->dwCash = s.dwCash; #ifndef PAL_CLASSIC gpGlobals->bBattleSpeed = s.wBattleSpeed; if (gpGlobals->bBattleSpeed > 5 || gpGlobals->bBattleSpeed == 0) { gpGlobals->bBattleSpeed = 2; } #endif memcpy(gpGlobals->rgParty, s.rgParty, sizeof(gpGlobals->rgParty)); memcpy(gpGlobals->rgTrail, s.rgTrail, sizeof(gpGlobals->rgTrail)); gpGlobals->Exp = s.Exp; gpGlobals->g.PlayerRoles = s.PlayerRoles; memset(gpGlobals->rgPoisonStatus, 0, sizeof(gpGlobals->rgPoisonStatus)); memcpy(gpGlobals->rgInventory, s.rgInventory, sizeof(gpGlobals->rgInventory)); memcpy(gpGlobals->g.rgScene, s.rgScene, sizeof(gpGlobals->g.rgScene)); memcpy(gpGlobals->g.rgObject, s.rgObject, sizeof(gpGlobals->g.rgObject)); memcpy(gpGlobals->g.lprgEventObject, s.rgEventObject, sizeof(EVENTOBJECT) * gpGlobals->g.nEventObject); gpGlobals->fEnteringScene = FALSE; PAL_CompressInventory(); // // Success // return 0; }