Split all references to bsnes core to dedicated file

This commit is contained in:
Ilari Liusvaara 2012-06-30 12:42:29 +03:00
parent 17b92632e5
commit d9bc16598c
17 changed files with 950 additions and 584 deletions

View file

@ -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
View 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

View file

@ -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
View 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;

View file

@ -1,4 +1,5 @@
#include "lsnes.hpp"
#include "core/emucore.hpp"
#include "core/command.hpp"
#include "core/controller.hpp"

View file

@ -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];

View file

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

View file

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

View file

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

View file

@ -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 + "'");

View file

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

View file

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

View file

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

View file

@ -1,5 +1,7 @@
#include "lsnes.hpp"
#include "core/emucore.hpp"
#include "core/command.hpp"
#include "core/controller.hpp"
#include "core/controllerframe.hpp"

View file

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

View file

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

View file

@ -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