diff --git a/src/g_game.c b/src/g_game.c index 03a0fe7c..cbad5cab 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -99,7 +99,7 @@ #define SAVEGAMESIZE 0x20000 #define SAVESTRINGSIZE 24 -static size_t savegamesize = SAVEGAMESIZE; // killough +size_t savegamesize = SAVEGAMESIZE; // killough static char *demoname = NULL; // the original name of the demo, without "-00000" and file extension static char *demoname_orig = NULL; @@ -2311,16 +2311,6 @@ void G_SaveGame(int slot, char *description) sendsave = true; } -// Check for overrun and realloc if necessary -- Lee Killough 1/22/98 -void CheckSaveGame(size_t size) -{ - size_t pos = save_p - savebuffer; - size += 1024; // breathing room - if (pos+size > savegamesize) - save_p = (savebuffer = Z_Realloc(savebuffer, - savegamesize += (size+1023) & ~1023, PU_STATIC, 0)) + pos; -} - // killough 3/22/98: form savegame name in one location // (previously code was scattered around in multiple places) @@ -2412,7 +2402,7 @@ static void DoSaveGame(char *name) save_p = savebuffer = Z_Malloc(savegamesize, PU_STATIC, 0); - CheckSaveGame(SAVESTRINGSIZE+VERSIONSIZE+sizeof(uint64_t)); + saveg_buffer_size(SAVESTRINGSIZE + VERSIONSIZE); memcpy (save_p, description, SAVESTRINGSIZE); save_p += SAVESTRINGSIZE; memset (name2,0,sizeof(name2)); @@ -2424,14 +2414,14 @@ static void DoSaveGame(char *name) memcpy (save_p, name2, VERSIONSIZE); save_p += VERSIONSIZE; - *save_p++ = demo_version; + saveg_write8(demo_version); // killough 2/14/98: save old compatibility flag: - *save_p++ = compatibility; + saveg_write8(compatibility); - *save_p++ = gameskill; - *save_p++ = gameepisode; - *save_p++ = gamemap; + saveg_write8(gameskill); + saveg_write8(gameepisode); + saveg_write8(gamemap); { // killough 3/16/98, 12/98: store lump name checksum uint64_t checksum = G_Signature(gameepisode, gamemap); @@ -2444,29 +2434,28 @@ static void DoSaveGame(char *name) for (*save_p = 0, i = 0; i < array_size(wadfiles); i++) { const char *basename = M_BaseName(wadfiles[i]); - CheckSaveGame(strlen(basename)+2); + saveg_buffer_size(strlen(basename)+2); strcat(strcat((char *) save_p, basename), "\n"); } save_p += strlen((char *) save_p)+1; } - CheckSaveGame(G_GameOptionSize()+MIN_MAXPLAYERS+10); - for (i=0 ; i 0) memcpy(save_p, lumpinfo[musinfo.current_item].name, 8); else @@ -2490,11 +2478,10 @@ static void DoSaveGame(char *name) save_p += 8; // save max_kill_requirement - CheckSaveGame(sizeof(max_kill_requirement)); saveg_write32(max_kill_requirement); // [FG] save snapshot - CheckSaveGame(MN_SnapshotDataSize()); + saveg_buffer_size(MN_SnapshotDataSize()); MN_WriteSnapshot(save_p); save_p += MN_SnapshotDataSize(); diff --git a/src/p_saveg.c b/src/p_saveg.c index 0a71abf0..9cf4b22d 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -47,85 +47,9 @@ byte *save_p; saveg_compat_t saveg_compat = saveg_woof510; -// Endian-safe integer read/write functions - -byte saveg_read8(void) -{ - return *save_p++; -} - -void saveg_write8(byte value) -{ - *save_p++ = value; -} - -static short saveg_read16(void) -{ - int result; - - result = saveg_read8(); - result |= saveg_read8() << 8; - - return result; -} - -static void saveg_write16(short value) -{ - saveg_write8(value & 0xff); - saveg_write8((value >> 8) & 0xff); -} - -int saveg_read32(void) -{ - int result; - - result = saveg_read8(); - result |= saveg_read8() << 8; - result |= saveg_read8() << 16; - result |= saveg_read8() << 24; - - return result; -} - -void saveg_write32(int value) -{ - saveg_write8(value & 0xff); - saveg_write8((value >> 8) & 0xff); - saveg_write8((value >> 16) & 0xff); - saveg_write8((value >> 24) & 0xff); -} - -int64_t saveg_read64(void) -{ - int64_t result; - - result = (int64_t)(saveg_read8()); - result |= (int64_t)(saveg_read8()) << 8; - result |= (int64_t)(saveg_read8()) << 16; - result |= (int64_t)(saveg_read8()) << 24; - result |= (int64_t)(saveg_read8()) << 32; - result |= (int64_t)(saveg_read8()) << 40; - result |= (int64_t)(saveg_read8()) << 48; - result |= (int64_t)(saveg_read8()) << 56; - - return result; -} - -void saveg_write64(int64_t value) -{ - saveg_write8(value & 0xff); - saveg_write8((value >> 8) & 0xff); - saveg_write8((value >> 16) & 0xff); - saveg_write8((value >> 24) & 0xff); - saveg_write8((value >> 32) & 0xff); - saveg_write8((value >> 40) & 0xff); - saveg_write8((value >> 48) & 0xff); - saveg_write8((value >> 56) & 0xff); -} - // Pad to 4-byte boundaries -static void saveg_read_pad(void) +inline static void saveg_read_pad(void) { int padding; int i; @@ -138,28 +62,29 @@ static void saveg_read_pad(void) } } -static void saveg_write_pad(void) +inline static void saveg_write_pad(void) { int padding; int i; padding = (4 - ((intptr_t)save_p & 3)) & 3; + saveg_buffer_size(padding); for (i=0; ifloorheight + sizeof sec->ceilingheight - + sizeof(sec->floor_xoffs) + sizeof(sec->floor_yoffs) - + sizeof(sec->ceiling_xoffs) + sizeof(sec->ceiling_yoffs) - + sizeof(sec->ceiling_rotation) + sizeof(sec->floor_rotation)) * numsectors - + (sizeof(short) * 3 + sizeof(li->angle) + sizeof(li->frontmusic) - + sizeof(li->backmusic) + sizeof(short)) * numlines + 4; - - for (i=0; itextureoffset + sizeof si->rowoffset; - if (lines[i].sidenum[1] != NO_INDEX) - size += - sizeof(short)*3 + sizeof si->textureoffset + sizeof si->rowoffset; - } - - CheckSaveGame(size); // killough - saveg_write_pad(); // killough 3/22/98 // do sectors @@ -2282,7 +2184,7 @@ void P_ArchiveThinkers (void) size_t size = 0; mobj_t tmp; - CheckSaveGame(sizeof brain); // killough 3/26/98: Save boss brain state + // killough 3/26/98: Save boss brain state saveg_write32(brain.easy); saveg_write32(brain.targeton); @@ -2294,9 +2196,6 @@ void P_ArchiveThinkers (void) if (th->function.p1 == (actionf_p1)P_MobjThinker) th->prev = (thinker_t *) ++size; - // check that enough room is available in savegame buffer - CheckSaveGame(size*(sizeof(mobj_t)+4)); // killough 2/14/98 - // save off the current thinkers for (th = thinkercap.next ; th != &thinkercap ; th=th->next) @@ -2357,7 +2256,6 @@ void P_ArchiveThinkers (void) // killough 9/14/98: save soundtargets { int i; - CheckSaveGame(numsectors * sizeof(mobj_t *)); // killough 9/14/98 for (i = 0; i < numsectors; i++) { mobj_t *target = sectors[i].soundtarget; @@ -2560,46 +2458,6 @@ enum { void P_ArchiveSpecials (void) { thinker_t *th; - size_t size = 0; // killough - - // save off the current thinkers (memory size calculation -- killough) - - for (th = thinkercap.next ; th != &thinkercap ; th=th->next) - if (!th->function.v) - { - platlist_t *pl; - ceilinglist_t *cl; //jff 2/22/98 need this for ceilings too now - for (pl=activeplats; pl; pl=pl->next) - if (pl->plat == (plat_t *) th) // killough 2/14/98 - { - size += 4+sizeof(plat_t); - goto end; - } - for (cl=activeceilings; cl; cl=cl->next) // search for activeceiling - if (cl->ceiling == (ceiling_t *) th) //jff 2/22/98 - { - size += 4+sizeof(ceiling_t); - goto end; - } - end:; - } - else - size += - th->function.p1==(actionf_p1)T_MoveCeiling ? 4+sizeof(ceiling_t) : - th->function.p1==(actionf_p1)T_VerticalDoor ? 4+sizeof(vldoor_t) : - th->function.p1==(actionf_p1)T_MoveFloor ? 4+sizeof(floormove_t): - th->function.p1==(actionf_p1)T_PlatRaise ? 4+sizeof(plat_t) : - th->function.p1==(actionf_p1)T_LightFlash ? 4+sizeof(lightflash_t): - th->function.p1==(actionf_p1)T_StrobeFlash ? 4+sizeof(strobe_t) : - th->function.p1==(actionf_p1)T_Glow ? 4+sizeof(glow_t) : - th->function.p1==(actionf_p1)T_MoveElevator ? 4+sizeof(elevator_t): - th->function.p1==(actionf_p1)T_Scroll ? 4+sizeof(scroll_t) : - th->function.p1==(actionf_p1)T_Pusher ? 4+sizeof(pusher_t) : - th->function.p1==(actionf_p1)T_FireFlicker ? 4+sizeof(fireflicker_t) : - th->function.p1==(actionf_p1)T_Friction ? 4+sizeof(friction_t) : - 0; - - CheckSaveGame(size); // killough // save off the current thinkers for (th=thinkercap.next; th!=&thinkercap; th=th->next) @@ -2728,8 +2586,6 @@ void P_ArchiveSpecials (void) } } - CheckSaveGame(MAXBUTTONS * sizeof(button_t)); - for (int i = 0; i < MAXBUTTONS; i++) { if (buttonlist[i].btimer != 0) @@ -2915,7 +2771,6 @@ void P_UnArchiveSpecials (void) void P_ArchiveRNG(void) { - CheckSaveGame(sizeof rng); saveg_write_rng_t(&rng); } @@ -2927,10 +2782,6 @@ void P_UnArchiveRNG(void) // killough 2/22/98: Save/restore automap state void P_ArchiveMap(void) { - CheckSaveGame(sizeof followplayer + sizeof markpointnum + - markpointnum * sizeof *markpoints + - sizeof automapactive + sizeof viewactive); - saveg_write32(automapactive); saveg_write32(viewactive); saveg_write32(followplayer); diff --git a/src/p_saveg.h b/src/p_saveg.h index 6f08bdbb..091e0b5a 100644 --- a/src/p_saveg.h +++ b/src/p_saveg.h @@ -21,6 +21,7 @@ #define __P_SAVEG__ #include "doomtype.h" +#include "z_zone.h" // Persistent storage/archiving. // These are the load / save game routines. @@ -41,15 +42,112 @@ void P_UnArchiveRNG(void); void P_ArchiveMap(void); void P_UnArchiveMap(void); -extern byte *save_p; -void CheckSaveGame(size_t); // killough +extern byte *save_p, *savebuffer; +extern size_t savegamesize; -byte saveg_read8(void); -void saveg_write8(byte value); -int saveg_read32(void); -void saveg_write32(int value); -int64_t saveg_read64(void); -void saveg_write64(int64_t value); +// Check for overrun and realloc if necessary -- Lee Killough 1/22/98 +inline static void saveg_buffer_size(size_t size) +{ + size_t offset = save_p - savebuffer; + + if (offset + size <= savegamesize) + { + return; + } + + while (offset + size > savegamesize) + { + savegamesize *= 2; + } + + savebuffer = Z_Realloc(savebuffer, savegamesize, PU_STATIC, NULL); + save_p = savebuffer + offset; +} + +// Endian-safe integer read/write functions + +inline static void savep_putbyte(byte value) +{ + *save_p++ = value; +} + +inline static void saveg_write8(byte value) +{ + saveg_buffer_size(sizeof(byte)); + savep_putbyte(value); +} + +inline static void saveg_write16(short value) +{ + saveg_buffer_size(sizeof(int16_t)); + savep_putbyte(value & 0xff); + savep_putbyte((value >> 8) & 0xff); +} + +inline static void saveg_write32(int value) +{ + saveg_buffer_size(sizeof(int32_t)); + savep_putbyte(value & 0xff); + savep_putbyte((value >> 8) & 0xff); + savep_putbyte((value >> 16) & 0xff); + savep_putbyte((value >> 24) & 0xff); +} + +inline static void saveg_write64(int64_t value) +{ + saveg_buffer_size(sizeof(int64_t)); + savep_putbyte(value & 0xff); + savep_putbyte((value >> 8) & 0xff); + savep_putbyte((value >> 16) & 0xff); + savep_putbyte((value >> 24) & 0xff); + savep_putbyte((value >> 32) & 0xff); + savep_putbyte((value >> 40) & 0xff); + savep_putbyte((value >> 48) & 0xff); + savep_putbyte((value >> 56) & 0xff); +} + +inline static byte saveg_read8(void) +{ + return *save_p++; +} + +inline static short saveg_read16(void) +{ + int result; + + result = saveg_read8(); + result |= saveg_read8() << 8; + + return result; +} + +inline static int saveg_read32(void) +{ + int result; + + result = saveg_read8(); + result |= saveg_read8() << 8; + result |= saveg_read8() << 16; + result |= saveg_read8() << 24; + + return result; +} + +inline static int64_t saveg_read64(void) +{ + int64_t result; + + result = (int64_t)(saveg_read8()); + result |= (int64_t)(saveg_read8()) << 8; + result |= (int64_t)(saveg_read8()) << 16; + result |= (int64_t)(saveg_read8()) << 24; + result |= (int64_t)(saveg_read8()) << 32; + result |= (int64_t)(saveg_read8()) << 40; + result |= (int64_t)(saveg_read8()) << 48; + result |= (int64_t)(saveg_read8()) << 56; + + return result; +} typedef enum {