mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-26 03:51:50 +00:00
Merge branch 'save_p-unglobal' into 'master'
Make save_p / savebuffers not global See merge request KartKrew/Kart!834
This commit is contained in:
commit
546b4dcb88
17 changed files with 2555 additions and 2487 deletions
|
|
@ -1124,8 +1124,6 @@ static boolean SV_SendServerConfig(INT32 node)
|
|||
return waspacketsent;
|
||||
}
|
||||
|
||||
#define SAVEGAMESIZE (768*1024)
|
||||
|
||||
static boolean SV_ResendingSavegameToAnyone(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
|
@ -1139,34 +1137,32 @@ static boolean SV_ResendingSavegameToAnyone(void)
|
|||
static void SV_SendSaveGame(INT32 node, boolean resending)
|
||||
{
|
||||
size_t length, compressedlen;
|
||||
UINT8 *savebuffer;
|
||||
savebuffer_t save = {0};
|
||||
UINT8 *compressedsave;
|
||||
UINT8 *buffertosend;
|
||||
|
||||
// first save it in a malloced buffer
|
||||
savebuffer = (UINT8 *)malloc(SAVEGAMESIZE);
|
||||
if (!savebuffer)
|
||||
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 = savebuffer + sizeof(UINT32);
|
||||
save.p += sizeof(UINT32);
|
||||
|
||||
P_SaveNetGame(resending);
|
||||
P_SaveNetGame(&save, resending);
|
||||
|
||||
length = save_p - savebuffer;
|
||||
if (length > SAVEGAMESIZE)
|
||||
length = save.p - save.buffer;
|
||||
if (length > NETSAVEGAMESIZE)
|
||||
{
|
||||
free(savebuffer);
|
||||
save_p = NULL;
|
||||
P_SaveBufferFree(&save);
|
||||
I_Error("Savegame buffer overrun");
|
||||
}
|
||||
|
||||
// Allocate space for compressed save: one byte fewer than for the
|
||||
// uncompressed data to ensure that the compression is worthwhile.
|
||||
compressedsave = malloc(length - 1);
|
||||
compressedsave = Z_Malloc(length - 1, PU_STATIC, NULL);
|
||||
if (!compressedsave)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for savegame\n"));
|
||||
|
|
@ -1174,11 +1170,10 @@ static void SV_SendSaveGame(INT32 node, boolean resending)
|
|||
}
|
||||
|
||||
// Attempt to compress it.
|
||||
if((compressedlen = lzf_compress(savebuffer + sizeof(UINT32), length - sizeof(UINT32), compressedsave + sizeof(UINT32), length - sizeof(UINT32) - 1)))
|
||||
if ((compressedlen = lzf_compress(save.buffer + sizeof(UINT32), length - sizeof(UINT32), compressedsave + sizeof(UINT32), length - sizeof(UINT32) - 1)))
|
||||
{
|
||||
// Compressing succeeded; send compressed data
|
||||
|
||||
free(savebuffer);
|
||||
P_SaveBufferFree(&save);
|
||||
|
||||
// State that we're compressed.
|
||||
buffertosend = compressedsave;
|
||||
|
|
@ -1188,16 +1183,14 @@ static void SV_SendSaveGame(INT32 node, boolean resending)
|
|||
else
|
||||
{
|
||||
// Compression failed to make it smaller; send original
|
||||
|
||||
free(compressedsave);
|
||||
Z_Free(compressedsave);
|
||||
|
||||
// State that we're not compressed
|
||||
buffertosend = savebuffer;
|
||||
WRITEUINT32(savebuffer, 0);
|
||||
buffertosend = save.buffer;
|
||||
WRITEUINT32(save.buffer, 0);
|
||||
}
|
||||
|
||||
AddRamToSendQueue(node, buffertosend, length, SF_RAM, 0);
|
||||
save_p = NULL;
|
||||
AddRamToSendQueue(node, buffertosend, length, SF_Z_RAM, 0);
|
||||
|
||||
// Remember when we started sending the savegame so we can handle timeouts
|
||||
sendingsavegame[node] = true;
|
||||
|
|
@ -1211,7 +1204,7 @@ static consvar_t cv_dumpconsistency = CVAR_INIT ("dumpconsistency", "Off", CV_SA
|
|||
static void SV_SavedGame(void)
|
||||
{
|
||||
size_t length;
|
||||
UINT8 *savebuffer;
|
||||
savebuffer_t save = {0};
|
||||
char tmpsave[256];
|
||||
|
||||
if (!cv_dumpconsistency.value)
|
||||
|
|
@ -1220,29 +1213,26 @@ static void SV_SavedGame(void)
|
|||
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
|
||||
|
||||
// first save it in a malloced buffer
|
||||
save_p = savebuffer = (UINT8 *)malloc(SAVEGAMESIZE);
|
||||
if (!save_p)
|
||||
if (P_SaveBufferAlloc(&save, NETSAVEGAMESIZE) == false)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for savegame\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
P_SaveNetGame(false);
|
||||
P_SaveNetGame(&save, false);
|
||||
|
||||
length = save_p - savebuffer;
|
||||
if (length > SAVEGAMESIZE)
|
||||
length = save.p - save.buffer;
|
||||
if (length > NETSAVEGAMESIZE)
|
||||
{
|
||||
free(savebuffer);
|
||||
save_p = NULL;
|
||||
P_SaveBufferFree(&save);
|
||||
I_Error("Savegame buffer overrun");
|
||||
}
|
||||
|
||||
// then save it!
|
||||
if (!FIL_WriteFile(tmpsave, savebuffer, length))
|
||||
if (!FIL_WriteFile(tmpsave, save.buffer, length))
|
||||
CONS_Printf(M_GetText("Didn't save %s for netgame"), tmpsave);
|
||||
|
||||
free(savebuffer);
|
||||
save_p = NULL;
|
||||
P_SaveBufferFree(&save);
|
||||
}
|
||||
|
||||
#undef TMPSAVENAME
|
||||
|
|
@ -1252,31 +1242,31 @@ static void SV_SavedGame(void)
|
|||
|
||||
static void CL_LoadReceivedSavegame(boolean reloading)
|
||||
{
|
||||
UINT8 *savebuffer = NULL;
|
||||
savebuffer_t save = {0};
|
||||
size_t length, decompressedlen;
|
||||
char tmpsave[256];
|
||||
|
||||
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
|
||||
|
||||
length = FIL_ReadFile(tmpsave, &savebuffer);
|
||||
|
||||
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 = savebuffer;
|
||||
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)
|
||||
decompressedlen = READUINT32(save.p);
|
||||
if (decompressedlen > 0)
|
||||
{
|
||||
UINT8 *decompressedbuffer = Z_Malloc(decompressedlen, PU_STATIC, NULL);
|
||||
lzf_decompress(save_p, length - sizeof(UINT32), decompressedbuffer, decompressedlen);
|
||||
Z_Free(savebuffer);
|
||||
save_p = savebuffer = decompressedbuffer;
|
||||
|
||||
lzf_decompress(save.p, length - sizeof(UINT32), decompressedbuffer, decompressedlen);
|
||||
|
||||
P_SaveBufferFree(&save);
|
||||
P_SaveBufferFromExisting(&save, decompressedbuffer, decompressedlen);
|
||||
}
|
||||
|
||||
paused = false;
|
||||
|
|
@ -1286,7 +1276,7 @@ static void CL_LoadReceivedSavegame(boolean reloading)
|
|||
automapactive = false;
|
||||
|
||||
// load a base level
|
||||
if (P_LoadNetGame(reloading))
|
||||
if (P_LoadNetGame(&save, reloading))
|
||||
{
|
||||
if (!reloading)
|
||||
{
|
||||
|
|
@ -1308,10 +1298,13 @@ static void CL_LoadReceivedSavegame(boolean reloading)
|
|||
}
|
||||
|
||||
// done
|
||||
Z_Free(savebuffer);
|
||||
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();
|
||||
|
||||
|
|
@ -6064,6 +6057,7 @@ void CL_ClearRewinds(void)
|
|||
|
||||
rewind_t *CL_SaveRewindPoint(size_t demopos)
|
||||
{
|
||||
savebuffer_t save = {0};
|
||||
rewind_t *rewind;
|
||||
|
||||
if (rewindhead && rewindhead->leveltime + REWIND_POINT_INTERVAL > leveltime)
|
||||
|
|
@ -6073,8 +6067,9 @@ rewind_t *CL_SaveRewindPoint(size_t demopos)
|
|||
if (!rewind)
|
||||
return NULL;
|
||||
|
||||
save_p = rewind->savebuffer;
|
||||
P_SaveNetGame(false);
|
||||
P_SaveBufferFromExisting(&save, rewind->savebuffer, NETSAVEGAMESIZE);
|
||||
P_SaveNetGame(&save, false);
|
||||
|
||||
rewind->leveltime = leveltime;
|
||||
rewind->next = rewindhead;
|
||||
rewind->demopos = demopos;
|
||||
|
|
@ -6085,6 +6080,7 @@ rewind_t *CL_SaveRewindPoint(size_t demopos)
|
|||
|
||||
rewind_t *CL_RewindToTime(tic_t time)
|
||||
{
|
||||
savebuffer_t save = {0};
|
||||
rewind_t *rewind;
|
||||
|
||||
while (rewindhead && rewindhead->leveltime > time)
|
||||
|
|
@ -6097,8 +6093,9 @@ rewind_t *CL_RewindToTime(tic_t time)
|
|||
if (!rewindhead)
|
||||
return NULL;
|
||||
|
||||
save_p = rewindhead->savebuffer;
|
||||
P_LoadNetGame(false);
|
||||
P_SaveBufferFromExisting(&save, rewindhead->savebuffer, NETSAVEGAMESIZE);
|
||||
P_LoadNetGame(&save, false);
|
||||
|
||||
wipegamestate = gamestate; // No fading back in!
|
||||
timeinmap = leveltime;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "mserv.h"
|
||||
|
||||
#include "k_pwrlv.h" // PWRLV_NUMTYPES
|
||||
#include "p_saveg.h" // NETSAVEGAMESIZE
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -534,7 +535,7 @@ extern boolean hu_stopped;
|
|||
//
|
||||
|
||||
struct rewind_t {
|
||||
UINT8 savebuffer[(768*1024)];
|
||||
UINT8 savebuffer[NETSAVEGAMESIZE];
|
||||
tic_t leveltime;
|
||||
size_t demopos;
|
||||
|
||||
|
|
|
|||
|
|
@ -5815,10 +5815,9 @@ static void Command_Togglemodified_f(void)
|
|||
modifiedgame = !modifiedgame;
|
||||
}
|
||||
|
||||
extern UINT8 *save_p;
|
||||
static void Command_Archivetest_f(void)
|
||||
{
|
||||
UINT8 *buf;
|
||||
savebuffer_t save = {0};
|
||||
UINT32 i, wrote;
|
||||
thinker_t *th;
|
||||
if (gamestate != GS_LEVEL)
|
||||
|
|
@ -5834,28 +5833,34 @@ static void Command_Archivetest_f(void)
|
|||
((mobj_t *)th)->mobjnum = i++;
|
||||
|
||||
// allocate buffer
|
||||
buf = save_p = ZZ_Alloc(1024);
|
||||
if (P_SaveBufferAlloc(&save, 1024) == false)
|
||||
{
|
||||
CONS_Printf("Unable to allocate buffer.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// test archive
|
||||
CONS_Printf("LUA_Archive...\n");
|
||||
LUA_Archive(&save_p);
|
||||
WRITEUINT8(save_p, 0x7F);
|
||||
wrote = (UINT32)(save_p-buf);
|
||||
LUA_Archive(&save, true);
|
||||
WRITEUINT8(save.p, 0x7F);
|
||||
wrote = (UINT32)(save.p - save.buffer);
|
||||
|
||||
// clear Lua state, so we can really see what happens!
|
||||
CONS_Printf("Clearing state!\n");
|
||||
LUA_ClearExtVars();
|
||||
|
||||
// test unarchive
|
||||
save_p = buf;
|
||||
save.p = save.buffer;
|
||||
CONS_Printf("LUA_UnArchive...\n");
|
||||
LUA_UnArchive(&save_p);
|
||||
i = READUINT8(save_p);
|
||||
if (i != 0x7F || wrote != (UINT32)(save_p-buf))
|
||||
CONS_Printf("Savegame corrupted. (write %u, read %u)\n", wrote, (UINT32)(save_p-buf));
|
||||
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(buf);
|
||||
P_SaveBufferFree(&save);
|
||||
CONS_Printf("Done. No crash.\n");
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
678
src/g_demo.c
678
src/g_demo.c
File diff suppressed because it is too large
Load diff
|
|
@ -22,8 +22,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern UINT8 *demo_p;
|
||||
|
||||
// ======================================
|
||||
// DEMO playback/recording related stuff.
|
||||
// ======================================
|
||||
|
|
|
|||
200
src/g_game.c
200
src/g_game.c
|
|
@ -72,9 +72,6 @@ UINT8 ultimatemode = false;
|
|||
|
||||
JoyType_t Joystick[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
// 1024 bytes is plenty for a savegame
|
||||
#define SAVEGAMESIZE (1024)
|
||||
|
||||
// SRB2kart
|
||||
char gamedatafilename[64] =
|
||||
#if defined (TESTERS) || defined (HOSTTESTERS)
|
||||
|
|
@ -343,8 +340,6 @@ boolean precache = true; // if true, load all graphics at start
|
|||
|
||||
INT16 prevmap, nextmap;
|
||||
|
||||
static UINT8 *savebuffer;
|
||||
|
||||
static void weaponPrefChange(void);
|
||||
static void weaponPrefChange2(void);
|
||||
static void weaponPrefChange3(void);
|
||||
|
|
@ -4200,11 +4195,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 = {0};
|
||||
|
||||
//For records
|
||||
UINT32 numgamedatamapheaders;
|
||||
|
|
@ -4233,43 +4228,38 @@ void G_LoadGameData(void)
|
|||
return;
|
||||
}
|
||||
|
||||
length = FIL_ReadFile(va(pandf, srb2home, gamedatafilename), &savebuffer);
|
||||
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 = savebuffer;
|
||||
|
||||
// Version check
|
||||
versionID = READUINT32(save_p);
|
||||
versionID = READUINT32(save.p);
|
||||
if (versionID != GD_VERSIONCHECK)
|
||||
{
|
||||
const char *gdfolder = "the Ring Racers folder";
|
||||
if (strcmp(srb2home,"."))
|
||||
gdfolder = srb2home;
|
||||
|
||||
Z_Free(savebuffer);
|
||||
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);
|
||||
versionMinor = READUINT8(save.p);
|
||||
if (versionMinor > GD_VERSIONMINOR)
|
||||
{
|
||||
Z_Free(savebuffer);
|
||||
save_p = NULL;
|
||||
P_SaveBufferFree(&save);
|
||||
I_Error("Game data is from the future! (expected %d, got %d)", GD_VERSIONMINOR, versionMinor);
|
||||
}
|
||||
|
||||
gamedata->totalplaytime = READUINT32(save_p);
|
||||
gamedata->matchesplayed = READUINT32(save_p);
|
||||
gamedata->totalplaytime = READUINT32(save.p);
|
||||
gamedata->matchesplayed = READUINT32(save.p);
|
||||
|
||||
{
|
||||
// Quick & dirty hash for what mod this save file is for.
|
||||
UINT32 modID = READUINT32(save_p);
|
||||
UINT32 modID = READUINT32(save.p);
|
||||
UINT32 expectedID = quickncasehash(timeattackfolder, 64);
|
||||
|
||||
if (modID != expectedID)
|
||||
|
|
@ -4282,34 +4272,34 @@ void G_LoadGameData(void)
|
|||
// To save space, use one bit per collected/achieved/unlocked flag
|
||||
for (i = 0; i < MAXEMBLEMS;)
|
||||
{
|
||||
rtemp = READUINT8(save_p);
|
||||
rtemp = READUINT8(save.p);
|
||||
for (j = 0; j < 8 && j+i < MAXEMBLEMS; ++j)
|
||||
gamedata->collected[j+i] = ((rtemp >> j) & 1);
|
||||
i += j;
|
||||
}
|
||||
for (i = 0; i < MAXUNLOCKABLES;)
|
||||
{
|
||||
rtemp = READUINT8(save_p);
|
||||
rtemp = READUINT8(save.p);
|
||||
for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j)
|
||||
gamedata->unlocked[j+i] = ((rtemp >> j) & 1);
|
||||
i += j;
|
||||
}
|
||||
for (i = 0; i < MAXUNLOCKABLES;)
|
||||
{
|
||||
rtemp = READUINT8(save_p);
|
||||
rtemp = READUINT8(save.p);
|
||||
for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j)
|
||||
gamedata->unlockpending[j+i] = ((rtemp >> j) & 1);
|
||||
i += j;
|
||||
}
|
||||
for (i = 0; i < MAXCONDITIONSETS;)
|
||||
{
|
||||
rtemp = READUINT8(save_p);
|
||||
rtemp = READUINT8(save.p);
|
||||
for (j = 0; j < 8 && j+i < MAXCONDITIONSETS; ++j)
|
||||
gamedata->achieved[j+i] = ((rtemp >> j) & 1);
|
||||
i += j;
|
||||
}
|
||||
|
||||
gamedata->challengegridwidth = READUINT16(save_p);
|
||||
gamedata->challengegridwidth = READUINT16(save.p);
|
||||
Z_Free(gamedata->challengegrid);
|
||||
if (gamedata->challengegridwidth)
|
||||
{
|
||||
|
|
@ -4318,7 +4308,7 @@ void G_LoadGameData(void)
|
|||
PU_STATIC, NULL);
|
||||
for (i = 0; i < (gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT); i++)
|
||||
{
|
||||
gamedata->challengegrid[i] = READUINT8(save_p);
|
||||
gamedata->challengegrid[i] = READUINT8(save.p);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -4326,10 +4316,10 @@ void G_LoadGameData(void)
|
|||
gamedata->challengegrid = NULL;
|
||||
}
|
||||
|
||||
gamedata->timesBeaten = READUINT32(save_p);
|
||||
gamedata->timesBeaten = READUINT32(save.p);
|
||||
|
||||
// Main records
|
||||
numgamedatamapheaders = READUINT32(save_p);
|
||||
numgamedatamapheaders = READUINT32(save.p);
|
||||
if (numgamedatamapheaders >= NEXTMAP_SPECIAL)
|
||||
goto datacorrupt;
|
||||
|
||||
|
|
@ -4340,12 +4330,12 @@ void G_LoadGameData(void)
|
|||
tic_t rectime;
|
||||
tic_t reclap;
|
||||
|
||||
READSTRINGN(save_p, mapname, sizeof(mapname));
|
||||
READSTRINGN(save.p, mapname, sizeof(mapname));
|
||||
mapnum = G_MapNumber(mapname);
|
||||
|
||||
rtemp = READUINT8(save_p);
|
||||
rectime = (tic_t)READUINT32(save_p);
|
||||
reclap = (tic_t)READUINT32(save_p);
|
||||
rtemp = READUINT8(save.p);
|
||||
rectime = (tic_t)READUINT32(save.p);
|
||||
reclap = (tic_t)READUINT32(save.p);
|
||||
|
||||
if (mapnum < nummapheaders && mapheaderinfo[mapnum])
|
||||
{
|
||||
|
|
@ -4371,8 +4361,7 @@ void G_LoadGameData(void)
|
|||
}
|
||||
|
||||
// done
|
||||
Z_Free(savebuffer);
|
||||
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
|
||||
|
|
@ -4392,8 +4381,7 @@ void G_LoadGameData(void)
|
|||
if (strcmp(srb2home,"."))
|
||||
gdfolder = srb2home;
|
||||
|
||||
Z_Free(savebuffer);
|
||||
save_p = NULL;
|
||||
P_SaveBufferFree(&save);
|
||||
|
||||
I_Error("Corrupt game data file.\nDelete %s(maybe in %s) and try again.", gamedatafilename, gdfolder);
|
||||
}
|
||||
|
|
@ -4406,6 +4394,7 @@ void G_SaveGameData(void)
|
|||
size_t length;
|
||||
INT32 i, j;
|
||||
UINT8 btemp;
|
||||
savebuffer_t save = {0};
|
||||
|
||||
if (!gamedata->loaded)
|
||||
return; // If never loaded (-nodata), don't save
|
||||
|
|
@ -4425,8 +4414,7 @@ void G_SaveGameData(void)
|
|||
}
|
||||
length += nummapheaders * (MAXMAPLUMPNAME+1+4+4);
|
||||
|
||||
save_p = savebuffer = (UINT8 *)malloc(length);
|
||||
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;
|
||||
|
|
@ -4434,11 +4422,11 @@ void G_SaveGameData(void)
|
|||
|
||||
// Version test
|
||||
|
||||
WRITEUINT32(save_p, GD_VERSIONCHECK); // 4
|
||||
WRITEUINT8(save_p, GD_VERSIONMINOR); // 1
|
||||
WRITEUINT32(save_p, gamedata->totalplaytime); // 4
|
||||
WRITEUINT32(save_p, gamedata->matchesplayed); // 4
|
||||
WRITEUINT32(save_p, quickncasehash(timeattackfolder, 64));
|
||||
WRITEUINT32(save.p, GD_VERSIONCHECK); // 4
|
||||
WRITEUINT8(save.p, GD_VERSIONMINOR); // 1
|
||||
WRITEUINT32(save.p, gamedata->totalplaytime); // 4
|
||||
WRITEUINT32(save.p, gamedata->matchesplayed); // 4
|
||||
WRITEUINT32(save.p, quickncasehash(timeattackfolder, 64));
|
||||
|
||||
// To save space, use one bit per collected/achieved/unlocked flag
|
||||
for (i = 0; i < MAXEMBLEMS;) // MAXEMBLEMS * 1;
|
||||
|
|
@ -4446,7 +4434,7 @@ void G_SaveGameData(void)
|
|||
btemp = 0;
|
||||
for (j = 0; j < 8 && j+i < MAXEMBLEMS; ++j)
|
||||
btemp |= (gamedata->collected[j+i] << j);
|
||||
WRITEUINT8(save_p, btemp);
|
||||
WRITEUINT8(save.p, btemp);
|
||||
i += j;
|
||||
}
|
||||
|
||||
|
|
@ -4456,7 +4444,7 @@ void G_SaveGameData(void)
|
|||
btemp = 0;
|
||||
for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j)
|
||||
btemp |= (gamedata->unlocked[j+i] << j);
|
||||
WRITEUINT8(save_p, btemp);
|
||||
WRITEUINT8(save.p, btemp);
|
||||
i += j;
|
||||
}
|
||||
for (i = 0; i < MAXUNLOCKABLES;)
|
||||
|
|
@ -4464,7 +4452,7 @@ void G_SaveGameData(void)
|
|||
btemp = 0;
|
||||
for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j)
|
||||
btemp |= (gamedata->unlockpending[j+i] << j);
|
||||
WRITEUINT8(save_p, btemp);
|
||||
WRITEUINT8(save.p, btemp);
|
||||
i += j;
|
||||
}
|
||||
|
||||
|
|
@ -4473,52 +4461,51 @@ void G_SaveGameData(void)
|
|||
btemp = 0;
|
||||
for (j = 0; j < 8 && j+i < MAXCONDITIONSETS; ++j)
|
||||
btemp |= (gamedata->achieved[j+i] << j);
|
||||
WRITEUINT8(save_p, btemp);
|
||||
WRITEUINT8(save.p, btemp);
|
||||
i += j;
|
||||
}
|
||||
|
||||
if (gamedata->challengegrid) // 2 + gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT
|
||||
{
|
||||
WRITEUINT16(save_p, gamedata->challengegridwidth);
|
||||
WRITEUINT16(save.p, gamedata->challengegridwidth);
|
||||
for (i = 0; i < (gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT); i++)
|
||||
{
|
||||
WRITEUINT8(save_p, gamedata->challengegrid[i]);
|
||||
WRITEUINT8(save.p, gamedata->challengegrid[i]);
|
||||
}
|
||||
}
|
||||
else // 2
|
||||
{
|
||||
WRITEUINT16(save_p, 0);
|
||||
WRITEUINT16(save.p, 0);
|
||||
}
|
||||
|
||||
WRITEUINT32(save_p, gamedata->timesBeaten); // 4
|
||||
WRITEUINT32(save.p, gamedata->timesBeaten); // 4
|
||||
|
||||
// Main records
|
||||
WRITEUINT32(save_p, nummapheaders); // 4
|
||||
WRITEUINT32(save.p, nummapheaders); // 4
|
||||
|
||||
for (i = 0; i < nummapheaders; i++) // nummapheaders * (255+1+4+4)
|
||||
{
|
||||
// For figuring out which header to assing it to on load
|
||||
WRITESTRINGN(save_p, mapheaderinfo[i]->lumpname, MAXMAPLUMPNAME);
|
||||
WRITESTRINGN(save.p, mapheaderinfo[i]->lumpname, MAXMAPLUMPNAME);
|
||||
|
||||
WRITEUINT8(save_p, (mapheaderinfo[i]->mapvisited & MV_MAX));
|
||||
WRITEUINT8(save.p, (mapheaderinfo[i]->mapvisited & MV_MAX));
|
||||
|
||||
if (mapheaderinfo[i]->mainrecord)
|
||||
{
|
||||
WRITEUINT32(save_p, mapheaderinfo[i]->mainrecord->time);
|
||||
WRITEUINT32(save_p, mapheaderinfo[i]->mainrecord->lap);
|
||||
WRITEUINT32(save.p, mapheaderinfo[i]->mainrecord->time);
|
||||
WRITEUINT32(save.p, mapheaderinfo[i]->mainrecord->lap);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITEUINT32(save_p, 0);
|
||||
WRITEUINT32(save_p, 0);
|
||||
WRITEUINT32(save.p, 0);
|
||||
WRITEUINT32(save.p, 0);
|
||||
}
|
||||
}
|
||||
|
||||
length = save_p - savebuffer;
|
||||
length = save.p - save.buffer;
|
||||
|
||||
FIL_WriteFile(va(pandf, srb2home, gamedatafilename), savebuffer, length);
|
||||
free(savebuffer);
|
||||
save_p = savebuffer = NULL;
|
||||
FIL_WriteFile(va(pandf, srb2home, gamedatafilename), save.buffer, length);
|
||||
P_SaveBufferFree(&save);
|
||||
|
||||
// Also save profiles here.
|
||||
PR_SaveProfiles();
|
||||
|
|
@ -4532,9 +4519,9 @@ void G_SaveGameData(void)
|
|||
//
|
||||
void G_LoadGame(UINT32 slot, INT16 mapoverride)
|
||||
{
|
||||
size_t length;
|
||||
char vcheck[VERSIONSIZE];
|
||||
char savename[255];
|
||||
savebuffer_t save = {0};
|
||||
|
||||
// memset savedata to all 0, fixes calling perfectly valid saves corrupt because of bots
|
||||
memset(&savedata, 0, sizeof(savedata));
|
||||
|
|
@ -4549,18 +4536,15 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
|
|||
else
|
||||
sprintf(savename, savegamename, slot);
|
||||
|
||||
length = FIL_ReadFile(savename, &savebuffer);
|
||||
if (!length)
|
||||
if (P_SaveBufferFromFile(&save, savename) == false)
|
||||
{
|
||||
CONS_Printf(M_GetText("Couldn't read file %s\n"), savename);
|
||||
return;
|
||||
}
|
||||
|
||||
save_p = savebuffer;
|
||||
|
||||
memset(vcheck, 0, sizeof (vcheck));
|
||||
sprintf(vcheck, (marathonmode ? "back-up %d" : "version %d"), VERSION);
|
||||
if (strcmp((const char *)save_p, (const char *)vcheck))
|
||||
if (strcmp((const char *)save.p, (const char *)vcheck))
|
||||
{
|
||||
#ifdef SAVEGAME_OTHERVERSIONS
|
||||
M_StartMessage(M_GetText("Save game from different version.\nYou can load this savegame, but\nsaving afterwards will be disabled.\n\nDo you want to continue anyway?\n\n(Press 'Y' to confirm)\n"),
|
||||
|
|
@ -4570,15 +4554,14 @@ 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(savebuffer);
|
||||
save_p = savebuffer = NULL;
|
||||
P_SaveBufferFree(&save);
|
||||
|
||||
// no cheating!
|
||||
memset(&savedata, 0, sizeof(savedata));
|
||||
#endif
|
||||
return; // bad version
|
||||
}
|
||||
save_p += VERSIONSIZE;
|
||||
save.p += VERSIONSIZE;
|
||||
|
||||
if (demo.playback) // reset game engine
|
||||
G_StopDemo();
|
||||
|
|
@ -4587,13 +4570,13 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
|
|||
// automapactive = false;
|
||||
|
||||
// dearchive all the modifications
|
||||
if (!P_LoadGame(mapoverride))
|
||||
if (!P_LoadGame(&save, mapoverride))
|
||||
{
|
||||
M_ClearMenus(true); // so ESC backs out to title
|
||||
M_StartMessage(M_GetText("Savegame file corrupted\n\nPress ESC\n"), NULL, MM_NOTHING);
|
||||
Command_ExitGame_f();
|
||||
Z_Free(savebuffer);
|
||||
save_p = savebuffer = NULL;
|
||||
Z_Free(save.buffer);
|
||||
save.p = save.buffer = NULL;
|
||||
|
||||
// no cheating!
|
||||
memset(&savedata, 0, sizeof(savedata));
|
||||
|
|
@ -4601,13 +4584,12 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
|
|||
}
|
||||
if (marathonmode)
|
||||
{
|
||||
marathontime = READUINT32(save_p);
|
||||
marathonmode |= READUINT8(save_p);
|
||||
marathontime = READUINT32(save.p);
|
||||
marathonmode |= READUINT8(save.p);
|
||||
}
|
||||
|
||||
// done
|
||||
Z_Free(savebuffer);
|
||||
save_p = savebuffer = NULL;
|
||||
P_SaveBufferFree(&save);
|
||||
|
||||
// gameaction = ga_nothing;
|
||||
// G_SetGamestate(GS_LEVEL);
|
||||
|
|
@ -4633,6 +4615,7 @@ void G_SaveGame(UINT32 slot, INT16 mapnum)
|
|||
boolean saved;
|
||||
char savename[256] = "";
|
||||
const char *backup;
|
||||
savebuffer_t save = {0};
|
||||
|
||||
if (marathonmode)
|
||||
strcpy(savename, liveeventbackup);
|
||||
|
|
@ -4645,8 +4628,7 @@ void G_SaveGame(UINT32 slot, INT16 mapnum)
|
|||
char name[VERSIONSIZE];
|
||||
size_t length;
|
||||
|
||||
save_p = savebuffer = (UINT8 *)malloc(SAVEGAMESIZE);
|
||||
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;
|
||||
|
|
@ -4654,22 +4636,21 @@ void G_SaveGame(UINT32 slot, INT16 mapnum)
|
|||
|
||||
memset(name, 0, sizeof (name));
|
||||
sprintf(name, (marathonmode ? "back-up %d" : "version %d"), VERSION);
|
||||
WRITEMEM(save_p, name, VERSIONSIZE);
|
||||
WRITEMEM(save.p, name, VERSIONSIZE);
|
||||
|
||||
P_SaveGame(mapnum);
|
||||
P_SaveGame(&save, mapnum);
|
||||
if (marathonmode)
|
||||
{
|
||||
UINT32 writetime = marathontime;
|
||||
if (!(marathonmode & MA_INGAME))
|
||||
writetime += TICRATE*5; // live event backup penalty because we don't know how long it takes to get to the next map
|
||||
WRITEUINT32(save_p, writetime);
|
||||
WRITEUINT8(save_p, (marathonmode & ~MA_INIT));
|
||||
WRITEUINT32(save.p, writetime);
|
||||
WRITEUINT8(save.p, (marathonmode & ~MA_INIT));
|
||||
}
|
||||
|
||||
length = save_p - savebuffer;
|
||||
saved = FIL_WriteFile(backup, savebuffer, length);
|
||||
free(savebuffer);
|
||||
save_p = savebuffer = NULL;
|
||||
length = save.p - save.buffer;
|
||||
saved = FIL_WriteFile(backup, save.buffer, length);
|
||||
P_SaveBufferFree(&save);
|
||||
}
|
||||
|
||||
gameaction = ga_nothing;
|
||||
|
|
@ -4681,7 +4662,7 @@ void G_SaveGame(UINT32 slot, INT16 mapnum)
|
|||
}
|
||||
|
||||
#define BADSAVE goto cleanup;
|
||||
#define CHECKPOS if (save_p >= end_p) BADSAVE
|
||||
#define CHECKPOS if (save.p >= save.end) BADSAVE
|
||||
void G_SaveGameOver(UINT32 slot, boolean modifylives)
|
||||
{
|
||||
boolean saved = false;
|
||||
|
|
@ -4689,6 +4670,7 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives)
|
|||
char vcheck[VERSIONSIZE];
|
||||
char savename[255];
|
||||
const char *backup;
|
||||
savebuffer_t save = {0};
|
||||
|
||||
if (marathonmode)
|
||||
strcpy(savename, liveeventbackup);
|
||||
|
|
@ -4696,44 +4678,43 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives)
|
|||
sprintf(savename, savegamename, slot);
|
||||
backup = va("%s",savename);
|
||||
|
||||
length = FIL_ReadFile(savename, &savebuffer);
|
||||
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 *end_p = savebuffer + length;
|
||||
UINT8 *lives_p;
|
||||
SINT8 pllives;
|
||||
|
||||
save_p = savebuffer;
|
||||
// Version check
|
||||
memset(vcheck, 0, sizeof (vcheck));
|
||||
sprintf(vcheck, (marathonmode ? "back-up %d" : "version %d"), VERSION);
|
||||
if (strcmp((const char *)save_p, (const char *)vcheck)) BADSAVE
|
||||
save_p += VERSIONSIZE;
|
||||
if (strcmp((const char *)save.p, (const char *)vcheck)) BADSAVE
|
||||
save.p += VERSIONSIZE;
|
||||
|
||||
// P_UnArchiveMisc()
|
||||
(void)READINT16(save_p);
|
||||
(void)READINT16(save.p);
|
||||
CHECKPOS
|
||||
(void)READUINT16(save_p); // emeralds
|
||||
(void)READUINT16(save.p); // emeralds
|
||||
CHECKPOS
|
||||
READSTRINGN(save_p, temp, sizeof(temp)); // mod it belongs to
|
||||
READSTRINGN(save.p, temp, sizeof(temp)); // mod it belongs to
|
||||
if (strcmp(temp, timeattackfolder)) BADSAVE
|
||||
|
||||
// P_UnArchivePlayer()
|
||||
CHECKPOS
|
||||
(void)READUINT16(save_p);
|
||||
(void)READUINT16(save.p);
|
||||
CHECKPOS
|
||||
|
||||
WRITEUINT8(save_p, numgameovers);
|
||||
WRITEUINT8(save.p, numgameovers);
|
||||
CHECKPOS
|
||||
|
||||
lives_p = save_p;
|
||||
pllives = READSINT8(save_p); // lives
|
||||
lives_p = save.p;
|
||||
pllives = READSINT8(save.p); // lives
|
||||
CHECKPOS
|
||||
if (modifylives && pllives < startinglivesbalance[numgameovers])
|
||||
{
|
||||
|
|
@ -4741,28 +4722,28 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives)
|
|||
WRITESINT8(lives_p, pllives);
|
||||
}
|
||||
|
||||
(void)READINT32(save_p); // Score
|
||||
(void)READINT32(save.p); // Score
|
||||
CHECKPOS
|
||||
(void)READINT32(save_p); // continues
|
||||
(void)READINT32(save.p); // continues
|
||||
|
||||
// File end marker check
|
||||
CHECKPOS
|
||||
switch (READUINT8(save_p))
|
||||
switch (READUINT8(save.p))
|
||||
{
|
||||
case 0xb7:
|
||||
{
|
||||
UINT8 i, banksinuse;
|
||||
CHECKPOS
|
||||
banksinuse = READUINT8(save_p);
|
||||
banksinuse = READUINT8(save.p);
|
||||
CHECKPOS
|
||||
if (banksinuse > NUM_LUABANKS)
|
||||
BADSAVE
|
||||
for (i = 0; i < banksinuse; i++)
|
||||
{
|
||||
(void)READINT32(save_p);
|
||||
(void)READINT32(save.p);
|
||||
CHECKPOS
|
||||
}
|
||||
if (READUINT8(save_p) != 0x1d)
|
||||
if (READUINT8(save.p) != 0x1d)
|
||||
BADSAVE
|
||||
}
|
||||
case 0x1d:
|
||||
|
|
@ -4772,7 +4753,7 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives)
|
|||
}
|
||||
|
||||
// done
|
||||
saved = FIL_WriteFile(backup, savebuffer, length);
|
||||
saved = FIL_WriteFile(backup, save.buffer, length);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
|
@ -4780,9 +4761,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(savebuffer);
|
||||
save_p = savebuffer = NULL;
|
||||
|
||||
P_SaveBufferFree(&save);
|
||||
}
|
||||
#undef CHECKPOS
|
||||
#undef BADSAVE
|
||||
|
|
|
|||
|
|
@ -10,9 +10,10 @@
|
|||
/// \file k_profiles.c
|
||||
/// \brief implements methods for profiles etc.
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "d_main.h" // pandf
|
||||
#include "byteptr.h" // READ/WRITE macros
|
||||
#include "p_saveg.h" // save_p
|
||||
#include "p_saveg.h" // savebuffer_t
|
||||
#include "m_misc.h" //FIL_WriteFile()
|
||||
#include "k_profiles.h"
|
||||
#include "z_zone.h"
|
||||
|
|
@ -211,73 +212,69 @@ void PR_InitNewProfile(void)
|
|||
PR_AddProfile(dprofile);
|
||||
}
|
||||
|
||||
static UINT8 *savebuffer;
|
||||
|
||||
void PR_SaveProfiles(void)
|
||||
{
|
||||
size_t length = 0;
|
||||
const size_t headerlen = strlen(PROFILEHEADER);
|
||||
UINT8 i, j, k;
|
||||
savebuffer_t save = {0};
|
||||
|
||||
save_p = savebuffer = (UINT8 *)malloc(sizeof(UINT32) + (numprofiles * sizeof(profile_t)));
|
||||
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;
|
||||
}
|
||||
|
||||
// Add header.
|
||||
WRITESTRINGN(save_p, PROFILEHEADER, headerlen);
|
||||
WRITEUINT8(save_p, PROFILEVER);
|
||||
WRITEUINT8(save_p, numprofiles);
|
||||
WRITESTRINGN(save.p, PROFILEHEADER, headerlen);
|
||||
WRITEUINT8(save.p, PROFILEVER);
|
||||
WRITEUINT8(save.p, numprofiles);
|
||||
|
||||
for (i = 1; i < numprofiles; i++)
|
||||
{
|
||||
// Names.
|
||||
WRITESTRINGN(save_p, profilesList[i]->profilename, PROFILENAMELEN);
|
||||
WRITESTRINGN(save_p, profilesList[i]->playername, MAXPLAYERNAME);
|
||||
WRITESTRINGN(save.p, profilesList[i]->profilename, PROFILENAMELEN);
|
||||
WRITESTRINGN(save.p, profilesList[i]->playername, MAXPLAYERNAME);
|
||||
|
||||
// Character and colour.
|
||||
WRITESTRINGN(save_p, profilesList[i]->skinname, SKINNAMESIZE);
|
||||
WRITEUINT16(save_p, profilesList[i]->color);
|
||||
WRITESTRINGN(save.p, profilesList[i]->skinname, SKINNAMESIZE);
|
||||
WRITEUINT16(save.p, profilesList[i]->color);
|
||||
|
||||
// Follower and colour.
|
||||
WRITESTRINGN(save_p, profilesList[i]->follower, SKINNAMESIZE);
|
||||
WRITEUINT16(save_p, profilesList[i]->followercolor);
|
||||
WRITESTRINGN(save.p, profilesList[i]->follower, SKINNAMESIZE);
|
||||
WRITEUINT16(save.p, profilesList[i]->followercolor);
|
||||
|
||||
// PWR.
|
||||
for (j = 0; j < PWRLV_NUMTYPES; j++)
|
||||
{
|
||||
WRITEUINT16(save_p, profilesList[i]->powerlevels[j]);
|
||||
WRITEUINT16(save.p, profilesList[i]->powerlevels[j]);
|
||||
}
|
||||
|
||||
// Consvars.
|
||||
WRITEUINT8(save_p, profilesList[i]->kickstartaccel);
|
||||
WRITEUINT8(save.p, profilesList[i]->kickstartaccel);
|
||||
|
||||
// Controls.
|
||||
for (j = 0; j < num_gamecontrols; j++)
|
||||
{
|
||||
for (k = 0; k < MAXINPUTMAPPING; k++)
|
||||
{
|
||||
WRITEINT32(save_p, profilesList[i]->controls[j][k]);
|
||||
WRITEINT32(save.p, profilesList[i]->controls[j][k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
length = save_p - savebuffer;
|
||||
length = save.p - save.buffer;
|
||||
|
||||
if (!FIL_WriteFile(va(pandf, srb2home, PROFILESFILE), savebuffer, length))
|
||||
if (!FIL_WriteFile(va(pandf, srb2home, PROFILESFILE), save.buffer, length))
|
||||
{
|
||||
free(savebuffer);
|
||||
P_SaveBufferFree(&save);
|
||||
I_Error("Couldn't save profiles. Are you out of Disk space / playing in a protected folder?");
|
||||
}
|
||||
free(savebuffer);
|
||||
save_p = savebuffer = NULL;
|
||||
P_SaveBufferFree(&save);
|
||||
}
|
||||
|
||||
void PR_LoadProfiles(void)
|
||||
{
|
||||
size_t length = 0;
|
||||
const size_t headerlen = strlen(PROFILEHEADER);
|
||||
UINT8 i, j, k, version;
|
||||
profile_t *dprofile = PR_MakeProfile(
|
||||
|
|
@ -288,38 +285,34 @@ void PR_LoadProfiles(void)
|
|||
gamecontroldefault,
|
||||
true
|
||||
);
|
||||
savebuffer_t save = {0};
|
||||
|
||||
length = FIL_ReadFile(va(pandf, srb2home, PROFILESFILE), &savebuffer);
|
||||
if (!length)
|
||||
if (P_SaveBufferFromFile(&save, va(pandf, srb2home, PROFILESFILE)) == false)
|
||||
{
|
||||
// No profiles. Add the default one.
|
||||
PR_AddProfile(dprofile);
|
||||
return;
|
||||
}
|
||||
|
||||
save_p = savebuffer;
|
||||
|
||||
if (strncmp(PROFILEHEADER, (const char *)savebuffer, headerlen))
|
||||
if (strncmp(PROFILEHEADER, (const char *)save.buffer, headerlen))
|
||||
{
|
||||
const char *gdfolder = "the Ring Racers folder";
|
||||
if (strcmp(srb2home,"."))
|
||||
gdfolder = srb2home;
|
||||
|
||||
Z_Free(savebuffer);
|
||||
save_p = NULL;
|
||||
P_SaveBufferFree(&save);
|
||||
I_Error("Not a valid Profile file.\nDelete %s (maybe in %s) and try again.", PROFILESFILE, gdfolder);
|
||||
}
|
||||
save_p += headerlen;
|
||||
save.p += headerlen;
|
||||
|
||||
version = READUINT8(save_p);
|
||||
version = READUINT8(save.p);
|
||||
if (version > PROFILEVER)
|
||||
{
|
||||
Z_Free(savebuffer);
|
||||
save_p = NULL;
|
||||
P_SaveBufferFree(&save);
|
||||
I_Error("Existing %s is from the future! (expected %d, got %d)", PROFILESFILE, PROFILEVER, version);
|
||||
}
|
||||
|
||||
numprofiles = READUINT8(save_p);
|
||||
numprofiles = READUINT8(save.p);
|
||||
if (numprofiles > MAXPROFILES)
|
||||
numprofiles = MAXPROFILES;
|
||||
|
||||
|
|
@ -331,12 +324,12 @@ void PR_LoadProfiles(void)
|
|||
profilesList[i]->version = PROFILEVER;
|
||||
|
||||
// Names.
|
||||
READSTRINGN(save_p, profilesList[i]->profilename, PROFILENAMELEN);
|
||||
READSTRINGN(save_p, profilesList[i]->playername, MAXPLAYERNAME);
|
||||
READSTRINGN(save.p, profilesList[i]->profilename, PROFILENAMELEN);
|
||||
READSTRINGN(save.p, profilesList[i]->playername, MAXPLAYERNAME);
|
||||
|
||||
// Character and colour.
|
||||
READSTRINGN(save_p, profilesList[i]->skinname, SKINNAMESIZE);
|
||||
profilesList[i]->color = READUINT16(save_p);
|
||||
READSTRINGN(save.p, profilesList[i]->skinname, SKINNAMESIZE);
|
||||
profilesList[i]->color = READUINT16(save.p);
|
||||
|
||||
if (profilesList[i]->color == SKINCOLOR_NONE)
|
||||
{
|
||||
|
|
@ -349,8 +342,8 @@ void PR_LoadProfiles(void)
|
|||
}
|
||||
|
||||
// Follower and colour.
|
||||
READSTRINGN(save_p, profilesList[i]->follower, SKINNAMESIZE);
|
||||
profilesList[i]->followercolor = READUINT16(save_p);
|
||||
READSTRINGN(save.p, profilesList[i]->follower, SKINNAMESIZE);
|
||||
profilesList[i]->followercolor = READUINT16(save.p);
|
||||
|
||||
if (profilesList[i]->followercolor == FOLLOWERCOLOR_MATCH
|
||||
|| profilesList[i]->followercolor == FOLLOWERCOLOR_OPPOSITE)
|
||||
|
|
@ -367,7 +360,7 @@ void PR_LoadProfiles(void)
|
|||
// PWR.
|
||||
for (j = 0; j < PWRLV_NUMTYPES; j++)
|
||||
{
|
||||
profilesList[i]->powerlevels[j] = READUINT16(save_p);
|
||||
profilesList[i]->powerlevels[j] = READUINT16(save.p);
|
||||
if (profilesList[i]->powerlevels[j] < PWRLVRECORD_MIN
|
||||
|| profilesList[i]->powerlevels[j] > PWRLVRECORD_MAX)
|
||||
{
|
||||
|
|
@ -377,7 +370,7 @@ void PR_LoadProfiles(void)
|
|||
}
|
||||
|
||||
// Consvars.
|
||||
profilesList[i]->kickstartaccel = (boolean)READUINT8(save_p);
|
||||
profilesList[i]->kickstartaccel = (boolean)READUINT8(save.p);
|
||||
|
||||
// Controls.
|
||||
for (j = 0; j < num_gamecontrols; j++)
|
||||
|
|
@ -396,7 +389,7 @@ void PR_LoadProfiles(void)
|
|||
|
||||
for (k = 0; k < MAXINPUTMAPPING; k++)
|
||||
{
|
||||
profilesList[i]->controls[j][k] = READINT32(save_p);
|
||||
profilesList[i]->controls[j][k] = READINT32(save.p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1949,6 +1949,7 @@ static waypoint_t *K_MakeWaypoint(mobj_t *const mobj)
|
|||
madewaypoint = &waypointheap[numwaypoints];
|
||||
numwaypoints++;
|
||||
|
||||
madewaypoint->mobj = NULL;
|
||||
P_SetTarget(&madewaypoint->mobj, mobj);
|
||||
|
||||
// Don't allow a waypoint that has its next ID set to itself to work
|
||||
|
|
|
|||
|
|
@ -834,7 +834,7 @@ int LUA_HookHurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 d
|
|||
return hook.status;
|
||||
}
|
||||
|
||||
void LUA_HookNetArchive(lua_CFunction archFunc)
|
||||
void LUA_HookNetArchive(lua_CFunction archFunc, savebuffer_t *save)
|
||||
{
|
||||
const hook_t * map = &hookIds[HOOK(NetVars)];
|
||||
Hook_State hook;
|
||||
|
|
@ -852,8 +852,9 @@ void LUA_HookNetArchive(lua_CFunction archFunc)
|
|||
|
||||
// tables becomes an upvalue of archFunc
|
||||
lua_pushvalue(gL, -1);
|
||||
lua_pushcclosure(gL, archFunc, 1);
|
||||
// stack: tables, archFunc
|
||||
lua_pushlightuserdata(gL, save);
|
||||
lua_pushcclosure(gL, archFunc, 2);
|
||||
// stack: tables, savebuffer_t, archFunc
|
||||
|
||||
init_hook_call(&hook, 0, res_none);
|
||||
call_mapped(&hook, map);
|
||||
|
|
|
|||
|
|
@ -1245,10 +1245,10 @@ static UINT8 ArchiveValue(UINT8 **p, int TABLESINDEX, int myindex)
|
|||
{
|
||||
polyobj_t *polyobj = *((polyobj_t **)lua_touserdata(gL, myindex));
|
||||
if (!polyobj)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
WRITEUINT8(*p, ARCH_NULL);
|
||||
else {
|
||||
WRITEUINT8(save_p, ARCH_POLYOBJ);
|
||||
WRITEUINT16(save_p, polyobj-PolyObjects);
|
||||
WRITEUINT8(*p, ARCH_POLYOBJ);
|
||||
WRITEUINT16(*p, polyobj-PolyObjects);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -1350,9 +1350,10 @@ static void ArchiveExtVars(UINT8 **p, void *pointer, const char *ptype)
|
|||
static int NetArchive(lua_State *L)
|
||||
{
|
||||
int TABLESINDEX = lua_upvalueindex(1);
|
||||
savebuffer_t *save = lua_touserdata(L, lua_upvalueindex(2));
|
||||
int i, n = lua_gettop(L);
|
||||
for (i = 1; i <= n; i++)
|
||||
ArchiveValue(&save_p, TABLESINDEX, i);
|
||||
ArchiveValue(&save->p, TABLESINDEX, i);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
|
@ -1514,7 +1515,7 @@ static UINT8 UnArchiveValue(UINT8 **p, int TABLESINDEX)
|
|||
break;
|
||||
}
|
||||
case ARCH_POLYOBJ:
|
||||
LUA_PushUserdata(gL, &PolyObjects[READUINT16(save_p)], META_POLYOBJ);
|
||||
LUA_PushUserdata(gL, &PolyObjects[READUINT16(*p)], META_POLYOBJ);
|
||||
break;
|
||||
case ARCH_SLOPE:
|
||||
LUA_PushUserdata(gL, P_SlopeById(READUINT16(*p)), META_SLOPE);
|
||||
|
|
@ -1563,9 +1564,10 @@ static void UnArchiveExtVars(UINT8 **p, void *pointer)
|
|||
static int NetUnArchive(lua_State *L)
|
||||
{
|
||||
int TABLESINDEX = lua_upvalueindex(1);
|
||||
savebuffer_t *save = lua_touserdata(L, lua_upvalueindex(2));
|
||||
int i, n = lua_gettop(L);
|
||||
for (i = 1; i <= n; i++)
|
||||
UnArchiveValue(&save_p, TABLESINDEX);
|
||||
UnArchiveValue(&save->p, TABLESINDEX);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
|
@ -1599,7 +1601,7 @@ static void UnArchiveTables(UINT8 **p)
|
|||
lua_rawset(gL, -3);
|
||||
}
|
||||
|
||||
metatableid = READUINT16(save_p);
|
||||
metatableid = READUINT16(*p);
|
||||
if (metatableid)
|
||||
{
|
||||
// setmetatable(table, registry.metatables[metatableid])
|
||||
|
|
@ -1623,7 +1625,7 @@ void LUA_Step(void)
|
|||
lua_gc(gL, LUA_GCSTEP, 1);
|
||||
}
|
||||
|
||||
void LUA_Archive(UINT8 **p)
|
||||
void LUA_Archive(savebuffer_t *save, boolean network)
|
||||
{
|
||||
INT32 i;
|
||||
thinker_t *th;
|
||||
|
|
@ -1636,10 +1638,10 @@ void LUA_Archive(UINT8 **p)
|
|||
if (!playeringame[i] && i > 0) // NEVER skip player 0, this is for dedi servs.
|
||||
continue;
|
||||
// all players in game will be archived, even if they just add a 0.
|
||||
ArchiveExtVars(p, &players[i], "player");
|
||||
ArchiveExtVars(&save->p, &players[i], "player");
|
||||
}
|
||||
|
||||
if (p == &save_p)
|
||||
if (network == true)
|
||||
{
|
||||
if (gamestate == GS_LEVEL)
|
||||
{
|
||||
|
|
@ -1650,22 +1652,22 @@ void LUA_Archive(UINT8 **p)
|
|||
|
||||
// archive function will determine when to skip mobjs,
|
||||
// and write mobjnum in otherwise.
|
||||
ArchiveExtVars(p, th, "mobj");
|
||||
ArchiveExtVars(&save->p, th, "mobj");
|
||||
}
|
||||
}
|
||||
|
||||
WRITEUINT32(*p, UINT32_MAX); // end of mobjs marker, replaces mobjnum.
|
||||
WRITEUINT32(save->p, UINT32_MAX); // end of mobjs marker, replaces mobjnum.
|
||||
|
||||
LUA_HookNetArchive(NetArchive); // call the NetArchive hook in archive mode
|
||||
LUA_HookNetArchive(NetArchive, save); // call the NetArchive hook in archive mode
|
||||
}
|
||||
|
||||
ArchiveTables(p);
|
||||
ArchiveTables(&save->p);
|
||||
|
||||
if (gL)
|
||||
lua_pop(gL, 1); // pop tables
|
||||
}
|
||||
|
||||
void LUA_UnArchive(UINT8 **p)
|
||||
void LUA_UnArchive(savebuffer_t *save, boolean network)
|
||||
{
|
||||
UINT32 mobjnum;
|
||||
INT32 i;
|
||||
|
|
@ -1678,27 +1680,27 @@ void LUA_UnArchive(UINT8 **p)
|
|||
{
|
||||
if (!playeringame[i] && i > 0) // same here, this is to synch dediservs properly.
|
||||
continue;
|
||||
UnArchiveExtVars(p, &players[i]);
|
||||
UnArchiveExtVars(&save->p, &players[i]);
|
||||
}
|
||||
|
||||
if (p == &save_p)
|
||||
if (network == true)
|
||||
{
|
||||
do {
|
||||
mobjnum = READUINT32(*p); // read a mobjnum
|
||||
mobjnum = READUINT32(save->p); // read a mobjnum
|
||||
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
|
||||
{
|
||||
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
|
||||
continue;
|
||||
if (((mobj_t *)th)->mobjnum != mobjnum) // find matching mobj
|
||||
continue;
|
||||
UnArchiveExtVars(p, th); // apply variables
|
||||
UnArchiveExtVars(&save->p, th); // apply variables
|
||||
}
|
||||
} while(mobjnum != UINT32_MAX); // repeat until end of mobjs marker.
|
||||
|
||||
LUA_HookNetArchive(NetUnArchive); // call the NetArchive hook in unarchive mode
|
||||
LUA_HookNetArchive(NetUnArchive, save); // call the NetArchive hook in unarchive mode
|
||||
}
|
||||
|
||||
UnArchiveTables(p);
|
||||
UnArchiveTables(&save->p);
|
||||
|
||||
if (gL)
|
||||
lua_pop(gL, 1); // pop tables
|
||||
|
|
|
|||
|
|
@ -57,8 +57,8 @@ void LUA_DumpFile(const char *filename);
|
|||
#endif
|
||||
fixed_t LUA_EvalMath(const char *word);
|
||||
void LUA_Step(void);
|
||||
void LUA_Archive(UINT8 **p);
|
||||
void LUA_UnArchive(UINT8 **p);
|
||||
void LUA_Archive(savebuffer_t *save, boolean network);
|
||||
void LUA_UnArchive(savebuffer_t *save, boolean network);
|
||||
|
||||
int LUA_PushGlobals(lua_State *L, const char *word);
|
||||
int LUA_WriteGlobals(lua_State *L, const char *word);
|
||||
|
|
@ -67,7 +67,7 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum); // lua_consolelib.c
|
|||
void LUA_CVarChanged(void *cvar); // lua_consolelib.c
|
||||
int Lua_optoption(lua_State *L, int narg,
|
||||
const char *def, const char *const lst[]);
|
||||
void LUA_HookNetArchive(lua_CFunction archFunc);
|
||||
void LUA_HookNetArchive(lua_CFunction archFunc, savebuffer_t *save);
|
||||
|
||||
void LUA_PushTaggableObjectArray
|
||||
( lua_State *L,
|
||||
|
|
|
|||
27
src/p_mobj.c
27
src/p_mobj.c
|
|
@ -12557,6 +12557,21 @@ static mobj_t *P_MakeSoftwareCorona(mobj_t *mo, INT32 height)
|
|||
return corona;
|
||||
}
|
||||
|
||||
void P_InitSkyboxPoint(mobj_t *mobj, mapthing_t *mthing)
|
||||
{
|
||||
mtag_t tag = Tag_FGet(&mthing->tags);
|
||||
if (tag < 0 || tag > 15)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "P_InitSkyboxPoint: Skybox ID %d of mapthing %s is not between 0 and 15!\n", tag, sizeu1((size_t)(mthing - mapthings)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (mthing->args[0])
|
||||
P_SetTarget(&skyboxcenterpnts[tag], mobj);
|
||||
else
|
||||
P_SetTarget(&skyboxviewpnts[tag], mobj);
|
||||
}
|
||||
|
||||
static boolean P_MapAlreadyHasStarPost(mobj_t *mobj)
|
||||
{
|
||||
thinker_t *th;
|
||||
|
|
@ -12602,17 +12617,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
|
|||
}
|
||||
case MT_SKYBOX:
|
||||
{
|
||||
mtag_t tag = Tag_FGet(&mthing->tags);
|
||||
if (tag < 0 || tag > 15)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "P_SetupSpawnedMapThing: Skybox ID %d of mapthing %s is not between 0 and 15!\n", tag, sizeu1((size_t)(mthing - mapthings)));
|
||||
break;
|
||||
}
|
||||
|
||||
if (mthing->args[0])
|
||||
skyboxcenterpnts[tag] = mobj;
|
||||
else
|
||||
skyboxviewpnts[tag] = mobj;
|
||||
P_InitSkyboxPoint(mobj, mthing);
|
||||
break;
|
||||
}
|
||||
case MT_EGGSTATUE:
|
||||
|
|
|
|||
3809
src/p_saveg.c
3809
src/p_saveg.c
File diff suppressed because it is too large
Load diff
|
|
@ -22,13 +22,19 @@ extern "C" {
|
|||
#pragma interface
|
||||
#endif
|
||||
|
||||
// 1024 bytes is plenty for a savegame
|
||||
#define SAVEGAMESIZE (1024)
|
||||
|
||||
// For netgames
|
||||
#define NETSAVEGAMESIZE (768*1024)
|
||||
|
||||
// Persistent storage/archiving.
|
||||
// These are the load / save game routines.
|
||||
|
||||
void P_SaveGame(INT16 mapnum);
|
||||
void P_SaveNetGame(boolean resending);
|
||||
boolean P_LoadGame(INT16 mapoverride);
|
||||
boolean P_LoadNetGame(boolean reloading);
|
||||
void P_SaveGame(savebuffer_t *save, INT16 mapnum);
|
||||
void P_SaveNetGame(savebuffer_t *save, boolean resending);
|
||||
boolean P_LoadGame(savebuffer_t *save, INT16 mapoverride);
|
||||
boolean P_LoadNetGame(savebuffer_t *save, boolean reloading);
|
||||
|
||||
mobj_t *P_FindNewPosition(UINT32 oldposition);
|
||||
|
||||
|
|
@ -42,7 +48,21 @@ struct savedata_t
|
|||
};
|
||||
|
||||
extern savedata_t savedata;
|
||||
extern UINT8 *save_p;
|
||||
|
||||
struct savebuffer_t
|
||||
{
|
||||
UINT8 *buffer;
|
||||
UINT8 *p;
|
||||
UINT8 *end;
|
||||
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"
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ UINT16 numtubewaypoints[NUMTUBEWAYPOINTSEQUENCES];
|
|||
|
||||
void P_AddTubeWaypoint(UINT8 sequence, UINT8 id, mobj_t *waypoint)
|
||||
{
|
||||
tubewaypoints[sequence][id] = waypoint;
|
||||
P_SetTarget(&tubewaypoints[sequence][id], waypoint);
|
||||
if (id >= numtubewaypoints[sequence])
|
||||
numtubewaypoints[sequence] = id + 1;
|
||||
}
|
||||
|
|
@ -722,12 +722,10 @@ void P_WriteThings(void)
|
|||
const char * filename;
|
||||
size_t i, length;
|
||||
mapthing_t *mt;
|
||||
UINT8 *savebuffer, *savebuf_p;
|
||||
savebuffer_t save = {0};
|
||||
INT16 temp;
|
||||
|
||||
savebuf_p = savebuffer = (UINT8 *)malloc(nummapthings * sizeof (mapthing_t));
|
||||
|
||||
if (!savebuf_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;
|
||||
|
|
@ -736,23 +734,22 @@ void P_WriteThings(void)
|
|||
mt = mapthings;
|
||||
for (i = 0; i < nummapthings; i++, mt++)
|
||||
{
|
||||
WRITEINT16(savebuf_p, mt->x);
|
||||
WRITEINT16(savebuf_p, mt->y);
|
||||
WRITEINT16(save.p, mt->x);
|
||||
WRITEINT16(save.p, mt->y);
|
||||
|
||||
WRITEINT16(savebuf_p, mt->angle);
|
||||
WRITEINT16(save.p, mt->angle);
|
||||
|
||||
temp = (INT16)(mt->type + ((INT16)mt->extrainfo << 12));
|
||||
WRITEINT16(savebuf_p, temp);
|
||||
WRITEUINT16(savebuf_p, mt->options);
|
||||
WRITEINT16(save.p, temp);
|
||||
WRITEUINT16(save.p, mt->options);
|
||||
}
|
||||
|
||||
length = savebuf_p - savebuffer;
|
||||
length = save.p - save.buffer;
|
||||
|
||||
filename = va("newthings-%s.lmp", G_BuildMapName(gamemap));
|
||||
|
||||
FIL_WriteFile(filename, savebuffer, length);
|
||||
free(savebuffer);
|
||||
savebuf_p = NULL;
|
||||
FIL_WriteFile(filename, save.buffer, length);
|
||||
P_SaveBufferFree(&save);
|
||||
|
||||
CONS_Printf(M_GetText("%s saved.\n"), filename);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ extern "C" {
|
|||
extern mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs
|
||||
extern mobj_t *skyboxcenterpnts[16]; // array of MT_SKYBOX centerpoint mobjs
|
||||
|
||||
void P_InitSkyboxPoint(mobj_t *mobj, mapthing_t *mthing);
|
||||
|
||||
// Amount (dx, dy) vector linedef is shifted right to get scroll amount
|
||||
#define SCROLL_SHIFT 5
|
||||
|
||||
|
|
|
|||
|
|
@ -266,6 +266,7 @@ TYPEDEF (polyfadedata_t);
|
|||
|
||||
// p_saveg.h
|
||||
TYPEDEF (savedata_t);
|
||||
TYPEDEF (savebuffer_t);
|
||||
|
||||
// p_setup.h
|
||||
TYPEDEF (levelflat_t);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue