Refactor SRAM handling to interface/bsnes.cpp
This commit is contained in:
parent
627eb15db6
commit
e42ce000cb
5 changed files with 134 additions and 50 deletions
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue