PCExhumed: Improve the cheat code fixes in CheckKeys.

- Replace direct calls to strtok with calls to a new wrapper function,
safeStrtok. Whenever strtok returns a null pointer, safeStrtok returns
an empty string instead. This should assist with replicating
the behaviors with the DOS EXE, without leading to crashes.
- This way, the "GOTO" and "CREATURE" codes are fixed.
The code handling "LEVEL" is additionally simplified.
- The code executed if nStringLen == 0 || pToken == NULL is now gone.
As is the case under DOS, if you enter a non-empty string which isn't
matched at all, sHollyStr will be emptified, but you'll otherwise
still be able to enter a code, with no need to retype "HOLLY".
This commit is contained in:
NY00123 2020-01-05 21:20:33 +02:00 committed by Christoph Oelckers
parent 134122335b
commit d5d60afdc3

View file

@ -979,6 +979,13 @@ void mysetbrightness(char nBrightness)
g_visibility = 2048 - (nBrightness << 9); g_visibility = 2048 - (nBrightness << 9);
} }
// Replicate original DOS EXE behaviour when pointer is null
static const char *safeStrtok(char *s, const char *d)
{
const char *r = strtok(s, d);
return r ? r : "";
}
void CheckKeys() void CheckKeys()
{ {
if (buttonMap.ButtonDown(gamefunc_Enlarge_Screen)) if (buttonMap.ButtonDown(gamefunc_Enlarge_Screen))
@ -1074,21 +1081,16 @@ void CheckKeys()
if (ch == asc_Enter) if (ch == asc_Enter)
{ {
char *pToken = strtok(sHollyStr, " "); const char *pToken = safeStrtok(sHollyStr, " ");
if (nStringLen == 0 || pToken == NULL) // bjd - added this check. watcom allows passing NULL to strcmp so the below checks will all fail OK on DOS but will cause a crash on Windows if (!strcmp(pToken, "GOTO"))
{
bHolly = kFalse;
StatusMessage(1, " ");
}
else if (!strcmp(pToken, "GOTO"))
{ {
// move player to X, Y coordinates // move player to X, Y coordinates
int nSprite = PlayerList[0].nSprite; int nSprite = PlayerList[0].nSprite;
pToken = strtok(NULL, ","); pToken = safeStrtok(NULL, ",");
sprite[nSprite].x = atoi(pToken); sprite[nSprite].x = atoi(pToken);
pToken = strtok(NULL, ","); pToken = safeStrtok(NULL, ",");
sprite[nSprite].y = atoi(pToken); sprite[nSprite].y = atoi(pToken);
setsprite(nSprite, &sprite[nSprite].pos); setsprite(nSprite, &sprite[nSprite].pos);
@ -1096,14 +1098,9 @@ void CheckKeys()
} }
else if (!strcmp(pToken, "LEVEL")) else if (!strcmp(pToken, "LEVEL"))
{ {
pToken = strtok(NULL, " "); pToken = safeStrtok(NULL, " ");
if (pToken) {
levelnew = atoi(pToken); levelnew = atoi(pToken);
} }
else {
levelnew = 0; // replicate original DOS EXE behaviour when no level number is specified.
}
}
else if (!strcmp(pToken, "DOORS")) else if (!strcmp(pToken, "DOORS"))
{ {
for (int i = 0; i < kMaxChannels; i++) for (int i = 0; i < kMaxChannels; i++)
@ -1126,7 +1123,7 @@ void CheckKeys()
// i = nNetPlayerCount; // i = nNetPlayerCount;
if (!nNetPlayerCount) if (!nNetPlayerCount)
{ {
pToken = strtok(NULL, " "); pToken = safeStrtok(NULL, " ");
switch (atoi(pToken)) switch (atoi(pToken))
{ {
// TODO - enums? // TODO - enums?