Refactor SRAM handling to interface/bsnes.cpp

This commit is contained in:
Ilari Liusvaara 2012-03-12 13:27:36 +02:00
parent 627eb15db6
commit e42ce000cb
5 changed files with 134 additions and 50 deletions

View file

@ -2,6 +2,7 @@
#define _interface__core__hpp__included__
#include <string>
#include <vector>
#include <map>
std::string emucore_get_version();
@ -9,4 +10,16 @@ std::pair<uint32_t, uint32_t> emucore_get_video_rate(bool interlace = false);
std::pair<uint32_t, uint32_t> 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<char>& content) = 0;
virtual void copy_from_core(std::vector<char>& 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

View file

@ -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<std::string>& 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<std::string, std::vector<char>> save_sram() throw(std::bad_alloc)
{
std::map<std::string, std::vector<char>> 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<char> 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<std::string, std::vector<char>>& sram) throw(std::bad_al
std::set<std::string> 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<char>& 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<char>& 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<std::string, std::vector<char>> 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 {

View file

@ -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<char>& content)
{
memcpy(memory, &content[0], (content.size() < size) ? content.size() : size);
}
void copy_from_core(std::vector<char>& content)
{
content.resize(size);
memcpy(&content[0], memory, size);
}
size_t get_size()
{
return size;
}
};
std::vector<bsnes_sram_slot*> 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<bsnes_sram_slot*> 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;
}

View file

@ -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();

View file

@ -1,8 +1,5 @@
//Gaah... wx/wx.h (contains something that breaks if included after snes/snes.hpp from bsnes v085.
#include <wx/wx.h>
#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<std::string> wxwin_project::get_sram_set()
{
std::set<std::string> 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;
}