From 9741676e79b92e8f629642c3d0ba5ce372bf3331 Mon Sep 17 00:00:00 2001 From: Spoike Date: Wed, 1 Sep 2021 07:30:48 +0000 Subject: [PATCH] Try to fix some hexen2 saved game issues. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6054 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/qclib/pr_edict.c | 4 +++- engine/qclib/progsint.h | 2 +- engine/qclib/progslib.h | 3 ++- engine/server/pr_cmds.c | 4 ++-- engine/server/pr_q1qvm.c | 1 + engine/server/savegame.c | 23 ++++++++++++++++++++--- engine/server/sv_init.c | 8 ++++---- 7 files changed, 33 insertions(+), 12 deletions(-) diff --git a/engine/qclib/pr_edict.c b/engine/qclib/pr_edict.c index 28ec6b19b..d6c75e06c 100644 --- a/engine/qclib/pr_edict.c +++ b/engine/qclib/pr_edict.c @@ -2024,7 +2024,7 @@ char *PDECL PR_SaveEnts(pubprogfuncs_t *ppf, char *buf, size_t *bufofs, size_t b int header_crc; //if 'general' block is found, this is a compleate state, otherwise, we should spawn entities like -int PDECL PR_LoadEnts(pubprogfuncs_t *ppf, const char *file, void *ctx, void (PDECL *entspawned) (pubprogfuncs_t *progfuncs, struct edict_s *ed, void *ctx, const char *entstart, const char *entend), pbool(PDECL *extendedterm)(pubprogfuncs_t *progfuncs, void *ctx, const char **extline)) +int PDECL PR_LoadEnts(pubprogfuncs_t *ppf, const char *file, void *ctx, void (PDECL *memoryreset) (pubprogfuncs_t *progfuncs, void *ctx), void (PDECL *entspawned) (pubprogfuncs_t *progfuncs, struct edict_s *ed, void *ctx, const char *entstart, const char *entend), pbool(PDECL *extendedterm)(pubprogfuncs_t *progfuncs, void *ctx, const char **extline)) { progfuncs_t *progfuncs = (progfuncs_t*)ppf; const char *datastart; @@ -2209,6 +2209,8 @@ int PDECL PR_LoadEnts(pubprogfuncs_t *ppf, const char *file, void *ctx, void (PD if (entsize == 0 && resethunk) //by the time we parse some globals, we MUST have loaded all progs { entsize = PR_InitEnts(&progfuncs->funcs, prinst.maxedicts); + if (memoryreset) + memoryreset(&progfuncs->funcs, ctx); // sv_num_edicts = numents; for (num = 0; num < numents; num++) diff --git a/engine/qclib/progsint.h b/engine/qclib/progsint.h index dc1fe4cfb..486f0927b 100644 --- a/engine/qclib/progsint.h +++ b/engine/qclib/progsint.h @@ -331,7 +331,7 @@ int PDECL Comp_Continue(pubprogfuncs_t *progfuncs); pbool PDECL PR_SetWatchPoint(pubprogfuncs_t *progfuncs, const char *key); char *PDECL PR_EvaluateDebugString(pubprogfuncs_t *progfuncs, const char *key); char *PDECL PR_SaveEnts(pubprogfuncs_t *progfuncs, char *mem, size_t *size, size_t maxsize, int mode); -int PDECL PR_LoadEnts(pubprogfuncs_t *ppf, const char *file, void *ctx, void (PDECL *entspawned) (pubprogfuncs_t *progfuncs, struct edict_s *ed, void *ctx, const char *entstart, const char *entend), pbool(PDECL *extendedterm)(pubprogfuncs_t *progfuncs, void *ctx, const char **extline)); +int PDECL PR_LoadEnts(pubprogfuncs_t *ppf, const char *file, void *ctx, void (PDECL *memoryreset) (pubprogfuncs_t *progfuncs, void *ctx), void (PDECL *entspawned) (pubprogfuncs_t *progfuncs, struct edict_s *ed, void *ctx, const char *entstart, const char *entend), pbool(PDECL *extendedterm)(pubprogfuncs_t *progfuncs, void *ctx, const char **extline)); char *PDECL PR_SaveEnt (pubprogfuncs_t *progfuncs, char *buf, size_t *size, size_t maxsize, struct edict_s *ed); struct edict_s *PDECL PR_RestoreEnt (pubprogfuncs_t *progfuncs, const char *buf, size_t *size, struct edict_s *ed); void PDECL PR_StackTrace (pubprogfuncs_t *progfuncs, int showlocals); diff --git a/engine/qclib/progslib.h b/engine/qclib/progslib.h index 678a383b3..d04ee8ffa 100644 --- a/engine/qclib/progslib.h +++ b/engine/qclib/progslib.h @@ -155,6 +155,7 @@ struct pubprogfuncs_s void (PDECL *ED_Print) (pubprogfuncs_t *prinst, struct edict_s *ed); char *(PDECL *save_ents) (pubprogfuncs_t *prinst, char *buf, size_t *size, size_t maxsize, int mode); //dump the entire progs info into one big self allocated string int (PDECL *load_ents) (pubprogfuncs_t *prinst, const char *s, void *ctx, + void (PDECL *memoryreset) (pubprogfuncs_t *progfuncs, void *ctx), void (PDECL *entspawned) (pubprogfuncs_t *progfuncs, struct edict_s *ed, void *ctx, const char *entstart, const char *entend), pbool(PDECL *extendedterm)(pubprogfuncs_t *progfuncs, void *ctx, const char **extline) ); //restore the entire progs state (or just add some more ents) (returns edicts ize) @@ -323,7 +324,7 @@ typedef union eval_s #define ED_Free(pf, ed) (*pf->EntFree) (pf, ed, false) #define ED_Clear(pf, ed) (*pf->EntClear) (pf, ed) -#define PR_LoadEnts(pf, s, ctx, entcb, extcb) (*pf->load_ents) (pf, s, ctx, entcb, extcb) +#define PR_LoadEnts(pf, s, ctx, memreset, entcb, extcb) (*pf->load_ents) (pf, s, ctx, memreset, entcb, extcb) #define PR_SaveEnts(pf, buf, size, maxsize, mode) (*pf->save_ents) (pf, buf, size, maxsize, mode) #if 0//def _DEBUG diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 4b5b7624b..225f35038 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -1427,7 +1427,7 @@ static void PR_ApplyCompilation_f (void) PR_RegisterFields(); sv.world.edict_size=PR_InitEnts(svprogfuncs, sv.world.max_edicts); - sv.world.edict_size=svprogfuncs->load_ents(svprogfuncs, s, NULL, NULL, NULL); + sv.world.edict_size=svprogfuncs->load_ents(svprogfuncs, s, NULL, NULL, NULL, NULL); PR_LoadGlabalStruct(false); @@ -1920,7 +1920,7 @@ void PR_SpawnInitialEntities(const char *file) ctx.fulldata = PR_FindGlobal(svprogfuncs, "__fullspawndata", PR_ANY, NULL); if (svprogfuncs) - sv.world.edict_size = PR_LoadEnts(svprogfuncs, file, &ctx, PR_DoSpawnInitialEntity, NULL); + sv.world.edict_size = PR_LoadEnts(svprogfuncs, file, &ctx, NULL, PR_DoSpawnInitialEntity, NULL); else sv.world.edict_size = 0; } diff --git a/engine/server/pr_q1qvm.c b/engine/server/pr_q1qvm.c index 839556d4a..81c1e7867 100755 --- a/engine/server/pr_q1qvm.c +++ b/engine/server/pr_q1qvm.c @@ -522,6 +522,7 @@ static edict_t *QDECL Q1QVMPF_EntAlloc(pubprogfuncs_t *pf, pbool object, size_t } static int QDECL Q1QVMPF_LoadEnts(pubprogfuncs_t *pf, const char *mapstring, void *ctx, + void (PDECL *memoryreset) (pubprogfuncs_t *progfuncs, void *ctx), void (PDECL *ent_callback) (pubprogfuncs_t *progfuncs, struct edict_s *ed, void *ctx, const char *entstart, const char *entend), pbool (PDECL *ext_callback)(pubprogfuncs_t *pf, void *ctx, const char **str)) { diff --git a/engine/server/savegame.c b/engine/server/savegame.c index 697660cc1..595975785 100644 --- a/engine/server/savegame.c +++ b/engine/server/savegame.c @@ -384,7 +384,6 @@ void SV_FlushLevelCache(void) Z_Free(svs.levcache); svs.levcache = cache; } - } void LoadModelsAndSounds(vfsfile_t *f) @@ -429,6 +428,24 @@ void LoadModelsAndSounds(vfsfile_t *f) sv.strings.sound_precache[i] = NULL; } +static void PDECL SV_SaveMemoryReset (pubprogfuncs_t *progfuncs, void *ctx) +{ + size_t i; + //model names are pointers to vm-accessible memory. as that memory is going away, we need to destroy and recreate, which requires preserving them. + for (i = 1; i < MAX_PRECACHE_MODELS; i++) + { + if (!sv.strings.model_precache[i]) + break; + sv.strings.model_precache[i] = PR_AddString(svprogfuncs, sv.strings.model_precache[i], 0, false); + } + for (i = 1; i < MAX_PRECACHE_SOUNDS; i++) + { + if (!sv.strings.sound_precache[i]) + break; + sv.strings.sound_precache[i] = PR_AddString(svprogfuncs, sv.strings.sound_precache[i], 0, false); + } +} + /*ignoreplayers - says to not tell gamecode (a loadgame rather than a level change)*/ qboolean SV_LoadLevelCache(const char *savename, const char *level, const char *startspot, qboolean isloadgame) { @@ -800,7 +817,7 @@ qboolean SV_LoadLevelCache(const char *savename, const char *level, const char * memset(file, 0, filelen+1); VFS_READ(f, file, filelen); file[filelen]='\0'; - sv.world.edict_size=svprogfuncs->load_ents(svprogfuncs, file, NULL, NULL, SV_ExtendedSaveData); + sv.world.edict_size=svprogfuncs->load_ents(svprogfuncs, file, NULL, SV_SaveMemoryReset, NULL, SV_ExtendedSaveData); BZ_Free(file); progstype = pt; @@ -2006,7 +2023,7 @@ static qboolean SV_Loadgame_Legacy(const char *savename, const char *filename, v strcpy(file, "loadgame"); clnum=VFS_READ(f, file+8, filelen); file[filelen+8]='\0'; - sv.world.edict_size=svprogfuncs->load_ents(svprogfuncs, file, &loadinfo, NULL, SV_ExtendedSaveData); + sv.world.edict_size=svprogfuncs->load_ents(svprogfuncs, file, &loadinfo, SV_SaveMemoryReset, NULL, SV_ExtendedSaveData); BZ_Free(file); PR_LoadGlabalStruct(false); diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index efced3db6..16f59910d 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -359,8 +359,8 @@ void SV_SaveSpawnparmsClient(client_t *client, float *transferparms) char buffer[65536*4]; size_t bufsize = 0; char *buf; - for (j=0 ; jspawn_parms[j] = 0; +// for (j=0 ; jspawn_parms[j] = 0; buf = svprogfuncs->saveent(svprogfuncs, buffer, &bufsize, sizeof(buffer), client->edict); @@ -1656,12 +1656,12 @@ MSV_OpenUserDatabase(); #ifdef SAVEDGAMES SV_FlushLevelCache(); //to make sure it's caught #endif - for (i=0 ; i