Add multiline cheat support. Delimited based on any non-hexdec character.

Individual codes can be split into two parts [8+4char] or in a single part [12char].
This commit is contained in:
iLag 2017-04-06 10:46:37 -07:00
parent 55ea4eee14
commit 19ab2e1081

View File

@ -20,6 +20,10 @@
#include "../pgxp/pgxp_main.h"
#include <vector>
#include <iostream>
#define ISHEXDEC ((codeLine[cursor]>='0') && (codeLine[cursor]<='9')) || ((codeLine[cursor]>='a') && (codeLine[cursor]<='f')) || ((codeLine[cursor]>='A') && (codeLine[cursor]<='F'))
struct retro_perf_callback perf_cb;
retro_get_cpu_features_t perf_get_cpu_features_cb = NULL;
retro_log_printf_t log_cb;
@ -4174,42 +4178,81 @@ size_t retro_get_memory_size(unsigned type)
void retro_cheat_reset(void)
{
MDFN_FlushGameCheats(1);
MDFN_FlushGameCheats(1);
}
void retro_cheat_set(unsigned index, bool enabled, const char * code)
void retro_cheat_set(unsigned index, bool enabled, const char * codeLine)
{
const CheatFormatStruct* cf = CheatFormats;
char name[256];
MemoryPatch patch;
const CheatFormatStruct* cf = CheatFormats;
std::string name;
std::vector<std::string> codeParts;
std::vector<MemoryPatch> patches;
int matchLength=0;
int cursor;
std::string part;
//Decode the cheat
try
{
cf->DecodeCheat(std::string(code), &patch);
}
catch(std::exception &e)
{
return;
}
if (codeLine==NULL) return;
//Generate a name
sprintf(name,"cheat_%u",index);
//Break the code into Parts
for (cursor=0;;cursor++)
{
if (ISHEXDEC){
matchLength++;
} else {
if (matchLength){
part=codeLine+cursor-matchLength;
part.erase(matchLength,std::string::npos);
codeParts.push_back(part);
matchLength=0;
}
}
if (!codeLine[cursor]){
break;
}
}
for (cursor=0;cursor<codeParts.size();cursor++)
{
part=codeParts[cursor];
if (part.length()==8){
part+=codeParts[++cursor];
}
if (part.length()==12) {
//Decode the cheat
try
{
MemoryPatch patch;
cf->DecodeCheat(std::string(part), &patch);
patches.push_back(patch);
}
catch(std::exception &e)
{
continue;
}
}
}
//Generate a name
name="cheat_"+index;
for (cursor=0;cursor<patches.size();cursor++){
//Set parameters
patches[cursor].name=name;
patches[cursor].status=enabled;
//Add the Cheat
try
{
MDFNI_AddCheat(name.c_str(),patches[cursor].addr,patches[cursor].val,patches[cursor].compare,patches[cursor].type,patches[cursor].length,patches[cursor].bigendian);
}
catch(std::exception &e)
{
continue;
}
}
//Set parameters
patch.name=std::string(name);
patch.status=enabled;
//Add the Cheat
try
{
MDFNI_AddCheat(name,patch.addr,patch.val,patch.compare,patch.type,patch.length,patch.bigendian);
}
catch(std::exception &e)
{
return;
}
}
#ifdef _WIN32