aboutsummaryrefslogtreecommitdiff
path: root/sword2/save_rest.cpp
diff options
context:
space:
mode:
authorMax Horn2003-09-13 13:04:55 +0000
committerMax Horn2003-09-13 13:04:55 +0000
commitd2e56ed4a2b7464644ceafce7a8f3469c7425d4c (patch)
tree3460fc56da1ce77ee8a98aee1cadda1b5f760ada /sword2/save_rest.cpp
parent49f84b9c41520f8c858e1bac6a78ecca8751fd47 (diff)
downloadscummvm-rg350-d2e56ed4a2b7464644ceafce7a8f3469c7425d4c.tar.gz
scummvm-rg350-d2e56ed4a2b7464644ceafce7a8f3469c7425d4c.tar.bz2
scummvm-rg350-d2e56ed4a2b7464644ceafce7a8f3469c7425d4c.zip
endian conversion in save/restore code (may not be complete, beware!)
svn-id: r10223
Diffstat (limited to 'sword2/save_rest.cpp')
-rw-r--r--sword2/save_rest.cpp171
1 files changed, 119 insertions, 52 deletions
diff --git a/sword2/save_rest.cpp b/sword2/save_rest.cpp
index 4b041592c2..91955e9172 100644
--- a/sword2/save_rest.cpp
+++ b/sword2/save_rest.cpp
@@ -56,17 +56,17 @@
//------------------------------------------------------------------------------------
// local function prototypes
-void GetPlayerStructures(void); // James27feb97
-void PutPlayerStructures(void); // James27feb97
+static void GetPlayerStructures(void); // James27feb97
+static void PutPlayerStructures(void); // James27feb97
-uint32 SaveData(uint16 slotNo, uint8 *buffer, uint32 bufferSize);
-uint32 RestoreData(uint16 slotNo, uint8 *buffer, uint32 bufferSize);
+static uint32 SaveData(uint16 slotNo, uint8 *buffer, uint32 bufferSize);
+static uint32 RestoreData(uint16 slotNo, uint8 *buffer, uint32 bufferSize);
-uint32 CalcChecksum(uint8 *buffer, uint32 size); // James04aug97
+static uint32 CalcChecksum(uint8 *buffer, uint32 size); // James04aug97
//------------------------------------------------------------------------------------
-typedef struct // savegame file header (James06feb97)
+typedef struct // savegame file g_header (James06feb97)
{
uint32 checksum; // sum of all bytes in file, excluding this uint32
char description[SAVE_DESCRIPTION_LEN]; // player's description of savegame
@@ -83,9 +83,56 @@ typedef struct // savegame file header (James06feb97)
}
_savegameHeader;
-// savegame consists of header & global variables resource
+// savegame consists of g_header & global variables resource
-_savegameHeader header; // global because easier to copy to/from player object structures
+static _savegameHeader g_header; // global because easier to copy to/from player object structures
+
+#ifdef SCUMM_BIG_ENDIAN
+// Quick macro to make swapping in-place easier to write
+#define SWAP32_S(x) x = (int16)SWAP_BYTES_32(x)
+#define SWAP32_U(x) x = SWAP_BYTES_32(x)
+static void converHeaderEndian(_savegameHeader &header) {
+ int i;
+
+ // _savegameHeader
+ SWAP32_U(header.checksum);
+ SWAP32_U(header.varLength);
+ SWAP32_U(header.screenId);
+ SWAP32_U(header.runListId);
+ SWAP32_U(header.feet_x);
+ SWAP32_U(header.feet_y);
+ SWAP32_U(header.music_id);
+
+ // _object_hub
+ SWAP32_S(header.player_hub.type);
+ SWAP32_U(header.player_hub.logic_level);
+ for (i = 0; i < TREE_SIZE; i++) {
+ SWAP32_U(header.player_hub.logic[i]);
+ SWAP32_U(header.player_hub.script_id[i]);
+ SWAP32_U(header.player_hub.script_pc[i]);
+ }
+
+ // Object_logic
+ SWAP32_S(header.logic.looping);
+ SWAP32_S(header.logic.pause);
+
+ // Object_graphic
+ SWAP32_S(header.graphic.type);
+ SWAP32_S(header.graphic.anim_resource);
+ SWAP32_S(header.graphic.anim_pc);
+
+ // Object_mega
+ SWAP32_S(header.mega.currently_walking);
+ SWAP32_S(header.mega.walk_pc);
+ SWAP32_S(header.mega.scale_a);
+ SWAP32_S(header.mega.scale_b);
+ SWAP32_S(header.mega.feet_x);
+ SWAP32_S(header.mega.feet_y);
+ SWAP32_S(header.mega.current_dir);
+ SWAP32_S(header.mega.colliding);
+ SWAP32_S(header.mega.megaset_res);
+}
+#endif
//------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------
@@ -126,7 +173,7 @@ uint32 SaveGame(uint16 slotNo, uint8 *desc) // (James05feb97)
uint32 FindBufferSize( void )
{
- return (sizeof(header) + res_man.Res_fetch_len(1)); // size of savegame header + size of global variables
+ return (sizeof(g_header) + res_man.Res_fetch_len(1)); // size of savegame g_header + size of global variables
}
//------------------------------------------------------------------------------------
@@ -136,41 +183,51 @@ void FillSaveBuffer(mem *buffer, uint32 size, uint8 *desc)
uint8 *varsRes;
//------------------------------------------------------
- // set up the header
+ // set up the g_header
// 'checksum' gets filled in last of all
- sprintf(header.description, "%s", (char*)desc); // player's description of savegame
- header.varLength = res_man.Res_fetch_len(1); // length of global variables resource
- header.screenId = this_screen.background_layer_id; // resource id of current screen file
- header.runListId = LLogic.Return_run_list(); // resource id of current run-list
- header.feet_x = this_screen.feet_x; // those scroll position control things
- header.feet_y = this_screen.feet_y; //
- header.music_id = looping_music_id; // id of currently looping music (or zero)
+ sprintf(g_header.description, "%s", (char*)desc); // player's description of savegame
+ g_header.varLength = res_man.Res_fetch_len(1); // length of global variables resource
+ g_header.screenId = this_screen.background_layer_id; // resource id of current screen file
+ g_header.runListId = LLogic.Return_run_list(); // resource id of current run-list
+ g_header.feet_x = this_screen.feet_x; // those scroll position control things
+ g_header.feet_y = this_screen.feet_y; //
+ g_header.music_id = looping_music_id; // id of currently looping music (or zero)
// object hub
- memcpy (&header.player_hub, res_man.Res_open(CUR_PLAYER_ID) + sizeof(_standardHeader), sizeof(_object_hub));
+ memcpy (&g_header.player_hub, res_man.Res_open(CUR_PLAYER_ID) + sizeof(_standardHeader), sizeof(_object_hub));
res_man.Res_close(CUR_PLAYER_ID);
// logic, graphic & mega structures
- GetPlayerStructures(); // copy the 4 essential player object structures into the header
+ GetPlayerStructures(); // copy the 4 essential player object structures into the g_header
//------------------------------------------------------
- // copy the header to the buffer
+ // copy the g_header to the buffer
- memcpy( buffer->ad, &header, sizeof(header) ); // copy the header to the savegame buffer
+#ifdef SCUMM_BIG_ENDIAN
+ converHeaderEndian(g_header);
+#endif
+ memcpy( buffer->ad, &g_header, sizeof(g_header) ); // copy the g_header to the savegame buffer
//------------------------------------------------------
// copy the global variables to the buffer
varsRes = res_man.Res_open(1); // open variables resource
- memcpy( buffer->ad + sizeof(header), varsRes, header.varLength ); // copy that to the buffer, following the header
+ memcpy( buffer->ad + sizeof(g_header), varsRes, FROM_LE_32(g_header.varLength) ); // copy that to the buffer, following the g_header
+#ifdef SCUMM_BIG_ENDIAN
+ uint32 *globalVars = (uint32 *)(buffer->ad + sizeof(g_header));
+ const uint numVars = FROM_LE_32(g_header.varLength)/4;
+ for (uint i = 0; i < numVars; i++) {
+ globalVars[i] = SWAP_BYTES_32(globalVars[i]);
+ }
+#endif
res_man.Res_close(1); // close variables resource
//------------------------------------------------------
// set the checksum & copy that to the buffer (James05aug97)
- header.checksum = CalcChecksum((buffer->ad)+sizeof(header.checksum), size-sizeof(header.checksum));
- memcpy( buffer->ad, &header.checksum, sizeof(header.checksum) ); // copy the header to the savegame buffer
+ g_header.checksum = TO_LE_32(CalcChecksum((buffer->ad)+sizeof(g_header.checksum), size-sizeof(g_header.checksum)));
+ memcpy( buffer->ad, &g_header.checksum, sizeof(g_header.checksum) ); // copy the g_header to the savegame buffer
//------------------------------------------------------
}
@@ -289,12 +346,15 @@ uint32 RestoreFromBuffer(mem *buffer, uint32 size)
uint8 *varsRes;
int32 pars[2];
- memcpy( &header, buffer->ad, sizeof(header) ); // get a copy of the header from the savegame buffer
+ memcpy( &g_header, buffer->ad, sizeof(g_header) ); // get a copy of the g_header from the savegame buffer
+#ifdef SCUMM_BIG_ENDIAN
+ converHeaderEndian(g_header);
+#endif
//------------------------------------------------------
- // Calc checksum & check that aginst the value stored in the header (James05aug97)
+ // Calc checksum & check that aginst the value stored in the g_header (James05aug97)
- if (header.checksum != CalcChecksum((buffer->ad)+sizeof(header.checksum), size-sizeof(header.checksum)))
+ if (g_header.checksum != CalcChecksum((buffer->ad)+sizeof(g_header.checksum), size-sizeof(g_header.checksum)))
{
Free_mem( buffer );
return(SR_ERR_INCOMPATIBLE); // error: incompatible save-data - can't use!
@@ -305,7 +365,7 @@ uint32 RestoreFromBuffer(mem *buffer, uint32 size)
// Note that during development, earlier savegames will often be shorter than the current expected length
- if (header.varLength != res_man.Res_fetch_len(1)) // if header contradicts actual current size of global variables
+ if (g_header.varLength != res_man.Res_fetch_len(1)) // if g_header contradicts actual current size of global variables
{
Free_mem( buffer );
return(SR_ERR_INCOMPATIBLE); // error: incompatible save-data - can't use!
@@ -318,35 +378,42 @@ uint32 RestoreFromBuffer(mem *buffer, uint32 size)
//----------------------------------
// get player character data from savegame buffer
- // object hub is just after the standard header
- memcpy (res_man.Res_open(CUR_PLAYER_ID) + sizeof(_standardHeader), &header.player_hub, sizeof(_object_hub));
+ // object hub is just after the standard g_header
+ memcpy (res_man.Res_open(CUR_PLAYER_ID) + sizeof(_standardHeader), &g_header.player_hub, sizeof(_object_hub));
res_man.Res_close(CUR_PLAYER_ID);
- PutPlayerStructures(); // fill in the 4 essential player object structures from the header
+ PutPlayerStructures(); // fill in the 4 essential player object structures from the g_header
//----------------------------------
// get variables resource from the savegame buffer
varsRes = res_man.Res_open(1); // open variables resource
- memcpy( varsRes, buffer->ad + sizeof(header), header.varLength );// copy that to the buffer, following the header
+ memcpy( varsRes, buffer->ad + sizeof(g_header), g_header.varLength );// copy that to the buffer, following the g_header
+#ifdef SCUMM_BIG_ENDIAN
+ uint32 *globalVars = (uint32 *)varsRes;
+ const uint numVars = g_header.varLength/4;
+ for (uint i = 0; i < numVars; i++) {
+ globalVars[i] = SWAP_BYTES_32(globalVars[i]);
+ }
+#endif
res_man.Res_close(1); // close variables resource
Free_mem( buffer ); // free it now, rather than in RestoreGame, to unblock memory before new screen & runlist loaded
- pars[0] = header.screenId;
+ pars[0] = g_header.screenId;
pars[1] = 1;
FN_init_background(pars);
this_screen.new_palette=99; // (JEL08oct97) so palette not restored immediately after control panel - we want to fade up instead!
- this_screen.feet_x = header.feet_x; // these need setting after the defaults get set in FN_init_background
- this_screen.feet_y = header.feet_y; // remember that these can change through the game, so need saving & restoring too
- LLogic.Express_change_session(header.runListId); // start the new run list
+ this_screen.feet_x = g_header.feet_x; // these need setting after the defaults get set in FN_init_background
+ this_screen.feet_y = g_header.feet_y; // remember that these can change through the game, so need saving & restoring too
+ LLogic.Express_change_session(g_header.runListId); // start the new run list
//----------------------------------------------------------------------------
// (James01aug97)
// Force in the new scroll position, so unsightly scroll-catch-up does not occur
// when screen first draws after returning from restore panel
- this_screen.player_feet_x = header.mega.feet_x; // set 'this_screen's record of player position
- this_screen.player_feet_y = header.mega.feet_y; // - ready for Set_scrolling()
+ this_screen.player_feet_x = g_header.mega.feet_x; // set 'this_screen's record of player position
+ this_screen.player_feet_y = g_header.mega.feet_y; // - ready for Set_scrolling()
if (this_screen.scroll_flag) // if this screen is wide
Set_scrolling(); // recompute the scroll offsets now,
@@ -354,19 +421,19 @@ uint32 RestoreFromBuffer(mem *buffer, uint32 size)
//----------------------------------------------------------------------------
// Any music required will be started after we've returned from Restore_control()
// - see System_menu() in mouse.cpp!
- looping_music_id = header.music_id;
+ looping_music_id = g_header.music_id;
//------------------------------------------------------
//--------------------------------------
// Write to walkthrough file (zebug0.txt)
#ifdef _SWORD2_DEBUG
Zdebug(0,"*************************************");
- Zdebug(0,"RESTORED GAME \"%s\"", header.description);
+ Zdebug(0,"RESTORED GAME \"%s\"", g_header.description);
Zdebug(0,"*************************************");
// Also write this to system debug file
Zdebug("*************************************");
- Zdebug("RESTORED GAME \"%s\"", header.description);
+ Zdebug("RESTORED GAME \"%s\"", g_header.description);
Zdebug("*************************************");
#endif
//--------------------------------------
@@ -394,7 +461,7 @@ uint32 GetSaveDescription(uint16 slotNo, uint8 *description) // (James05feb97)
return(SR_ERR_FILEOPEN); // error: couldn't open file
- in->read(&dummy, sizeof(_savegameHeader)); // read header
+ in->read(&dummy, sizeof(_savegameHeader)); // read g_header
delete in;
delete mgr;
sprintf((char*)description, dummy.description);
@@ -445,7 +512,7 @@ void PutPlayerStructures(void) // James27feb97 (updated by James on 29july97)
null_pc=14; // script no. 14 - 'set_up_nico_anim_tables'
RunScript( raw_script_ad, raw_script_ad, &null_pc );
- switch (header.mega.megaset_res) // which megaset was the player at the time of saving?
+ switch (g_header.mega.megaset_res) // which megaset was the player at the time of saving?
{
case 36: // GeoMega:
null_pc=9; // script no.9 - 'player_is_george'
@@ -475,7 +542,7 @@ void PutPlayerStructures(void) // James27feb97 (updated by James on 29july97)
//------------------------------------------------------------------------------------
int32 FN_pass_player_savedata(int32 *params) // James27feb97
{
- // copies the 4 essential player structures into the savegame header
+ // copies the 4 essential player structures into the savegame g_header
// - run script 7 of player object to request this
// remember, we cannot simply read a compact any longer but instead must request it from the object itself
@@ -484,10 +551,10 @@ int32 FN_pass_player_savedata(int32 *params) // James27feb97
// 1 pointer to object's graphic structure
// 2 pointer to object's mega structure
- // copy from player object to savegame header
- memcpy( &header.logic, (uint8*)params[0], sizeof(Object_logic) );
- memcpy( &header.graphic, (uint8*)params[1], sizeof(Object_graphic) );
- memcpy( &header.mega, (uint8*)params[2], sizeof(Object_mega) );
+ // copy from player object to savegame g_header
+ memcpy( &g_header.logic, (uint8*)params[0], sizeof(Object_logic) );
+ memcpy( &g_header.graphic, (uint8*)params[1], sizeof(Object_graphic) );
+ memcpy( &g_header.mega, (uint8*)params[2], sizeof(Object_mega) );
return(IR_CONT); //makes no odds
}
@@ -508,10 +575,10 @@ int32 FN_get_player_savedata(int32 *params) // James27feb97
int32 pars[3];
- // copy from savegame header to player object
- memcpy( (uint8*)ob_logic, &header.logic, sizeof(Object_logic) );
- memcpy( (uint8*)ob_graphic, &header.graphic, sizeof(Object_graphic) );
- memcpy( (uint8*)ob_mega, &header.mega, sizeof(Object_mega) );
+ // copy from savegame g_header to player object
+ memcpy( (uint8*)ob_logic, &g_header.logic, sizeof(Object_logic) );
+ memcpy( (uint8*)ob_graphic, &g_header.graphic, sizeof(Object_graphic) );
+ memcpy( (uint8*)ob_mega, &g_header.mega, sizeof(Object_mega) );
// any walk-data must be cleared - the player will be set to stand if he was walking when saved