2020-05-17 06:51:49 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// Copyright 1999-2016 Randy Heit
|
2020-07-04 08:22:20 +00:00
|
|
|
// Copyright 2002-2016 Christoph Oelckers
|
2020-05-17 06:51:49 +00:00
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program. If not, see http://www.gnu.org/licenses/
|
|
|
|
//
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// DESCRIPTION:
|
2020-07-04 08:22:20 +00:00
|
|
|
// Generic Cheat code.
|
2020-05-17 06:51:49 +00:00
|
|
|
//
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#include "c_cvars.h"
|
|
|
|
#include "c_dispatch.h"
|
|
|
|
#include "d_event.h"
|
2020-07-04 08:22:20 +00:00
|
|
|
#include "cheathandler.h"
|
2020-07-04 13:51:02 +00:00
|
|
|
#include "printf.h"
|
|
|
|
#include "gamestruct.h"
|
2020-05-17 06:51:49 +00:00
|
|
|
|
2020-07-04 20:03:22 +00:00
|
|
|
static cheatseq_t *cheatlist;
|
2020-07-04 08:22:20 +00:00
|
|
|
static int numcheats;
|
2020-05-17 06:51:49 +00:00
|
|
|
|
2020-07-04 08:22:20 +00:00
|
|
|
void SetCheats(cheatseq_t *cht, int count)
|
2020-05-17 06:51:49 +00:00
|
|
|
{
|
2020-07-04 20:03:22 +00:00
|
|
|
cheatlist = cht;
|
2020-07-04 08:22:20 +00:00
|
|
|
numcheats = count;
|
2020-05-17 06:51:49 +00:00
|
|
|
}
|
|
|
|
|
2020-07-04 08:22:20 +00:00
|
|
|
CVAR(Bool, nocheats, false, CVAR_ARCHIVE)
|
2020-05-17 06:51:49 +00:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// FUNC CheatAddkey
|
|
|
|
//
|
|
|
|
// Returns true if the added key completed the cheat, false otherwise.
|
|
|
|
//
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
static bool CheatAddKey (cheatseq_t *cheat, uint8_t key, bool *eat)
|
|
|
|
{
|
|
|
|
if (cheat->Pos == NULL)
|
|
|
|
{
|
|
|
|
cheat->Pos = cheat->Sequence;
|
|
|
|
cheat->CurrentArg = 0;
|
|
|
|
}
|
2020-07-04 13:51:02 +00:00
|
|
|
if (*cheat->Pos == '#' && key >= '0' && key <= '9')
|
2020-05-17 06:51:49 +00:00
|
|
|
{
|
|
|
|
*eat = true;
|
|
|
|
cheat->Args[cheat->CurrentArg++] = key;
|
|
|
|
cheat->Pos++;
|
|
|
|
}
|
|
|
|
else if (key == *cheat->Pos)
|
|
|
|
{
|
|
|
|
cheat->Pos++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cheat->Pos = cheat->Sequence;
|
2020-07-04 08:22:20 +00:00
|
|
|
cheat->CurrentArg = 0;
|
2020-05-17 06:51:49 +00:00
|
|
|
}
|
|
|
|
if (*cheat->Pos == 0)
|
|
|
|
{
|
|
|
|
cheat->Pos = cheat->Sequence;
|
2020-07-04 08:22:20 +00:00
|
|
|
cheat->CurrentArg = 0;
|
2020-05-17 06:51:49 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-07-04 08:22:20 +00:00
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// Respond to keyboard input events, intercept cheats.
|
|
|
|
// [RH] Cheats eat the last keypress used to trigger them
|
|
|
|
//
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
bool Cheat_Responder (event_t *ev)
|
|
|
|
{
|
|
|
|
bool eat = false;
|
|
|
|
|
|
|
|
if (nocheats)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (ev->type == EV_KeyDown)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2020-07-04 20:03:22 +00:00
|
|
|
auto cheats = cheatlist;
|
2020-07-04 08:22:20 +00:00
|
|
|
for (i = 0; i < numcheats; i++, cheats++)
|
|
|
|
{
|
|
|
|
if (CheatAddKey (cheats, (uint8_t)ev->data2, &eat))
|
|
|
|
{
|
|
|
|
if (cheats->DontCheck || !CheckCheatmode ())
|
|
|
|
{
|
|
|
|
eat |= cheats->Handler (cheats);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (cheats->Pos - cheats->Sequence > 2)
|
|
|
|
{ // If more than two characters into the sequence,
|
2020-07-04 13:51:02 +00:00
|
|
|
// eat the keypress.
|
2020-07-04 08:22:20 +00:00
|
|
|
eat = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return eat;
|
|
|
|
}
|
|
|
|
|
2020-07-04 13:51:02 +00:00
|
|
|
void PlaybackCheat(const char *p)
|
|
|
|
{
|
|
|
|
if (!gi->CheatAllowed(false))
|
|
|
|
{
|
|
|
|
event_t ev = { EV_KeyDown, 0, 0, -1 };
|
|
|
|
Cheat_Responder(&ev); // Reset the parser by passing a non-existent key.
|
|
|
|
for (; *p; p++)
|
|
|
|
{
|
|
|
|
// just play the cheat command through the event parser
|
|
|
|
ev.data2 = *p;
|
|
|
|
Cheat_Responder(&ev);
|
|
|
|
}
|
|
|
|
ev.data2 = -1;
|
|
|
|
Cheat_Responder(&ev);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
Printf("activatecheat: Cheats not allowed.\n");
|
|
|
|
|
|
|
|
}
|