Add functions to initialize savebuffer_t

g_demo.c is mostly unaltered because it is made of twigs.
This commit is contained in:
Sally Coolatta 2023-01-02 19:47:59 -05:00
parent 3dc5d019bc
commit aa4fd8ab13
8 changed files with 174 additions and 130 deletions

View file

@ -1141,29 +1141,26 @@ static boolean SV_ResendingSavegameToAnyone(void)
static void SV_SendSaveGame(INT32 node, boolean resending)
{
size_t length, compressedlen;
savebuffer_t save;
savebuffer_t save = {0};
UINT8 *compressedsave;
UINT8 *buffertosend;
// first save it in a malloced buffer
save.size = NETSAVEGAMESIZE;
save.buffer = (UINT8 *)malloc(save.size);
if (!save.buffer)
if (P_SaveBufferAlloc(&save, NETSAVEGAMESIZE) == false)
{
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for savegame\n"));
return;
}
// Leave room for the uncompressed length.
save.p = save.buffer + sizeof(UINT32);
save.end = save.buffer + save.size;
save.p += sizeof(UINT32);
P_SaveNetGame(&save, resending);
length = save.p - save.buffer;
if (length > NETSAVEGAMESIZE)
{
free(save.buffer);
P_SaveBufferFree(&save);
I_Error("Savegame buffer overrun");
}
@ -1180,7 +1177,7 @@ static void SV_SendSaveGame(INT32 node, boolean resending)
if ((compressedlen = lzf_compress(save.buffer + sizeof(UINT32), length - sizeof(UINT32), compressedsave + sizeof(UINT32), length - sizeof(UINT32) - 1)))
{
// Compressing succeeded; send compressed data
free(save.buffer);
P_SaveBufferFree(&save);
// State that we're compressed.
buffertosend = compressedsave;
@ -1211,7 +1208,7 @@ static consvar_t cv_dumpconsistency = CVAR_INIT ("dumpconsistency", "Off", CV_SA
static void SV_SavedGame(void)
{
size_t length;
savebuffer_t save;
savebuffer_t save = {0};
char tmpsave[256];
if (!cv_dumpconsistency.value)
@ -1220,22 +1217,18 @@ static void SV_SavedGame(void)
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
// first save it in a malloced buffer
save.size = NETSAVEGAMESIZE;
save.p = save.buffer = (UINT8 *)malloc(save.size);
if (!save.p)
if (P_SaveBufferAlloc(&save, NETSAVEGAMESIZE) == false)
{
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for savegame\n"));
return;
}
save.end = save.buffer + save.size;
P_SaveNetGame(&save, false);
length = save.p - save.buffer;
if (length > NETSAVEGAMESIZE)
{
free(save.buffer);
P_SaveBufferFree(&save);
I_Error("Savegame buffer overrun");
}
@ -1243,7 +1236,7 @@ static void SV_SavedGame(void)
if (!FIL_WriteFile(tmpsave, save.buffer, length))
CONS_Printf(M_GetText("Didn't save %s for netgame"), tmpsave);
free(save.buffer);
P_SaveBufferFree(&save);
}
#undef TMPSAVENAME
@ -1253,37 +1246,31 @@ static void SV_SavedGame(void)
static void CL_LoadReceivedSavegame(boolean reloading)
{
savebuffer_t save;
savebuffer_t save = {0};
size_t length, decompressedlen;
char tmpsave[256];
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
length = FIL_ReadFile(tmpsave, &save.buffer);
CONS_Printf(M_GetText("Loading savegame length %s\n"), sizeu1(length));
if (!length)
if (P_SaveBufferFromFile(&save, tmpsave) == false)
{
I_Error("Can't read savegame sent");
return;
}
save.p = save.buffer;
save.size = length;
save.end = save.buffer + save.size;
length = save.size;
CONS_Printf(M_GetText("Loading savegame length %s\n"), sizeu1(length));
// Decompress saved game if necessary.
decompressedlen = READUINT32(save.p);
if(decompressedlen > 0)
if (decompressedlen > 0)
{
UINT8 *decompressedbuffer = Z_Malloc(decompressedlen, PU_STATIC, NULL);
lzf_decompress(save.p, length - sizeof(UINT32), decompressedbuffer, decompressedlen);
Z_Free(save.buffer);
save.p = save.buffer = decompressedbuffer;
save.size = decompressedlen;
save.end = save.buffer + decompressedlen;
P_SaveBufferFree(&save);
P_SaveBufferFromExisting(&save, decompressedbuffer, decompressedlen);
}
paused = false;
@ -1315,10 +1302,13 @@ static void CL_LoadReceivedSavegame(boolean reloading)
}
// done
Z_Free(save.buffer);
save.p = NULL;
P_SaveBufferFree(&save);
if (unlink(tmpsave) == -1)
{
CONS_Alert(CONS_ERROR, M_GetText("Can't delete %s\n"), tmpsave);
}
consistancy[gametic%BACKUPTICS] = Consistancy();
CON_ToggleOff();
@ -6067,7 +6057,7 @@ void CL_ClearRewinds(void)
rewind_t *CL_SaveRewindPoint(size_t demopos)
{
savebuffer_t save;
savebuffer_t save = {0};
rewind_t *rewind;
if (rewindhead && rewindhead->leveltime + REWIND_POINT_INTERVAL > leveltime)
@ -6077,10 +6067,7 @@ rewind_t *CL_SaveRewindPoint(size_t demopos)
if (!rewind)
return NULL;
save.buffer = save.p = rewind->savebuffer;
save.size = NETSAVEGAMESIZE;
save.end = save.buffer + save.size;
P_SaveBufferFromExisting(&save, rewind->savebuffer, NETSAVEGAMESIZE);
P_SaveNetGame(&save, false);
rewind->leveltime = leveltime;
@ -6093,7 +6080,7 @@ rewind_t *CL_SaveRewindPoint(size_t demopos)
rewind_t *CL_RewindToTime(tic_t time)
{
savebuffer_t save;
savebuffer_t save = {0};
rewind_t *rewind;
while (rewindhead && rewindhead->leveltime > time)
@ -6106,10 +6093,7 @@ rewind_t *CL_RewindToTime(tic_t time)
if (!rewindhead)
return NULL;
save.buffer = save.p = rewindhead->savebuffer;
save.size = NETSAVEGAMESIZE;
save.end = save.buffer + save.size;
P_SaveBufferFromExisting(&save, rewindhead->savebuffer, NETSAVEGAMESIZE);
P_LoadNetGame(&save, false);
wipegamestate = gamestate; // No fading back in!

View file

@ -5778,7 +5778,7 @@ static void Command_Togglemodified_f(void)
static void Command_Archivetest_f(void)
{
savebuffer_t save;
savebuffer_t save = {0};
UINT32 i, wrote;
thinker_t *th;
if (gamestate != GS_LEVEL)
@ -5794,9 +5794,11 @@ static void Command_Archivetest_f(void)
((mobj_t *)th)->mobjnum = i++;
// allocate buffer
save.size = 1024;
save.buffer = save.p = ZZ_Alloc(save.size);
save.end = save.buffer + save.size;
if (P_SaveBufferAlloc(&save, 1024) == false)
{
CONS_Printf("Unable to allocate buffer.\n");
return;
}
// test archive
CONS_Printf("LUA_Archive...\n");
@ -5814,10 +5816,12 @@ static void Command_Archivetest_f(void)
LUA_UnArchive(&save, true);
i = READUINT8(save.p);
if (i != 0x7F || wrote != (UINT32)(save.p - save.buffer))
{
CONS_Printf("Savegame corrupted. (write %u, read %u)\n", wrote, (UINT32)(save.p - save.buffer));
}
// free buffer
Z_Free(save.buffer);
P_SaveBufferFree(&save);
CONS_Printf("Done. No crash.\n");
}
#endif

View file

@ -70,7 +70,7 @@ boolean noblit; // for comparative timing purposes
tic_t demostarttime; // for comparative timing purposes
static char demoname[MAX_WADPATH];
static savebuffer_t demobuf;
static savebuffer_t demobuf = {0};
static UINT8 *demotime_p, *demoinfo_p;
static UINT8 demoflags;
boolean demosynced = true; // console warning message
@ -2019,10 +2019,8 @@ void G_RecordDemo(const char *name)
// if (demobuf.buffer)
// P_SaveBufferFree(&demobuf);
demobuf.size = maxsize;
demobuf.buffer = (UINT8 *)malloc(maxsize);
P_SaveBufferAlloc(&demobuf, maxsize);
demobuf.p = NULL;
demobuf.end = demobuf.buffer + demobuf.size;
demo.recording = true;
}
@ -2034,10 +2032,8 @@ void G_RecordMetal(void)
if (M_CheckParm("-maxdemo") && M_IsNextParm())
maxsize = atoi(M_GetNextParm()) * 1024;
demobuf.size = maxsize;
demobuf.buffer = (UINT8 *)malloc(maxsize);
P_SaveBufferAlloc(&demobuf, maxsize);
demobuf.p = NULL;
demobuf.end = demobuf.buffer + demobuf.size;
metalrecording = true;
}
@ -2982,7 +2978,7 @@ void G_DoPlayDemo(char *defdemoname)
if (FIL_CheckExtension(defdemoname))
{
//FIL_DefaultExtension(defdemoname, ".lmp");
if (!FIL_ReadFile(defdemoname, &demobuf.buffer))
if (P_SaveBufferFromFile(&demobuf, defdemoname) == false)
{
snprintf(msg, 1024, M_GetText("Failed to read file '%s'.\n"), defdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
@ -2990,20 +2986,20 @@ void G_DoPlayDemo(char *defdemoname)
M_StartMessage(msg, NULL, MM_NOTHING);
return;
}
demobuf.p = demobuf.buffer;
}
// load demo resource from WAD
else if ((l = W_CheckNumForName(defdemoname)) == LUMPERROR)
else
{
snprintf(msg, 1024, M_GetText("Failed to read lump '%s'.\n"), defdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
gameaction = ga_nothing;
M_StartMessage(msg, NULL, MM_NOTHING);
return;
}
else // it's an internal demo
{
demobuf.buffer = demobuf.p = W_CacheLumpNum(l, PU_STATIC);
if ((l = W_CheckNumForName(defdemoname)) == LUMPERROR)
{
snprintf(msg, 1024, M_GetText("Failed to read lump '%s'.\n"), defdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
gameaction = ga_nothing;
M_StartMessage(msg, NULL, MM_NOTHING);
return;
}
P_SaveBufferFromLump(&demobuf, l);
#if defined(SKIPERRORS) && !defined(DEVELOP)
skiperrors = true; // SRB2Kart: Don't print warnings for staff ghosts, since they'll inevitably happen when we make bugfixes/changes...
#endif
@ -3945,7 +3941,7 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill)
WriteDemoChecksum();
saved = FIL_WriteFile(va("%sMS.LMP", G_BuildMapName(gamemap)), demobuf.buffer, demobuf.p - demobuf.buffer); // finally output the file.
}
free(demobuf.buffer);
Z_Free(demobuf.buffer);
metalrecording = false;
if (saved)
I_Error("Saved to %sMS.LMP", G_BuildMapName(gamemap));
@ -4165,7 +4161,7 @@ void G_SaveDemo(void)
if (FIL_WriteFile(demoname, demobuf.buffer, demobuf.p - demobuf.buffer)) // finally output the file.
demo.savemode = DSM_SAVED;
free(demobuf.buffer);
Z_Free(demobuf.buffer);
demo.recording = false;
if (!modeattacking)

View file

@ -4303,12 +4303,11 @@ void G_LoadGameSettings(void)
// Loads the main data file, which stores information such as emblems found, etc.
void G_LoadGameData(void)
{
size_t length;
UINT32 i, j;
UINT32 versionID;
UINT8 versionMinor;
UINT8 rtemp;
savebuffer_t save;
savebuffer_t save = {0};
//For records
UINT32 numgamedatamapheaders;
@ -4337,16 +4336,13 @@ void G_LoadGameData(void)
return;
}
length = FIL_ReadFile(va(pandf, srb2home, gamedatafilename), &save.buffer);
if (!length)
if (P_SaveBufferFromFile(&save, va(pandf, srb2home, gamedatafilename)) == false)
{
// No gamedata. We can save a new one.
gamedata->loaded = true;
return;
}
save.p = save.buffer;
// Version check
versionID = READUINT32(save.p);
if (versionID != GD_VERSIONCHECK)
@ -4355,16 +4351,14 @@ void G_LoadGameData(void)
if (strcmp(srb2home,"."))
gdfolder = srb2home;
Z_Free(save.buffer);
save.p = NULL;
P_SaveBufferFree(&save);
I_Error("Game data is not for Ring Racers v2.0.\nDelete %s(maybe in %s) and try again.", gamedatafilename, gdfolder);
}
versionMinor = READUINT8(save.p);
if (versionMinor > GD_VERSIONMINOR)
{
Z_Free(save.buffer);
save.p = NULL;
P_SaveBufferFree(&save);
I_Error("Game data is from the future! (expected %d, got %d)", GD_VERSIONMINOR, versionMinor);
}
@ -4475,8 +4469,7 @@ void G_LoadGameData(void)
}
// done
Z_Free(save.buffer);
save.p = NULL;
P_SaveBufferFree(&save);
// Don't consider loaded until it's a success!
// It used to do this much earlier, but this would cause the gamedata to
@ -4496,8 +4489,7 @@ void G_LoadGameData(void)
if (strcmp(srb2home,"."))
gdfolder = srb2home;
Z_Free(save.buffer);
save.p = NULL;
P_SaveBufferFree(&save);
I_Error("Corrupt game data file.\nDelete %s(maybe in %s) and try again.", gamedatafilename, gdfolder);
}
@ -4510,7 +4502,7 @@ void G_SaveGameData(void)
size_t length;
INT32 i, j;
UINT8 btemp;
savebuffer_t save;
savebuffer_t save = {0};
if (!gamedata->loaded)
return; // If never loaded (-nodata), don't save
@ -4530,14 +4522,11 @@ void G_SaveGameData(void)
}
length += nummapheaders * (MAXMAPLUMPNAME+1+4+4);
save.size = length;
save.p = save.buffer = (UINT8 *)malloc(save.size);
if (!save.p)
if (P_SaveBufferAlloc(&save, length) == false)
{
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for saving game data\n"));
return;
}
save.end = save.buffer + save.size;
// Version test
@ -4624,7 +4613,7 @@ void G_SaveGameData(void)
length = save.p - save.buffer;
FIL_WriteFile(va(pandf, srb2home, gamedatafilename), save.buffer, length);
free(save.buffer);
P_SaveBufferFree(&save);
// Also save profiles here.
PR_SaveProfiles();
@ -4638,10 +4627,9 @@ void G_SaveGameData(void)
//
void G_LoadGame(UINT32 slot, INT16 mapoverride)
{
size_t length;
char vcheck[VERSIONSIZE];
char savename[255];
savebuffer_t save;
savebuffer_t save = {0};
// memset savedata to all 0, fixes calling perfectly valid saves corrupt because of bots
memset(&savedata, 0, sizeof(savedata));
@ -4656,17 +4644,12 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
else
sprintf(savename, savegamename, slot);
length = FIL_ReadFile(savename, &save.buffer);
if (!length)
if (P_SaveBufferFromFile(&save, savename) == false)
{
CONS_Printf(M_GetText("Couldn't read file %s\n"), savename);
return;
}
save.p = save.buffer;
save.size = length;
save.end = save.buffer + save.size;
memset(vcheck, 0, sizeof (vcheck));
sprintf(vcheck, (marathonmode ? "back-up %d" : "version %d"), VERSION);
if (strcmp((const char *)save.p, (const char *)vcheck))
@ -4679,7 +4662,7 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
M_ClearMenus(true); // so ESC backs out to title
M_StartMessage(M_GetText("Save game from different version\n\nPress ESC\n"), NULL, MM_NOTHING);
Command_ExitGame_f();
Z_Free(save.buffer);
P_SaveBufferFree(&save);
// no cheating!
memset(&savedata, 0, sizeof(savedata));
@ -4714,7 +4697,7 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
}
// done
Z_Free(save.buffer);
P_SaveBufferFree(&save);
// gameaction = ga_nothing;
// G_SetGamestate(GS_LEVEL);
@ -4740,7 +4723,7 @@ void G_SaveGame(UINT32 slot, INT16 mapnum)
boolean saved;
char savename[256] = "";
const char *backup;
savebuffer_t save;
savebuffer_t save = {0};
if (marathonmode)
strcpy(savename, liveeventbackup);
@ -4753,14 +4736,11 @@ void G_SaveGame(UINT32 slot, INT16 mapnum)
char name[VERSIONSIZE];
size_t length;
save.size = SAVEGAMESIZE;
save.p = save.buffer = (UINT8 *)malloc(save.size);
if (!save.p)
if (P_SaveBufferAlloc(&save, SAVEGAMESIZE) == false)
{
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for saving game data\n"));
return;
}
save.end = save.buffer + save.size;
memset(name, 0, sizeof (name));
sprintf(name, (marathonmode ? "back-up %d" : "version %d"), VERSION);
@ -4778,7 +4758,7 @@ void G_SaveGame(UINT32 slot, INT16 mapnum)
length = save.p - save.buffer;
saved = FIL_WriteFile(backup, save.buffer, length);
free(save.buffer);
P_SaveBufferFree(&save);
}
gameaction = ga_nothing;
@ -4798,7 +4778,7 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives)
char vcheck[VERSIONSIZE];
char savename[255];
const char *backup;
savebuffer_t save;
savebuffer_t save = {0};
if (marathonmode)
strcpy(savename, liveeventbackup);
@ -4806,22 +4786,19 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives)
sprintf(savename, savegamename, slot);
backup = va("%s",savename);
length = FIL_ReadFile(savename, &save.buffer);
if (!length)
if (P_SaveBufferFromFile(&save, savename) == false)
{
CONS_Printf(M_GetText("Couldn't read file %s\n"), savename);
return;
}
length = save.size;
{
char temp[sizeof(timeattackfolder)];
UINT8 *lives_p;
SINT8 pllives;
save.p = save.buffer;
save.size = length;
save.end = save.buffer + save.size;
// Version check
memset(vcheck, 0, sizeof (vcheck));
sprintf(vcheck, (marathonmode ? "back-up %d" : "version %d"), VERSION);
@ -4892,9 +4869,8 @@ cleanup:
CONS_Printf(M_GetText("Game saved.\n"));
else if (!saved)
CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, slot, (marathonmode ? liveeventbackup : savegamename));
Z_Free(save.buffer);
save.p = save.buffer = NULL;
P_SaveBufferFree(&save);
}
#undef CHECKPOS
#undef BADSAVE

