#include #define CHEAT_CPP namespace SuperFamicom { Cheat cheat; bool Cheat::enabled() const { return system_enabled; } void Cheat::enable(bool state) { system_enabled = state; cheat_enabled = system_enabled && code_enabled; } void Cheat::synchronize() { memset(override, 0x00, 16 * 1024 * 1024); code_enabled = size() > 0; for(unsigned i = 0; i < size(); i++) { const CheatCode &code = operator[](i); unsigned addr = mirror(code.addr); override[addr] = true; if((addr & 0xffe000) == 0x7e0000) { //mirror $7e:0000-1fff to $00-3f|80-bf:0000-1fff unsigned mirroraddr; for(unsigned x = 0; x <= 0x3f; x++) { mirroraddr = ((0x00 + x) << 16) + (addr & 0x1fff); override[mirroraddr] = true; mirroraddr = ((0x80 + x) << 16) + (addr & 0x1fff); override[mirroraddr] = true; } } } cheat_enabled = system_enabled && code_enabled; } uint8 Cheat::read(unsigned addr) const { addr = mirror(addr); for(unsigned i = 0; i < size(); i++) { const CheatCode& code = operator[](i); if(addr == mirror(code.addr)) { return code.data; } } return 0x00; } void Cheat::init() { memset(override, 0x00, 16 * 1024 * 1024); } Cheat::Cheat() { override = new uint8[16 * 1024 * 1024]; system_enabled = true; } Cheat::~Cheat() { delete[] override; } bool Cheat::decode(string code, unsigned& addr, unsigned& data) { string t = code; t.lower(); #define ischr(n) ((n >= '0' && n <= '9') || (n >= 'a' && n <= 'f')) if(t.match("??????:??")) { //Direct t = {substr(t, 0, 6), substr(t, 7, 2)}; for(unsigned n = 0; n < 8; n++) if(!ischr(t[n])) return false; //validate input unsigned r = hex(t); addr = r >> 8; data = r & 0xff; return true; } if(t.match(R"(????-????)")) { //Game Genie t = {substr(t, 0, 4), substr(t, 5, 4)}; for(unsigned n = 0; n < 8; n++) if(!ischr(t[n])) return false; //validate input t.transform("df4709156bc8a23e", "0123456789abcdef"); unsigned r = hex(t); static unsigned bits[] = {13, 12, 11, 10, 5, 4, 3, 2, 23, 22, 21, 20, 1, 0, 15, 14, 19, 18, 17, 16, 9, 8, 7, 6}; addr = 0; for(unsigned n = 0; n < 24; n++) addr |= r & (1 << bits[n]) ? 0x800000 >> n : 0; data = r >> 24; return true; } else { return false; } #undef ischr } unsigned Cheat::mirror(unsigned addr) const { //$00-3f|80-bf:0000-1fff -> $7e:0000-1fff if((addr & 0x40e000) == 0x000000) return (0x7e0000 + (addr & 0x1fff)); return addr; } }