From 3c8c7acaf892269a6efef333b34b8c49b67f633e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 13 May 2020 21:24:17 +0200 Subject: [PATCH] - gamevars should be working now, there was a bad case of out of bounds access in the implementation --- source/games/duke/CMakeLists.txt | 1 - source/games/duke/src/gamevar.cpp | 141 ++++++++++++++-------------- source/games/duke/src/gamevar.h | 1 - source/games/duke/src/zz_premap.cpp | 2 +- 4 files changed, 69 insertions(+), 76 deletions(-) diff --git a/source/games/duke/CMakeLists.txt b/source/games/duke/CMakeLists.txt index 8665e096a..7e363b59f 100644 --- a/source/games/duke/CMakeLists.txt +++ b/source/games/duke/CMakeLists.txt @@ -21,7 +21,6 @@ set( PCH_SOURCES src/zz_game.cpp src/zz_gamedef.cpp src/zz_gameexec.cpp - src/zz_gamevars.cpp src/zz_global.cpp src/zz_interpolate.cpp src/zz_namesdyn.cpp diff --git a/source/games/duke/src/gamevar.cpp b/source/games/duke/src/gamevar.cpp index 4429eda14..35d0dbabb 100644 --- a/source/games/duke/src/gamevar.cpp +++ b/source/games/duke/src/gamevar.cpp @@ -67,12 +67,32 @@ spritetype *g_sp; //--------------------------------------------------------------------------- // -// to do +// // //--------------------------------------------------------------------------- void SerializeGameVars(FSerializer &arc) { + if (arc.BeginObject("gamevars")) + { + // Only save the ones which hold their own data, i.e. skip pointer variables. + for (auto& gv : aGameVars) + { + if (!(gv.dwFlags & GAMEVAR_FLAG_PLONG)) + { + if (arc.BeginObject(gv.szLabel)) + { + arc("value", gv.lValue); + if (gv.dwFlags & (GAMEVAR_FLAG_PERPLAYER | GAMEVAR_FLAG_PERACTOR)) + { + arc("array", gv.plArray); + } + arc.EndObject(); + } + } + } + arc.EndObject(); + } } //--------------------------------------------------------------------------- @@ -81,31 +101,31 @@ void SerializeGameVars(FSerializer &arc) // //--------------------------------------------------------------------------- -bool AddGameVar(const char *pszLabel, intptr_t lValue, unsigned dwFlags) +bool AddGameVar(const char* pszLabel, intptr_t lValue, unsigned dwFlags) { - + int i; int j; - int b=0; + int b = 0; - if(dwFlags & GAMEVAR_FLAG_PLONG) - dwFlags|=GAMEVAR_FLAG_SYSTEM; // force system if PLONG + if (dwFlags & GAMEVAR_FLAG_PLONG) + dwFlags |= GAMEVAR_FLAG_SYSTEM; // force system if PLONG - if(strlen(pszLabel) > (MAXVARLABEL-1) ) + if (strlen(pszLabel) > (MAXVARLABEL - 1)) { warningcount++; Printf(TEXTCOLOR_RED " * WARNING.(L%ld) Variable Name '%s' too int (max is %d)\n", line_number, pszLabel, MAXVARLABEL - 1); return 0; } - for(i=0;i= 0) aGameVars[id].plArray[sPlayer] = lValue; + else for (auto& i : aGameVars[id].plArray) i = lValue; // -1 sets all players - was undefined OOB access in WW2GI. } else if( aGameVars[id].dwFlags & GAMEVAR_FLAG_PERACTOR ) { // for the current actor - aGameVars[id].plArray[sActor]=lValue; + if (sActor >= 0) aGameVars[id].plArray[sActor]=lValue; + else for (auto& i : aGameVars[id].plArray) i = lValue; // -1 sets all actors - was undefined OOB access in WW2GI. } else if( aGameVars[id].dwFlags & GAMEVAR_FLAG_PLONG ) { @@ -422,7 +417,7 @@ int *GetGameValuePtr(char *szGameLabel) { if(aGameVars[i].dwFlags & (GAMEVAR_FLAG_PERACTOR | GAMEVAR_FLAG_PERPLAYER)) { - if(!aGameVars[i].plArray.Size() == 0) + if(aGameVars[i].plArray.Size() == 0) { Printf("INTERNAL ERROR: NULL array !!!\n"); } @@ -566,7 +561,7 @@ void InitGameVarPointers(void) char aszBuf[64]; // called from game Init AND when level is loaded... - for(i=0;i