diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi.cs index 28d9a04a9d..cc4ae5b64d 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi.cs @@ -56,11 +56,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES { Filename = "libsnes.wbx", Path = dllPath, - SbrkHeapSizeKB = 32 * 1024, - InvisibleHeapSizeKB = 32 * 1024, - MmapHeapSizeKB = 256 * 1024, - PlainHeapSizeKB = 32 * 1024, - SealedHeapSizeKB = 256 * 1024 + SbrkHeapSizeKB = 4 * 1024, + InvisibleHeapSizeKB = 1024, + MmapHeapSizeKB = 32 * 1024, // TODO: see if we can safely make libco stacks smaller + PlainHeapSizeKB = 2 * 1024, // TODO: wasn't there more in here? + SealedHeapSizeKB = 128 * 1024 }); _core = BizInvoker.GetInvoker(_exe, _exe); diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IStatable.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IStatable.cs index 2a3d61bb04..6f6ff4298d 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IStatable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IStatable.cs @@ -12,73 +12,38 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES public void SaveStateText(TextWriter writer) { - /*var temp = SaveStateBinary(); + var temp = SaveStateBinary(); temp.SaveAsHexFast(writer); - writer.WriteLine("Frame {0}", Frame); // we don't parse this, it's only for the client to use - writer.WriteLine("Profile {0}", CurrentProfile);*/ } public void LoadStateText(TextReader reader) { - /*string hex = reader.ReadLine(); + string hex = reader.ReadLine(); byte[] state = new byte[hex.Length / 2]; state.ReadFromHexFast(hex); LoadStateBinary(new BinaryReader(new MemoryStream(state))); - reader.ReadLine(); // Frame # - var profile = reader.ReadLine().Split(' ')[1]; - ValidateLoadstateProfile(profile);*/ } public void SaveStateBinary(BinaryWriter writer) { - /*writer.Write(DeterministicEmulation ? _savestatebuff : CoreSaveState()); - - // other variables + Api.SaveStateBinary(writer); writer.Write(IsLagFrame); writer.Write(LagCount); writer.Write(Frame); - writer.Write(CurrentProfile); - - writer.Flush();*/ } public void LoadStateBinary(BinaryReader reader) { - /*int size = Api.QUERY_serialize_size(); - byte[] buf = reader.ReadBytes(size); - CoreLoadState(buf); - - if (DeterministicEmulation) // deserialize controller and fast-foward now - { - // reconstruct savestatebuff at the same time to avoid a costly core serialize - var ms = new MemoryStream(); - var bw = new BinaryWriter(ms); - bw.Write(buf); - bool framezero = reader.ReadBoolean(); - bw.Write(framezero); - if (!framezero) - { - var ssc = new SaveController(ControllerDefinition); - ssc.DeSerialize(reader); - IController tmp = _controller; - _controller = ssc; - _nocallbacks = true; - FrameAdvance(ssc, false, false); - _nocallbacks = false; - _controller = tmp; - ssc.Serialize(bw); - } - - bw.Close(); - _savestatebuff = ms.ToArray(); - } - - // other variables + Api.LoadStateBinary(reader); IsLagFrame = reader.ReadBoolean(); LagCount = reader.ReadInt32(); Frame = reader.ReadInt32(); - var profile = reader.ReadString(); - ValidateLoadstateProfile(profile);*/ + // refresh all callbacks now + Api.QUERY_set_video_refresh(snes_video_refresh); + Api.QUERY_set_input_poll(snes_input_poll); + Api.QUERY_set_input_state(snes_input_state); + Api.QUERY_set_input_notify(snes_input_notify); + Api.QUERY_set_audio_sample(_soundcb); } public byte[] SaveStateBinary() @@ -89,13 +54,5 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES bw.Flush(); return ms.ToArray(); } - - private void ValidateLoadstateProfile(string profile) - { - if (profile != CurrentProfile) - { - throw new InvalidOperationException($"You've attempted to load a savestate made using a different SNES profile ({profile}) than your current configuration ({CurrentProfile}). We COULD automatically switch for you, but we havent done that yet. This error is to make sure you know that this isnt going to work right now."); - } - } } } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs index b2158805fc..2e7d98a608 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs @@ -169,13 +169,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES } Api.QUERY_set_path_request(null); - Api.Seal(); - RefreshPalette(); Api.QUERY_set_video_refresh(snes_video_refresh); Api.QUERY_set_input_poll(snes_input_poll); Api.QUERY_set_input_state(snes_input_state); Api.QUERY_set_input_notify(snes_input_notify); Api.QUERY_set_audio_sample(_soundcb); + Api.Seal(); + RefreshPalette(); } private readonly GameInfo _game; diff --git a/waterbox/libsnes/Makefile b/waterbox/libsnes/Makefile index 4f0bb16418..3cad80df7c 100644 --- a/waterbox/libsnes/Makefile +++ b/waterbox/libsnes/Makefile @@ -34,7 +34,6 @@ SRCS_ALL:= \ $(ROOT_DIR)/bsnes/base/base.cpp \ $(ROOT_DIR)/bsnes/gameboy/apu/apu.cpp \ $(ROOT_DIR)/bsnes/gameboy/cartridge/cartridge.cpp \ - $(ROOT_DIR)/bsnes/gameboy/cheat/cheat.cpp \ $(ROOT_DIR)/bsnes/gameboy/cpu/cpu.cpp \ $(ROOT_DIR)/bsnes/snes/alt/dsp/dsp.cpp \ $(ROOT_DIR)/bsnes/gameboy/interface/interface.cpp \ @@ -44,7 +43,6 @@ SRCS_ALL:= \ $(ROOT_DIR)/bsnes/gameboy/system/system.cpp \ $(ROOT_DIR)/bsnes/gameboy/video/video.cpp \ $(ROOT_DIR)/bsnes/snes/cartridge/cartridge.cpp \ - $(ROOT_DIR)/bsnes/snes/cheat/cheat.cpp \ $(ROOT_DIR)/bsnes/snes/chip/armdsp/armdsp.cpp \ $(ROOT_DIR)/bsnes/snes/chip/bsx/bsx.cpp \ $(ROOT_DIR)/bsnes/snes/chip/hitachidsp/hitachidsp.cpp \ diff --git a/waterbox/libsnes/bsnes/gameboy/cheat/cheat.cpp b/waterbox/libsnes/bsnes/gameboy/cheat/cheat.cpp deleted file mode 100644 index bd72ef6928..0000000000 --- a/waterbox/libsnes/bsnes/gameboy/cheat/cheat.cpp +++ /dev/null @@ -1,91 +0,0 @@ -#include - -namespace GameBoy { - -Cheat cheat; - -bool Cheat::decode(const string &code_, unsigned &addr, unsigned &data, unsigned &comp) { - static bool initialize = false; - static uint8 mapProActionReplay[256], mapGameGenie[256]; - - if(initialize == false) { - initialize = true; - - for(auto &n : mapProActionReplay) n = ~0; - mapProActionReplay['0'] = 0; mapProActionReplay['1'] = 1; mapProActionReplay['2'] = 2; mapProActionReplay['3'] = 3; - mapProActionReplay['4'] = 4; mapProActionReplay['5'] = 5; mapProActionReplay['6'] = 6; mapProActionReplay['7'] = 7; - mapProActionReplay['8'] = 8; mapProActionReplay['9'] = 9; mapProActionReplay['A'] = 10; mapProActionReplay['B'] = 11; - mapProActionReplay['C'] = 12; mapProActionReplay['D'] = 13; mapProActionReplay['E'] = 14; mapProActionReplay['F'] = 15; - - for(auto &n : mapGameGenie) n = ~0; - mapGameGenie['0'] = 0; mapGameGenie['1'] = 1; mapGameGenie['2'] = 2; mapGameGenie['3'] = 3; - mapGameGenie['4'] = 4; mapGameGenie['5'] = 5; mapGameGenie['6'] = 6; mapGameGenie['7'] = 7; - mapGameGenie['8'] = 8; mapGameGenie['9'] = 9; mapGameGenie['A'] = 10; mapGameGenie['B'] = 11; - mapGameGenie['C'] = 12; mapGameGenie['D'] = 13; mapGameGenie['E'] = 14; mapGameGenie['F'] = 15; - } - - string code = code_; - code.upper(); - unsigned length = code.length(), bits = 0; - - if(code.wildcard("????:??")) { - code = { substr(code, 0, 4), substr(code, 5, 2) }; - for(unsigned n = 0; n < 6; n++) if(mapProActionReplay[code[n]] > 15) return false; - bits = hex(code); - addr = (bits >> 8) & 0xffff; - data = (bits >> 0) & 0xff; - comp = ~0; - return true; - } - - if(code.wildcard("????:??:??")) { - code = { substr(code, 0, 4), substr(code, 5, 2), substr(code, 8, 2) }; - for(unsigned n = 0; n < 8; n++) if(mapProActionReplay[code[n]] > 15) return false; - bits = hex(code); - addr = (bits >> 16) & 0xffff; - data = (bits >> 8) & 0xff; - comp = (bits >> 0) & 0xff; - return true; - } - - if(code.wildcard("???" "-" "???")) { - code = { substr(code, 0, 3), substr(code, 4, 3) }; - for(unsigned n = 0; n < 6; n++) if(mapGameGenie[code[n]] > 15) return false; - for(unsigned n = 0; n < 6; n++) bits |= mapGameGenie[code[n]] << (20 - n * 4); - - addr = (bits >> 0) & 0xffff; - data = (bits >> 16) & 0xff; - comp = ~0; - - addr = (((addr >> 4) | (addr << 12)) & 0xffff) ^ 0xf000; - - return true; - } - - if(code.wildcard("???" "-" "???" "-" "???")) { - code = { substr(code, 0, 3), substr(code, 4, 3), substr(code, 8, 1), substr(code, 10, 1) }; - for(unsigned n = 0; n < 8; n++) if(mapGameGenie[code[n]] > 15) return false; - for(unsigned n = 0; n < 8; n++) bits |= mapGameGenie[code[n]] << (28 - n * 4); - - addr = (bits >> 8) & 0xffff; - data = (bits >> 24) & 0xff; - comp = (bits >> 0) & 0xff; - - addr = (((addr >> 4) | (addr << 12)) & 0xffff) ^ 0xf000; - comp = (((comp >> 2) | (comp << 6)) & 0xff) ^ 0xba; - - return true; - } - - return false; -} - -void Cheat::synchronize() { - for(auto &n : override) n = false; - - for(unsigned n = 0; n < size(); n++) { - override[operator[](n).addr] = true; - } -} - -} diff --git a/waterbox/libsnes/bsnes/gameboy/cheat/cheat.hpp b/waterbox/libsnes/bsnes/gameboy/cheat/cheat.hpp deleted file mode 100644 index 4446a52b1c..0000000000 --- a/waterbox/libsnes/bsnes/gameboy/cheat/cheat.hpp +++ /dev/null @@ -1,14 +0,0 @@ -struct CheatCode { - unsigned addr; - unsigned data; - unsigned comp; -}; - -struct Cheat : public linear_vector { - static bool decode(const string &code, unsigned &addr, unsigned &data, unsigned &comp); - - void synchronize(); - bool override[65536]; -}; - -extern Cheat cheat; diff --git a/waterbox/libsnes/bsnes/gameboy/gameboy.hpp b/waterbox/libsnes/bsnes/gameboy/gameboy.hpp index 6397a72e2f..21b3015e83 100644 --- a/waterbox/libsnes/bsnes/gameboy/gameboy.hpp +++ b/waterbox/libsnes/bsnes/gameboy/gameboy.hpp @@ -53,7 +53,6 @@ namespace GameBoy { #include #include #include - #include #include }; diff --git a/waterbox/libsnes/bsnes/gameboy/memory/memory.cpp b/waterbox/libsnes/bsnes/gameboy/memory/memory.cpp index ad2818449a..bb3bb3f970 100644 --- a/waterbox/libsnes/bsnes/gameboy/memory/memory.cpp +++ b/waterbox/libsnes/bsnes/gameboy/memory/memory.cpp @@ -43,18 +43,6 @@ Memory::~Memory() { uint8 Bus::read(uint16 addr) { uint8 data = mmio[addr]->mmio_read(addr); - - if(cheat.override[addr]) { - for(unsigned n = 0; n < cheat.size(); n++) { - if(cheat[n].addr == addr) { - if(cheat[n].comp > 255 || cheat[n].comp == data) { - data = cheat[n].data; - break; - } - } - } - } - return data; } diff --git a/waterbox/libsnes/bsnes/snes/cheat/cheat.cpp b/waterbox/libsnes/bsnes/snes/cheat/cheat.cpp deleted file mode 100644 index 46c42d1c9b..0000000000 --- a/waterbox/libsnes/bsnes/snes/cheat/cheat.cpp +++ /dev/null @@ -1,110 +0,0 @@ -#include - -#define CHEAT_CPP -namespace SNES { - -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(const string &code, unsigned &addr, unsigned &data) { - string t = code; - t.lower(); - - #define ischr(n) ((n >= '0' && n <= '9') || (n >= 'a' && n <= 'f')) - - if(t.wildcard("??????:??")) { - //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.wildcard("????" "-" "????")) { - //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; -} - -} diff --git a/waterbox/libsnes/bsnes/snes/cheat/cheat.hpp b/waterbox/libsnes/bsnes/snes/cheat/cheat.hpp deleted file mode 100644 index 306b99b158..0000000000 --- a/waterbox/libsnes/bsnes/snes/cheat/cheat.hpp +++ /dev/null @@ -1,27 +0,0 @@ -struct CheatCode { - unsigned addr; - unsigned data; -}; - -struct Cheat : public linear_vector { - uint8 *override; - - bool enabled() const; - void enable(bool); - void synchronize(); - uint8 read(unsigned) const; - void init(); - - Cheat(); - ~Cheat(); - - static bool decode(const string&, unsigned&, unsigned&); - -private: - bool system_enabled; - bool code_enabled; - bool cheat_enabled; - unsigned mirror(unsigned) const; -}; - -extern Cheat cheat; diff --git a/waterbox/libsnes/bsnes/snes/memory/memory-inline.hpp b/waterbox/libsnes/bsnes/snes/memory/memory-inline.hpp index d7968f199e..6fce1b1d47 100644 --- a/waterbox/libsnes/bsnes/snes/memory/memory-inline.hpp +++ b/waterbox/libsnes/bsnes/snes/memory/memory-inline.hpp @@ -55,7 +55,6 @@ MappedRAM::MappedRAM(const char* name) : data_(0), size_(0), write_protect_(fals //Bus uint8 Bus::read(unsigned addr) { - if(cheat.override[addr]) return cheat.read(addr); return reader[lookup[addr]](target[addr]); } diff --git a/waterbox/libsnes/bsnes/snes/snes.hpp b/waterbox/libsnes/bsnes/snes/snes.hpp index 50bf91f363..84f2e28ed7 100644 --- a/waterbox/libsnes/bsnes/snes/snes.hpp +++ b/waterbox/libsnes/bsnes/snes/snes.hpp @@ -67,7 +67,6 @@ namespace SNES { #include #include #include - #include #include #include diff --git a/waterbox/libsnes/bsnes/snes/system/system.cpp b/waterbox/libsnes/bsnes/snes/system/system.cpp index edd5c26057..647dfc98e4 100644 --- a/waterbox/libsnes/bsnes/snes/system/system.cpp +++ b/waterbox/libsnes/bsnes/snes/system/system.cpp @@ -124,7 +124,6 @@ void System::load() { if(cartridge.has_link()) link.load(); serialize_init(); - cheat.init(); } void System::unload() { diff --git a/waterbox/libsnes/bsnes/target-libsnes/libsnes.cpp b/waterbox/libsnes/bsnes/target-libsnes/libsnes.cpp index 61ca62e7b8..e05c0493d8 100644 --- a/waterbox/libsnes/bsnes/target-libsnes/libsnes.cpp +++ b/waterbox/libsnes/bsnes/target-libsnes/libsnes.cpp @@ -296,60 +296,6 @@ bool snes_unserialize(const uint8_t *data, unsigned size) { return SNES::system.unserialize(s); } -struct CheatList { - bool enable; - string code; - CheatList() : enable(false) {} -}; - -static linear_vector cheatList; - -void snes_cheat_reset(void) { - cheatList.reset(); - GameBoy::cheat.reset(); - GameBoy::cheat.synchronize(); - SNES::cheat.reset(); - SNES::cheat.synchronize(); -} - -void snes_cheat_set(unsigned index, bool enable, const char *code) { - cheatList[index].enable = enable; - cheatList[index].code = code; - lstring list; - for(unsigned n = 0; n < cheatList.size(); n++) { - if(cheatList[n].enable) list.append(cheatList[n].code); - } - - if(SNES::cartridge.mode() == SNES::Cartridge::Mode::SuperGameBoy) { - GameBoy::cheat.reset(); - for(auto &code : list) { - lstring codelist; - codelist.split("+", code); - for(auto &part : codelist) { - unsigned addr, data, comp; - if(GameBoy::Cheat::decode(part, addr, data, comp)) { - GameBoy::cheat.append({ addr, data, comp }); - } - } - } - GameBoy::cheat.synchronize(); - return; - } - - SNES::cheat.reset(); - for(auto &code : list) { - lstring codelist; - codelist.split("+", code); - for(auto &part : codelist) { - unsigned addr, data; - if(SNES::Cheat::decode(part, addr, data)) { - SNES::cheat.append({ addr, data }); - } - } - } - SNES::cheat.synchronize(); -} - //zero 21-sep-2012 void snes_set_scanlineStart(snes_scanlineStart_t cb) { @@ -464,7 +410,6 @@ int snes_peek_logical_register(int reg) bool snes_load_cartridge_normal( const char *rom_xml, const uint8_t *rom_data, unsigned rom_size ) { - snes_cheat_reset(); if(rom_data) SNES::cartridge.rom.copy(rom_data, rom_size); iface->cart = SnesCartridge(rom_data, rom_size); string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : iface->cart.markup; @@ -477,7 +422,6 @@ bool snes_load_cartridge_bsx_slotted( const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, const char *bsx_xml, const uint8_t *bsx_data, unsigned bsx_size ) { - snes_cheat_reset(); if(rom_data) SNES::cartridge.rom.copy(rom_data, rom_size); iface->cart = SnesCartridge(rom_data, rom_size); string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : iface->cart.markup; @@ -492,7 +436,6 @@ bool snes_load_cartridge_bsx( const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, const char *bsx_xml, const uint8_t *bsx_data, unsigned bsx_size ) { - snes_cheat_reset(); if(rom_data) SNES::cartridge.rom.copy(rom_data, rom_size); iface->cart = SnesCartridge(rom_data, rom_size); string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : iface->cart.markup; @@ -508,7 +451,6 @@ bool snes_load_cartridge_sufami_turbo( const char *sta_xml, const uint8_t *sta_data, unsigned sta_size, const char *stb_xml, const uint8_t *stb_data, unsigned stb_size ) { - snes_cheat_reset(); if(rom_data) SNES::cartridge.rom.copy(rom_data, rom_size); iface->cart = SnesCartridge(rom_data, rom_size); string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : iface->cart.markup; @@ -525,7 +467,6 @@ bool snes_load_cartridge_super_game_boy( const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, const char *dmg_xml, const uint8_t *dmg_data, unsigned dmg_size ) { - snes_cheat_reset(); if(rom_data) SNES::cartridge.rom.copy(rom_data, rom_size); iface->cart = SnesCartridge(rom_data, rom_size); string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : iface->cart.markup; diff --git a/waterbox/libsnes/bsnes/target-libsnes/libsnes.hpp b/waterbox/libsnes/bsnes/target-libsnes/libsnes.hpp index 4d22dea1fc..59f39a5a60 100644 --- a/waterbox/libsnes/bsnes/target-libsnes/libsnes.hpp +++ b/waterbox/libsnes/bsnes/target-libsnes/libsnes.hpp @@ -118,9 +118,6 @@ unsigned snes_serialize_size(void); bool snes_serialize(uint8_t *data, unsigned size); bool snes_unserialize(const uint8_t *data, unsigned size); -void snes_cheat_reset(void); -void snes_cheat_set(unsigned index, bool enable, const char *code); - bool snes_load_cartridge_normal( const char *rom_xml, const uint8_t *rom_data, unsigned rom_size );