Split all references to bsnes core to dedicated file
This commit is contained in:
parent
17b92632e5
commit
d9bc16598c
17 changed files with 950 additions and 584 deletions
|
@ -17,13 +17,12 @@
|
|||
#include <set>
|
||||
|
||||
/**
|
||||
* For now, reserve 20 bytes, for:
|
||||
* For now, reserve 23 bytes, for:
|
||||
*
|
||||
* - 5 bytes for system.
|
||||
* - 6 bytes for port 1 (multitap).
|
||||
* - 9 bytes for port 2 (justifiers).
|
||||
* - 9 bytes for ports 1&2 (justifiers).
|
||||
*/
|
||||
#define MAXIMUM_CONTROLLER_FRAME_SIZE 20
|
||||
#define MAXIMUM_CONTROLLER_FRAME_SIZE 23
|
||||
|
||||
/**
|
||||
* Maximum amount of data controller_frame::display() can write.
|
||||
|
@ -61,35 +60,7 @@
|
|||
* Analog indices.
|
||||
*/
|
||||
#define MAX_ANALOG 3
|
||||
/**
|
||||
* Logical button IDs.
|
||||
*/
|
||||
#define LOGICAL_BUTTON_LEFT 0
|
||||
#define LOGICAL_BUTTON_RIGHT 1
|
||||
#define LOGICAL_BUTTON_UP 2
|
||||
#define LOGICAL_BUTTON_DOWN 3
|
||||
#define LOGICAL_BUTTON_A 4
|
||||
#define LOGICAL_BUTTON_B 5
|
||||
#define LOGICAL_BUTTON_X 6
|
||||
#define LOGICAL_BUTTON_Y 7
|
||||
#define LOGICAL_BUTTON_L 8
|
||||
#define LOGICAL_BUTTON_R 9
|
||||
#define LOGICAL_BUTTON_SELECT 10
|
||||
#define LOGICAL_BUTTON_START 11
|
||||
#define LOGICAL_BUTTON_TRIGGER 12
|
||||
#define LOGICAL_BUTTON_CURSOR 13
|
||||
#define LOGICAL_BUTTON_TURBO 14
|
||||
#define LOGICAL_BUTTON_PAUSE 15
|
||||
#define MAX_LOGICAL_BUTTONS 16
|
||||
|
||||
/**
|
||||
* Get name of logical button.
|
||||
*
|
||||
* Parameter lbid: ID of logical button.
|
||||
* Returns: The name of button.
|
||||
* Throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
std::string get_logical_button_name(unsigned lbid) throw(std::bad_alloc);
|
||||
|
||||
/**
|
||||
* This enumeration gives the type of port.
|
||||
|
@ -328,17 +299,6 @@ struct porttype_info
|
|||
* Number of controllers connected to this port.
|
||||
*/
|
||||
unsigned controllers;
|
||||
/**
|
||||
* Internal type value for port.
|
||||
*/
|
||||
unsigned internal_type;
|
||||
/**
|
||||
* Return if type is legal for port.
|
||||
*
|
||||
* Parameter port: Number of port.
|
||||
* Returns: True if legal, false if not.
|
||||
*/
|
||||
bool (*legal)(unsigned port);
|
||||
/**
|
||||
* Translate controller and logical button id pair into physical button id.
|
||||
*
|
||||
|
|
169
include/core/emucore.hpp
Normal file
169
include/core/emucore.hpp
Normal file
|
@ -0,0 +1,169 @@
|
|||
#ifndef _emucore__hpp__included__
|
||||
#define _emucore__hpp__included__
|
||||
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include "core/render.hpp"
|
||||
|
||||
/**
|
||||
* Logical button IDs.
|
||||
*/
|
||||
#define LOGICAL_BUTTON_LEFT 0
|
||||
#define LOGICAL_BUTTON_RIGHT 1
|
||||
#define LOGICAL_BUTTON_UP 2
|
||||
#define LOGICAL_BUTTON_DOWN 3
|
||||
#define LOGICAL_BUTTON_A 4
|
||||
#define LOGICAL_BUTTON_B 5
|
||||
#define LOGICAL_BUTTON_X 6
|
||||
#define LOGICAL_BUTTON_Y 7
|
||||
#define LOGICAL_BUTTON_L 8
|
||||
#define LOGICAL_BUTTON_R 9
|
||||
#define LOGICAL_BUTTON_SELECT 10
|
||||
#define LOGICAL_BUTTON_START 11
|
||||
#define LOGICAL_BUTTON_TRIGGER 12
|
||||
#define LOGICAL_BUTTON_CURSOR 13
|
||||
#define LOGICAL_BUTTON_TURBO 14
|
||||
#define LOGICAL_BUTTON_PAUSE 15
|
||||
#define MAX_LOGICAL_BUTTONS 16
|
||||
|
||||
#define EC_REGION_AUTO -1
|
||||
#define EC_REGION_NTSC 0
|
||||
#define EC_REGION_PAL 1
|
||||
|
||||
//Get the CPU rate.
|
||||
uint32_t get_snes_cpu_rate();
|
||||
//Get the APU rate.
|
||||
uint32_t get_snes_apu_rate();
|
||||
//Get the core identifier.
|
||||
std::string get_core_identifier();
|
||||
//Do basic core initialization (to get it to stable state).
|
||||
void do_basic_core_init();
|
||||
//Get set of SRAMs.
|
||||
std::set<std::string> get_sram_set();
|
||||
//Get region.
|
||||
bool core_get_region();
|
||||
//Get the current video rate.
|
||||
std::pair<uint32_t, uint32_t> get_video_rate();
|
||||
//Get the current audio rate.
|
||||
std::pair<uint32_t, uint32_t> get_audio_rate();
|
||||
//Set preload settings.
|
||||
void set_preload_settings();
|
||||
//Set controller type to none.
|
||||
void set_core_controller_none(unsigned port) throw();
|
||||
//Set controller type to gamepad.
|
||||
void set_core_controller_gamepad(unsigned port) throw();
|
||||
//Set controller type to mouse.
|
||||
void set_core_controller_mouse(unsigned port) throw();
|
||||
//Set controller type to multitap.
|
||||
void set_core_controller_multitap(unsigned port) throw();
|
||||
//Set controller type to superscope.
|
||||
void set_core_controller_superscope(unsigned port) throw();
|
||||
//Set controller type to justifier.
|
||||
void set_core_controller_justifier(unsigned port) throw();
|
||||
//Set controller type to justifiers.
|
||||
void set_core_controller_justifiers(unsigned port) throw();
|
||||
//Button ID function for none.
|
||||
int get_button_id_none(unsigned controller, unsigned lbid) throw();
|
||||
//Button ID function for gamepad.
|
||||
int get_button_id_gamepad(unsigned controller, unsigned lbid) throw();
|
||||
//Button ID function for mouse.
|
||||
int get_button_id_mouse(unsigned controller, unsigned lbid) throw();
|
||||
//Button ID function for multitap.
|
||||
int get_button_id_multitap(unsigned controller, unsigned lbid) throw();
|
||||
//Button ID function for superscope.
|
||||
int get_button_id_superscope(unsigned controller, unsigned lbid) throw();
|
||||
//Button ID function for justifier.
|
||||
int get_button_id_justifier(unsigned controller, unsigned lbid) throw();
|
||||
//Button ID function for justifiers.
|
||||
int get_button_id_justifiers(unsigned controller, unsigned lbid) throw();
|
||||
//Load SNES cartridge.
|
||||
bool core_load_cartridge_normal(const char* rom_markup, const unsigned char* rom, size_t romsize);
|
||||
//Load BS-X cartridge.
|
||||
bool core_load_cartridge_bsx(const char* bios_markup, const unsigned char* bios, size_t biossize,
|
||||
const char* rom_markup, const unsigned char* rom, size_t romsize);
|
||||
//Load slotted BS-X cartridge.
|
||||
bool core_load_cartridge_bsx_slotted(const char* bios_markup, const unsigned char* bios, size_t biossize,
|
||||
const char* rom_markup, const unsigned char* rom, size_t romsize);
|
||||
//Load Super Game Boy cartridge.
|
||||
bool core_load_cartridge_super_game_boy(const char* bios_markup, const unsigned char* bios, size_t biossize,
|
||||
const char* rom_markup, const unsigned char* rom, size_t romsize);
|
||||
//Load Sufami turbo cartridge.
|
||||
bool core_load_cartridge_sufami_turbo(const char* bios_markup, const unsigned char* bios, size_t biossize,
|
||||
const char* romA_markup, const unsigned char* romA, size_t romAsize, const char* romB_markup,
|
||||
const unsigned char* romB, size_t romBsize);
|
||||
//Set the region.
|
||||
void core_set_region(int region);
|
||||
//Power the core.
|
||||
void core_power();
|
||||
//Save SRAM set.
|
||||
std::map<std::string, std::vector<char>> save_sram() throw(std::bad_alloc);
|
||||
//Load SRAM set.
|
||||
void load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc);
|
||||
//Serialize state.
|
||||
void core_serialize(std::vector<char>& out);
|
||||
//Unserialize state.
|
||||
void core_unserialize(const char* in, size_t insize);
|
||||
//Install handler.
|
||||
void core_install_handler();
|
||||
//Uninstall handler.
|
||||
void core_uninstall_handler();
|
||||
//Emulate a frame.
|
||||
void core_emulate_frame();
|
||||
//Run specified number of frames inside frame.
|
||||
std::pair<bool, uint32_t> core_emulate_cycles(uint32_t cycles);
|
||||
//Do soft reset.
|
||||
void core_reset();
|
||||
//Run to point save.
|
||||
void core_runtosave();
|
||||
|
||||
/**
|
||||
* Get name of logical button.
|
||||
*
|
||||
* Parameter lbid: ID of logical button.
|
||||
* Returns: The name of button.
|
||||
* Throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
std::string get_logical_button_name(unsigned lbid) throw(std::bad_alloc);
|
||||
|
||||
//Callbacks.
|
||||
struct emucore_callbacks
|
||||
{
|
||||
public:
|
||||
virtual ~emucore_callbacks() throw();
|
||||
//Get the input for specified control.
|
||||
virtual int16_t get_input(unsigned port, unsigned index, unsigned control) = 0;
|
||||
//Do timer tick.
|
||||
virtual void timer_tick(uint32_t increment, uint32_t per_second) = 0;
|
||||
//Get the firmware path.
|
||||
virtual std::string get_firmware_path() = 0;
|
||||
//Get the base path.
|
||||
virtual std::string get_base_path() = 0;
|
||||
//Get the current time.
|
||||
virtual time_t get_time() = 0;
|
||||
//Get random seed.
|
||||
virtual time_t get_randomseed() = 0;
|
||||
//Output frame.
|
||||
virtual void output_frame(lcscreen& screen, uint32_t fps_n, uint32_t fps_d) = 0;
|
||||
};
|
||||
|
||||
extern struct emucore_callbacks* ecore_callbacks;
|
||||
|
||||
//A VMA.
|
||||
struct vma_info
|
||||
{
|
||||
std::string name;
|
||||
uint64_t base;
|
||||
uint64_t size;
|
||||
void* backing_ram;
|
||||
bool readonly;
|
||||
bool native_endian;
|
||||
uint8_t (*iospace_rw)(uint64_t offset, uint8_t data, bool write);
|
||||
};
|
||||
|
||||
std::list<vma_info> get_vma_list();
|
||||
|
||||
#endif
|
|
@ -3,13 +3,6 @@
|
|||
|
||||
#include <cstdint>
|
||||
|
||||
/**
|
||||
* Number clocks per field/frame on NTSC/PAL
|
||||
*/
|
||||
#define DURATION_NTSC_FRAME 357366
|
||||
#define DURATION_NTSC_FIELD 357368
|
||||
#define DURATION_PAL_FRAME 425568
|
||||
#define DURATION_PAL_FIELD 425568
|
||||
|
||||
/**
|
||||
* Sets the nominal frame rate. Framerate limiting tries to maintain the nominal framerate when there is no other
|
||||
|
|
655
src/core/bsnes-legacy.cpp
Normal file
655
src/core/bsnes-legacy.cpp
Normal file
|
@ -0,0 +1,655 @@
|
|||
#include "lsnes.hpp"
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "core/misc.hpp"
|
||||
#include "core/emucore.hpp"
|
||||
#include "core/dispatch.hpp"
|
||||
#include "core/framebuffer.hpp"
|
||||
#include "core/window.hpp"
|
||||
#include "library/string.hpp"
|
||||
#include <snes/snes.hpp>
|
||||
#include <gameboy/gameboy.hpp>
|
||||
#ifdef BSNES_V087
|
||||
#include <target-libsnes/libsnes.hpp>
|
||||
#else
|
||||
#include <ui-libsnes/libsnes.hpp>
|
||||
#endif
|
||||
|
||||
#define DURATION_NTSC_FRAME 357366
|
||||
#define DURATION_NTSC_FIELD 357368
|
||||
#define DURATION_PAL_FRAME 425568
|
||||
#define DURATION_PAL_FIELD 425568
|
||||
#define ROM_TYPE_NONE 0
|
||||
#define ROM_TYPE_SNES 1
|
||||
#define ROM_TYPE_BSX 2
|
||||
#define ROM_TYPE_BSXSLOTTED 3
|
||||
#define ROM_TYPE_SUFAMITURBO 4
|
||||
#define ROM_TYPE_SGB 5
|
||||
|
||||
namespace
|
||||
{
|
||||
bool last_hires = false;
|
||||
bool last_interlace = false;
|
||||
bool stepping_into_save;
|
||||
bool video_refresh_done;
|
||||
//Delay reset.
|
||||
unsigned long long delayreset_cycles_run;
|
||||
unsigned long long delayreset_cycles_target;
|
||||
|
||||
bool p1disable = false;
|
||||
unsigned internal_rom = ROM_TYPE_NONE;
|
||||
std::map<int16_t, std::pair<uint64_t, uint64_t>> ptrmap;
|
||||
|
||||
const char* buttonnames[MAX_LOGICAL_BUTTONS] = {
|
||||
"left", "right", "up", "down", "A", "B", "X", "Y", "L", "R", "select", "start", "trigger",
|
||||
"cursor", "turbo", "pause"
|
||||
};
|
||||
|
||||
class my_interfaced : public SNES::Interface
|
||||
{
|
||||
string path(SNES::Cartridge::Slot slot, const string &hint)
|
||||
{
|
||||
return "./";
|
||||
}
|
||||
};
|
||||
|
||||
std::string sram_name(const nall::string& _id, SNES::Cartridge::Slot slotname)
|
||||
{
|
||||
std::string id(_id, _id.length());
|
||||
//Fixup name change by bsnes v087...
|
||||
if(id == "bsx.ram")
|
||||
id = ".bss";
|
||||
if(id == "bsx.psram")
|
||||
id = ".bsp";
|
||||
if(id == "program.rtc")
|
||||
id = ".rtc";
|
||||
if(id == "upd96050.ram")
|
||||
id = ".dsp";
|
||||
if(id == "program.ram")
|
||||
id = ".srm";
|
||||
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);
|
||||
}
|
||||
|
||||
uint8_t snes_bus_iospace_rw(uint64_t offset, uint8_t data, bool write)
|
||||
{
|
||||
if(write)
|
||||
SNES::bus.write(offset, data);
|
||||
else
|
||||
return SNES::bus.read(offset);
|
||||
}
|
||||
|
||||
uint8_t ptrtable_iospace_rw(uint64_t offset, uint8_t data, bool write)
|
||||
{
|
||||
uint16_t entry = offset >> 4;
|
||||
if(!ptrmap.count(entry))
|
||||
return 0;
|
||||
uint64_t val = ((offset & 15) < 8) ? ptrmap[entry].first : ptrmap[entry].second;
|
||||
uint8_t byte = offset & 7;
|
||||
//These things are always little-endian.
|
||||
return (val >> (8 * byte));
|
||||
}
|
||||
|
||||
void create_region(std::list<vma_info>& inf, const std::string& name, uint64_t base, uint64_t size,
|
||||
uint8_t (*iospace_rw)(uint64_t offset, uint8_t data, bool write)) throw(std::bad_alloc)
|
||||
{
|
||||
if(size == 0)
|
||||
return;
|
||||
vma_info i;
|
||||
i.name = name;
|
||||
i.base = base;
|
||||
i.size = size;
|
||||
i.readonly = false;
|
||||
i.native_endian = false;
|
||||
i.iospace_rw = iospace_rw;
|
||||
inf.push_back(i);
|
||||
}
|
||||
|
||||
void create_region(std::list<vma_info>& inf, const std::string& name, uint64_t base, uint8_t* memory,
|
||||
uint64_t size, bool readonly, bool native_endian = false) throw(std::bad_alloc)
|
||||
{
|
||||
if(size == 0)
|
||||
return;
|
||||
vma_info i;
|
||||
i.name = name;
|
||||
i.base = base;
|
||||
i.size = size;
|
||||
i.backing_ram = memory;
|
||||
i.readonly = readonly;
|
||||
i.native_endian = native_endian;
|
||||
i.iospace_rw = NULL;
|
||||
inf.push_back(i);
|
||||
}
|
||||
|
||||
void create_region(std::list<vma_info>& inf, const std::string& name, uint64_t base,
|
||||
SNES::MappedRAM& memory, bool readonly, bool native_endian = false) throw(std::bad_alloc)
|
||||
{
|
||||
create_region(inf, name, base, memory.data(), memory.size(), readonly, native_endian);
|
||||
}
|
||||
|
||||
void map_internal(std::list<vma_info>& inf, const std::string& name, uint16_t index, void* memory,
|
||||
size_t memsize)
|
||||
{
|
||||
ptrmap[index] = std::make_pair(reinterpret_cast<uint64_t>(memory), static_cast<uint64_t>(memsize));
|
||||
create_region(inf, name, 0x101000000 + index * 0x1000000, reinterpret_cast<uint8_t*>(memory),
|
||||
memsize, true, true);
|
||||
}
|
||||
|
||||
bool delayreset_fn()
|
||||
{
|
||||
if(delayreset_cycles_run == delayreset_cycles_target || video_refresh_done)
|
||||
return true;
|
||||
delayreset_cycles_run++;
|
||||
return false;
|
||||
}
|
||||
|
||||
class my_interface : public SNES::Interface
|
||||
{
|
||||
string path(SNES::Cartridge::Slot slot, const string &hint)
|
||||
{
|
||||
const char* _hint = hint;
|
||||
std::string _hint2 = _hint;
|
||||
std::string fwp = ecore_callbacks->get_firmware_path();
|
||||
regex_results r;
|
||||
std::string msubase = ecore_callbacks->get_base_path();
|
||||
if(regex_match(".*\\.sfc", msubase))
|
||||
msubase = msubase.substr(0, msubase.length() - 4);
|
||||
|
||||
if(_hint2 == "msu1.rom" || _hint2 == ".msu") {
|
||||
//MSU-1 main ROM.
|
||||
std::string x = msubase + ".msu";
|
||||
messages << "MSU main data file: " << x << std::endl;
|
||||
return x.c_str();
|
||||
}
|
||||
if(r = regex("(track)?(-([0-9])+\\.pcm)", _hint2)) {
|
||||
//MSU track.
|
||||
std::string x = msubase + r[2];
|
||||
messages << "MSU track " << r[3] << "': " << x << std::endl;
|
||||
return x.c_str();
|
||||
}
|
||||
std::string finalpath = fwp + "/" + _hint2;
|
||||
return finalpath.c_str();
|
||||
}
|
||||
|
||||
time_t currentTime()
|
||||
{
|
||||
return ecore_callbacks->get_time();
|
||||
}
|
||||
|
||||
time_t randomSeed()
|
||||
{
|
||||
return ecore_callbacks->get_randomseed();
|
||||
}
|
||||
|
||||
void videoRefresh(const uint32_t* data, bool hires, bool interlace, bool overscan)
|
||||
{
|
||||
last_hires = hires;
|
||||
last_interlace = interlace;
|
||||
bool region = core_get_region();
|
||||
if(stepping_into_save)
|
||||
messages << "Got video refresh in runtosave, expect desyncs!" << std::endl;
|
||||
video_refresh_done = true;
|
||||
uint32_t fps_n, fps_d;
|
||||
auto fps = get_video_rate();
|
||||
fps_n = fps.first;
|
||||
fps_d = fps.second;
|
||||
uint32_t g = gcd(fps_n, fps_d);
|
||||
fps_n /= g;
|
||||
fps_d /= g;
|
||||
lcscreen ls(data, hires, interlace, overscan, region);
|
||||
ecore_callbacks->output_frame(ls, fps_n, fps_d);
|
||||
information_dispatch::do_raw_frame(data, hires, interlace, overscan, region ?
|
||||
VIDEO_REGION_PAL : VIDEO_REGION_NTSC);
|
||||
}
|
||||
|
||||
void audioSample(int16_t l_sample, int16_t r_sample)
|
||||
{
|
||||
uint16_t _l = l_sample;
|
||||
uint16_t _r = r_sample;
|
||||
platform::audio_sample(_l + 32768, _r + 32768);
|
||||
information_dispatch::do_sample(l_sample, r_sample);
|
||||
//The SMP emits a sample every 768 ticks of its clock. Use this in order to keep track of
|
||||
//time.
|
||||
auto hz = get_audio_rate();
|
||||
ecore_callbacks->timer_tick(hz.second, hz.first);
|
||||
}
|
||||
|
||||
int16_t inputPoll(bool port, SNES::Input::Device device, unsigned index, unsigned id)
|
||||
{
|
||||
return ecore_callbacks->get_input(port ? 1 : 0, index, id);
|
||||
}
|
||||
};
|
||||
|
||||
my_interface my_interface_obj;
|
||||
SNES::Interface* old;
|
||||
}
|
||||
|
||||
void core_install_handler()
|
||||
{
|
||||
old = SNES::interface;
|
||||
SNES::interface = &my_interface_obj;
|
||||
SNES::system.init();
|
||||
}
|
||||
|
||||
void core_uninstall_handler()
|
||||
{
|
||||
SNES::interface = old;
|
||||
}
|
||||
|
||||
uint32_t get_snes_cpu_rate()
|
||||
{
|
||||
return SNES::system.cpu_frequency();
|
||||
}
|
||||
|
||||
uint32_t get_snes_apu_rate()
|
||||
{
|
||||
return SNES::system.apu_frequency();
|
||||
}
|
||||
|
||||
std::string get_core_identifier()
|
||||
{
|
||||
std::ostringstream x;
|
||||
x << snes_library_id() << " (" << SNES::Info::Profile << " core)";
|
||||
return x.str();
|
||||
}
|
||||
|
||||
void do_basic_core_init()
|
||||
{
|
||||
static my_interfaced i;
|
||||
SNES::interface = &i;
|
||||
}
|
||||
|
||||
std::set<std::string> 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));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void set_preload_settings()
|
||||
{
|
||||
SNES::config.random = false;
|
||||
SNES::config.expansion_port = SNES::System::ExpansionPortDevice::None;
|
||||
}
|
||||
|
||||
void set_core_controller_generic(unsigned port, unsigned id, bool p2only)
|
||||
{
|
||||
if(port > 1)
|
||||
return;
|
||||
if(port == 1)
|
||||
snes_set_controller_port_device(true, id);
|
||||
if(port == 0) {
|
||||
snes_set_controller_port_device(false, p2only ? SNES_DEVICE_NONE : id);
|
||||
p1disable = p2only;
|
||||
}
|
||||
}
|
||||
|
||||
void set_core_controller_none(unsigned port) throw()
|
||||
{
|
||||
set_core_controller_generic(port, SNES_DEVICE_NONE, false);
|
||||
}
|
||||
|
||||
void set_core_controller_gamepad(unsigned port) throw()
|
||||
{
|
||||
set_core_controller_generic(port, SNES_DEVICE_JOYPAD, false);
|
||||
}
|
||||
|
||||
void set_core_controller_mouse(unsigned port) throw()
|
||||
{
|
||||
set_core_controller_generic(port, SNES_DEVICE_MOUSE, false);
|
||||
}
|
||||
|
||||
void set_core_controller_multitap(unsigned port) throw()
|
||||
{
|
||||
set_core_controller_generic(port, SNES_DEVICE_MULTITAP, false);
|
||||
}
|
||||
|
||||
void set_core_controller_superscope(unsigned port) throw()
|
||||
{
|
||||
set_core_controller_generic(port, SNES_DEVICE_SUPER_SCOPE, true);
|
||||
}
|
||||
|
||||
void set_core_controller_justifier(unsigned port) throw()
|
||||
{
|
||||
set_core_controller_generic(port, SNES_DEVICE_JUSTIFIER, true);
|
||||
}
|
||||
|
||||
void set_core_controller_justifiers(unsigned port) throw()
|
||||
{
|
||||
set_core_controller_generic(port, SNES_DEVICE_JUSTIFIERS, true);
|
||||
}
|
||||
|
||||
int get_button_id_none(unsigned controller, unsigned lbid) throw()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int get_button_id_gamepad(unsigned controller, unsigned lbid) throw()
|
||||
{
|
||||
if(controller > 0)
|
||||
return -1;
|
||||
switch(lbid) {
|
||||
case LOGICAL_BUTTON_LEFT: return SNES_DEVICE_ID_JOYPAD_LEFT;
|
||||
case LOGICAL_BUTTON_RIGHT: return SNES_DEVICE_ID_JOYPAD_RIGHT;
|
||||
case LOGICAL_BUTTON_UP: return SNES_DEVICE_ID_JOYPAD_UP;
|
||||
case LOGICAL_BUTTON_DOWN: return SNES_DEVICE_ID_JOYPAD_DOWN;
|
||||
case LOGICAL_BUTTON_A: return SNES_DEVICE_ID_JOYPAD_A;
|
||||
case LOGICAL_BUTTON_B: return SNES_DEVICE_ID_JOYPAD_B;
|
||||
case LOGICAL_BUTTON_X: return SNES_DEVICE_ID_JOYPAD_X;
|
||||
case LOGICAL_BUTTON_Y: return SNES_DEVICE_ID_JOYPAD_Y;
|
||||
case LOGICAL_BUTTON_L: return SNES_DEVICE_ID_JOYPAD_L;
|
||||
case LOGICAL_BUTTON_R: return SNES_DEVICE_ID_JOYPAD_R;
|
||||
case LOGICAL_BUTTON_SELECT: return SNES_DEVICE_ID_JOYPAD_SELECT;
|
||||
case LOGICAL_BUTTON_START: return SNES_DEVICE_ID_JOYPAD_START;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int get_button_id_mouse(unsigned controller, unsigned lbid) throw()
|
||||
{
|
||||
if(controller > 0)
|
||||
return -1;
|
||||
switch(lbid) {
|
||||
case LOGICAL_BUTTON_L: return SNES_DEVICE_ID_MOUSE_LEFT;
|
||||
case LOGICAL_BUTTON_R: return SNES_DEVICE_ID_MOUSE_RIGHT;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int get_button_id_multitap(unsigned controller, unsigned lbid) throw()
|
||||
{
|
||||
if(controller > 3)
|
||||
return -1;
|
||||
switch(lbid) {
|
||||
case LOGICAL_BUTTON_LEFT: return SNES_DEVICE_ID_JOYPAD_LEFT;
|
||||
case LOGICAL_BUTTON_RIGHT: return SNES_DEVICE_ID_JOYPAD_RIGHT;
|
||||
case LOGICAL_BUTTON_UP: return SNES_DEVICE_ID_JOYPAD_UP;
|
||||
case LOGICAL_BUTTON_DOWN: return SNES_DEVICE_ID_JOYPAD_DOWN;
|
||||
case LOGICAL_BUTTON_A: return SNES_DEVICE_ID_JOYPAD_A;
|
||||
case LOGICAL_BUTTON_B: return SNES_DEVICE_ID_JOYPAD_B;
|
||||
case LOGICAL_BUTTON_X: return SNES_DEVICE_ID_JOYPAD_X;
|
||||
case LOGICAL_BUTTON_Y: return SNES_DEVICE_ID_JOYPAD_Y;
|
||||
case LOGICAL_BUTTON_L: return SNES_DEVICE_ID_JOYPAD_L;
|
||||
case LOGICAL_BUTTON_R: return SNES_DEVICE_ID_JOYPAD_R;
|
||||
case LOGICAL_BUTTON_SELECT: return SNES_DEVICE_ID_JOYPAD_SELECT;
|
||||
case LOGICAL_BUTTON_START: return SNES_DEVICE_ID_JOYPAD_START;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int get_button_id_superscope(unsigned controller, unsigned lbid) throw()
|
||||
{
|
||||
if(controller > 0)
|
||||
return -1;
|
||||
switch(lbid) {
|
||||
case LOGICAL_BUTTON_TRIGGER: return SNES_DEVICE_ID_SUPER_SCOPE_TRIGGER;
|
||||
case LOGICAL_BUTTON_CURSOR: return SNES_DEVICE_ID_SUPER_SCOPE_CURSOR;
|
||||
case LOGICAL_BUTTON_TURBO: return SNES_DEVICE_ID_SUPER_SCOPE_TURBO;
|
||||
case LOGICAL_BUTTON_PAUSE: return SNES_DEVICE_ID_SUPER_SCOPE_PAUSE;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int get_button_id_justifier(unsigned controller, unsigned lbid) throw()
|
||||
{
|
||||
if(controller > 0)
|
||||
return -1;
|
||||
switch(lbid) {
|
||||
case LOGICAL_BUTTON_START: return SNES_DEVICE_ID_JUSTIFIER_START;
|
||||
case LOGICAL_BUTTON_TRIGGER: return SNES_DEVICE_ID_JUSTIFIER_TRIGGER;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int get_button_id_justifiers(unsigned controller, unsigned lbid) throw()
|
||||
{
|
||||
if(controller > 1)
|
||||
return -1;
|
||||
switch(lbid) {
|
||||
case LOGICAL_BUTTON_START: return SNES_DEVICE_ID_JUSTIFIER_START;
|
||||
case LOGICAL_BUTTON_TRIGGER: return SNES_DEVICE_ID_JUSTIFIER_TRIGGER;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
std::string get_logical_button_name(unsigned lbid) throw(std::bad_alloc)
|
||||
{
|
||||
if(lbid >= MAX_LOGICAL_BUTTONS)
|
||||
return "";
|
||||
return buttonnames[lbid];
|
||||
}
|
||||
|
||||
bool core_get_region()
|
||||
{
|
||||
bool r = (SNES::system.region() == SNES::System::Region::PAL);
|
||||
return r;
|
||||
}
|
||||
|
||||
bool core_load_cartridge_normal(const char* rom_markup, const unsigned char* rom, size_t romsize)
|
||||
{
|
||||
bool r = snes_load_cartridge_normal(rom_markup, rom, romsize);
|
||||
if(r)
|
||||
internal_rom = ROM_TYPE_SNES;
|
||||
return r;
|
||||
}
|
||||
|
||||
bool core_load_cartridge_bsx(const char* bios_markup, const unsigned char* bios, size_t biossize,
|
||||
const char* rom_markup, const unsigned char* rom, size_t romsize)
|
||||
{
|
||||
bool r = snes_load_cartridge_bsx(bios_markup, bios, biossize, rom_markup, rom, romsize);
|
||||
if(r)
|
||||
internal_rom = ROM_TYPE_BSX;
|
||||
return r;
|
||||
}
|
||||
|
||||
bool core_load_cartridge_bsx_slotted(const char* bios_markup, const unsigned char* bios, size_t biossize,
|
||||
const char* rom_markup, const unsigned char* rom, size_t romsize)
|
||||
{
|
||||
bool r = snes_load_cartridge_bsx_slotted(bios_markup, bios, biossize, rom_markup, rom, romsize);
|
||||
if(r)
|
||||
internal_rom = ROM_TYPE_BSXSLOTTED;
|
||||
return r;
|
||||
}
|
||||
|
||||
bool core_load_cartridge_super_game_boy(const char* bios_markup, const unsigned char* bios, size_t biossize,
|
||||
const char* rom_markup, const unsigned char* rom, size_t romsize)
|
||||
{
|
||||
bool r = snes_load_cartridge_super_game_boy(bios_markup, bios, biossize, rom_markup, rom, romsize);
|
||||
if(r)
|
||||
internal_rom = ROM_TYPE_SGB;
|
||||
return r;
|
||||
}
|
||||
|
||||
bool core_load_cartridge_sufami_turbo(const char* bios_markup, const unsigned char* bios, size_t biossize,
|
||||
const char* romA_markup, const unsigned char* romA, size_t romAsize, const char* romB_markup,
|
||||
const unsigned char* romB, size_t romBsize)
|
||||
{
|
||||
bool r = snes_load_cartridge_sufami_turbo(bios_markup, bios, biossize, romA_markup, romA, romAsize,
|
||||
romB_markup, romB, romBsize);
|
||||
if(r)
|
||||
internal_rom = ROM_TYPE_SUFAMITURBO;
|
||||
return r;
|
||||
}
|
||||
|
||||
void core_power()
|
||||
{
|
||||
snes_power();
|
||||
}
|
||||
|
||||
//Get the current video rate.
|
||||
std::pair<uint32_t, uint32_t> get_video_rate()
|
||||
{
|
||||
uint32_t div;
|
||||
if(snes_get_region())
|
||||
div = last_interlace ? DURATION_PAL_FIELD : DURATION_PAL_FRAME;
|
||||
else
|
||||
div = last_interlace ? DURATION_NTSC_FIELD : DURATION_NTSC_FRAME;
|
||||
return std::make_pair(get_snes_cpu_rate(), div);
|
||||
}
|
||||
|
||||
//Get the current audio rate.
|
||||
std::pair<uint32_t, uint32_t> get_audio_rate()
|
||||
{
|
||||
return std::make_pair(get_snes_apu_rate(), static_cast<uint32_t>(768));
|
||||
}
|
||||
|
||||
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);
|
||||
std::vector<char> x;
|
||||
x.resize(r.size);
|
||||
memcpy(&x[0], r.data, r.size);
|
||||
out[savename] = x;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc)
|
||||
{
|
||||
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);
|
||||
} else
|
||||
messages << "WARNING: SRAM '" << savename << ": No data." << std::endl;
|
||||
}
|
||||
for(auto i : sram)
|
||||
if(!used.count(i.first))
|
||||
messages << "WARNING: SRAM '" << i.first << ": Not found on cartridge." << std::endl;
|
||||
}
|
||||
|
||||
void core_set_region(int region)
|
||||
{
|
||||
switch(region) {
|
||||
case EC_REGION_AUTO: SNES::config.region = SNES::System::Region::Autodetect; break;
|
||||
case EC_REGION_NTSC: SNES::config.region = SNES::System::Region::NTSC; break;
|
||||
case EC_REGION_PAL: SNES::config.region = SNES::System::Region::PAL; break;
|
||||
}
|
||||
}
|
||||
|
||||
void core_serialize(std::vector<char>& out)
|
||||
{
|
||||
serializer s = SNES::system.serialize();
|
||||
out.resize(s.size());
|
||||
memcpy(&out[0], s.data(), s.size());
|
||||
}
|
||||
|
||||
void core_unserialize(const char* in, size_t insize)
|
||||
{
|
||||
serializer s(reinterpret_cast<const uint8_t*>(in), insize);
|
||||
if(!SNES::system.unserialize(s))
|
||||
throw std::runtime_error("SNES core rejected savestate");
|
||||
}
|
||||
|
||||
std::pair<bool, uint32_t> core_emulate_cycles(uint32_t cycles)
|
||||
{
|
||||
#if defined(BSNES_V084) || defined(BSNES_V085)
|
||||
messages << "Executing delayed reset... This can take some time!" << std::endl;
|
||||
video_refresh_done = false;
|
||||
delayreset_cycles_run = 0;
|
||||
delayreset_cycles_target = cycles;
|
||||
SNES::cpu.step_event = delayreset_fn;
|
||||
SNES::system.run();
|
||||
SNES::cpu.step_event = nall::function<bool()>();
|
||||
return std::make_pair(!video_refresh_done, delayreset_cycles_run);
|
||||
#else
|
||||
messages << "Delayresets not supported on this bsnes version (needs v084 or v085)"
|
||||
<< std::endl;
|
||||
return std::make_pair(false, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void core_emulate_frame()
|
||||
{
|
||||
SNES::system.run();
|
||||
}
|
||||
|
||||
void core_reset()
|
||||
{
|
||||
SNES::system.reset();
|
||||
}
|
||||
|
||||
void core_runtosave()
|
||||
{
|
||||
stepping_into_save = true;
|
||||
SNES::system.runtosave();
|
||||
stepping_into_save = false;
|
||||
}
|
||||
|
||||
std::list<vma_info> get_vma_list()
|
||||
{
|
||||
std::list<vma_info> ret;
|
||||
if(internal_rom == ROM_TYPE_NONE)
|
||||
return ret;
|
||||
create_region(ret, "WRAM", 0x007E0000, SNES::cpu.wram, 131072, false);
|
||||
create_region(ret, "APURAM", 0x00000000, SNES::smp.apuram, 65536, false);
|
||||
create_region(ret, "VRAM", 0x00010000, SNES::ppu.vram, 65536, false);
|
||||
create_region(ret, "OAM", 0x00020000, SNES::ppu.oam, 544, false);
|
||||
create_region(ret, "CGRAM", 0x00021000, SNES::ppu.cgram, 512, false);
|
||||
if(SNES::cartridge.has_srtc()) create_region(ret, "RTC", 0x00022000, SNES::srtc.rtc, 20, false);
|
||||
if(SNES::cartridge.has_spc7110rtc()) create_region(ret, "RTC", 0x00022000, SNES::spc7110.rtc, 20, false);
|
||||
if(SNES::cartridge.has_necdsp()) {
|
||||
create_region(ret, "DSPRAM", 0x00023000, reinterpret_cast<uint8_t*>(SNES::necdsp.dataRAM), 4096,
|
||||
false, true);
|
||||
create_region(ret, "DSPPROM", 0xF0000000, reinterpret_cast<uint8_t*>(SNES::necdsp.programROM), 65536,
|
||||
true, true);
|
||||
create_region(ret, "DSPDROM", 0xF0010000, reinterpret_cast<uint8_t*>(SNES::necdsp.dataROM), 4096,
|
||||
true, true);
|
||||
}
|
||||
create_region(ret, "SRAM", 0x10000000, SNES::cartridge.ram, false);
|
||||
create_region(ret, "ROM", 0x80000000, SNES::cartridge.rom, true);
|
||||
create_region(ret, "BUS", 0x1000000, 0x1000000, snes_bus_iospace_rw);
|
||||
create_region(ret, "PTRTABLE", 0x100000000, 0x100000, ptrtable_iospace_rw);
|
||||
map_internal(ret, "CPU_STATE", 0, &SNES::cpu, sizeof(SNES::cpu));
|
||||
map_internal(ret, "PPU_STATE", 1, &SNES::ppu, sizeof(SNES::ppu));
|
||||
map_internal(ret, "SMP_STATE", 2, &SNES::smp, sizeof(SNES::smp));
|
||||
map_internal(ret, "DSP_STATE", 3, &SNES::dsp, sizeof(SNES::dsp));
|
||||
switch(internal_rom) {
|
||||
case ROM_TYPE_BSX:
|
||||
case ROM_TYPE_BSXSLOTTED:
|
||||
create_region(ret, "BSXFLASH", 0x90000000, SNES::bsxflash.memory, true);
|
||||
create_region(ret, "BSX_RAM", 0x20000000, SNES::bsxcartridge.sram, false);
|
||||
create_region(ret, "BSX_PRAM", 0x30000000, SNES::bsxcartridge.psram, false);
|
||||
break;
|
||||
case ROM_TYPE_SUFAMITURBO:
|
||||
create_region(ret, "SLOTA_ROM", 0x90000000, SNES::sufamiturbo.slotA.rom, true);
|
||||
create_region(ret, "SLOTB_ROM", 0xA0000000, SNES::sufamiturbo.slotB.rom, true);
|
||||
create_region(ret, "SLOTA_RAM", 0x20000000, SNES::sufamiturbo.slotA.ram, false);
|
||||
create_region(ret, "SLOTB_RAM", 0x30000000, SNES::sufamiturbo.slotB.ram, false);
|
||||
break;
|
||||
case ROM_TYPE_SGB:
|
||||
create_region(ret, "GBROM", 0x90000000, GameBoy::cartridge.romdata, GameBoy::cartridge.romsize, true);
|
||||
create_region(ret, "GBRAM", 0x20000000, GameBoy::cartridge.ramdata, GameBoy::cartridge.ramsize, false);
|
||||
break;
|
||||
case ROM_TYPE_SNES:
|
||||
case ROM_TYPE_NONE:
|
||||
break;
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
|
||||
emucore_callbacks::~emucore_callbacks() throw()
|
||||
{
|
||||
}
|
||||
|
||||
struct emucore_callbacks* ecore_callbacks;
|
|
@ -1,4 +1,5 @@
|
|||
#include "lsnes.hpp"
|
||||
#include "core/emucore.hpp"
|
||||
|
||||
#include "core/command.hpp"
|
||||
#include "core/controller.hpp"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "core/bsnes.hpp"
|
||||
#include "core/emucore.hpp"
|
||||
|
||||
#include "core/controllerframe.hpp"
|
||||
#include "core/dispatch.hpp"
|
||||
|
@ -17,19 +18,6 @@ namespace
|
|||
return p;
|
||||
}
|
||||
|
||||
const char* buttonnames[MAX_LOGICAL_BUTTONS] = {
|
||||
"left", "right", "up", "down", "A", "B", "X", "Y", "L", "R", "select", "start", "trigger",
|
||||
"cursor", "turbo", "pause"
|
||||
};
|
||||
|
||||
template<unsigned type>
|
||||
void set_core_controller_bsnes(unsigned port) throw()
|
||||
{
|
||||
if(port > 1)
|
||||
return;
|
||||
snes_set_controller_port_device(port != 0, type);
|
||||
}
|
||||
|
||||
void set_core_controller_illegal(unsigned port) throw()
|
||||
{
|
||||
std::cerr << "Attempt to set core port type to INVALID port type" << std::endl;
|
||||
|
@ -47,8 +35,6 @@ namespace
|
|||
deserialize = NULL;
|
||||
devicetype = generic_port_devicetype<0, DT_NONE>;
|
||||
controllers = 0;
|
||||
internal_type = 0;
|
||||
legal = generic_port_legal<0xFFFFFFFFU>;
|
||||
set_core_controller = set_core_controller_illegal;
|
||||
}
|
||||
|
||||
|
@ -68,31 +54,13 @@ namespace
|
|||
serialize = generic_port_serialize<1, 0, 12, 0>;
|
||||
deserialize = generic_port_deserialize<1, 0, 12>;
|
||||
devicetype = generic_port_devicetype<1, DT_GAMEPAD>;
|
||||
legal = generic_port_legal<3>;
|
||||
controllers = 1;
|
||||
internal_type = SNES_DEVICE_JOYPAD;
|
||||
set_core_controller = set_core_controller_bsnes<SNES_DEVICE_JOYPAD>;
|
||||
set_core_controller = set_core_controller_gamepad;
|
||||
}
|
||||
|
||||
int button_id(unsigned controller, unsigned lbid) const throw()
|
||||
{
|
||||
if(controller > 0)
|
||||
return -1;
|
||||
switch(lbid) {
|
||||
case LOGICAL_BUTTON_LEFT: return SNES_DEVICE_ID_JOYPAD_LEFT;
|
||||
case LOGICAL_BUTTON_RIGHT: return SNES_DEVICE_ID_JOYPAD_RIGHT;
|
||||
case LOGICAL_BUTTON_UP: return SNES_DEVICE_ID_JOYPAD_UP;
|
||||
case LOGICAL_BUTTON_DOWN: return SNES_DEVICE_ID_JOYPAD_DOWN;
|
||||
case LOGICAL_BUTTON_A: return SNES_DEVICE_ID_JOYPAD_A;
|
||||
case LOGICAL_BUTTON_B: return SNES_DEVICE_ID_JOYPAD_B;
|
||||
case LOGICAL_BUTTON_X: return SNES_DEVICE_ID_JOYPAD_X;
|
||||
case LOGICAL_BUTTON_Y: return SNES_DEVICE_ID_JOYPAD_Y;
|
||||
case LOGICAL_BUTTON_L: return SNES_DEVICE_ID_JOYPAD_L;
|
||||
case LOGICAL_BUTTON_R: return SNES_DEVICE_ID_JOYPAD_R;
|
||||
case LOGICAL_BUTTON_SELECT: return SNES_DEVICE_ID_JOYPAD_SELECT;
|
||||
case LOGICAL_BUTTON_START: return SNES_DEVICE_ID_JOYPAD_START;
|
||||
default: return -1;
|
||||
}
|
||||
return get_button_id_gamepad(controller, lbid);
|
||||
}
|
||||
} gamepad;
|
||||
|
||||
|
@ -106,21 +74,13 @@ namespace
|
|||
serialize = generic_port_serialize<1, 2, 2, 12>;
|
||||
deserialize = generic_port_deserialize<1, 2, 2>;
|
||||
devicetype = generic_port_devicetype<1, DT_LIGHTGUN>;
|
||||
legal = generic_port_legal<2>;
|
||||
controllers = 1;
|
||||
internal_type = SNES_DEVICE_JUSTIFIER;
|
||||
set_core_controller = set_core_controller_bsnes<SNES_DEVICE_JUSTIFIER>;
|
||||
set_core_controller = set_core_controller_justifier;
|
||||
}
|
||||
|
||||
int button_id(unsigned controller, unsigned lbid) const throw()
|
||||
{
|
||||
if(controller > 0)
|
||||
return -1;
|
||||
switch(lbid) {
|
||||
case LOGICAL_BUTTON_START: return SNES_DEVICE_ID_JUSTIFIER_START;
|
||||
case LOGICAL_BUTTON_TRIGGER: return SNES_DEVICE_ID_JUSTIFIER_TRIGGER;
|
||||
default: return -1;
|
||||
}
|
||||
return get_button_id_justifier(controller, lbid);
|
||||
}
|
||||
} justifier;
|
||||
|
||||
|
@ -134,21 +94,13 @@ namespace
|
|||
serialize = generic_port_serialize<2, 2, 2, 12>;
|
||||
deserialize = generic_port_deserialize<2, 2, 2>;
|
||||
devicetype = generic_port_devicetype<2, DT_LIGHTGUN>;
|
||||
legal = generic_port_legal<2>;
|
||||
controllers = 2;
|
||||
internal_type = SNES_DEVICE_JUSTIFIERS;
|
||||
set_core_controller = set_core_controller_bsnes<SNES_DEVICE_JUSTIFIERS>;
|
||||
set_core_controller = set_core_controller_justifiers;
|
||||
}
|
||||
|
||||
int button_id(unsigned controller, unsigned lbid) const throw()
|
||||
{
|
||||
if(controller > 1)
|
||||
return -1;
|
||||
switch(lbid) {
|
||||
case LOGICAL_BUTTON_START: return SNES_DEVICE_ID_JUSTIFIER_START;
|
||||
case LOGICAL_BUTTON_TRIGGER: return SNES_DEVICE_ID_JUSTIFIER_TRIGGER;
|
||||
default: return -1;
|
||||
}
|
||||
return get_button_id_justifiers(controller, lbid);
|
||||
}
|
||||
} justifiers;
|
||||
|
||||
|
@ -162,21 +114,13 @@ namespace
|
|||
serialize = generic_port_serialize<1, 2, 2, 12>;
|
||||
deserialize = generic_port_deserialize<1, 2, 2>;
|
||||
devicetype = generic_port_devicetype<1, DT_MOUSE>;
|
||||
legal = generic_port_legal<3>;
|
||||
controllers = 1;
|
||||
internal_type = SNES_DEVICE_MOUSE;
|
||||
set_core_controller = set_core_controller_bsnes<SNES_DEVICE_MOUSE>;
|
||||
set_core_controller = set_core_controller_mouse;
|
||||
}
|
||||
|
||||
int button_id(unsigned controller, unsigned lbid) const throw()
|
||||
{
|
||||
if(controller > 0)
|
||||
return -1;
|
||||
switch(lbid) {
|
||||
case LOGICAL_BUTTON_L: return SNES_DEVICE_ID_MOUSE_LEFT;
|
||||
case LOGICAL_BUTTON_R: return SNES_DEVICE_ID_MOUSE_RIGHT;
|
||||
default: return -1;
|
||||
}
|
||||
return get_button_id_mouse(controller, lbid);
|
||||
}
|
||||
} mouse;
|
||||
|
||||
|
@ -190,31 +134,13 @@ namespace
|
|||
serialize = generic_port_serialize<4, 0, 12, 0>;
|
||||
deserialize = generic_port_deserialize<4, 0, 12>;
|
||||
devicetype = generic_port_devicetype<4, DT_GAMEPAD>;
|
||||
legal = generic_port_legal<3>;
|
||||
controllers = 4;
|
||||
internal_type = SNES_DEVICE_MULTITAP;
|
||||
set_core_controller = set_core_controller_bsnes<SNES_DEVICE_MULTITAP>;
|
||||
set_core_controller = set_core_controller_multitap;
|
||||
}
|
||||
|
||||
int button_id(unsigned controller, unsigned lbid) const throw()
|
||||
{
|
||||
if(controller > 3)
|
||||
return -1;
|
||||
switch(lbid) {
|
||||
case LOGICAL_BUTTON_LEFT: return SNES_DEVICE_ID_JOYPAD_LEFT;
|
||||
case LOGICAL_BUTTON_RIGHT: return SNES_DEVICE_ID_JOYPAD_RIGHT;
|
||||
case LOGICAL_BUTTON_UP: return SNES_DEVICE_ID_JOYPAD_UP;
|
||||
case LOGICAL_BUTTON_DOWN: return SNES_DEVICE_ID_JOYPAD_DOWN;
|
||||
case LOGICAL_BUTTON_A: return SNES_DEVICE_ID_JOYPAD_A;
|
||||
case LOGICAL_BUTTON_B: return SNES_DEVICE_ID_JOYPAD_B;
|
||||
case LOGICAL_BUTTON_X: return SNES_DEVICE_ID_JOYPAD_X;
|
||||
case LOGICAL_BUTTON_Y: return SNES_DEVICE_ID_JOYPAD_Y;
|
||||
case LOGICAL_BUTTON_L: return SNES_DEVICE_ID_JOYPAD_L;
|
||||
case LOGICAL_BUTTON_R: return SNES_DEVICE_ID_JOYPAD_R;
|
||||
case LOGICAL_BUTTON_SELECT: return SNES_DEVICE_ID_JOYPAD_SELECT;
|
||||
case LOGICAL_BUTTON_START: return SNES_DEVICE_ID_JOYPAD_START;
|
||||
default: return -1;
|
||||
}
|
||||
return get_button_id_multitap(controller, lbid);
|
||||
}
|
||||
} multitap;
|
||||
|
||||
|
@ -228,15 +154,13 @@ namespace
|
|||
serialize = generic_port_serialize<0, 0, 0, 0>;
|
||||
deserialize = generic_port_deserialize<0, 0, 0>;
|
||||
devicetype = generic_port_devicetype<0, DT_GAMEPAD>;
|
||||
legal = generic_port_legal<3>;
|
||||
controllers = 0;
|
||||
internal_type = SNES_DEVICE_NONE;
|
||||
set_core_controller = set_core_controller_bsnes<SNES_DEVICE_NONE>;
|
||||
set_core_controller = set_core_controller_none;
|
||||
}
|
||||
|
||||
int button_id(unsigned controller, unsigned lbid) const throw()
|
||||
{
|
||||
return -1;
|
||||
return get_button_id_none(controller, lbid);
|
||||
}
|
||||
} none;
|
||||
|
||||
|
@ -250,23 +174,13 @@ namespace
|
|||
serialize = generic_port_serialize<1, 2, 4, 14>;
|
||||
deserialize = generic_port_deserialize<1, 2, 4>;
|
||||
devicetype = generic_port_devicetype<1, DT_LIGHTGUN>;
|
||||
legal = generic_port_legal<2>;
|
||||
controllers = 1;
|
||||
internal_type = SNES_DEVICE_SUPER_SCOPE;
|
||||
set_core_controller = set_core_controller_bsnes<SNES_DEVICE_SUPER_SCOPE>;
|
||||
set_core_controller = set_core_controller_superscope;
|
||||
}
|
||||
|
||||
int button_id(unsigned controller, unsigned lbid) const throw()
|
||||
{
|
||||
if(controller > 0)
|
||||
return -1;
|
||||
switch(lbid) {
|
||||
case LOGICAL_BUTTON_TRIGGER: return SNES_DEVICE_ID_SUPER_SCOPE_TRIGGER;
|
||||
case LOGICAL_BUTTON_CURSOR: return SNES_DEVICE_ID_SUPER_SCOPE_CURSOR;
|
||||
case LOGICAL_BUTTON_TURBO: return SNES_DEVICE_ID_SUPER_SCOPE_TURBO;
|
||||
case LOGICAL_BUTTON_PAUSE: return SNES_DEVICE_ID_SUPER_SCOPE_PAUSE;
|
||||
default: return -1;
|
||||
}
|
||||
return get_button_id_superscope(controller, lbid);
|
||||
}
|
||||
} superscope;
|
||||
|
||||
|
@ -277,20 +191,6 @@ namespace
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name of logical button.
|
||||
*
|
||||
* Parameter lbid: ID of logical button.
|
||||
* Returns: The name of button.
|
||||
* Throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
std::string get_logical_button_name(unsigned lbid) throw(std::bad_alloc)
|
||||
{
|
||||
if(lbid >= MAX_LOGICAL_BUTTONS)
|
||||
return "";
|
||||
return buttonnames[lbid];
|
||||
}
|
||||
|
||||
const porttype_info& porttype_info::lookup(porttype_t p) throw(std::runtime_error)
|
||||
{
|
||||
get_invalid_port_type();
|
||||
|
@ -467,8 +367,6 @@ void controller_frame::set_types(const porttype_t* tarr)
|
|||
for(unsigned i = 0; i < MAX_PORTS; i++) {
|
||||
if(memory != backing && types[i] != tarr[i])
|
||||
throw std::runtime_error("Controller_frame: Type mismatch");
|
||||
if(!porttype_info::lookup(tarr[i]).legal(i))
|
||||
throw std::runtime_error("Illegal port type for port index");
|
||||
}
|
||||
size_t offset = SYSTEM_BYTES;
|
||||
for(unsigned i = 0; i < MAX_PORTS; i++) {
|
||||
|
@ -721,8 +619,6 @@ controller_frame::controller_frame() throw()
|
|||
void controller_frame::set_port_type(unsigned port, porttype_t ptype) throw(std::runtime_error)
|
||||
{
|
||||
char tmp[MAXIMUM_CONTROLLER_FRAME_SIZE] = {0};
|
||||
if(!porttype_info::lookup(ptype).legal(port))
|
||||
throw std::runtime_error("Illegal port type for port index");
|
||||
if(memory != backing)
|
||||
throw std::runtime_error("Can't set port type on non-dedicated controller frame");
|
||||
if(port >= MAX_PORTS)
|
||||
|
@ -889,8 +785,6 @@ void controller_state::set_port(unsigned port, porttype_t ptype, bool set_core)
|
|||
if(port >= MAX_PORTS)
|
||||
throw std::runtime_error("Port number invalid");
|
||||
const porttype_info* info = &porttype_info::lookup(ptype);
|
||||
if(!info->legal(port))
|
||||
throw std::runtime_error("Port type not valid for port");
|
||||
if(set_core)
|
||||
info->set_core_controller(port);
|
||||
porttype_t oldtype = porttypes[port];
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#include "lsnes.hpp"
|
||||
#include "core/bsnes.hpp"
|
||||
#include "core/emucore.hpp"
|
||||
|
||||
#include "core/command.hpp"
|
||||
#include "core/controller.hpp"
|
||||
|
@ -60,14 +62,11 @@ namespace
|
|||
std::string pending_load;
|
||||
//Queued saves (all savestates).
|
||||
std::set<std::string> queued_saves;
|
||||
bool stepping_into_save;
|
||||
//Save jukebox.
|
||||
numeric_setting jukebox_size("jukebox-size", 0, 999, 12);
|
||||
size_t save_jukebox_pointer;
|
||||
//Pending reset cycles. -1 if no reset pending, otherwise, cycle count for reset.
|
||||
long pending_reset_cycles = -1;
|
||||
//Set by every video refresh.
|
||||
bool video_refresh_done;
|
||||
//Special subframe location. One of SPECIAL_* constants.
|
||||
int location_special;
|
||||
//Few settings.
|
||||
|
@ -76,23 +75,12 @@ namespace
|
|||
//Last frame params.
|
||||
bool last_hires = false;
|
||||
bool last_interlace = false;
|
||||
//Delay reset.
|
||||
unsigned long long delayreset_cycles_run;
|
||||
unsigned long long delayreset_cycles_target;
|
||||
//Unsafe rewind.
|
||||
bool do_unsafe_rewind = false;
|
||||
void* unsafe_rewind_obj = NULL;
|
||||
|
||||
enum advance_mode old_mode;
|
||||
|
||||
bool delayreset_fn()
|
||||
{
|
||||
if(delayreset_cycles_run == delayreset_cycles_target || video_refresh_done)
|
||||
return true;
|
||||
delayreset_cycles_run++;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string save_jukebox_name(size_t i)
|
||||
{
|
||||
return (stringfmt() << "${project}" << (i + 1) << ".lsmv").str();
|
||||
|
@ -201,27 +189,6 @@ namespace
|
|||
queued_saves.insert(filename);
|
||||
messages << "Pending save on '" << filename << "'" << std::endl;
|
||||
}
|
||||
|
||||
uint32_t lpalette[0x80000];
|
||||
void init_palette()
|
||||
{
|
||||
static bool palette_init = false;
|
||||
if(palette_init)
|
||||
return;
|
||||
palette_init = true;
|
||||
for(unsigned i = 0; i < 0x80000; i++) {
|
||||
unsigned l = (i >> 15) & 0xF;
|
||||
unsigned r = (i >> 0) & 0x1F;
|
||||
unsigned g = (i >> 5) & 0x1F;
|
||||
unsigned b = (i >> 10) & 0x1F;
|
||||
double _l = static_cast<double>(l);
|
||||
double m = 17.0 / 31.0;
|
||||
r = floor(m * r * _l + 0.5);
|
||||
g = floor(m * g * _l + 0.5);
|
||||
b = floor(m * b * _l + 0.5);
|
||||
lpalette[i] = r * 65536 + g * 256 + b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void update_movie_state()
|
||||
|
@ -301,111 +268,60 @@ uint64_t controller_irq_time;
|
|||
uint64_t frame_irq_time;
|
||||
std::string msu1_base_path;
|
||||
|
||||
class my_interface : public SNES::Interface
|
||||
struct lsnes_callbacks : public emucore_callbacks
|
||||
{
|
||||
string path(SNES::Cartridge::Slot slot, const string &hint)
|
||||
public:
|
||||
~lsnes_callbacks() throw()
|
||||
{
|
||||
const char* _hint = hint;
|
||||
std::string _hint2 = _hint;
|
||||
std::string fwp = firmwarepath_setting;
|
||||
regex_results r;
|
||||
std::string msubase = msu1_base_path;
|
||||
if(regex_match(".*\\.sfc", msu1_base_path))
|
||||
msubase = msu1_base_path.substr(0, msu1_base_path.length() - 4);
|
||||
|
||||
if(_hint2 == "msu1.rom" || _hint2 == ".msu") {
|
||||
//MSU-1 main ROM.
|
||||
std::string x = msubase + ".msu";
|
||||
messages << "MSU main data file: " << x << std::endl;
|
||||
return x.c_str();
|
||||
}
|
||||
if(r = regex("(track)?(-([0-9])+\\.pcm)", _hint2)) {
|
||||
//MSU track.
|
||||
std::string x = msubase + r[2];
|
||||
messages << "MSU track " << r[3] << "': " << x << std::endl;
|
||||
return x.c_str();
|
||||
}
|
||||
std::string finalpath = fwp + "/" + _hint2;
|
||||
return finalpath.c_str();
|
||||
}
|
||||
|
||||
time_t currentTime()
|
||||
int16_t get_input(unsigned port, unsigned index, unsigned control)
|
||||
{
|
||||
int16_t x;
|
||||
x = movb.input_poll(port, index, control);
|
||||
lua_callback_snoop_input(port, index, control, x);
|
||||
return x;
|
||||
}
|
||||
|
||||
void timer_tick(uint32_t increment, uint32_t per_second)
|
||||
{
|
||||
our_movie.rtc_subsecond += increment;
|
||||
while(our_movie.rtc_subsecond >= per_second) {
|
||||
our_movie.rtc_second++;
|
||||
our_movie.rtc_subsecond -= per_second;
|
||||
}
|
||||
}
|
||||
|
||||
std::string get_firmware_path()
|
||||
{
|
||||
return firmwarepath_setting;
|
||||
}
|
||||
|
||||
std::string get_base_path()
|
||||
{
|
||||
return msu1_base_path;
|
||||
}
|
||||
|
||||
time_t get_time()
|
||||
{
|
||||
return our_movie.rtc_second;
|
||||
}
|
||||
|
||||
time_t randomSeed()
|
||||
time_t get_randomseed()
|
||||
{
|
||||
return random_seed_value;
|
||||
}
|
||||
|
||||
void videoRefresh(const uint32_t* data, bool hires, bool interlace, bool overscan)
|
||||
void output_frame(lcscreen& screen, uint32_t fps_n, uint32_t fps_d)
|
||||
{
|
||||
// uint64_t time_x = get_utime();
|
||||
last_hires = hires;
|
||||
last_interlace = interlace;
|
||||
init_palette();
|
||||
if(stepping_into_save)
|
||||
messages << "Got video refresh in runtosave, expect desyncs!" << std::endl;
|
||||
video_refresh_done = true;
|
||||
lua_callback_do_frame_emulated();
|
||||
bool region = (SNES::system.region() == SNES::System::Region::PAL);
|
||||
information_dispatch::do_raw_frame(data, hires, interlace, overscan, region ? VIDEO_REGION_PAL :
|
||||
VIDEO_REGION_NTSC);
|
||||
//std::cerr << "Frame: hires flag is " << (hires ? " " : "un") << "set." << std::endl;
|
||||
//std::cerr << "Frame: interlace flag is " << (interlace ? " " : "un") << "set." << std::endl;
|
||||
//std::cerr << "Frame: overscan flag is " << (overscan ? " " : "un") << "set." << std::endl;
|
||||
//std::cerr << "Frame: region flag is " << (region ? " " : "un") << "set." << std::endl;
|
||||
lcscreen ls(data, hires, interlace, overscan, region);
|
||||
location_special = SPECIAL_FRAME_VIDEO;
|
||||
update_movie_state();
|
||||
redraw_framebuffer(ls, false, true);
|
||||
uint32_t fps_n, fps_d;
|
||||
uint32_t fclocks;
|
||||
if(region)
|
||||
fclocks = interlace ? DURATION_PAL_FIELD : DURATION_PAL_FRAME;
|
||||
else
|
||||
fclocks = interlace ? DURATION_NTSC_FIELD : DURATION_NTSC_FRAME;
|
||||
fps_n = SNES::system.cpu_frequency();
|
||||
fps_d = fclocks;
|
||||
redraw_framebuffer(screen, false, true);
|
||||
uint32_t g = gcd(fps_n, fps_d);
|
||||
fps_n /= g;
|
||||
fps_d /= g;
|
||||
information_dispatch::do_frame(ls, fps_n, fps_d);
|
||||
// time_x = get_utime() - time_x;
|
||||
// std::cerr << "IRQ TIMINGS (microseconds): "
|
||||
// << "V: " << time_x << " "
|
||||
// << "A: " << audio_irq_time << " "
|
||||
// << "C: " << controller_irq_time << " "
|
||||
// << "F: " << frame_irq_time << " "
|
||||
// << "Total: " << (time_x + audio_irq_time + controller_irq_time + frame_irq_time) << std::endl;
|
||||
audio_irq_time = controller_irq_time = 0;
|
||||
}
|
||||
|
||||
void audioSample(int16_t l_sample, int16_t r_sample)
|
||||
{
|
||||
// uint64_t time_x = get_utime();
|
||||
uint16_t _l = l_sample;
|
||||
uint16_t _r = r_sample;
|
||||
platform::audio_sample(_l + 32768, _r + 32768);
|
||||
information_dispatch::do_sample(l_sample, r_sample);
|
||||
//The SMP emits a sample every 768 ticks of its clock. Use this in order to keep track of time.
|
||||
our_movie.rtc_subsecond += 768;
|
||||
while(our_movie.rtc_subsecond >= SNES::system.apu_frequency()) {
|
||||
our_movie.rtc_second++;
|
||||
our_movie.rtc_subsecond -= SNES::system.apu_frequency();
|
||||
}
|
||||
// audio_irq_time += get_utime() - time_x;
|
||||
}
|
||||
|
||||
int16_t inputPoll(bool port, SNES::Input::Device device, unsigned index, unsigned id)
|
||||
{
|
||||
// uint64_t time_x = get_utime();
|
||||
int16_t x;
|
||||
x = movb.input_poll(port, index, id);
|
||||
lua_callback_snoop_input(port ? 1 : 0, index, id, x);
|
||||
// controller_irq_time += get_utime() - time_x;
|
||||
return x;
|
||||
information_dispatch::do_frame(screen, fps_n, fps_d);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -828,9 +744,7 @@ namespace
|
|||
void handle_saves()
|
||||
{
|
||||
if(!queued_saves.empty() || (do_unsafe_rewind && !unsafe_rewind_obj)) {
|
||||
stepping_into_save = true;
|
||||
SNES::system.runtosave();
|
||||
stepping_into_save = false;
|
||||
core_runtosave();
|
||||
for(auto i : queued_saves)
|
||||
do_save_state(i);
|
||||
if(do_unsafe_rewind && !unsafe_rewind_obj) {
|
||||
|
@ -851,27 +765,18 @@ namespace
|
|||
{
|
||||
if(cycles < 0)
|
||||
return true;
|
||||
video_refresh_done = false;
|
||||
bool video_refresh_done = false;
|
||||
if(cycles == 0)
|
||||
messages << "SNES reset" << std::endl;
|
||||
else if(cycles > 0) {
|
||||
#if defined(BSNES_V084) || defined(BSNES_V085)
|
||||
messages << "Executing delayed reset... This can take some time!" << std::endl;
|
||||
delayreset_cycles_run = 0;
|
||||
delayreset_cycles_target = cycles;
|
||||
SNES::cpu.step_event = delayreset_fn;
|
||||
SNES::system.run();
|
||||
SNES::cpu.step_event = nall::function<bool()>();
|
||||
if(!video_refresh_done)
|
||||
messages << "SNES reset (delayed " << delayreset_cycles_run << ")" << std::endl;
|
||||
auto x = core_emulate_cycles(cycles);
|
||||
if(x.first)
|
||||
messages << "SNES reset (delayed " << x.second << ")" << std::endl;
|
||||
else
|
||||
messages << "SNES reset (forced at " << delayreset_cycles_run << ")" << std::endl;
|
||||
#else
|
||||
messages << "Delayresets not supported on this bsnes version (needs v084 or v085)"
|
||||
<< std::endl;
|
||||
#endif
|
||||
messages << "SNES reset (forced at " << x.second << ")" << std::endl;
|
||||
video_refresh_done = !x.first;
|
||||
}
|
||||
SNES::system.reset();
|
||||
core_reset();
|
||||
lua_callback_do_reset();
|
||||
redraw_framebuffer(screen_nosignal);
|
||||
if(video_refresh_done) {
|
||||
|
@ -903,10 +808,9 @@ void main_loop(struct loaded_rom& rom, struct moviefile& initial, bool load_has_
|
|||
//Basic initialization.
|
||||
init_special_screens();
|
||||
our_rom = &rom;
|
||||
my_interface intrf;
|
||||
auto old_inteface = SNES::interface;
|
||||
SNES::interface = &intrf;
|
||||
SNES::system.init();
|
||||
lsnes_callbacks lsnes_callbacks_obj;
|
||||
ecore_callbacks = &lsnes_callbacks_obj;
|
||||
core_install_handler();
|
||||
|
||||
//Load our given movie.
|
||||
bool first_round = false;
|
||||
|
@ -989,7 +893,7 @@ void main_loop(struct loaded_rom& rom, struct moviefile& initial, bool load_has_
|
|||
just_did_loadstate = false;
|
||||
}
|
||||
frame_irq_time = get_utime() - time_x;
|
||||
SNES::system.run();
|
||||
core_emulate_frame();
|
||||
time_x = get_utime();
|
||||
if(amode == ADVANCE_AUTO)
|
||||
platform::wait(to_wait_frame(get_utime()));
|
||||
|
@ -997,5 +901,5 @@ void main_loop(struct loaded_rom& rom, struct moviefile& initial, bool load_has_
|
|||
lua_callback_do_frame();
|
||||
}
|
||||
information_dispatch::do_dump_end();
|
||||
SNES::interface = old_inteface;
|
||||
core_uninstall_handler();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "core/bsnes.hpp"
|
||||
#include <gameboy/gameboy.hpp>
|
||||
#include "core/emucore.hpp"
|
||||
|
||||
#include "core/command.hpp"
|
||||
#include "core/memorymanip.hpp"
|
||||
|
@ -56,26 +55,6 @@ namespace
|
|||
std::vector<region> memory_regions;
|
||||
uint64_t linear_ram_size = 0;
|
||||
bool system_little_endian = true;
|
||||
std::map<int16_t, std::pair<uint64_t, uint64_t>> ptrmap;
|
||||
|
||||
uint8_t snes_bus_iospace_rw(uint64_t offset, uint8_t data, bool write)
|
||||
{
|
||||
if(write)
|
||||
SNES::bus.write(offset, data);
|
||||
else
|
||||
return SNES::bus.read(offset);
|
||||
}
|
||||
|
||||
uint8_t ptrtable_iospace_rw(uint64_t offset, uint8_t data, bool write)
|
||||
{
|
||||
uint16_t entry = offset >> 4;
|
||||
if(!ptrmap.count(entry))
|
||||
return 0;
|
||||
uint64_t val = ((offset & 15) < 8) ? ptrmap[entry].first : ptrmap[entry].second;
|
||||
uint8_t byte = offset & 7;
|
||||
//These things are always little-endian.
|
||||
return (val >> (8 * byte));
|
||||
}
|
||||
|
||||
struct translated_address translate_address(uint64_t rawaddr) throw()
|
||||
{
|
||||
|
@ -167,19 +146,6 @@ namespace
|
|||
return base + size;
|
||||
}
|
||||
|
||||
uint64_t map_internal(const std::string& name, uint16_t index, void* memory, size_t memsize)
|
||||
{
|
||||
ptrmap[index] = std::make_pair(reinterpret_cast<uint64_t>(memory), static_cast<uint64_t>(memsize));
|
||||
return create_region(name, 0x101000000 + index * 0x1000000, reinterpret_cast<uint8_t*>(memory),
|
||||
memsize, true, true);
|
||||
}
|
||||
|
||||
uint64_t create_region(const std::string& name, uint64_t base, SNES::MappedRAM& memory, bool readonly,
|
||||
bool native_endian = false) throw(std::bad_alloc)
|
||||
{
|
||||
return create_region(name, base, memory.data(), memory.size(), readonly, native_endian);
|
||||
}
|
||||
|
||||
uint8_t native_littleendian_convert(uint8_t x) throw()
|
||||
{
|
||||
return x;
|
||||
|
@ -257,50 +223,14 @@ void refresh_cart_mappings() throw(std::bad_alloc)
|
|||
memory_regions.clear();
|
||||
if(get_current_rom_info().first == ROMTYPE_NONE)
|
||||
return;
|
||||
create_region("WRAM", 0x007E0000, SNES::cpu.wram, 131072, false);
|
||||
create_region("APURAM", 0x00000000, SNES::smp.apuram, 65536, false);
|
||||
create_region("VRAM", 0x00010000, SNES::ppu.vram, 65536, false);
|
||||
create_region("OAM", 0x00020000, SNES::ppu.oam, 544, false);
|
||||
create_region("CGRAM", 0x00021000, SNES::ppu.cgram, 512, false);
|
||||
if(SNES::cartridge.has_srtc()) create_region("RTC", 0x00022000, SNES::srtc.rtc, 20, false);
|
||||
if(SNES::cartridge.has_spc7110rtc()) create_region("RTC", 0x00022000, SNES::spc7110.rtc, 20, false);
|
||||
if(SNES::cartridge.has_necdsp()) {
|
||||
create_region("DSPRAM", 0x00023000, reinterpret_cast<uint8_t*>(SNES::necdsp.dataRAM), 4096, false,
|
||||
true);
|
||||
create_region("DSPPROM", 0xF0000000, reinterpret_cast<uint8_t*>(SNES::necdsp.programROM), 65536, true,
|
||||
true);
|
||||
create_region("DSPDROM", 0xF0010000, reinterpret_cast<uint8_t*>(SNES::necdsp.dataROM), 4096, true,
|
||||
true);
|
||||
auto vmalist = get_vma_list();
|
||||
for(auto i : vmalist) {
|
||||
if(i.iospace_rw)
|
||||
create_region(i.name, i.base, i.size, i.iospace_rw);
|
||||
else
|
||||
create_region(i.name, i.base, reinterpret_cast<uint8_t*>(i.backing_ram), i.size, i.readonly,
|
||||
i.native_endian);
|
||||
}
|
||||
create_region("SRAM", 0x10000000, SNES::cartridge.ram, false);
|
||||
create_region("ROM", 0x80000000, SNES::cartridge.rom, true);
|
||||
create_region("BUS", 0x1000000, 0x1000000, snes_bus_iospace_rw);
|
||||
create_region("PTRTABLE", 0x100000000, 0x100000, ptrtable_iospace_rw);
|
||||
map_internal("CPU_STATE", 0, &SNES::cpu, sizeof(SNES::cpu));
|
||||
map_internal("PPU_STATE", 1, &SNES::ppu, sizeof(SNES::ppu));
|
||||
map_internal("SMP_STATE", 2, &SNES::smp, sizeof(SNES::smp));
|
||||
map_internal("DSP_STATE", 3, &SNES::dsp, sizeof(SNES::dsp));
|
||||
switch(get_current_rom_info().first) {
|
||||
case ROMTYPE_BSX:
|
||||
case ROMTYPE_BSXSLOTTED:
|
||||
create_region("BSXFLASH", 0x90000000, SNES::bsxflash.memory, true);
|
||||
create_region("BSX_RAM", 0x20000000, SNES::bsxcartridge.sram, false);
|
||||
create_region("BSX_PRAM", 0x30000000, SNES::bsxcartridge.psram, false);
|
||||
break;
|
||||
case ROMTYPE_SUFAMITURBO:
|
||||
create_region("SLOTA_ROM", 0x90000000, SNES::sufamiturbo.slotA.rom, true);
|
||||
create_region("SLOTB_ROM", 0xA0000000, SNES::sufamiturbo.slotB.rom, true);
|
||||
create_region("SLOTA_RAM", 0x20000000, SNES::sufamiturbo.slotA.ram, false);
|
||||
create_region("SLOTB_RAM", 0x30000000, SNES::sufamiturbo.slotB.ram, false);
|
||||
break;
|
||||
case ROMTYPE_SGB:
|
||||
create_region("GBROM", 0x90000000, GameBoy::cartridge.romdata, GameBoy::cartridge.romsize, true);
|
||||
create_region("GBRAM", 0x20000000, GameBoy::cartridge.ramdata, GameBoy::cartridge.ramsize, false);
|
||||
break;
|
||||
case ROMTYPE_SNES:
|
||||
case ROMTYPE_NONE:
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
std::vector<struct memory_region> get_regions() throw(std::bad_alloc)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "core/bsnes.hpp"
|
||||
#include "lsnes.hpp"
|
||||
#include "core/emucore.hpp"
|
||||
|
||||
#include "core/command.hpp"
|
||||
#include "core/controller.hpp"
|
||||
|
@ -271,8 +272,7 @@ extern time_t random_seed_value;
|
|||
|
||||
void do_load_beginning() throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
SNES::config.random = false;
|
||||
SNES::config.expansion_port = SNES::System::ExpansionPortDevice::None;
|
||||
set_preload_settings();
|
||||
|
||||
//Negative return.
|
||||
rrdata::add_internal();
|
||||
|
@ -337,8 +337,7 @@ void do_load_state(struct moviefile& _movie, int lmode)
|
|||
if(!rom_ok)
|
||||
throw std::runtime_error("Incorrect ROM");
|
||||
|
||||
SNES::config.random = false;
|
||||
SNES::config.expansion_port = SNES::System::ExpansionPortDevice::None;
|
||||
set_preload_settings();
|
||||
|
||||
movie newmovie;
|
||||
if(lmode == LOAD_STATE_PRESERVE)
|
||||
|
|
|
@ -285,8 +285,6 @@ porttype_t parse_controller_type(const std::string& type, bool port) throw(std::
|
|||
{
|
||||
try {
|
||||
const porttype_info& i = porttype_info::lookup(type);
|
||||
if(!i.legal(port ? 1 : 0))
|
||||
throw 42;
|
||||
return i.value;
|
||||
} catch(...) {
|
||||
throw std::runtime_error(std::string("Illegal port") + (port ? "2" : "1") + " device '" + type + "'");
|
||||
|
|
112
src/core/rom.cpp
112
src/core/rom.cpp
|
@ -1,3 +1,5 @@
|
|||
#include "lsnes.hpp"
|
||||
#include "core/emucore.hpp"
|
||||
#include "core/bsnes.hpp"
|
||||
|
||||
#include "core/command.hpp"
|
||||
|
@ -401,43 +403,37 @@ void loaded_rom::load() throw(std::bad_alloc, std::runtime_error)
|
|||
if(rtype == ROMTYPE_NONE)
|
||||
throw std::runtime_error("Can't insert cartridge of type NONE!");
|
||||
switch(region) {
|
||||
case REGION_AUTO:
|
||||
SNES::config.region = SNES::System::Region::Autodetect;
|
||||
break;
|
||||
case REGION_NTSC:
|
||||
SNES::config.region = SNES::System::Region::NTSC;
|
||||
break;
|
||||
case REGION_PAL:
|
||||
SNES::config.region = SNES::System::Region::PAL;
|
||||
break;
|
||||
case REGION_AUTO: core_set_region(EC_REGION_AUTO); break;
|
||||
case REGION_NTSC: core_set_region(EC_REGION_NTSC); break;
|
||||
case REGION_PAL: core_set_region(EC_REGION_PAL); break;
|
||||
default:
|
||||
throw std::runtime_error("Trying to force unknown region");
|
||||
}
|
||||
switch(rtype) {
|
||||
case ROMTYPE_SNES:
|
||||
if(!snes_load_cartridge_normal(rom_xml, rom, rom))
|
||||
if(!core_load_cartridge_normal(rom_xml, rom, rom))
|
||||
throw std::runtime_error("Can't load cartridge ROM");
|
||||
break;
|
||||
case ROMTYPE_BSX:
|
||||
if(region == REGION_PAL)
|
||||
throw std::runtime_error("BSX can't be PAL");
|
||||
if(!snes_load_cartridge_bsx(rom_xml, rom, rom, slota_xml, slota, slota))
|
||||
if(!core_load_cartridge_bsx(rom_xml, rom, rom, slota_xml, slota, slota))
|
||||
throw std::runtime_error("Can't load cartridge ROM");
|
||||
break;
|
||||
case ROMTYPE_BSXSLOTTED:
|
||||
if(region == REGION_PAL)
|
||||
throw std::runtime_error("Slotted BSX can't be PAL");
|
||||
if(!snes_load_cartridge_bsx_slotted(rom_xml, rom, rom, slota_xml, slota, slota))
|
||||
if(!core_load_cartridge_bsx_slotted(rom_xml, rom, rom, slota_xml, slota, slota))
|
||||
throw std::runtime_error("Can't load cartridge ROM");
|
||||
break;
|
||||
case ROMTYPE_SGB:
|
||||
if(!snes_load_cartridge_super_game_boy(rom_xml, rom, rom, slota_xml, slota, slota))
|
||||
if(!core_load_cartridge_super_game_boy(rom_xml, rom, rom, slota_xml, slota, slota))
|
||||
throw std::runtime_error("Can't load cartridge ROM");
|
||||
break;
|
||||
case ROMTYPE_SUFAMITURBO:
|
||||
if(region == REGION_PAL)
|
||||
throw std::runtime_error("Sufami Turbo can't be PAL");
|
||||
if(!snes_load_cartridge_sufami_turbo(rom_xml, rom, rom, slota_xml, slota, slota, slotb_xml, slotb,
|
||||
if(!core_load_cartridge_sufami_turbo(rom_xml, rom, rom, slota_xml, slota, slota, slotb_xml, slotb,
|
||||
slotb))
|
||||
throw std::runtime_error("Can't load cartridge ROM");
|
||||
break;
|
||||
|
@ -445,13 +441,12 @@ void loaded_rom::load() throw(std::bad_alloc, std::runtime_error)
|
|||
throw std::runtime_error("Unknown cartridge type");
|
||||
}
|
||||
if(region == REGION_AUTO)
|
||||
region = snes_get_region() ? REGION_PAL : REGION_NTSC;
|
||||
snes_power();
|
||||
if(region == REGION_PAL)
|
||||
set_nominal_framerate(SNES::system.cpu_frequency() / DURATION_PAL_FRAME);
|
||||
else
|
||||
set_nominal_framerate(SNES::system.cpu_frequency() / DURATION_NTSC_FRAME);
|
||||
information_dispatch::do_sound_rate(SNES::system.apu_frequency(), 768);
|
||||
region = core_get_region() ? REGION_PAL : REGION_NTSC;
|
||||
core_power();
|
||||
auto nominal_fps = get_video_rate();
|
||||
auto nominal_hz = get_audio_rate();
|
||||
set_nominal_framerate(1.0 * nominal_fps.first / nominal_fps.second);
|
||||
information_dispatch::do_sound_rate(nominal_hz.first, nominal_hz.second);
|
||||
current_rom_type = rtype;
|
||||
current_region = region;
|
||||
msu1_base_path = msu1_base;
|
||||
|
@ -501,67 +496,6 @@ 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());
|
||||
//Fixup name change by bsnes v087...
|
||||
if(id == "bsx.ram")
|
||||
id = ".bss";
|
||||
if(id == "bsx.psram")
|
||||
id = ".bsp";
|
||||
if(id == "program.rtc")
|
||||
id = ".rtc";
|
||||
if(id == "upd96050.ram")
|
||||
id = ".dsp";
|
||||
if(id == "program.ram")
|
||||
id = ".srm";
|
||||
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);
|
||||
std::vector<char> x;
|
||||
x.resize(r.size);
|
||||
memcpy(&x[0], r.data, r.size);
|
||||
out[savename] = x;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc)
|
||||
{
|
||||
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);
|
||||
} else
|
||||
messages << "WARNING: SRAM '" << savename << ": No data." << std::endl;
|
||||
}
|
||||
for(auto i : sram)
|
||||
if(!used.count(i.first))
|
||||
messages << "WARNING: SRAM '" << i.first << ": Not found on cartridge." << std::endl;
|
||||
}
|
||||
|
||||
std::map<std::string, std::vector<char>> load_sram_commandline(const std::vector<std::string>& cmdline)
|
||||
throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
|
@ -572,7 +506,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 {
|
||||
|
@ -603,9 +537,7 @@ std::map<std::string, std::vector<char>> load_sram_commandline(const std::vector
|
|||
std::vector<char> save_core_state(bool nochecksum) throw(std::bad_alloc)
|
||||
{
|
||||
std::vector<char> ret;
|
||||
serializer s = SNES::system.serialize();
|
||||
ret.resize(s.size());
|
||||
memcpy(&ret[0], s.data(), s.size());
|
||||
core_serialize(ret);
|
||||
if(nochecksum)
|
||||
return ret;
|
||||
size_t offset = ret.size();
|
||||
|
@ -619,9 +551,7 @@ std::vector<char> save_core_state(bool nochecksum) throw(std::bad_alloc)
|
|||
void load_core_state(const std::vector<char>& buf, bool nochecksum) throw(std::runtime_error)
|
||||
{
|
||||
if(nochecksum) {
|
||||
serializer s(reinterpret_cast<const uint8_t*>(&buf[0]), buf.size());
|
||||
if(!SNES::system.unserialize(s))
|
||||
throw std::runtime_error("SNES core rejected savestate");
|
||||
core_unserialize(&buf[0], buf.size());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -631,9 +561,7 @@ void load_core_state(const std::vector<char>& buf, bool nochecksum) throw(std::r
|
|||
sha256::hash(tmp, reinterpret_cast<const uint8_t*>(&buf[0]), buf.size() - 32);
|
||||
if(memcmp(tmp, &buf[buf.size() - 32], 32))
|
||||
throw std::runtime_error("Savestate corrupt");
|
||||
serializer s(reinterpret_cast<const uint8_t*>(&buf[0]), buf.size() - 32);
|
||||
if(!SNES::system.unserialize(s))
|
||||
throw std::runtime_error("SNES core rejected savestate");
|
||||
core_unserialize(&buf[0], buf.size() - 32);;
|
||||
}
|
||||
|
||||
std::string name_subrom(enum rom_type major, unsigned romnumber) throw(std::bad_alloc)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "core/bsnes.hpp"
|
||||
#include "lsnes.hpp"
|
||||
#include "core/emucore.hpp"
|
||||
|
||||
#include "core/command.hpp"
|
||||
#include "core/framerate.hpp"
|
||||
|
@ -21,14 +22,6 @@
|
|||
#endif
|
||||
|
||||
|
||||
class my_interfaced : public SNES::Interface
|
||||
{
|
||||
string path(SNES::Cartridge::Slot slot, const string &hint)
|
||||
{
|
||||
return "./";
|
||||
}
|
||||
};
|
||||
|
||||
struct moviefile generate_movie_template(std::vector<std::string> cmdline, loaded_rom& r)
|
||||
{
|
||||
struct moviefile movie;
|
||||
|
@ -149,19 +142,13 @@ 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 << get_core_identifier() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
my_interfaced intrf;
|
||||
SNES::interface = &intrf;
|
||||
do_basic_core_init();
|
||||
|
||||
set_random_seed();
|
||||
|
||||
{
|
||||
std::ostringstream x;
|
||||
x << snes_library_id() << " (" << SNES::Info::Profile << " core)";
|
||||
bsnes_core_version = x.str();
|
||||
}
|
||||
bsnes_core_version = get_core_identifier();
|
||||
platform::init();
|
||||
init_lua();
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
//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 "lsnes.hpp"
|
||||
#include "core/emucore.hpp"
|
||||
|
||||
#include "core/command.hpp"
|
||||
#include "core/controller.hpp"
|
||||
|
@ -346,12 +347,7 @@ bool lsnes_app::OnInit()
|
|||
ui_mutex = &mutex::aquire();
|
||||
ui_condition = &condition::aquire(*ui_mutex);
|
||||
|
||||
{
|
||||
std::ostringstream x;
|
||||
x << snes_library_id() << " (" << SNES::Info::Profile << " core)";
|
||||
bsnes_core_version = x.str();
|
||||
}
|
||||
|
||||
bsnes_core_version = get_core_identifier();
|
||||
ui_thread = &thread_id::me();
|
||||
platform::init();
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "lsnes.hpp"
|
||||
|
||||
#include "core/emucore.hpp"
|
||||
|
||||
#include "core/command.hpp"
|
||||
#include "core/controller.hpp"
|
||||
#include "core/controllerframe.hpp"
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
#include <wx/statbox.h>
|
||||
#include <wx/notebook.h>
|
||||
|
||||
#include "core/bsnes.hpp"
|
||||
#include "lsnes.hpp"
|
||||
#include "core/emucore.hpp"
|
||||
|
||||
#include "core/moviedata.hpp"
|
||||
#include "core/framerate.hpp"
|
||||
|
@ -53,35 +54,6 @@ void patching_done(struct loaded_rom& rom, wxWindow* modwin);
|
|||
|
||||
namespace
|
||||
{
|
||||
class my_interfaced : public SNES::Interface
|
||||
{
|
||||
string path(SNES::Cartridge::Slot slot, const string &hint)
|
||||
{
|
||||
return "./";
|
||||
}
|
||||
} simple_interface;
|
||||
|
||||
std::string sram_name(const nall::string& _id, SNES::Cartridge::Slot slotname)
|
||||
{
|
||||
std::string id(_id, _id.length());
|
||||
//Fixup name change by bsnes v087...
|
||||
if(id == "bsx.ram")
|
||||
id = ".bss";
|
||||
if(id == "bsx.psram")
|
||||
id = ".bsp";
|
||||
if(id == "program.rtc")
|
||||
id = ".rtc";
|
||||
if(id == "upd96050.ram")
|
||||
id = ".dsp";
|
||||
if(id == "program.ram")
|
||||
id = ".srm";
|
||||
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)
|
||||
|
@ -465,7 +437,6 @@ public:
|
|||
loaded_rom* our_rom;
|
||||
private:
|
||||
bool load_file;
|
||||
std::set<std::string> get_sram_set();
|
||||
struct moviefile make_movie();
|
||||
wxTextCtrl* savefile;
|
||||
wxButton* ask_savefile;
|
||||
|
@ -798,7 +769,7 @@ void patching_done(struct loaded_rom& rom, wxWindow* modwin)
|
|||
{
|
||||
struct loaded_rom* our_rom = &rom;
|
||||
try {
|
||||
SNES::interface = &simple_interface;
|
||||
do_basic_core_init();
|
||||
if(our_rom->slota.valid)
|
||||
our_rom_name = our_rom->slota.sha256;
|
||||
else if(our_rom->slotb.valid)
|
||||
|
@ -885,7 +856,7 @@ wxwin_project::wxwin_project(loaded_rom& rom)
|
|||
wxFlexGridSizer* mainblock = new wxFlexGridSizer(5 + sram_set.size(), 2, 0, 0);
|
||||
mainblock->Add(new wxStaticText(new_panel, wxID_ANY, wxT("Controller 1 Type:")), 0, wxGROW);
|
||||
mainblock->Add(controller1type = new wxComboBox(new_panel, wxID_ANY, cchoices[1], wxDefaultPosition,
|
||||
wxDefaultSize, CONTROLLERTYPES_P1, cchoices, wxCB_READONLY), 0, wxGROW);
|
||||
wxDefaultSize, CONTROLLERTYPES, cchoices, wxCB_READONLY), 0, wxGROW);
|
||||
mainblock->Add(new wxStaticText(new_panel, wxID_ANY, wxT("Controller 2 Type:")), 0, wxGROW);
|
||||
mainblock->Add(controller2type = new wxComboBox(new_panel, wxID_ANY, cchoices[0], wxDefaultPosition,
|
||||
wxDefaultSize, CONTROLLERTYPES, cchoices, wxCB_READONLY), 0, wxGROW);
|
||||
|
@ -1053,16 +1024,6 @@ 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));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
struct moviefile wxwin_project::make_movie()
|
||||
{
|
||||
moviefile f;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "core/bsnes.hpp"
|
||||
#include "lsnes.hpp"
|
||||
#include "core/emucore.hpp"
|
||||
|
||||
#include "core/advdumper.hpp"
|
||||
#include "core/command.hpp"
|
||||
|
@ -218,35 +219,20 @@ namespace
|
|||
}
|
||||
}
|
||||
|
||||
class my_interfaced : public SNES::Interface
|
||||
{
|
||||
string path(SNES::Cartridge::Slot slot, const string &hint)
|
||||
{
|
||||
return "./";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
reached_main();
|
||||
std::vector<std::string> cmdline;
|
||||
for(int i = 1; i < argc; i++)
|
||||
cmdline.push_back(argv[i]);
|
||||
my_interfaced intrf;
|
||||
uint64_t length;
|
||||
std::string mode, prefix;
|
||||
SNES::interface = &intrf;
|
||||
|
||||
do_basic_core_init();
|
||||
adv_dumper& dumper = get_dumper(cmdline, mode, prefix, length);
|
||||
|
||||
set_random_seed();
|
||||
|
||||
{
|
||||
std::ostringstream x;
|
||||
x << snes_library_id() << " (" << SNES::Info::Profile << " core)";
|
||||
bsnes_core_version = x.str();
|
||||
}
|
||||
bsnes_core_version = get_core_identifier();
|
||||
platform::init();
|
||||
init_lua();
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#if defined(BSNES_V084) || defined(BSNES_V085) || defined(BSNES_V086) || defined(BSNES_V087)
|
||||
#include "lsnes.hpp"
|
||||
#include <snes/snes.hpp>
|
||||
#include <core/emucore.hpp>
|
||||
#include "core/advdumper.hpp"
|
||||
#include "core/dispatch.hpp"
|
||||
#include "core/emucore.hpp"
|
||||
#include "library/serialization.hpp"
|
||||
#include "video/tcp.hpp"
|
||||
|
||||
|
@ -81,8 +83,8 @@ namespace
|
|||
if(!*out)
|
||||
throw std::runtime_error("Failed to open '" + str2 + "'");
|
||||
write32ube(tbuffer, 0x53444D50U);
|
||||
write32ube(tbuffer + 4, SNES::system.cpu_frequency());
|
||||
write32ube(tbuffer + 8, SNES::system.apu_frequency());
|
||||
write32ube(tbuffer + 4, get_snes_cpu_rate());
|
||||
write32ube(tbuffer + 8, get_snes_apu_rate());
|
||||
out->write(reinterpret_cast<char*>(tbuffer), 12);
|
||||
if(!*out)
|
||||
throw std::runtime_error("Failed to write header to '" + str2 + "'");
|
||||
|
@ -224,3 +226,4 @@ namespace
|
|||
{
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue