diff --git a/source/duke3d/src/gameexec.cpp b/source/duke3d/src/gameexec.cpp index c1bc442bf..a2f092bf4 100644 --- a/source/duke3d/src/gameexec.cpp +++ b/source/duke3d/src/gameexec.cpp @@ -4420,7 +4420,7 @@ finish_qsprintf: if (newBytes != oldBytes) { Baligned_free(pValues); - pValues = (intptr_t *) Xaligned_alloc(ACTOR_VAR_ALIGNMENT, newBytes); + pValues = (intptr_t *) Xaligned_alloc(ARRAY_ALIGNMENT, newBytes); } aGameArrays[arrayNum].size = numElements; @@ -4545,7 +4545,7 @@ finish_qsprintf: Baligned_free(aGameArrays[tw].pValues); - aGameArrays[tw].pValues = newSize != 0 ? (intptr_t *)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, eltSize * newSize) : NULL; + aGameArrays[tw].pValues = newSize != 0 ? (intptr_t *)Xaligned_alloc(ARRAY_ALIGNMENT, eltSize * newSize) : NULL; aGameArrays[tw].size = newSize; if (oldSize != 0) @@ -5739,7 +5739,7 @@ void G_SaveMapState(void) if (pMapInfo->savedstate == NULL) { - pMapInfo->savedstate = (mapstate_t *) Xaligned_alloc(16, sizeof(mapstate_t)); + pMapInfo->savedstate = (mapstate_t *) Xaligned_alloc(ACTOR_VAR_ALIGNMENT, sizeof(mapstate_t)); Bmemset(pMapInfo->savedstate, 0, sizeof(mapstate_t)); } @@ -5824,14 +5824,14 @@ void G_SaveMapState(void) if (aGameVars[i].flags & GAMEVAR_PERPLAYER) { if (!save->vars[i]) - save->vars[i] = (intptr_t *)Xaligned_alloc(16, MAXPLAYERS * sizeof(intptr_t)); - Bmemcpy(&save->vars[i][0],&aGameVars[i].pValues[0],sizeof(intptr_t) * MAXPLAYERS); + save->vars[i] = (intptr_t *)Xaligned_alloc(PLAYER_VAR_ALIGNMENT, MAXPLAYERS * sizeof(intptr_t)); + Bmemcpy(&save->vars[i][0], aGameVars[i].pValues, sizeof(intptr_t) * MAXPLAYERS); } else if (aGameVars[i].flags & GAMEVAR_PERACTOR) { if (!save->vars[i]) - save->vars[i] = (intptr_t *)Xaligned_alloc(16, MAXSPRITES * sizeof(intptr_t)); - Bmemcpy(&save->vars[i][0],&aGameVars[i].pValues[0],sizeof(intptr_t) * MAXSPRITES); + save->vars[i] = (intptr_t *)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, MAXSPRITES * sizeof(intptr_t)); + Bmemcpy(&save->vars[i][0], aGameVars[i].pValues, sizeof(intptr_t) * MAXSPRITES); } else save->vars[i] = (intptr_t *)aGameVars[i].global; } @@ -5841,10 +5841,10 @@ void G_SaveMapState(void) if ((aGameArrays[i].flags & GAMEARRAY_RESTORE) == 0) continue; - if (!save->arrays[i]) - save->arrays[i] = (intptr_t *)Xaligned_alloc(16, Gv_GetArrayAllocSize(i)); - - Bmemcpy(&save->arrays[i][0], &aGameArrays[i].pValues[0], Gv_GetArrayAllocSize(i)); + save->arraysiz[i] = aGameArrays[i].size; + Baligned_free(save->arrays[i]); + save->arrays[i] = (intptr_t *)Xaligned_alloc(ARRAY_ALIGNMENT, Gv_GetArrayAllocSize(i)); + Bmemcpy(&save->arrays[i][0], aGameArrays[i].pValues, Gv_GetArrayAllocSize(i)); } #else int32_t slen; @@ -5955,25 +5955,29 @@ void G_RestoreMapState(void) if (aGameVars[i].flags & GAMEVAR_PERPLAYER) { if (!pSavedState->vars[i]) continue; - Bmemcpy(&aGameVars[i].pValues[0],&pSavedState->vars[i][0],sizeof(intptr_t) * MAXPLAYERS); + Bmemcpy(aGameVars[i].pValues, pSavedState->vars[i], sizeof(intptr_t) * MAXPLAYERS); } else if (aGameVars[i].flags & GAMEVAR_PERACTOR) { if (!pSavedState->vars[i]) continue; - Bmemcpy(&aGameVars[i].pValues[0],&pSavedState->vars[i][0],sizeof(intptr_t) * MAXSPRITES); + Bmemcpy(aGameVars[i].pValues, pSavedState->vars[i], sizeof(intptr_t) * MAXSPRITES); } else aGameVars[i].global = (intptr_t)pSavedState->vars[i]; } - Gv_RefreshPointers(); - for (bssize_t i=g_gameArrayCount-1; i>=0; i--) { - if ((aGameArrays[i].flags & GAMEARRAY_RESTORE) == 0 || !pSavedState->arrays[i]) + if ((aGameArrays[i].flags & GAMEARRAY_RESTORE) == 0) continue; - Bmemcpy(&aGameArrays[i].pValues[0], &pSavedState->arrays[i][0], Gv_GetArrayAllocSize(i)); + aGameArrays[i].size = pSavedState->arraysiz[i]; + Baligned_free(aGameArrays[i].pValues); + aGameArrays[i].pValues = (intptr_t *) Xaligned_alloc(ARRAY_ALIGNMENT, Gv_GetArrayAllocSize(i)); + + Bmemcpy(aGameArrays[i].pValues, pSavedState->arrays[i], Gv_GetArrayAllocSize(i)); } + + Gv_RefreshPointers(); #else if (pSavedState->savecode) { diff --git a/source/duke3d/src/gamevars.cpp b/source/duke3d/src/gamevars.cpp index ed8ed3639..3e6f3cb08 100644 --- a/source/duke3d/src/gamevars.cpp +++ b/source/duke3d/src/gamevars.cpp @@ -92,7 +92,7 @@ int Gv_Free(void) // Calls Gv_Free() and in addition frees the labels of all game variables and // arrays. -// Only call this function ONCE... +// Only call this function during initialization or at exit void Gv_Clear(void) { int gameVarCount = Gv_Free(); @@ -109,21 +109,13 @@ void Gv_Clear(void) int Gv_ReadSave(int32_t kFile) { - char savedstate[MAXVOLUMES*MAXLEVELS]; char tbuf[12]; if (kread(kFile, tbuf, 12)!=12) goto corrupt; if (Bmemcmp(tbuf, "BEG: EDuke32", 12)) { OSD_Printf("BEG ERR\n"); return 2; } - Bmemset(savedstate, 0, sizeof(savedstate)); - - // AddLog("Reading gamevars from savegame"); - Gv_Free(); // nuke 'em from orbit, it's the only way to be sure... - // Bsprintf(g_szBuf,"CP:%s %d",__FILE__,__LINE__); - // AddLog(g_szBuf); - if (kdfread(&g_gameVarCount,sizeof(g_gameVarCount),1,kFile) != 1) goto corrupt; for (bssize_t i=0; ivars[j]) - g_mapInfo[i].savedstate->vars[j] = (intptr_t *)Xaligned_alloc(PLAYER_VAR_ALIGNMENT, MAXPLAYERS * sizeof(intptr_t)); - if (kdfread(&g_mapInfo[i].savedstate->vars[j][0],sizeof(intptr_t) * MAXPLAYERS, 1, kFile) != 1) goto corrupt; - } - else if (aGameVars[j].flags & GAMEVAR_PERACTOR) - { -// if (!g_mapInfo[i].savedstate->vars[j]) - g_mapInfo[i].savedstate->vars[j] = (intptr_t *)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, MAXSPRITES * sizeof(intptr_t)); - if (kdfread(&g_mapInfo[i].savedstate->vars[j][0],sizeof(intptr_t), MAXSPRITES, kFile) != MAXSPRITES) goto corrupt; - } - } + G_FreeMapState(i); - for (bssize_t j=0; jarrays[j] = (intptr_t *) Xaligned_alloc(16, Gv_GetArrayAllocSize(j)); - if (kdfread(&g_mapInfo[i].savedstate->arrays[j][0], Gv_GetArrayAllocSize(j), 1, kFile) != (int32_t)Gv_GetArrayAllocSize(j)) goto corrupt; - } - } - else + if (!savedstate[i]) + continue; + + g_mapInfo[i].savedstate = (mapstate_t *)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, sizeof(mapstate_t)); + if (kdfread(g_mapInfo[i].savedstate, 1, sizeof(mapstate_t), kFile) != sizeof(mapstate_t)) return -8; + + mapstate_t &sv = *g_mapInfo[i].savedstate; + + for (bssize_t j = 0; j < g_gameVarCount; j++) { - G_FreeMapState(i); + if (aGameVars[j].flags & GAMEVAR_NORESET) continue; + if (aGameVars[j].flags & GAMEVAR_PERPLAYER) + { + sv.vars[j] = (intptr_t *) Xaligned_alloc(PLAYER_VAR_ALIGNMENT, MAXPLAYERS * sizeof(intptr_t)); + if (kdfread(sv.vars[j], sizeof(intptr_t) * MAXPLAYERS, 1, kFile) != 1) return -9; + } + else if (aGameVars[j].flags & GAMEVAR_PERACTOR) + { + sv.vars[j] = (intptr_t *) Xaligned_alloc(ACTOR_VAR_ALIGNMENT, MAXSPRITES * sizeof(intptr_t)); + if (kdfread(sv.vars[j], sizeof(intptr_t), MAXSPRITES, kFile) != MAXSPRITES) return -10; + } } + + if (kdfread(sv.arraysiz, sizeof(sv.arraysiz), 1, kFile) < 1) + return -11; + + for (bssize_t j = 0; j < g_gameArrayCount; j++) + if (aGameArrays[j].flags & GAMEARRAY_RESTORE) + { + size_t const siz = Gv_GetArrayAllocSizeForCount(j, sv.arraysiz[j]); + sv.arrays[j] = (intptr_t *) Xaligned_alloc(ARRAY_ALIGNMENT, siz); + if (kdfread(sv.arrays[j], siz, 1, kFile) < 1) return -12; + } } - if (kread(kFile, tbuf, 12)!=12) goto corrupt; + if (kread(kFile, tbuf, 12) != 12) return -13; if (Bmemcmp(tbuf, "EOF: EDuke32", 12)) { OSD_Printf("EOF ERR\n"); return 2; } -# if 0 - { - FILE *fp; - AddLog("Dumping Vars..."); - fp=fopen("xxx.txt","w"); - if (fp) - { - Gv_DumpValues(fp); - fclose(fp); - } - AddLog("Done Dumping..."); - } -# endif return 0; + corrupt: - return 1; + return -7; } void Gv_WriteSave(FILE *fil) { - char savedstate[MAXVOLUMES*MAXLEVELS]; - - Bmemset(savedstate, 0, sizeof(savedstate)); - // AddLog("Saving Game Vars to File"); fwrite("BEG: EDuke32", 12, 1, fil); dfwrite(&g_gameVarCount,sizeof(g_gameVarCount),1,fil); - for (bssize_t i=0; ivars[j][0],sizeof(intptr_t) * MAXPLAYERS, 1, fil); - } - else if (aGameVars[j].flags & GAMEVAR_PERACTOR) - { - dfwrite(&g_mapInfo[i].savedstate->vars[j][0],sizeof(intptr_t), MAXSPRITES, fil); - } - } - - for (bssize_t j=0; jarrays[j][0], Gv_GetArrayAllocSize(j), 1, fil); + if (aGameVars[j].flags & GAMEVAR_NORESET) continue; + if (aGameVars[j].flags & GAMEVAR_PERPLAYER) + dfwrite(sv.vars[j], sizeof(intptr_t) * MAXPLAYERS, 1, fil); + else if (aGameVars[j].flags & GAMEVAR_PERACTOR) + dfwrite(sv.vars[j], sizeof(intptr_t), MAXSPRITES, fil); } + dfwrite(sv.arraysiz, sizeof(sv.arraysiz), 1, fil); + + for (bssize_t j = 0; j < g_gameArrayCount; j++) + if (aGameArrays[j].flags & GAMEARRAY_RESTORE) + { + dfwrite(sv.arrays[j], Gv_GetArrayAllocSizeForCount(j, sv.arraysiz[j]), 1, fil); + } + } + fwrite("EOF: EDuke32", 12, 1, fil); } @@ -463,7 +433,7 @@ void Gv_NewArray(const char *pszLabel, void *arrayptr, intptr_t asize, uint32_t int const allocSize = Gv_GetArrayAllocSize(i); aGameArrays[i].flags |= GAMEARRAY_ALLOCATED; - aGameArrays[i].pValues = (intptr_t *) Xaligned_alloc(ACTOR_VAR_ALIGNMENT, allocSize); + aGameArrays[i].pValues = (intptr_t *) Xaligned_alloc(ARRAY_ALIGNMENT, allocSize); Bmemset(aGameArrays[i].pValues, 0, allocSize); } @@ -473,9 +443,6 @@ void Gv_NewArray(const char *pszLabel, void *arrayptr, intptr_t asize, uint32_t void Gv_NewVar(const char *pszLabel, intptr_t lValue, uint32_t dwFlags) { - //Bsprintf(g_szBuf,"Gv_NewVar(%s, %d, %X)",pszLabel, lValue, dwFlags); - //AddLog(g_szBuf); - if (EDUKE32_PREDICT_FALSE(g_gameVarCount >= MAXGAMEVARS)) { g_errorCnt++; diff --git a/source/duke3d/src/gamevars.h b/source/duke3d/src/gamevars.h index 89251c992..3cfc94e13 100644 --- a/source/duke3d/src/gamevars.h +++ b/source/duke3d/src/gamevars.h @@ -54,6 +54,8 @@ enum GamevarFlags_t #define PLAYER_VAR_ALIGNMENT (sizeof(intptr_t)) #define ACTOR_VAR_ALIGNMENT 16 +#define ARRAY_ALIGNMENT 16 + # define MAXGAMEARRAYS (MAXGAMEVARS>>2) // must be strictly smaller than MAXGAMEVARS # define MAXARRAYLABEL MAXVARLABEL diff --git a/source/duke3d/src/premap.cpp b/source/duke3d/src/premap.cpp index 968794c36..cea7f352d 100644 --- a/source/duke3d/src/premap.cpp +++ b/source/duke3d/src/premap.cpp @@ -2029,13 +2029,21 @@ void G_FreeMapState(int levelNum) #if !defined LUNATIC for (bssize_t j=0; jsavedstate->vars[j]); + ALIGNED_FREE_AND_NULL(pMapInfo->savedstate->vars[j]); + } + + for (bssize_t j=0; jsavedstate->arrays[j]); } #else Bfree(pMapInfo->savedstate->savecode); #endif - Baligned_free(pMapInfo->savedstate); - pMapInfo->savedstate = NULL; + + ALIGNED_FREE_AND_NULL(pMapInfo->savedstate); } diff --git a/source/duke3d/src/savegame.cpp b/source/duke3d/src/savegame.cpp index 8688337e8..189b49073 100644 --- a/source/duke3d/src/savegame.cpp +++ b/source/duke3d/src/savegame.cpp @@ -2038,7 +2038,9 @@ static int32_t doloadplayer2(int32_t fil, uint8_t **memptr) PRINTSIZE("animisc"); #if !defined LUNATIC - if (Gv_ReadSave(fil)) return -7; + int i; + + if ((i = Gv_ReadSave(fil))) return i; if (mem) { diff --git a/source/duke3d/src/sector.h b/source/duke3d/src/sector.h index fbf145b60..3349ff884 100644 --- a/source/duke3d/src/sector.h +++ b/source/duke3d/src/sector.h @@ -90,6 +90,7 @@ typedef struct { #if !defined LUNATIC intptr_t *vars[MAXGAMEVARS]; intptr_t *arrays[MAXGAMEARRAYS]; + int32_t arraysiz[MAXGAMEARRAYS]; #else char *savecode; #endif