From e42ce000cbdff06018bbd7ecc67e954781c7a8b1 Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Mon, 12 Mar 2012 13:27:36 +0200 Subject: [PATCH] Refactor SRAM handling to interface/bsnes.cpp --- include/interface/core.hpp | 13 ++++ src/core/rom.cpp | 47 +++++-------- src/interface/bsnes.cpp | 100 +++++++++++++++++++++++++++ src/platform/sdl/main.cpp | 5 +- src/platform/wxwidgets/romselect.cpp | 19 +---- 5 files changed, 134 insertions(+), 50 deletions(-) diff --git a/include/interface/core.hpp b/include/interface/core.hpp index bf482a59..bc129b91 100644 --- a/include/interface/core.hpp +++ b/include/interface/core.hpp @@ -2,6 +2,7 @@ #define _interface__core__hpp__included__ #include +#include #include std::string emucore_get_version(); @@ -9,4 +10,16 @@ std::pair emucore_get_video_rate(bool interlace = false); std::pair emucore_get_audio_rate(); void emucore_basic_init(); +struct sram_slot_structure +{ + virtual std::string get_name() = 0; + virtual void copy_to_core(const std::vector& content) = 0; + virtual void copy_from_core(std::vector& content) = 0; + virtual size_t get_size() = 0; //0 if variable size. +}; + +size_t emucore_sram_slots(); +struct sram_slot_structure* emucore_sram_slot(size_t index); +void emucore_refresh_cart(); + #endif diff --git a/src/core/rom.cpp b/src/core/rom.cpp index d417b35b..f616a133 100644 --- a/src/core/rom.cpp +++ b/src/core/rom.cpp @@ -449,6 +449,7 @@ void loaded_rom::load() throw(std::bad_alloc, std::runtime_error) information_dispatch::do_sound_rate(soundrate.first, soundrate.second); current_rom_type = rtype; current_region = region; + emucore_refresh_cart(); refresh_cart_mappings(); } @@ -495,29 +496,14 @@ void loaded_rom::do_patch(const std::vector& cmdline) throw(std::ba } } -namespace -{ - std::string sram_name(const nall::string& _id, SNES::Cartridge::Slot slotname) - { - std::string id(_id, _id.length()); - if(slotname == SNES::Cartridge::Slot::SufamiTurboA) - return "slota." + id.substr(1); - if(slotname == SNES::Cartridge::Slot::SufamiTurboB) - return "slotb." + id.substr(1); - return id.substr(1); - } -} - std::map> save_sram() throw(std::bad_alloc) { std::map> out; - for(unsigned i = 0; i < SNES::cartridge.nvram.size(); i++) { - SNES::Cartridge::NonVolatileRAM& r = SNES::cartridge.nvram[i]; - std::string savename = sram_name(r.id, r.slot); + for(unsigned i = 0; i < emucore_sram_slots(); i++) { + sram_slot_structure* r = emucore_sram_slot(i); std::vector x; - x.resize(r.size); - memcpy(&x[0], r.data, r.size); - out[savename] = x; + r->copy_from_core(x); + out[r->get_name()] = x; } return out; } @@ -527,18 +513,17 @@ void load_sram(std::map>& sram) throw(std::bad_al std::set used; if(sram.empty()) return; - for(unsigned i = 0; i < SNES::cartridge.nvram.size(); i++) { - SNES::Cartridge::NonVolatileRAM& r = SNES::cartridge.nvram[i]; - std::string savename = sram_name(r.id, r.slot); - if(sram.count(savename)) { - std::vector& x = sram[savename]; - if(r.size != x.size()) - messages << "WARNING: SRAM '" << savename << "': Loaded " << x.size() - << " bytes, but the SRAM is " << r.size << "." << std::endl; - memcpy(r.data, &x[0], (r.size < x.size()) ? r.size : x.size()); - used.insert(savename); + for(unsigned i = 0; i < emucore_sram_slots(); i++) { + sram_slot_structure* r = emucore_sram_slot(i); + if(sram.count(r->get_name())) { + std::vector& x = sram[r->get_name()]; + if(r->get_size() != x.size() && r->get_size()) + messages << "WARNING: SRAM '" << r->get_name() << "': Loaded " << x.size() + << " bytes, but the SRAM is " << r->get_size() << "." << std::endl; + r->copy_to_core(x); + used.insert(r->get_name()); } else - messages << "WARNING: SRAM '" << savename << ": No data." << std::endl; + messages << "WARNING: SRAM '" << r->get_name() << ": No data." << std::endl; } for(auto i : sram) if(!used.count(i.first)) @@ -555,7 +540,7 @@ std::map> load_sram_commandline(const std::vector zip_reader r(opt[1]); for(auto j : r) { auto sramname = regex("sram\\.(.*)", j); - if(!sram_name) + if(!sramname) continue; std::istream& x = r[j]; try { diff --git a/src/interface/bsnes.cpp b/src/interface/bsnes.cpp index 1e6b09ea..9fad0613 100644 --- a/src/interface/bsnes.cpp +++ b/src/interface/bsnes.cpp @@ -52,3 +52,103 @@ void emucore_basic_init() SNES::interface = intrf; done = true; } + +namespace +{ + //Wunderbar... bsnes v087 goes to change the sram names... + std::string remap_sram_name(const std::string& name, SNES::Cartridge::Slot slotname) + { + std::string iname = name; + if(iname == "bsx.ram") + iname = ".bss"; + if(iname == "bsx.psram") + iname = ".bsp"; + if(iname == "program.rtc") + iname = ".rtc"; + if(iname == "upd96050.ram") + iname = ".dsp"; + if(iname == "program.ram") + iname = ".srm"; + if(slotname == SNES::Cartridge::Slot::SufamiTurboA) + return "slota" + iname; + if(slotname == SNES::Cartridge::Slot::SufamiTurboB) + return "slotb" + iname; + else + return iname.substr(1); + } + + struct bsnes_sram_slot : public sram_slot_structure + { + std::string name; + size_t size; + unsigned char* memory; + + bsnes_sram_slot(const nall::string& _id, SNES::Cartridge::Slot slotname, unsigned char* mem, + size_t sramsize) + { + std::string id(_id, _id.length()); + name = remap_sram_name(id, slotname); + memory = mem; + size = sramsize; + } + + std::string get_name() + { + return name; + } + + void copy_to_core(const std::vector& content) + { + memcpy(memory, &content[0], (content.size() < size) ? content.size() : size); + } + + void copy_from_core(std::vector& content) + { + content.resize(size); + memcpy(&content[0], memory, size); + } + + size_t get_size() + { + return size; + } + }; + + std::vector sram_slots; +} + +size_t emucore_sram_slots() +{ + return sram_slots.size(); +} + +struct sram_slot_structure* emucore_sram_slot(size_t index) +{ + if(index >= sram_slots.size()) + return NULL; + return sram_slots[index]; +} + +void emucore_refresh_cart() +{ + std::vector new_sram_slots; + size_t slots = SNES::cartridge.nvram.size(); + new_sram_slots.resize(slots); + for(size_t i = 0; i < slots; i++) + new_sram_slots[i] = NULL; + + try { + for(unsigned i = 0; i < slots; i++) { + SNES::Cartridge::NonVolatileRAM& s = SNES::cartridge.nvram[i]; + new_sram_slots[i] = new bsnes_sram_slot(s.id, s.slot, s.data, s.size); + } + } catch(...) { + for(auto i : new_sram_slots) + delete i; + throw; + } + + std::swap(sram_slots, new_sram_slots); + for(auto i : new_sram_slots) + delete i; +} diff --git a/src/platform/sdl/main.cpp b/src/platform/sdl/main.cpp index 501c957e..6f80232b 100644 --- a/src/platform/sdl/main.cpp +++ b/src/platform/sdl/main.cpp @@ -1,5 +1,3 @@ -#include "core/bsnes.hpp" - #include "core/command.hpp" #include "core/framerate.hpp" #include "core/keymapper.hpp" @@ -10,6 +8,7 @@ #include "core/rom.hpp" #include "core/rrdata.hpp" #include "core/window.hpp" +#include "interface/core.hpp" #include "platform/sdl/platform.hpp" @@ -141,7 +140,7 @@ int main(int argc, char** argv) cmdline.push_back(argv[i]); if(cmdline.size() == 1 && cmdline[0] == "--version") { std::cout << "lsnes rr" << lsnes_version << " (" << lsnes_git_revision << ")" << std::endl; - std::cout << snes_library_id() << " (" << SNES::Info::Profile << " core)" << std::endl; + std::cout << emucore_get_version() << std::endl; return 0; } emucore_basic_init(); diff --git a/src/platform/wxwidgets/romselect.cpp b/src/platform/wxwidgets/romselect.cpp index bffdc416..39e99c24 100644 --- a/src/platform/wxwidgets/romselect.cpp +++ b/src/platform/wxwidgets/romselect.cpp @@ -1,8 +1,5 @@ -//Gaah... wx/wx.h (contains something that breaks if included after snes/snes.hpp from bsnes v085. #include -#include "core/bsnes.hpp" - #include "core/moviedata.hpp" #include "core/framerate.hpp" #include "library/zip.hpp" @@ -70,16 +67,6 @@ namespace ask->Disable(); } - std::string sram_name(const nall::string& _id, SNES::Cartridge::Slot slotname) - { - std::string id(_id, _id.length()); - if(slotname == SNES::Cartridge::Slot::SufamiTurboA) - return "slota." + id.substr(1); - if(slotname == SNES::Cartridge::Slot::SufamiTurboB) - return "slotb." + id.substr(1); - return id.substr(1); - } - porttype_t get_controller_type(const std::string& s) { if(s == CNAME_NONE) @@ -821,9 +808,9 @@ void wxwin_project::on_load(wxCommandEvent& e) std::set wxwin_project::get_sram_set() { std::set r; - for(unsigned i = 0; i < SNES::cartridge.nvram.size(); i++) { - SNES::Cartridge::NonVolatileRAM& s = SNES::cartridge.nvram[i]; - r.insert(sram_name(s.id, s.slot)); + for(size_t i = 0; i < emucore_sram_slots(); i++) { + sram_slot_structure* s = emucore_sram_slot(i); + r.insert(s->get_name()); } return r; }