- gamevars should be working now, there was a bad case of out of bounds access in the implementation

This commit is contained in:
Christoph Oelckers 2020-05-13 21:24:17 +02:00
parent d3652f0ed9
commit 3c8c7acaf8
4 changed files with 69 additions and 76 deletions

View file

@ -21,7 +21,6 @@ set( PCH_SOURCES
src/zz_game.cpp src/zz_game.cpp
src/zz_gamedef.cpp src/zz_gamedef.cpp
src/zz_gameexec.cpp src/zz_gameexec.cpp
src/zz_gamevars.cpp
src/zz_global.cpp src/zz_global.cpp
src/zz_interpolate.cpp src/zz_interpolate.cpp
src/zz_namesdyn.cpp src/zz_namesdyn.cpp

View file

@ -67,12 +67,32 @@ spritetype *g_sp;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// to do //
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void SerializeGameVars(FSerializer &arc) 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();
}
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -176,14 +196,12 @@ bool AddGameVar(const char *pszLabel, intptr_t lValue, unsigned dwFlags)
} }
} }
return 1; return 1;
} }
else else
{ {
// no room to add... // no room to add...
return 0; return 0;
} }
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -230,30 +248,6 @@ int GetDefID(const char *szGameLabel)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void FreeGameVars(void)
{
// call this function as many times as needed.
int i;
for(i=0;i<MAXGAMEVARS;i++)
{
if(!(aGameVars[i].dwFlags & GAMEVAR_FLAG_SYSTEM))
{
aGameVars[i].lValue=0;
aGameVars[i].szLabel[0]=0;
aGameVars[i].dwFlags=0;
}
aGameVars[i].plValue=NULL;
}
iGameVarCount=0;
return;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void ClearGameVars(void) void ClearGameVars(void)
{ {
// only call this function ONCE (at game init)... // only call this function ONCE (at game init)...
@ -274,7 +268,6 @@ void ClearGameVars(void)
// "utterly broken by design" ... // "utterly broken by design" ...
// I hope this version is saner, there's really no need to tear down and // I hope this version is saner, there's really no need to tear down and
// rebuild the complete set of game vars just to reset them to the defaults... // rebuild the complete set of game vars just to reset them to the defaults...
// It makes no sense anyway for actor gamevars because the actor list is dynamic.
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -370,12 +363,14 @@ void SetGameVarID(int id, int lValue, int sActor, int sPlayer)
if( aGameVars[id].dwFlags & GAMEVAR_FLAG_PERPLAYER ) if( aGameVars[id].dwFlags & GAMEVAR_FLAG_PERPLAYER )
{ {
// for the current player // for the current player
aGameVars[id].plArray[sPlayer]=lValue; if (sPlayer >= 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 ) else if( aGameVars[id].dwFlags & GAMEVAR_FLAG_PERACTOR )
{ {
// for the current actor // 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 ) 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].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"); Printf("INTERNAL ERROR: NULL array !!!\n");
} }
@ -566,7 +561,7 @@ void InitGameVarPointers(void)
char aszBuf[64]; char aszBuf[64];
// called from game Init AND when level is loaded... // called from game Init AND when level is loaded...
for(i=0;i<MAX_WEAPONS;i++) for(i=0;i<12/*MAX_WEAPONS*/;i++) // Setup only exists for the original 12 weapons.
{ {
sprintf(aszBuf,"WEAPON%d_CLIP",i); sprintf(aszBuf,"WEAPON%d_CLIP",i);
aplWeaponClip[i]=GetGameValuePtr(aszBuf); aplWeaponClip[i]=GetGameValuePtr(aszBuf);
@ -1230,7 +1225,7 @@ void ResetSystemDefaults(void)
for(j=0;j<MAXPLAYERS;j++) for(j=0;j<MAXPLAYERS;j++)
{ {
for(i=0;i<MAX_WEAPONS;i++) for(i=0;i<12/*MAX_WEAPONS*/;i++)
{ {
sprintf(aszBuf,"WEAPON%d_CLIP",i); sprintf(aszBuf,"WEAPON%d_CLIP",i);
aplWeaponClip[i][j]=GetGameVar(aszBuf,0, -1, j); aplWeaponClip[i][j]=GetGameVar(aszBuf,0, -1, j);

View file

@ -169,7 +169,6 @@ extern uint8_t killit_flag;
bool AddGameVar(const char *pszLabel, intptr_t lValue, unsigned dwFlags); bool AddGameVar(const char *pszLabel, intptr_t lValue, unsigned dwFlags);
int GetGameID(const char *szGameLabel); int GetGameID(const char *szGameLabel);
int GetDefID(const char *szGameLabel); int GetDefID(const char *szGameLabel);
void FreeGameVars(void);
void ClearGameVars(void); void ClearGameVars(void);
void AddSystemVars(); void AddSystemVars();
void ResetGameVars(void); void ResetGameVars(void);

View file

@ -1939,7 +1939,7 @@ end_vol4a:
if (m_coop != 1) if (m_coop != 1)
{ {
for (bssize_t weaponNum = 0; weaponNum < MAX_WEAPONS; weaponNum++) for (bssize_t weaponNum = 0; weaponNum < 12/*MAX_WEAPONS*/; weaponNum++)
{ {
auto const worksLike = WW2GI ? PWEAPON(0, weaponNum, WorksLike) : weaponNum; auto const worksLike = WW2GI ? PWEAPON(0, weaponNum, WorksLike) : weaponNum;
if (worksLike == PISTOL_WEAPON) if (worksLike == PISTOL_WEAPON)