View file

@ -217,16 +217,13 @@ void PR_SaveProfiles(void)
size_t length = 0;
const size_t headerlen = strlen(PROFILEHEADER);
UINT8 i, j, k;
savebuffer_t save;
savebuffer_t save = {0};
save.size = sizeof(UINT32) + (numprofiles * sizeof(profile_t));
save.p = save.buffer = (UINT8 *)malloc(save.size);
if (!save.p)
if (P_SaveBufferAlloc(&save, sizeof(UINT32) + (numprofiles * sizeof(profile_t))) == false)
{
I_Error("No more free memory for saving profiles\n");
return;
}
save.end = save.buffer + save.size;
// Add header.
WRITESTRINGN(save.p, PROFILEHEADER, headerlen);
@ -278,7 +275,6 @@ void PR_SaveProfiles(void)
void PR_LoadProfiles(void)
{
size_t length = 0;
const size_t headerlen = strlen(PROFILEHEADER);
UINT8 i, j, k, version;
profile_t *dprofile = PR_MakeProfile(
@ -289,18 +285,15 @@ void PR_LoadProfiles(void)
gamecontroldefault,
true
);
savebuffer_t save;
savebuffer_t save = {0};
length = FIL_ReadFile(va(pandf, srb2home, PROFILESFILE), &save.buffer);
if (!length)
if (P_SaveBufferFromFile(&save, va(pandf, srb2home, PROFILESFILE)) == false)
{
// No profiles. Add the default one.
PR_AddProfile(dprofile);
return;
}
save.p = save.buffer;
if (strncmp(PROFILEHEADER, (const char *)save.buffer, headerlen))
{
const char *gdfolder = "the Ring Racers folder";

View file

@ -5226,3 +5226,92 @@ boolean P_LoadNetGame(savebuffer_t *save, boolean reloading)
return P_UnArchiveLuabanksAndConsistency(save);
}
boolean P_SaveBufferZAlloc(savebuffer_t *save, size_t alloc_size, INT32 tag, void *user)
{
I_Assert(save->buffer == NULL);
save->buffer = (UINT8 *)Z_Malloc(alloc_size, tag, user);
if (save->buffer == NULL)
{
return false;
}
save->size = alloc_size;
save->p = save->buffer;
save->end = save->buffer + save->size;
return true;
}
boolean P_SaveBufferFromExisting(savebuffer_t *save, UINT8 *existing_buffer, size_t existing_size)
{
I_Assert(save->buffer == NULL);
if (existing_buffer == NULL || existing_size == 0)
{
return false;
}
save->buffer = existing_buffer;
save->size = existing_size;
save->p = save->buffer;
save->end = save->buffer + save->size;
return true;
}
boolean P_SaveBufferFromLump(savebuffer_t *save, lumpnum_t lump)
{
I_Assert(save->buffer == NULL);
if (lump == LUMPERROR)
{
return false;
}
save->buffer = (UINT8 *)W_CacheLumpNum(lump, PU_STATIC);
if (save->buffer == NULL)
{
return false;
}
save->size = W_LumpLength(lump);
save->p = save->buffer;
save->end = save->buffer + save->size;
return true;
}
boolean P_SaveBufferFromFile(savebuffer_t *save, char const *name)
{
size_t len = 0;
I_Assert(save->buffer == NULL);
len = FIL_ReadFile(name, &save->buffer);
if (len != 0)
{
save->size = len;
save->p = save->buffer;
save->end = save->buffer + save->size;
}
return len;
}
static void P_SaveBufferInvalidate(savebuffer_t *save)
{
save->buffer = save->p = save->end = NULL;
save->size = 0;
}
void P_SaveBufferFree(savebuffer_t *save)
{
Z_Free(save->buffer);
P_SaveBufferInvalidate(save);
}

View file

@ -57,6 +57,13 @@ struct savebuffer_t
size_t size;
};
boolean P_SaveBufferZAlloc(savebuffer_t *save, size_t alloc_size, INT32 tag, void *user);
#define P_SaveBufferAlloc(a,b) P_SaveBufferZAlloc(a, b, PU_STATIC, NULL)
boolean P_SaveBufferFromExisting(savebuffer_t *save, UINT8 *existing_buffer, size_t existing_size);
boolean P_SaveBufferFromLump(savebuffer_t *save, lumpnum_t lump);
boolean P_SaveBufferFromFile(savebuffer_t *save, char const *name);
void P_SaveBufferFree(savebuffer_t *save);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -722,20 +722,15 @@ void P_WriteThings(void)
const char * filename;
size_t i, length;
mapthing_t *mt;
savebuffer_t save;
savebuffer_t save = {0};
INT16 temp;
save.size = nummapthings * sizeof (mapthing_t);
save.p = save.buffer = (UINT8 *)malloc(nummapthings * sizeof (mapthing_t));
if (!save.p)
if (P_SaveBufferAlloc(&save, nummapthings * sizeof (mapthing_t)) == false)
{
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for thing writing!\n"));
return;
}
save.end = save.buffer + save.size;
mt = mapthings;
for (i = 0; i < nummapthings; i++, mt++)
{