add oneshot and watchmode to cheat engine

This commit is contained in:
dinkc64 2016-09-10 23:17:29 +00:00
parent e8f8e3155a
commit 58548d1577
3 changed files with 71 additions and 13 deletions

View File

@ -53,12 +53,13 @@ INT32 CheatUpdate()
return 0;
}
INT32 CheatEnable(INT32 nCheat, INT32 nOption)
INT32 CheatEnable(INT32 nCheat, INT32 nOption) // -1 / 0 - disable, -2 disable & don't undo memory
{
INT32 nCurrentCheat = 0;
CheatInfo* pCurrentCheat = pCheatInfo;
CheatAddressInfo* pAddressInfo;
INT32 nOpenCPU = -1;
INT32 dontwriteback = 0;
if (!bCheatsAllowed) {
return 1;
@ -75,7 +76,8 @@ INT32 CheatEnable(INT32 nCheat, INT32 nOption)
if (nCurrentCheat == nCheat) { // Cheat found, let's process it.
INT32 deactivate = 0;
if (nOption == -1 || nOption == 0) {
if (nOption == -1 || nOption == 0 || nOption == -2) { // -2 = dont write back previous
if (nOption == -2) dontwriteback = 1;
nOption = pCurrentCheat->nDefault;
deactivate = 1;
}
@ -105,10 +107,12 @@ INT32 CheatEnable(INT32 nCheat, INT32 nOption)
cheat_subptr->open(cheat_ptr->nCPU);
}
// Write back original values to memory
bprintf(0, _T("Cheat #%d, option #%d. action: "), nCheat, nOption);
bprintf(0, _T("Undo cheat @ 0x%X -> 0x%X.\n"), pAddressInfo->nAddress, pAddressInfo->nOriginalValue);
cheat_subptr->write(pAddressInfo->nAddress, pAddressInfo->nOriginalValue);
if (!dontwriteback) {
// Write back original values to memory
bprintf(0, _T("Cheat #%d, option #%d. action: "), nCheat, nOption);
bprintf(0, _T("Undo cheat @ 0x%X -> 0x%X.\n"), pAddressInfo->nAddress, pAddressInfo->nOriginalValue);
cheat_subptr->write(pAddressInfo->nAddress, pAddressInfo->nOriginalValue);
}
pAddressInfo++;
}
nOption = 0; // Set back to 0 (see above line: nOption = 1;)
@ -131,7 +135,15 @@ INT32 CheatEnable(INT32 nCheat, INT32 nOption)
pAddressInfo->nOriginalValue = cheat_subptr->read(pAddressInfo->nAddress);
bprintf(0, _T("Cheat #%d, option #%d. action: "), nCheat, nOption);
bprintf(0, _T("Apply cheat @ 0x%X -> 0x%X. (Undo 0x%X)\n"), pAddressInfo->nAddress, pAddressInfo->nValue, pAddressInfo->nOriginalValue);
if (pCurrentCheat->bWatchMode) {
bprintf(0, _T("Watch memory @ 0x%X (0x%X)\n"), pAddressInfo->nAddress, pAddressInfo->nOriginalValue);
} else
if (pCurrentCheat->bOneShot) {
bprintf(0, _T("Apply cheat @ 0x%X -> 0x%X. (Before 0x%X - One-Shot mode)\n"), pAddressInfo->nAddress, pAddressInfo->nValue, pAddressInfo->nOriginalValue);
pCurrentCheat->bOneShot = 3; // re-load the one-shot frame counter
} else {
bprintf(0, _T("Apply cheat @ 0x%X -> 0x%X. (Undo 0x%X)\n"), pAddressInfo->nAddress, pAddressInfo->nValue, pAddressInfo->nOriginalValue);
}
if (pCurrentCheat->nType != 0) {
if (pAddressInfo->nCPU != nOpenCPU) {
@ -145,8 +157,10 @@ INT32 CheatEnable(INT32 nCheat, INT32 nOption)
cheat_subptr->open(cheat_ptr->nCPU);
}
// Activate the cheat
cheat_subptr->write(pAddressInfo->nAddress, pAddressInfo->nValue);
if (!pCurrentCheat->bWatchMode) {
// Activate the cheat
cheat_subptr->write(pAddressInfo->nAddress, pAddressInfo->nValue);
}
}
pAddressInfo++;
@ -183,6 +197,10 @@ INT32 CheatEnable(INT32 nCheat, INT32 nOption)
return 1;
}
#if defined (BUILD_WIN32)
extern INT32 VidSNewTinyMsg(const TCHAR* pText, INT32 nRGB = 0, INT32 nDuration = 0, INT32 nPriority = 5);
#endif
INT32 CheatApply()
{
if (!bCheatsEnabled) {
@ -190,6 +208,7 @@ INT32 CheatApply()
}
INT32 nOpenCPU = -1;
INT32 nCurrentCheat = 0;
CheatInfo* pCurrentCheat = pCheatInfo;
CheatAddressInfo* pAddressInfo;
@ -209,11 +228,32 @@ INT32 CheatApply()
cheat_subptr->open(cheat_ptr->nCPU);
}
cheat_subptr->write(pAddressInfo->nAddress, pAddressInfo->nValue);
if (pCurrentCheat->bWatchMode) {
// Watch address mode, Win32-only for now.
#if defined (BUILD_WIN32)
pAddressInfo->nOriginalValue = cheat_subptr->read(pAddressInfo->nAddress);
wchar_t framestring[32];
swprintf(framestring, L"%X", pAddressInfo->nOriginalValue);
VidSNewTinyMsg(framestring, 0, 5, 5);
#endif
} else {
// update the cheat
cheat_subptr->write(pAddressInfo->nAddress, pAddressInfo->nValue);
}
pAddressInfo++;
}
if (pCurrentCheat->bOneShot == 2) {
if (nOpenCPU != -1) {
cheat_subptr->close();
nOpenCPU = -1;
}
bprintf(0, _T("One-Shot cheat #%d ends.\n"), nCurrentCheat);
CheatEnable(nCurrentCheat, -2);
}
if (pCurrentCheat->bOneShot > 1) pCurrentCheat->bOneShot--;
}
pCurrentCheat = pCurrentCheat->pNext;
nCurrentCheat++;
}
if (nOpenCPU != -1) {

View File

@ -19,10 +19,12 @@ struct CheatOption {
struct CheatInfo {
struct CheatInfo* pNext;
struct CheatInfo* pPrevious;
INT32 nType; // Cheat type
INT32 nType; // Cheat type
INT32 nStatus; // 0 = Inactive
INT32 nCurrent; // Currently selected option
INT32 nDefault; // Default option
INT32 bOneShot; // For one-shot cheats, also acts as a frame counter for them.
INT32 bWatchMode; // Display value on screen
TCHAR szCheatName[CHEAT_MAX_NAME];
struct CheatOption* pOption[CHEAT_MAX_OPTIONS];
};

View File

@ -520,9 +520,11 @@ static INT32 ConfigParseMAMEFile()
}
// Fill in defaults
pCurrentCheat->nType = 0; // Default to cheat type 0 (apply each frame)
pCurrentCheat->nType = 0; // Default to cheat type 0 (apply each frame)
pCurrentCheat->nStatus = -1; // Disable cheat
pCurrentCheat->nDefault = 0; // Set default option
pCurrentCheat->bOneShot = 0; // Set default option (off)
pCurrentCheat->bWatchMode = 0; // Set default option (off)
_tcsncpy (pCurrentCheat->szCheatName, tmp, QUOTE_MAX);
@ -536,7 +538,14 @@ static INT32 ConfigParseMAMEFile()
if (nAddress) {
n++;
OptionName(tmp);
if (flags & 0x1) {
pCurrentCheat->bOneShot = 1; // apply once and stop
}
if (flags & 0x6) {
pCurrentCheat->bWatchMode = 1; // display value @ address
}
OptionName(tmp);
AddressInfo();
} else {
menu = 1;
@ -549,6 +558,13 @@ static INT32 ConfigParseMAMEFile()
n++;
nCurrentAddress = 0;
if (flags & 0x1) {
pCurrentCheat->bOneShot = 1; // apply once and stop
}
if (flags & 0x6) {
pCurrentCheat->bWatchMode = 1; // display value @ address
}
OptionName(tmp);
AddressInfo();