Use virtual methods instead of pointers for core stuff

This commit is contained in:
Ilari Liusvaara 2013-07-03 18:21:16 +03:00
parent 84faf2f42e
commit a111afad42
8 changed files with 843 additions and 716 deletions

View file

@ -202,24 +202,6 @@ struct core_type_params
* System menu name.
*/
const char* sysname;
/**
* Load a ROM slot set. Changes the ROM currently loaded for core.
*
* Parameter images: The set of images to load.
* Parameter settings: The settings to use.
* Parameter rtc_sec: The initial RTC seconds value.
* Parameter rtc_subsec: The initial RTC subseconds value.
* Returns: -1 on failure, 0 on success.
*/
int (*load_rom)(core_romimage* images, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
uint64_t rtc_subsec);
/**
* Obtain controller config for given settings.
*
* Parameter settings: The settings to use.
* Returns: The controller configuration.
*/
controller_set (*controllerconfig)(std::map<std::string, std::string>& settings);
/**
* Semicolon-separated list of extensions this system type uses.
*/
@ -244,24 +226,6 @@ struct core_type_params
* Core this system is emulated by.
*/
core_core* core;
/**
* Get bus mapping.
*
* Returns: The bus mapping (base,size), or (0,0) if this system does not have bus mapping.
*/
std::pair<uint64_t, uint64_t> (*get_bus_map)();
/**
* Get list of valid VMAs. ROM must be loaded.
*
* Returns: The list of VMAs.
*/
std::list<core_vma_info> (*vma_list)();
/**
* Get list of valid SRAM names. ROM must be loaded.
*
* Returns: The list of SRAMs.
*/
std::set<std::string> (*srams)();
};
/**
@ -271,117 +235,10 @@ struct core_type_params
*/
struct core_core_params
{
/**
* Get the name of the core.
*/
std::string (*core_identifier)();
/**
* Set the current region.
*
* Parameter region: The new region.
* Returns: True on success, false on failure (bad region).
*/
bool (*set_region)(core_region& region);
/**
* Get current video frame rate as (numerator, denominator).
*/
std::pair<uint32_t, uint32_t> (*video_rate)();
/**
* Get audio sampling rate as (numerator, denominator).
*
* Note: This value should not be changed while ROM is running, since video dumper may malfunction.
*/
std::pair<uint32_t, uint32_t> (*audio_rate)();
/**
* Save all SRAMs.
*/
std::map<std::string, std::vector<char>> (*save_sram)() throw(std::bad_alloc);
/**
* Load all SRAMs.
*
* Note: Must handle SRAM being missing or shorter or longer than expected.
*/
void (*load_sram)(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc);
/**
* Serialize the system state.
*/
void (*serialize)(std::vector<char>& out);
/**
* Unserialize the system state.
*/
void (*unserialize)(const char* in, size_t insize);
/**
* Get current region.
*/
core_region& (*get_region)();
/**
* Poweron the console.
*/
void (*power)();
/**
* Unload the cartridge from the console.
*/
void (*unload_cartridge)();
/**
* Get the current scale factors for screen as (xscale, yscale).
*/
std::pair<uint32_t, uint32_t> (*get_scale_factors)(uint32_t width, uint32_t height);
/**
* Do basic core initialization. Called on lsnes startup.
*/
void (*install_handler)();
/**
* Do basic core uninitialization. Called on lsnes shutdown.
*/
void (*uninstall_handler)();
/**
* Emulate one frame.
*/
void (*emulate)();
/**
* Get core into state where saving is possible. Must run less than one frame.
*/
void (*runtosave)();
/**
* Get the polled flag.
*
* The emulator core sets polled flag when the game asks for input.
*
* If polled flag is clear when frame ends, the frame is marked as lag.
*/
bool (*get_pflag)();
/**
* Set the polled flag.
*/
void (*set_pflag)(bool pflag);
/**
* Set of valid port types for the core.
*/
std::vector<port_type*> port_types;
/**
* Draw run cover screen.
*
* Should display information about the ROM loaded.
*/
framebuffer_raw& (*draw_cover)();
/**
* Get shortened name of the core.
*/
std::string (*get_core_shortname)();
/**
* Set the system controls to appropriate values for next frame.
*
* E.g. if core supports resetting, set the reset button in the frame to pressed if reset is wanted.
*/
void (*pre_emulate_frame)(controller_frame& cf);
/**
* Execute action.
*/
void (*execute_action)(unsigned id, const std::vector<interface_action_paramval>& p);
/**
* Get set of interface device registers.
*/
const struct interface_device_reg* (*get_registers)();
};
struct core_region
@ -480,31 +337,116 @@ struct core_core
std::set<const interface_action*> get_actions();
_param_register_proxy param_register_proxy;
const interface_device_reg* get_registers();
protected:
/**
* Get the name of the core.
*/
virtual std::string c_core_identifier() = 0;
/**
* Set the current region.
*
* Parameter region: The new region.
* Returns: True on success, false on failure (bad region).
*/
virtual bool c_set_region(core_region& region) = 0;
/**
* Get current video frame rate as (numerator, denominator).
*/
virtual std::pair<uint32_t, uint32_t> c_video_rate() = 0;
/**
* Get audio sampling rate as (numerator, denominator).
*
* Note: This value should not be changed while ROM is running, since video dumper may malfunction.
*/
virtual std::pair<uint32_t, uint32_t> c_audio_rate() = 0;
/**
* Save all SRAMs.
*/
virtual std::map<std::string, std::vector<char>> c_save_sram() throw(std::bad_alloc) = 0;
/**
* Load all SRAMs.
*
* Note: Must handle SRAM being missing or shorter or longer than expected.
*/
virtual void c_load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc) = 0;
/**
* Serialize the system state.
*/
virtual void c_serialize(std::vector<char>& out) = 0;
/**
* Unserialize the system state.
*/
virtual void c_unserialize(const char* in, size_t insize) = 0;
/**
* Get current region.
*/
virtual core_region& c_get_region() = 0;
/**
* Poweron the console.
*/
virtual void c_power() = 0;
/**
* Unload the cartridge from the console.
*/
virtual void c_unload_cartridge() = 0;
/**
* Get the current scale factors for screen as (xscale, yscale).
*/
virtual std::pair<uint32_t, uint32_t> c_get_scale_factors(uint32_t width, uint32_t height) = 0;
/**
* Do basic core initialization. Called on lsnes startup.
*/
virtual void c_install_handler() = 0;
/**
* Do basic core uninitialization. Called on lsnes shutdown.
*/
virtual void c_uninstall_handler() = 0;
/**
* Emulate one frame.
*/
virtual void c_emulate() = 0;
/**
* Get core into state where saving is possible. Must run less than one frame.
*/
virtual void c_runtosave() = 0;
/**
* Get the polled flag.
*
* The emulator core sets polled flag when the game asks for input.
*
* If polled flag is clear when frame ends, the frame is marked as lag.
*/
virtual bool c_get_pflag() = 0;
/**
* Set the polled flag.
*/
virtual void c_set_pflag(bool pflag) = 0;
/**
* Draw run cover screen.
*
* Should display information about the ROM loaded.
*/
virtual framebuffer_raw& c_draw_cover() = 0;
/**
* Get shortened name of the core.
*/
virtual std::string c_get_core_shortname() = 0;
/**
* Set the system controls to appropriate values for next frame.
*
* E.g. if core supports resetting, set the reset button in the frame to pressed if reset is wanted.
*/
virtual void c_pre_emulate_frame(controller_frame& cf) = 0;
/**
* Execute action.
*/
virtual void c_execute_action(unsigned id, const std::vector<interface_action_paramval>& p) = 0;
/**
* Get set of interface device registers.
*/
virtual const struct interface_device_reg* c_get_registers() = 0;
private:
std::string (*_core_identifier)();
bool (*_set_region)(core_region& region);
std::pair<uint32_t, uint32_t> (*_video_rate)();
std::pair<uint32_t, uint32_t> (*_audio_rate)();
std::map<std::string, std::vector<char>> (*_save_sram)() throw(std::bad_alloc);
void (*_load_sram)(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc);
void (*_serialize)(std::vector<char>& out);
void (*_unserialize)(const char* in, size_t insize);
core_region& (*_get_region)();
void (*_power)();
void (*_unload_cartridge)();
std::pair<uint32_t, uint32_t> (*_get_scale_factors)(uint32_t width, uint32_t height);
void (*_install_handler)();
void (*_uninstall_handler)();
void (*_emulate)();
void (*_runtosave)();
bool (*_get_pflag)();
void (*_set_pflag)(bool pflag);
std::vector<port_type*> port_types;
framebuffer_raw& (*_draw_cover)();
std::string (*_get_core_shortname)();
void (*_pre_emulate_frame)(controller_frame& cf);
void (*_execute_action)(unsigned id, const std::vector<interface_action_paramval>& p);
const interface_device_reg* (*_get_registers)();
bool hidden;
std::map<std::string, interface_action*> actions;
mutex_class actions_lock;
@ -515,7 +457,7 @@ struct core_type
public:
core_type(const core_type_params& params);
core_type(std::initializer_list<core_type_params> p) : core_type(*p.begin()) {}
~core_type() throw();
virtual ~core_type() throw();
static std::list<core_type*> get_core_types();
core_region& get_preferred_region();
std::list<core_region*> get_regions();
@ -572,15 +514,46 @@ public:
void pre_emulate_frame(controller_frame& cf) { return core->pre_emulate_frame(cf); }
std::set<const interface_action*> get_actions() { return core->get_actions(); }
const interface_device_reg* get_registers() { return core->get_registers(); }
protected:
/**
* Load a ROM slot set. Changes the ROM currently loaded for core.
*
* Parameter images: The set of images to load.
* Parameter settings: The settings to use.
* Parameter rtc_sec: The initial RTC seconds value.
* Parameter rtc_subsec: The initial RTC subseconds value.
* Returns: -1 on failure, 0 on success.
*/
virtual int t_load_rom(core_romimage* images, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
uint64_t rtc_subsec) = 0;
/**
* Obtain controller config for given settings.
*
* Parameter settings: The settings to use.
* Returns: The controller configuration.
*/
virtual controller_set t_controllerconfig(std::map<std::string, std::string>& settings) = 0;
/**
* Get bus mapping.
*
* Returns: The bus mapping (base,size), or (0,0) if this system does not have bus mapping.
*/
virtual std::pair<uint64_t, uint64_t> t_get_bus_map() = 0;
/**
* Get list of valid VMAs. ROM must be loaded.
*
* Returns: The list of VMAs.
*/
virtual std::list<core_vma_info> t_vma_list() = 0;
/**
* Get list of valid SRAM names. ROM must be loaded.
*
* Returns: The list of SRAMs.
*/
virtual std::set<std::string> t_srams() = 0;
private:
core_type(const core_type&);
core_type& operator=(const core_type&);
int (*loadimg)(core_romimage* images, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
uint64_t rtc_subsec);
controller_set (*_controllerconfig)(std::map<std::string, std::string>& settings);
std::pair<uint64_t, uint64_t> (*_get_bus_map)();
std::list<core_vma_info> (*_vma_list)();
std::set<std::string> (*_srams)();
unsigned id;
std::string iname;
std::string hname;

View file

@ -59,73 +59,80 @@ namespace
core_setting_group null_settings;
core_region null_region{{"null", "(null)", 0, 0, false, {1, 60}, {0}}};
core_core core_null{{
.core_identifier = []() -> std::string { return "null core"; },
.set_region = [](core_region& reg) -> bool { return true; },
.video_rate = []() -> std::pair<unsigned, unsigned> { return std::make_pair(60, 1); },
.audio_rate = []() -> std::pair<unsigned, unsigned> { return std::make_pair(48000, 1); },
.save_sram = []() -> std::map<std::string, std::vector<char>> {
struct interface_device_reg null_registers[] = {
{NULL, NULL, NULL}
};
struct _core_null : public core_core, public core_type, public core_region, public core_sysregion
{
_core_null() : core_core({{{}}}), core_type({{
.iname = "null",
.hname = "(null)",
.id = 9999,
.sysname = "System",
.extensions = "",
.bios = NULL,
.regions = {this},
.images = {},
.settings = &null_settings,
.core = this,
}}), core_region({{"null", "(null)", 0, 0, false, {1, 60}, {0}}}),
core_sysregion("null", *this, *this) {}
std::string c_core_identifier() { return "null core"; }
bool c_set_region(core_region& reg) { return true; }
std::pair<unsigned, unsigned> c_video_rate() { return std::make_pair(60, 1); }
std::pair<unsigned, unsigned> c_audio_rate() { return std::make_pair(48000, 1); }
std::map<std::string, std::vector<char>> c_save_sram() throw (std::bad_alloc) {
std::map<std::string, std::vector<char>> x;
return x;
},
.load_sram = [](std::map<std::string, std::vector<char>>& sram) -> void {},
.serialize = [](std::vector<char>& out) -> void { out.clear(); },
.unserialize = [](const char* in, size_t insize) -> void {},
.get_region = []() -> core_region& { return null_region; },
.power = []() -> void {},
.unload_cartridge = []() -> void {},
.get_scale_factors = [](uint32_t width, uint32_t height) -> std::pair<uint32_t, uint32_t> {
}
void c_load_sram(std::map<std::string, std::vector<char>>& sram) throw (std::bad_alloc) {}
void c_serialize(std::vector<char>& out) { out.clear(); }
void c_unserialize(const char* in, size_t insize) {}
core_region& c_get_region() { return *this; }
void c_power() {}
void c_unload_cartridge() {}
std::pair<uint32_t, uint32_t> c_get_scale_factors(uint32_t width, uint32_t height) {
return std::make_pair(1, 1);
},
.install_handler = []() -> void {},
.uninstall_handler = []() -> void {},
.emulate = []() -> void {},
.runtosave = []() -> void {},
.get_pflag = []() -> bool { return false; },
.set_pflag = [](bool pflag) -> void {},
.port_types = {},
.draw_cover = []() -> framebuffer_raw& {
}
void c_install_handler() {}
void c_uninstall_handler() {}
void c_emulate() {}
void c_runtosave() {}
bool c_get_pflag() { return false; }
void c_set_pflag(bool pflag) {}
framebuffer_raw& c_draw_cover() {
static framebuffer_raw x(null_fbinfo);
for(size_t i = 0; i < sizeof(null_cover_fbmem)/sizeof(null_cover_fbmem[0]); i++)
null_cover_fbmem[i] = 0x0000;
std::string message = "NO ROM LOADED";
cover_render_string(null_cover_fbmem, 204, 220, message, 0xFFFF, 0x0000, 512, 448, 1024, 2);
return x;
},
.get_core_shortname = []() -> std::string { return "null"; },
.pre_emulate_frame = [](controller_frame& cf) -> void {},
.execute_action = [](unsigned id, const std::vector<interface_action_paramval>& p) -> void {}
}};
core_type type_null{{
"null", "(null)", 9999, "System",
[](core_romimage* img, std::map<std::string, std::string>& settings,
uint64_t secs, uint64_t subsecs) -> int {
}
std::string c_get_core_shortname() { return "null"; }
void c_pre_emulate_frame(controller_frame& cf) {}
void c_execute_action(unsigned id, const std::vector<interface_action_paramval>& p) {}
const interface_device_reg* c_get_registers() { return null_registers; }
int t_load_rom(core_romimage* img, std::map<std::string, std::string>& settings,
uint64_t secs, uint64_t subsecs)
{
ecore_callbacks->set_reset_actions(-1, -1);
return 0;
},
[](std::map<std::string, std::string>& settings) -> controller_set {
}
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
{
controller_set x;
x.ports.push_back(&get_default_system_port_type());
x.portindex.indices.push_back(sync_triple);
return x;
},
"", NULL, {&null_region}, {}, &null_settings, &core_null,
[]() -> std::pair<uint64_t, uint64_t> { return std::make_pair(0ULL, 0ULL); },
[]() -> std::list<core_vma_info> {
std::list<core_vma_info> x;
return x;
},
[]() -> std::set<std::string> {
std::set<std::string> x;
return x;
}
}};
core_sysregion sysregion_null("null", type_null, null_region);
std::pair<uint64_t, uint64_t> t_get_bus_map() { return std::make_pair(0ULL, 0ULL); }
std::list<core_vma_info> t_vma_list() { return std::list<core_vma_info>(); }
std::set<std::string> t_srams() { return std::set<std::string>(); }
} core_null;
core_type* current_rom_type = &type_null;
core_region* current_region = &null_region;
core_type* current_rom_type = &core_null;
core_region* current_region = &core_null;
core_type* find_core_by_extension(const std::string& ext, const std::string& tmpprefer)
{
@ -274,8 +281,8 @@ std::pair<core_type*, core_region*> get_current_rom_info() throw()
loaded_rom::loaded_rom() throw()
{
rtype = &type_null;
region = orig_region = &null_region;
rtype = &core_null;
region = orig_region = &core_null;
}
loaded_rom::loaded_rom(const std::string& file, core_type& ctype) throw(std::bad_alloc, std::runtime_error)
@ -432,8 +439,8 @@ void loaded_rom::load(std::map<std::string, std::string>& settings, uint64_t rtc
throw(std::bad_alloc, std::runtime_error)
{
core_core* old_core = current_rom_type->get_core();
current_rom_type = &type_null;
if(!orig_region && rtype != &type_null)
current_rom_type = &core_null;
if(!orig_region && rtype != &core_null)
orig_region = &rtype->get_preferred_region();
if(!region)
region = orig_region;

View file

@ -146,7 +146,10 @@ namespace
#include "ports.inc"
#include "slots.inc"
#include "regions.inc"
core_region region_auto{{"autodetect", "Autodetect", 1, 0, true, {178683, 10738636}, {0,1,2}}};
core_region region_pal{{"pal", "PAL", 0, 2, false, {6448, 322445}, {2}}};
core_region region_ntsc{{"ntsc", "NTSC", 0, 1, false, {178683, 10738636}, {1}}};
core_setting_group bsnes_settings;
core_setting setting_port1(bsnes_settings, "port1", "Port 1 Type", "gamepad", {
@ -162,7 +165,7 @@ namespace
{"0", "False", 0}, {"1", "True", 1}});
core_setting setting_randinit(bsnes_settings, "radominit", "Random initial state", "0", {
{"0", "False", 0}, {"1", "True", 1}});
////////////////// PORTS COMMON ///////////////////
port_type* index_to_ptype[] = {
&none, &gamepad, &gamepad16, &multitap, &multitap16, &mouse, &justifier, &justifiers, &superscope
@ -195,15 +198,6 @@ namespace
}
core_type* internal_rom = NULL;
extern core_core bsnes_core;
interface_action act_reset(bsnes_core, 0, "Soft reset", "reset", {});
interface_action act_hreset(bsnes_core, 1, "Hard reset", "hardreset", {});
#ifdef BSNES_HAS_DEBUGGER
interface_action act_dreset(bsnes_core, 2, "Delayed soft reset", "delayreset", {{"Delay","int:0,99999999"}});
interface_action act_dhreset(bsnes_core, 3, "Delayed hard reset", "delayhardreset",
{{"Delay","int:0,99999999"}});
#endif
template<bool(*T)(const char*,const unsigned char*, unsigned)>
bool load_rom_X1(core_romimage* img)
@ -228,9 +222,8 @@ namespace
}
template<core_type* ctype>
int load_rom(core_romimage* img, std::map<std::string, std::string>& settings, uint64_t secs,
uint64_t subsecs, bool(*fun)(core_romimage*))
int load_rom(core_type* ctype, core_romimage* img, std::map<std::string, std::string>& settings,
uint64_t secs, uint64_t subsecs, bool(*fun)(core_romimage*))
{
std::map<std::string, std::string> _settings = settings;
bsnes_settings.fill_defaults(_settings);
@ -284,7 +277,7 @@ namespace
tab.push_back(t(p, i, j, true));
}
controller_set _controllerconfig(std::map<std::string, std::string>& settings)
controller_set bsnes_controllerconfig(std::map<std::string, std::string>& settings)
{
std::map<std::string, std::string> _settings = settings;
bsnes_settings.fill_defaults(_settings);
@ -366,44 +359,7 @@ namespace
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 = (SNES::system.region() == SNES::System::Region::PAL);
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 = bsnes_core.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;
framebuffer_info inf;
inf.type = &_pixel_format_lrgb;
inf.mem = const_cast<char*>(reinterpret_cast<const char*>(data));
inf.physwidth = 512;
inf.physheight = 512;
inf.physstride = 2048;
inf.width = hires ? 512 : 256;
inf.height = (region ? 239 : 224) * (interlace ? 2 : 1);
inf.stride = interlace ? 2048 : 4096;
inf.offset_x = 0;
inf.offset_y = (region ? (overscan ? 9 : 1) : (overscan ? 16 : 9)) * 2;
framebuffer_raw ls(inf);
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);
if(soundbuf_fill > 0) {
auto freq = SNES::system.apu_frequency();
audioapi_submit_buffer(soundbuf, soundbuf_fill / 2, true, freq / 768.0);
soundbuf_fill = 0;
}
}
void videoRefresh(const uint32_t* data, bool hires, bool interlace, bool overscan);
void audioSample(int16_t l_sample, int16_t r_sample)
{
@ -574,56 +530,8 @@ namespace
memsize, true, true);
}
std::list<core_vma_info> get_VMAlist()
{
std::list<core_vma_info> ret;
if(!internal_rom)
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));
if(internal_rom == &type_bsx || internal_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);
}
if(internal_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);
}
if(internal_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);
}
return ret;
}
std::set<std::string> srams()
std::list<core_vma_info> get_VMAlist();
std::set<std::string> bsnes_srams()
{
std::set<std::string> r;
if(!internal_rom)
@ -637,35 +545,16 @@ namespace
const char* hexes = "0123456789ABCDEF";
void redraw_cover_fbinfo()
{
for(size_t i = 0; i < sizeof(cover_fbmem) / sizeof(cover_fbmem[0]); i++)
cover_fbmem[i] = 0;
std::string ident = bsnes_core.get_core_identifier();
cover_render_string(cover_fbmem, 0, 0, ident, 0x7FFFF, 0x00000, 512, 448, 2048, 4);
std::ostringstream name;
name << "Internal ROM name: ";
for(unsigned i = 0; i < 21; i++) {
unsigned busaddr = 0x00FFC0 + i;
unsigned char ch = SNES::bus.read(busaddr);
if(ch < 32 || ch > 126)
name << "<" << hexes[ch / 16] << hexes[ch % 16] << ">";
else
name << ch;
}
cover_render_string(cover_fbmem, 0, 16, name.str(), 0x7FFFF, 0x00000, 512, 448, 2048, 4);
unsigned y = 32;
for(auto i : cover_information()) {
cover_render_string(cover_fbmem, 0, y, i, 0x7FFFF, 0x00000, 512, 448, 2048, 4);
y += 16;
}
}
core_core bsnes_core{{
.core_identifier = []() -> std::string {
void redraw_cover_fbinfo();
struct _bsnes_core : public core_core
{
_bsnes_core() : core_core({{_port_types}}) {}
std::string c_core_identifier() {
return (stringfmt() << snes_library_id() << " (" << SNES::Info::Profile << " core)").str();
},
.set_region = [](core_region& region) -> bool {
}
bool c_set_region(core_region& region) {
if(&region == &region_auto)
SNES::config.region = SNES::System::Region::Autodetect;
else if(&region == &region_ntsc)
@ -675,8 +564,8 @@ namespace
else
return false;
return true;
},
.video_rate = []() -> std::pair<uint32_t, uint32_t> {
}
std::pair<uint32_t, uint32_t> c_video_rate() {
if(!internal_rom)
return std::make_pair(60, 1);
uint32_t div;
@ -685,13 +574,13 @@ namespace
else
div = last_interlace ? DURATION_NTSC_FIELD : DURATION_NTSC_FRAME;
return std::make_pair(SNES::system.cpu_frequency(), div);
},
.audio_rate = []() -> std::pair<uint32_t, uint32_t> {
}
std::pair<uint32_t, uint32_t> c_audio_rate() {
if(!internal_rom)
return std::make_pair(64081, 2);
return std::make_pair(SNES::system.apu_frequency(), static_cast<uint32_t>(768));
},
.save_sram = []() -> std::map<std::string, std::vector<char>> {
}
std::map<std::string, std::vector<char>> c_save_sram() throw(std::bad_alloc) {
std::map<std::string, std::vector<char>> out;
if(!internal_rom)
return out;
@ -704,8 +593,8 @@ namespace
out[savename] = x;
}
return out;
},
.load_sram = [](std::map<std::string, std::vector<char>>& sram) -> void {
}
void c_load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc) {
std::set<std::string> used;
if(!internal_rom) {
for(auto i : sram)
@ -732,15 +621,15 @@ namespace
if(!used.count(i.first))
messages << "WARNING: SRAM '" << i.first << ": Not found on cartridge."
<< std::endl;
},
.serialize = [](std::vector<char>& out) -> void {
}
void c_serialize(std::vector<char>& out) {
if(!internal_rom)
throw std::runtime_error("No ROM loaded");
serializer s = SNES::system.serialize();
out.resize(s.size());
memcpy(&out[0], s.data(), s.size());
},
.unserialize = [](const char* in, size_t insize) -> void {
}
void c_unserialize(const char* in, size_t insize) {
if(!internal_rom)
throw std::runtime_error("No ROM loaded");
serializer s(reinterpret_cast<const uint8_t*>(in), insize);
@ -748,31 +637,31 @@ namespace
throw std::runtime_error("SNES core rejected savestate");
have_saved_this_frame = true;
do_reset_flag = -1;
},
.get_region = []() -> core_region& {
}
core_region& c_get_region() {
return (SNES::system.region() == SNES::System::Region::PAL) ? region_pal : region_ntsc;
},
.power = []() -> void {
}
void c_power() {
if(internal_rom) snes_power();
},
.unload_cartridge = []() -> void {
}
void c_unload_cartridge() {
if(!internal_rom) return;
snes_term();
snes_unload_cartridge();
internal_rom = NULL;
},
.get_scale_factors = [](uint32_t width, uint32_t height) -> std::pair<uint32_t, uint32_t> {
}
std::pair<uint32_t, uint32_t> c_get_scale_factors(uint32_t width, uint32_t height) {
return std::make_pair((width < 400) ? 2 : 1, (height < 400) ? 2 : 1);
},
.install_handler = []() -> void {
}
void c_install_handler() {
basic_init();
old = SNES::interface;
SNES::interface = &my_interface_obj;
SNES::system.init();
magic_flags |= 1;
},
.uninstall_handler = []() -> void { SNES::interface = old; },
.emulate = []() -> void {
}
void c_uninstall_handler() { SNES::interface = old; }
void c_emulate() {
if(!internal_rom)
return;
bool was_delay_reset = false;
@ -856,32 +745,31 @@ again2:
SNES::cpu.step_event = nall::function<bool()>();
#endif
have_saved_this_frame = false;
},
.runtosave = []() -> void {
}
void c_runtosave() {
if(!internal_rom)
return;
stepping_into_save = true;
SNES::system.runtosave();
have_saved_this_frame = true;
stepping_into_save = false;
},
.get_pflag = []() -> bool { return SNES::cpu.controller_flag; },
.set_pflag = [](bool pflag) -> void { SNES::cpu.controller_flag = pflag; },
.port_types = port_types,
.draw_cover = []() -> framebuffer_raw& {
}
bool c_get_pflag() { return SNES::cpu.controller_flag; }
void c_set_pflag(bool pflag) { SNES::cpu.controller_flag = pflag; }
framebuffer_raw& c_draw_cover() {
static framebuffer_raw x(cover_fbinfo);
redraw_cover_fbinfo();
return x;
},
.get_core_shortname = []() -> std::string
}
std::string c_get_core_shortname()
{
#ifdef BSNES_IS_COMPAT
return (stringfmt() << "bsnes" << BSNES_VERSION << "c").str();
#else
return (stringfmt() << "bsnes" << BSNES_VERSION << "a").str();
#endif
},
.pre_emulate_frame = [](controller_frame& cf) -> void
}
void c_pre_emulate_frame(controller_frame& cf)
{
cf.axis3(0, 0, 1, (do_reset_flag >= 0) ? 1 : 0);
if(support_hreset)
@ -893,8 +781,8 @@ again2:
cf.axis3(0, 0, 2, 0);
cf.axis3(0, 0, 3, 0);
}
},
.execute_action = [](unsigned id, const std::vector<interface_action_paramval>& p) -> void
}
void c_execute_action(unsigned id, const std::vector<interface_action_paramval>& p)
{
switch(id) {
case 0: //Soft reset.
@ -914,67 +802,281 @@ again2:
do_hreset_flag = true;
break;
}
},
.get_registers = []() -> const interface_device_reg* { return snes_registers; },
}};
}
const interface_device_reg* c_get_registers() { return snes_registers; }
} bsnes_core;
core_type type_snes{{
.iname = "snes", .hname = "SNES", .id = 0, .sysname = "SNES",
.load_rom = [](core_romimage* img, std::map<std::string, std::string>& settings, uint64_t secs,
uint64_t subsecs) -> int {
return load_rom<&type_snes>(img, settings, secs, subsecs,
load_rom_X1<snes_load_cartridge_normal>);
},
.controllerconfig = _controllerconfig, .extensions = "sfc;smc;swc;fig;ufo;sf2;gd3;gd7;dx2;mgd;mgh",
.bios = NULL, .regions = snes_regions, .images = snes_images,
.settings = &bsnes_settings, .core = &bsnes_core, .get_bus_map = bsnes_get_bus_map,
.vma_list = get_VMAlist, .srams = srams
}};
core_type type_bsx{{
.iname = "bsx", .hname = "BS-X (non-slotted)", .id = 1, .sysname = "BS-X",
.load_rom = [](core_romimage* img, std::map<std::string, std::string>& settings, uint64_t secs,
uint64_t subsecs) -> int {
return load_rom<&type_bsx>(img, settings, secs, subsecs,
load_rom_X2<snes_load_cartridge_bsx>);
},
.controllerconfig = _controllerconfig, .extensions = "bs", .bios = "bsx.sfc", .regions = bsx_regions,
.images = bsx_images, .settings = &bsnes_settings, .core = &bsnes_core,
.get_bus_map = bsnes_get_bus_map, .vma_list = get_VMAlist, .srams = srams
}};
core_type type_bsxslotted{{
.iname = "bsxslotted", .hname = "BS-X (slotted)", .id = 2, .sysname = "BS-X",
.load_rom = [](core_romimage* img, std::map<std::string, std::string>& settings,
uint64_t secs, uint64_t subsecs) -> int {
return load_rom<&type_bsxslotted>(img, settings, secs, subsecs,
load_rom_X2<snes_load_cartridge_bsx_slotted>);
},
.controllerconfig = _controllerconfig, .extensions = "bss", .bios = "bsxslotted.sfc",
.regions = bsxs_regions, .images = bsxs_images, .settings = &bsnes_settings, .core = &bsnes_core,
.get_bus_map = bsnes_get_bus_map, .vma_list = get_VMAlist, .srams = srams
}};
core_type type_sufamiturbo{{
.iname = "sufamiturbo", .hname = "Sufami Turbo", .id = 3, .sysname = "SufamiTurbo",
.load_rom = [](core_romimage* img, std::map<std::string, std::string>& settings, uint64_t secs,
uint64_t subsecs) -> int {
return load_rom<&type_sufamiturbo>(img, settings, secs, subsecs,
load_rom_X3<snes_load_cartridge_sufami_turbo>);
},
.controllerconfig = _controllerconfig, .extensions = "st", .bios = "sufamiturbo.sfc",
.regions = sufamiturbo_regions, .images = sufamiturbo_images, .settings = &bsnes_settings,
.core = &bsnes_core, .get_bus_map = bsnes_get_bus_map, .vma_list = get_VMAlist, .srams = srams
}};
core_type type_sgb{{
.iname = "sgb", .hname = "Super Game Boy", .id = 4, .sysname = "SGB",
.load_rom = [](core_romimage* img, std::map<std::string, std::string>& settings, uint64_t secs,
uint64_t subsecs) -> int
interface_action act_reset(bsnes_core, 0, "Soft reset", "reset", {});
interface_action act_hreset(bsnes_core, 1, "Hard reset", "hardreset", {});
#ifdef BSNES_HAS_DEBUGGER
interface_action act_dreset(bsnes_core, 2, "Delayed soft reset", "delayreset", {{"Delay","int:0,99999999"}});
interface_action act_dhreset(bsnes_core, 3, "Delayed hard reset", "delayhardreset",
{{"Delay","int:0,99999999"}});
#endif
struct _type_snes : public core_type
{
_type_snes() : core_type({{
.iname = "snes",
.hname = "SNES",
.id = 0,
.sysname = "SNES",
.extensions = "sfc;smc;swc;fig;ufo;sf2;gd3;gd7;dx2;mgd;mgh",
.bios = NULL,
.regions = {&region_auto, &region_ntsc, &region_pal},
.images = snes_images,
.settings = &bsnes_settings,
.core = &bsnes_core,
}}) {}
int t_load_rom(core_romimage* img, std::map<std::string, std::string>& settings,
uint64_t secs, uint64_t subsecs)
{
return load_rom<&type_sgb>(img, settings, secs, subsecs,
return load_rom(this, img, settings, secs, subsecs,
load_rom_X1<snes_load_cartridge_normal>);
}
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
{
return bsnes_controllerconfig(settings);
}
std::pair<uint64_t, uint64_t> t_get_bus_map() { return bsnes_get_bus_map(); }
std::list<core_vma_info> t_vma_list() { return get_VMAlist(); }
std::set<std::string> t_srams() { return bsnes_srams(); }
} type_snes;
core_sysregion snes_pal("snes_pal", type_snes, region_pal);
core_sysregion snes_ntsc("snes_ntsc", type_snes, region_ntsc);
struct _type_bsx : public core_type
{
_type_bsx() : core_type({{
.iname = "bsx",
.hname = "BS-X (non-slotted)",
.id = 1,
.sysname = "BS-X",
.extensions = "bs",
.bios = "bsx.sfc",
.regions = {&region_ntsc},
.images = bsx_images,
.settings = &bsnes_settings,
.core = &bsnes_core,
}}) {}
int t_load_rom(core_romimage* img, std::map<std::string, std::string>& settings,
uint64_t secs, uint64_t subsecs)
{
return load_rom(this, img, settings, secs, subsecs,
load_rom_X2<snes_load_cartridge_bsx>);
}
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
{
return bsnes_controllerconfig(settings);
}
std::pair<uint64_t, uint64_t> t_get_bus_map() { return bsnes_get_bus_map(); }
std::list<core_vma_info> t_vma_list() { return get_VMAlist(); }
std::set<std::string> t_srams() { return bsnes_srams(); }
} type_bsx;
core_sysregion bsx_sr("bsx", type_bsx, region_ntsc);
struct _type_bsxslotted : public core_type
{
_type_bsxslotted() : core_type({{
.iname = "bsxslotted",
.hname = "BS-X (slotted)",
.id = 2,
.sysname = "BS-X",
.extensions = "bss",
.bios = "bsxslotted.sfc",
.regions = {&region_ntsc},
.images = bsxs_images,
.settings = &bsnes_settings,
.core = &bsnes_core,
}}) {}
int t_load_rom(core_romimage* img, std::map<std::string, std::string>& settings,
uint64_t secs, uint64_t subsecs)
{
return load_rom(this, img, settings, secs, subsecs,
load_rom_X2<snes_load_cartridge_bsx_slotted>);
}
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
{
return bsnes_controllerconfig(settings);
}
std::pair<uint64_t, uint64_t> t_get_bus_map() { return bsnes_get_bus_map(); }
std::list<core_vma_info> t_vma_list() { return get_VMAlist(); }
std::set<std::string> t_srams() { return bsnes_srams(); }
} type_bsxslotted;
core_sysregion bsxslotted_sr("bsxslotted", type_bsxslotted, region_ntsc);
struct _type_sufamiturbo : public core_type
{
_type_sufamiturbo() : core_type({{
.iname = "sufamiturbo",
.hname = "Sufami Turbo",
.id = 3,
.sysname = "SufamiTurbo",
.extensions = "st",
.bios = "sufamiturbo.sfc",
.regions = {&region_ntsc},
.images = sufamiturbo_images,
.settings = &bsnes_settings,
.core = &bsnes_core,
}}) {}
int t_load_rom(core_romimage* img, std::map<std::string, std::string>& settings,
uint64_t secs, uint64_t subsecs)
{
return load_rom(this, img, settings, secs, subsecs,
load_rom_X3<snes_load_cartridge_sufami_turbo>);
}
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
{
return bsnes_controllerconfig(settings);
}
std::pair<uint64_t, uint64_t> t_get_bus_map() { return bsnes_get_bus_map(); }
std::list<core_vma_info> t_vma_list() { return get_VMAlist(); }
std::set<std::string> t_srams() { return bsnes_srams(); }
} type_sufamiturbo;
core_sysregion sufamiturbo_sr("sufamiturbo", type_sufamiturbo, region_ntsc);
struct _type_sgb : public core_type
{
_type_sgb() : core_type({{
.iname = "sgb",
.hname = "Super Game Boy",
.id = 4,
.sysname = "SGB",
.extensions = "gb;dmg;sgb",
.bios = "sgb.sfc",
.regions = {&region_auto, &region_ntsc, &region_pal},
.images = sgb_images,
.settings = &bsnes_settings,
.core = &bsnes_core,
}}) {}
int t_load_rom(core_romimage* img, std::map<std::string, std::string>& settings,
uint64_t secs, uint64_t subsecs)
{
return load_rom(this, img, settings, secs, subsecs,
load_rom_X2<snes_load_cartridge_super_game_boy>);
},
.controllerconfig = _controllerconfig, .extensions = "gb;dmg;sgb", .bios = "sgb.sfc",
.regions = sgb_regions, .images = sgb_images, .settings = &bsnes_settings, .core = &bsnes_core,
.get_bus_map = bsnes_get_bus_map, .vma_list = get_VMAlist, .srams = srams
}};
}
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
{
return bsnes_controllerconfig(settings);
}
std::pair<uint64_t, uint64_t> t_get_bus_map() { return bsnes_get_bus_map(); }
std::list<core_vma_info> t_vma_list() { return get_VMAlist(); }
std::set<std::string> t_srams() { return bsnes_srams(); }
} type_sgb;
core_sysregion sgb_pal("sgb_pal", type_sgb, region_pal);
core_sysregion sgb_ntsc("sgb_ntsc", type_sgb, region_ntsc);
void redraw_cover_fbinfo()
{
for(size_t i = 0; i < sizeof(cover_fbmem) / sizeof(cover_fbmem[0]); i++)
cover_fbmem[i] = 0;
std::string ident = bsnes_core.get_core_identifier();
cover_render_string(cover_fbmem, 0, 0, ident, 0x7FFFF, 0x00000, 512, 448, 2048, 4);
std::ostringstream name;
name << "Internal ROM name: ";
for(unsigned i = 0; i < 21; i++) {
unsigned busaddr = 0x00FFC0 + i;
unsigned char ch = SNES::bus.read(busaddr);
if(ch < 32 || ch > 126)
name << "<" << hexes[ch / 16] << hexes[ch % 16] << ">";
else
name << ch;
}
cover_render_string(cover_fbmem, 0, 16, name.str(), 0x7FFFF, 0x00000, 512, 448, 2048, 4);
unsigned y = 32;
for(auto i : cover_information()) {
cover_render_string(cover_fbmem, 0, y, i, 0x7FFFF, 0x00000, 512, 448, 2048, 4);
y += 16;
}
}
void my_interface::videoRefresh(const uint32_t* data, bool hires, bool interlace, bool overscan)
{
last_hires = hires;
last_interlace = interlace;
bool region = (SNES::system.region() == SNES::System::Region::PAL);
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 = bsnes_core.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;
framebuffer_info inf;
inf.type = &_pixel_format_lrgb;
inf.mem = const_cast<char*>(reinterpret_cast<const char*>(data));
inf.physwidth = 512;
inf.physheight = 512;
inf.physstride = 2048;
inf.width = hires ? 512 : 256;
inf.height = (region ? 239 : 224) * (interlace ? 2 : 1);
inf.stride = interlace ? 2048 : 4096;
inf.offset_x = 0;
inf.offset_y = (region ? (overscan ? 9 : 1) : (overscan ? 16 : 9)) * 2;
framebuffer_raw ls(inf);
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);
if(soundbuf_fill > 0) {
auto freq = SNES::system.apu_frequency();
audioapi_submit_buffer(soundbuf, soundbuf_fill / 2, true, freq / 768.0);
soundbuf_fill = 0;
}
}
std::list<core_vma_info> get_VMAlist()
{
std::list<core_vma_info> ret;
if(!internal_rom)
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));
if(internal_rom == &type_bsx || internal_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);
}
if(internal_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);
}
if(internal_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);
}
return ret;
}
function_ptr_command<arg_filename> dump_core(lsnes_cmd, "dump-core", "No description available",
"No description available\n",

View file

@ -46,7 +46,6 @@ namespace
{
bool do_reset_flag = false;
core_type* internal_rom = NULL;
extern core_core gambatte_core;
bool rtc_fixed;
time_t rtc_fixed_val;
gambatte::GB* instance;
@ -59,7 +58,6 @@ namespace
unsigned accumulator_s = 0;
bool pflag = false;
interface_action act_reset(gambatte_core, 0, "Soft reset", "reset", {});
struct interface_device_reg gb_registers[] = {
{NULL, NULL, NULL}
@ -76,7 +74,6 @@ namespace
#include "ports.inc"
#include "slots.inc"
#include "regions.inc"
core_setting_group gambatte_settings;
@ -161,7 +158,7 @@ namespace
return x;
}
controller_set _controllerconfig(std::map<std::string, std::string>& settings)
controller_set gambatte_controllerconfig(std::map<std::string, std::string>& settings)
{
std::map<std::string, std::string> _settings = settings;
controller_set r;
@ -244,7 +241,7 @@ namespace
return vmas;
}
std::set<std::string> srams()
std::set<std::string> gambatte_srams()
{
std::set<std::string> s;
if(!internal_rom)
@ -270,27 +267,17 @@ namespace
return name.str();
}
void redraw_cover_fbinfo()
{
for(size_t i = 0; i < sizeof(cover_fbmem) / sizeof(cover_fbmem[0]); i++)
cover_fbmem[i] = 0x00000000;
std::string ident = gambatte_core.get_core_identifier();
cover_render_string(cover_fbmem, 0, 0, ident, 0xFFFFFF, 0x00000, 480, 432, 1920, 4);
cover_render_string(cover_fbmem, 0, 16, "Internal ROM name: " + get_cartridge_name(),
0xFFFFFF, 0x00000, 480, 432, 1920, 4);
unsigned y = 32;
for(auto i : cover_information()) {
cover_render_string(cover_fbmem, 0, y, i, 0xFFFFFF, 0x000000, 480, 432, 1920, 4);
y += 16;
}
}
void redraw_cover_fbinfo();
core_core gambatte_core{{
.core_identifier = []() -> std::string { return "libgambatte "+gambatte::GB::version(); },
.set_region = [](core_region& region) -> bool { return (&region == &region_world); },
.video_rate = []() -> std::pair<uint32_t, uint32_t> { return std::make_pair(262144, 4389); },
.audio_rate = []() -> std::pair<uint32_t, uint32_t> { return std::make_pair(32768, 1); },
.save_sram = []() -> std::map<std::string, std::vector<char>> {
struct _gambatte_core : public core_core, public core_region
{
_gambatte_core() : core_core({{_port_types}}),
core_region({{"world", "World", 0, 0, false, {4389, 262144}, {0}}}) {}
std::string c_core_identifier() { return "libgambatte "+gambatte::GB::version(); }
bool c_set_region(core_region& region) { return (&region == this); }
std::pair<uint32_t, uint32_t> c_video_rate() { return std::make_pair(262144, 4389); }
std::pair<uint32_t, uint32_t> c_audio_rate() { return std::make_pair(32768, 1); }
std::map<std::string, std::vector<char>> c_save_sram() throw(std::bad_alloc) {
std::map<std::string, std::vector<char>> s;
if(!internal_rom)
return s;
@ -302,8 +289,8 @@ namespace
for(size_t i = 0; i < 8; i++)
s["rtc"][i] = ((unsigned long long)timebase >> (8 * i));
return s;
},
.load_sram = [](std::map<std::string, std::vector<char>>& sram) -> void {
}
void c_load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc) {
if(!internal_rom)
return;
std::vector<char> x = sram.count("main") ? sram["main"] : std::vector<char>();
@ -321,8 +308,8 @@ namespace
timebase |= (unsigned long long)(unsigned char)x2[i] << (8 * i);
instance->setRtcBase(timebase);
}
},
.serialize = [](std::vector<char>& out) -> void {
}
void c_serialize(std::vector<char>& out) {
if(!internal_rom)
throw std::runtime_error("Can't save without ROM");
instance->saveState(out);
@ -332,8 +319,8 @@ namespace
write32ube(&out[osize + 4 * i], primary_framebuffer[i]);
out.push_back(frame_overflow >> 8);
out.push_back(frame_overflow);
},
.unserialize = [](const char* in, size_t insize) -> void {
}
void c_unserialize(const char* in, size_t insize) {
if(!internal_rom)
throw std::runtime_error("Can't load without ROM");
size_t foffset = insize - 2 - 4 * sizeof(primary_framebuffer) /
@ -349,16 +336,16 @@ namespace
unsigned x2 = (unsigned char)in[insize - 1];
frame_overflow = x1 * 256 + x2;
do_reset_flag = false;
},
.get_region = []() -> core_region& { return region_world; },
.power = []() -> void {},
.unload_cartridge = []() -> void {},
.get_scale_factors = [](uint32_t width, uint32_t height) -> std::pair<uint32_t, uint32_t> {
}
core_region& c_get_region() { return *this; }
void c_power() {}
void c_unload_cartridge() {}
std::pair<uint32_t, uint32_t> c_get_scale_factors(uint32_t width, uint32_t height) {
return std::make_pair(max(512 / width, (uint32_t)1), max(448 / height, (uint32_t)1));
},
.install_handler = []() -> void { magic_flags |= 2; },
.uninstall_handler = []() -> void {},
.emulate = []() -> void {
}
void c_install_handler() { magic_flags |= 2; }
void c_uninstall_handler() {}
void c_emulate() {
if(!internal_rom)
return;
int16_t reset = ecore_callbacks->get_input(0, 0, 1);
@ -412,61 +399,129 @@ namespace
framebuffer_raw ls(inf);
ecore_callbacks->output_frame(ls, 262144, 4389);
},
.runtosave = []() -> void {},
.get_pflag = []() -> bool { return pflag; },
.set_pflag = [](bool _pflag) -> void { pflag = _pflag; },
.port_types = port_types,
.draw_cover = []() -> framebuffer_raw& {
}
void c_runtosave() {}
bool c_get_pflag() { return pflag; }
void c_set_pflag(bool _pflag) { pflag = _pflag; }
framebuffer_raw& c_draw_cover() {
static framebuffer_raw x(cover_fbinfo);
redraw_cover_fbinfo();
return x;
},
.get_core_shortname = []() -> std::string { return "gambatte"+gambatte::GB::version(); },
.pre_emulate_frame = [](controller_frame& cf) -> void {
}
std::string c_get_core_shortname() { return "gambatte"+gambatte::GB::version(); }
void c_pre_emulate_frame(controller_frame& cf) {
cf.axis3(0, 0, 1, do_reset_flag ? 1 : 0);
},
.execute_action = [](unsigned id, const std::vector<interface_action_paramval>& p) -> void
}
void c_execute_action(unsigned id, const std::vector<interface_action_paramval>& p)
{
switch(id) {
case 0: //Soft reset.
do_reset_flag = true;
break;
}
},
.get_registers = []() -> const interface_device_reg* { return gb_registers; },
}};
core_type type_dmg{{
.iname = "dmg", .hname = "Game Boy", .id = 1, .sysname = "Gameboy",
.load_rom = [](core_romimage* img, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
uint64_t rtc_subsec) -> int {
return load_rom_common(img, gambatte::GB::FORCE_DMG, rtc_sec, rtc_subsec, &type_dmg);
},
.controllerconfig = _controllerconfig, .extensions = "gb;dmg", .bios = NULL, .regions = dmg_regions,
.images = dmg_images, .settings = &gambatte_settings, .core = &gambatte_core,
.get_bus_map = gambatte_bus_map, .vma_list = get_VMAlist, .srams = srams
}};
core_type type_gbc{{
.iname = "gbc", .hname = "Game Boy Color", .id = 0, .sysname = "Gameboy",
.load_rom = [](core_romimage* img, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
uint64_t rtc_subsec) -> int {
return load_rom_common(img, 0, rtc_sec, rtc_subsec, &type_gbc);
},
.controllerconfig = _controllerconfig, .extensions = "gbc;cgb", .bios = NULL, .regions = gbc_regions,
.images = gbc_images, .settings = &gambatte_settings, .core = &gambatte_core,
.get_bus_map = gambatte_bus_map, .vma_list = get_VMAlist, .srams = srams
}};
core_type type_gbca{{
.iname = "gbc_gba", .hname = "Game Boy Color (GBA)", .id = 2, .sysname = "Gameboy",
.load_rom = [](core_romimage* img, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
uint64_t rtc_subsec) -> int {
return load_rom_common(img, gambatte::GB::GBA_CGB, rtc_sec, rtc_subsec, &type_gbca);
},
.controllerconfig = _controllerconfig, .extensions = "", .bios = NULL, .regions = gbca_regions,
.images = gbca_images, .settings = &gambatte_settings, .core = &gambatte_core,
.get_bus_map = gambatte_bus_map, .vma_list = get_VMAlist, .srams = srams
}};
}
const interface_device_reg* c_get_registers() { return gb_registers; }
} gambatte_core;
interface_action act_reset(gambatte_core, 0, "Soft reset", "reset", {});
struct _type_dmg : public core_type, public core_sysregion
{
_type_dmg() : core_type({{
.iname = "dmg",
.hname = "Game Boy",
.id = 1,
.sysname = "Gameboy",
.extensions = "gb;dmg",
.bios = NULL,
.regions = {&gambatte_core},
.images = dmg_images,
.settings = &gambatte_settings,
.core = &gambatte_core,
}}), core_sysregion("gdmg", *this, gambatte_core) {}
int t_load_rom(core_romimage* img, std::map<std::string, std::string>& settings,
uint64_t secs, uint64_t subsecs)
{
return load_rom_common(img, gambatte::GB::FORCE_DMG, secs, subsecs, this);
}
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
{
return gambatte_controllerconfig(settings);
}
std::pair<uint64_t, uint64_t> t_get_bus_map() { return gambatte_bus_map(); }
std::list<core_vma_info> t_vma_list() { return get_VMAlist(); }
std::set<std::string> t_srams() { return gambatte_srams(); }
} type_dmg;
struct _type_gbc : public core_type, public core_sysregion
{
_type_gbc() : core_type({{
.iname = "gbc",
.hname = "Game Boy Color",
.id = 0,
.sysname = "Gameboy",
.extensions = "gbc;cgb",
.bios = NULL,
.regions = {&gambatte_core},
.images = gbc_images,
.settings = &gambatte_settings,
.core = &gambatte_core,
}}), core_sysregion("ggbc", *this, gambatte_core) {}
int t_load_rom(core_romimage* img, std::map<std::string, std::string>& settings,
uint64_t secs, uint64_t subsecs)
{
return load_rom_common(img, 0, secs, subsecs, this);
}
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
{
return gambatte_controllerconfig(settings);
}
std::pair<uint64_t, uint64_t> t_get_bus_map() { return gambatte_bus_map(); }
std::list<core_vma_info> t_vma_list() { return get_VMAlist(); }
std::set<std::string> t_srams() { return gambatte_srams(); }
} type_gbc;
struct _type_gbca : public core_type, public core_sysregion
{
_type_gbca() : core_type({{
.iname = "gbc_gba",
.hname = "Game Boy Color (GBA)",
.id = 2,
.sysname = "Gameboy",
.extensions = "",
.bios = NULL,
.regions = {&gambatte_core},
.images = gbca_images,
.settings = &gambatte_settings,
.core = &gambatte_core,
}}), core_sysregion("ggbca", *this, gambatte_core) {}
int t_load_rom(core_romimage* img, std::map<std::string, std::string>& settings,
uint64_t secs, uint64_t subsecs)
{
return load_rom_common(img, gambatte::GB::GBA_CGB, secs, subsecs, this);
}
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
{
return gambatte_controllerconfig(settings);
}
std::pair<uint64_t, uint64_t> t_get_bus_map() { return gambatte_bus_map(); }
std::list<core_vma_info> t_vma_list() { return get_VMAlist(); }
std::set<std::string> t_srams() { return gambatte_srams(); }
} type_gbca;
void redraw_cover_fbinfo()
{
for(size_t i = 0; i < sizeof(cover_fbmem) / sizeof(cover_fbmem[0]); i++)
cover_fbmem[i] = 0x00000000;
std::string ident = gambatte_core.get_core_identifier();
cover_render_string(cover_fbmem, 0, 0, ident, 0xFFFFFF, 0x00000, 480, 432, 1920, 4);
cover_render_string(cover_fbmem, 0, 16, "Internal ROM name: " + get_cartridge_name(),
0xFFFFFF, 0x00000, 480, 432, 1920, 4);
unsigned y = 32;
for(auto i : cover_information()) {
cover_render_string(cover_fbmem, 0, y, i, 0xFFFFFF, 0x000000, 480, 432, 1920, 4);
y += 16;
}
}
std::vector<char> cmp_save;

View file

@ -263,7 +263,7 @@ for i = 1,#ports do
print("\t}");
print("} "..port.symbol..";");
end
local s = "std::vector<port_type*> port_types{ ";
local s = "std::vector<port_type*> _port_types{ ";
for i = 1,#ports do
s = s .."&"..ports[i].symbol..", ";
end

View file

@ -217,7 +217,7 @@ namespace sky
controller_info = &X2;
}
} psystem;
port_index_triple t(unsigned p, unsigned c, unsigned i, bool nl)
{
port_index_triple x;
@ -228,56 +228,87 @@ namespace sky
return x;
}
void controller_magic()
{
if(magic_flags & 1) {
X2.controllers[1] = &A8;
cstyle = 1;
} else if(magic_flags & 2) {
X2.controllers[1] = &B8;
cstyle = 2;
} else if(magic_flags & 4) {
X2.controllers[1] = &C8;
cstyle = 2;
} else {
cstyle = 0;
}
}
struct core_setting_group sky_settings;
core_region world_region{{
.iname = "world", .hname = "World", .priority = 0, .handle = 0, .multi = false,
.framemagic = {656250, 18227}, .compatible_runs = {0, UINT_MAX}
}};
struct core_romimage_info skyzip{{"rom", "skyroads.zip", .mandatory = 1, .pass_mode = 1, .headersize = 0}};
extern struct core_core sky_core;
struct core_core sky_core{{
.core_identifier = []() -> std::string { return "Sky"; },
.set_region = [](core_region& region) -> bool { return (&region == &world_region); },
.video_rate = []() -> std::pair<uint32_t, uint32_t> { return std::make_pair(656250, 18227); },
.audio_rate = []() -> std::pair<uint32_t, uint32_t> { return std::make_pair(48000, 1); },
.save_sram = []() -> std::map<std::string, std::vector<char>> {
struct _sky_core : public core_core, public core_type, public core_region, public core_sysregion
{
_sky_core() : core_core({{{&psystem}}}), core_type({{
.iname = "sky",
.hname = "Sky",
.id = 3522,
.sysname = "Sky",
.extensions = "sky",
.bios = NULL,
.regions = {this},
.images = {&skyzip},
.settings = &sky_settings,
.core = this,
}}), core_region({{
.iname = "world",
.hname = "World",
.priority = 0,
.handle = 0,
.multi = false,
.framemagic = {656250, 18227},
.compatible_runs = {0}
}}), core_sysregion("sky", *this, *this) {}
std::string c_core_identifier() { return "Sky"; }
bool c_set_region(core_region& region) { return (&region == this); }
std::pair<uint32_t, uint32_t> c_video_rate() { return std::make_pair(656250, 18227); }
std::pair<uint32_t, uint32_t> c_audio_rate() { return std::make_pair(48000, 1); }
std::map<std::string, std::vector<char>> c_save_sram() throw(std::bad_alloc) {
std::map<std::string, std::vector<char>> r;
std::vector<char> sram;
sram.resize(32);
memcpy(&sram[0], _gstate.sram, 32);
r["sram"] = sram;
return r;
},
.load_sram = [](std::map<std::string, std::vector<char>>& sram) -> void {
}
void c_load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc) {
if(sram.count("sram") && sram["sram"].size() == 32)
memcpy(_gstate.sram, &sram["sram"][0], 32);
else
memset(_gstate.sram, 0, 32);
},
.serialize = [](std::vector<char>& out) -> void {
}
void c_serialize(std::vector<char>& out) {
auto wram = _gstate.as_ram();
out.resize(wram.second);
memcpy(&out[0], wram.first, wram.second);
},
.unserialize =[](const char* in, size_t insize) -> void {
}
void c_unserialize(const char* in, size_t insize) {
auto wram = _gstate.as_ram();
if(insize != wram.second)
throw std::runtime_error("Save is of wrong size");
memcpy(wram.first, in, wram.second);
handle_loadstate(_gstate);
},
.get_region = []() -> core_region& { return world_region; },
.power = []() -> void {},
.unload_cartridge = []() -> void {},
.get_scale_factors = [](uint32_t w, uint32_t h) -> std::pair<uint32_t, uint32_t> {
}
core_region& c_get_region() { return *this; }
void c_power() {}
void c_unload_cartridge() {}
std::pair<uint32_t, uint32_t> c_get_scale_factors(uint32_t w, uint32_t h) {
return std::make_pair(FB_WIDTH / w, FB_HEIGHT / h);
},
.install_handler = []() -> void { sky_core.hide(); },
.uninstall_handler = []() -> void {},
.emulate = []() -> void {
}
void c_install_handler() { hide(); }
void c_uninstall_handler() {}
void c_emulate() {
static unsigned count[4];
static unsigned tcount[4] = {5, 7, 8, 25};
uint16_t x = 0;
@ -318,41 +349,21 @@ namespace sky
audioapi_submit_buffer(sbuf, samples, true, 48000);
for(unsigned i = 0; i < samples; i++)
information_dispatch::do_sample(sbuf[2 * i + 0], sbuf[2 * i + 1]);
},
.runtosave = []() -> void {},
.get_pflag = []() -> bool { return pflag; },
.set_pflag = [](bool _pflag) -> void { pflag = _pflag; },
.port_types = {&psystem},
.draw_cover = []() -> framebuffer_raw& {
}
void c_runtosave() {}
bool c_get_pflag() { return pflag; }
void c_set_pflag(bool _pflag) { pflag = _pflag; }
framebuffer_raw& c_draw_cover() {
static framebuffer_raw x(cover_fbinfo);
return x;
},
.get_core_shortname = []() -> std::string { return "sky"; },
.pre_emulate_frame = [](controller_frame& cf) -> void {},
.execute_action = [](unsigned id, const std::vector<interface_action_paramval>& p) -> void {},
.get_registers = []() -> const interface_device_reg* { return sky_registers; },
}};
void controller_magic()
{
if(magic_flags & 1) {
X2.controllers[1] = &A8;
cstyle = 1;
} else if(magic_flags & 2) {
X2.controllers[1] = &B8;
cstyle = 2;
} else if(magic_flags & 4) {
X2.controllers[1] = &C8;
cstyle = 2;
} else {
cstyle = 0;
}
}
core_type skytype{{
.iname = "sky", .hname = "Sky", .id = 3522, .sysname = "Sky",
.load_rom = [](core_romimage* images, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
uint64_t rtc_subsec) -> int {
std::string c_get_core_shortname() { return "sky"; }
void c_pre_emulate_frame(controller_frame& cf) {}
void c_execute_action(unsigned id, const std::vector<interface_action_paramval>& p) {}
const interface_device_reg* c_get_registers() { return sky_registers; }
int t_load_rom(core_romimage* images, std::map<std::string, std::string>& settings,
uint64_t rtc_sec, uint64_t rtc_subsec)
{
controller_magic();
const unsigned char* _filename = images[0].data;
size_t size = images[0].size;
@ -366,8 +377,8 @@ namespace sky
rom_boot_vector(_gstate);
ecore_callbacks->set_reset_actions(-1, -1);
return 0;
},
.controllerconfig = [](std::map<std::string, std::string>& settings) -> controller_set
}
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
{
controller_magic();
controller_set r;
@ -378,13 +389,11 @@ namespace sky
r.portindex.logical_map.push_back(std::make_pair(0, 1));
r.portindex.pcid_map.push_back(std::make_pair(0, 1));
return r;
},
.extensions = "sky", .bios = NULL, .regions = {&world_region}, .images = {&skyzip},
.settings = &sky_settings, .core = &sky_core,
.get_bus_map = []() -> std::pair<uint64_t, uint64_t> { return std::make_pair(0, 0); },
.vma_list = []() -> std::list<core_vma_info> {
}
std::pair<uint64_t, uint64_t> t_get_bus_map() { return std::make_pair(0, 0); }
std::list<core_vma_info> t_vma_list()
{
std::list<core_vma_info> r;
core_vma_info ram;
ram.name = "RAM";
ram.backing_ram = _gstate.as_ram().first;
@ -394,14 +403,13 @@ namespace sky
ram.endian = 0;
ram.iospace_rw = NULL;
r.push_back(ram);
return r;
},
.srams = []() -> std::set<std::string> {
}
std::set<std::string> t_srams()
{
std::set<std::string> r;
r.insert("sram");
return r;
}
}};
core_sysregion X24("sky", skytype, world_region);
} sky_core;
}

View file

@ -58,7 +58,6 @@ namespace
#include "ports.inc"
#include "slots.inc"
#include "regions.inc"
core_setting_group test_settings;
@ -72,7 +71,7 @@ namespace
return x;
}
controller_set _controllerconfig(std::map<std::string, std::string>& settings)
controller_set test_controllerconfig(std::map<std::string, std::string>& settings)
{
std::map<std::string, std::string> _settings = settings;
controller_set r;
@ -125,29 +124,41 @@ namespace
}
}
extern core_core test_core;
core_core test_core{{
.core_identifier = []() -> std::string { return "TEST"; },
.set_region = [](core_region& region) -> bool { return (&region == &region_world); },
.video_rate = []() -> std::pair<uint32_t, uint32_t> { return std::make_pair(60, 1); },
.audio_rate = []() -> std::pair<uint32_t, uint32_t> { return std::make_pair(48000, 1); },
.save_sram = []() -> std::map<std::string, std::vector<char>> {
struct _test_core : public core_core, public core_type, public core_region, public core_sysregion
{
_test_core() : core_core({{_port_types}}), core_type({{
.iname = "test",
.hname = "test",
.id = 0,
.sysname = "Test",
.extensions = "test",
.bios = NULL,
.regions = {this},
.images = test_images,
.settings = &test_settings,
.core = this,
}}), core_region({{"world", "World", 0, 0, false, {1, 60}, {0}}}),
core_sysregion("test", *this, *this) {}
std::string c_core_identifier() { return "TEST"; }
bool c_set_region(core_region& region) { return (&region == this); }
std::pair<uint32_t, uint32_t> c_video_rate() { return std::make_pair(60, 1); }
std::pair<uint32_t, uint32_t> c_audio_rate() { return std::make_pair(48000, 1); }
std::map<std::string, std::vector<char>> c_save_sram() throw(std::bad_alloc) {
std::map<std::string, std::vector<char>> s;
return s;
},
.load_sram = [](std::map<std::string, std::vector<char>>& sram) -> void {},
.serialize = [](std::vector<char>& out) -> void { out.clear(); },
.unserialize = [](const char* in, size_t insize) -> void {},
.get_region = []() -> core_region& { return region_world; },
.power = []() -> void {},
.unload_cartridge = []() -> void {},
.get_scale_factors = [](uint32_t width, uint32_t height) -> std::pair<uint32_t, uint32_t> {
}
void c_load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc) {}
void c_serialize(std::vector<char>& out) { out.clear(); }
void c_unserialize(const char* in, size_t insize) {}
core_region& c_get_region() { return *this; }
void c_power() {}
void c_unload_cartridge() {}
std::pair<uint32_t, uint32_t> c_get_scale_factors(uint32_t width, uint32_t height) {
return std::make_pair(max(512 / width, (uint32_t)1), max(448 / height, (uint32_t)1));
},
.install_handler = []() -> void { test_core.hide(); },
.uninstall_handler = []() -> void {},
.emulate = []() -> void {
}
void c_install_handler() { hide(); }
void c_uninstall_handler() {}
void c_emulate() {
pflag = false;
redraw_screen();
framebuffer_info inf;
@ -163,30 +174,31 @@ namespace
inf.offset_y = 0;
framebuffer_raw ls(inf);
ecore_callbacks->output_frame(ls, 60,1);
},
.runtosave = []() -> void {},
.get_pflag = []() -> bool { return pflag; },
.set_pflag = [](bool _pflag) -> void { pflag = _pflag; },
.port_types = port_types,
.draw_cover = []() -> framebuffer_raw& {
}
void c_runtosave() {}
bool c_get_pflag() { return pflag; }
void c_set_pflag(bool _pflag) { pflag = _pflag; }
framebuffer_raw& c_draw_cover() {
static framebuffer_raw x(cover_fbinfo);
redraw_cover_fbinfo();
return x;
},
.get_core_shortname = []() -> std::string { return "test"; },
.pre_emulate_frame = [](controller_frame& cf) -> void {},
.execute_action = [](unsigned id, const std::vector<interface_action_paramval>& p) -> void {},
.get_registers = []() -> const interface_device_reg* { return test_registers; },
}};
core_type type_test{{
.iname = "test", .hname = "test", .id = 0, .sysname = "Test",
.load_rom = [](core_romimage* img, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
uint64_t rtc_subsec) -> int { ecore_callbacks->set_reset_actions(-1, -1); return 0; },
.controllerconfig = _controllerconfig, .extensions = "test", .bios = NULL, .regions = test_regions,
.images = test_images, .settings = &test_settings, .core = &test_core,
.get_bus_map = []() -> std::pair<uint64_t, uint64_t> { return std::make_pair(0, 0); },
.vma_list = []() -> std::list<core_vma_info> { return std::list<core_vma_info>();},
.srams = []() -> std::set<std::string> { return std::set<std::string>();}
}};
}
std::string c_get_core_shortname() { return "test"; }
void c_pre_emulate_frame(controller_frame& cf) {}
void c_execute_action(unsigned id, const std::vector<interface_action_paramval>& p) {}
const interface_device_reg* c_get_registers() { return test_registers; }
int t_load_rom(core_romimage* images, std::map<std::string, std::string>& settings,
uint64_t rtc_sec, uint64_t rtc_subsec)
{
ecore_callbacks->set_reset_actions(-1, -1);
return 0;
}
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
{
return test_controllerconfig(settings);
}
std::pair<uint64_t, uint64_t> t_get_bus_map() { return std::make_pair(0, 0); }
std::list<core_vma_info> t_vma_list() { return std::list<core_vma_info>(); }
std::set<std::string> t_srams() { return std::set<std::string>(); }
} test_core;
}

View file

@ -151,11 +151,6 @@ core_type::core_type(const core_type_params& params)
hname = params.hname;
sysname = params.sysname;
id = params.id;
loadimg = params.load_rom;
_controllerconfig = params.controllerconfig;
_get_bus_map = params.get_bus_map;
_vma_list = params.vma_list;
_srams = params.srams;
core = params.core;
settings = params.settings;
if(params.bios)
@ -245,7 +240,7 @@ core_region& core_type::get_preferred_region()
bool core_type::load(core_romimage* images, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
uint64_t rtc_subsec)
{
return (loadimg(images, settings, rtc_sec, rtc_subsec) >= 0);
return (t_load_rom(images, settings, rtc_sec, rtc_subsec) >= 0);
}
core_sysregion& core_type::combine_region(core_region& reg)
@ -278,22 +273,22 @@ bool core_type::is_known_extension(const std::string& ext)
controller_set core_type::controllerconfig(std::map<std::string, std::string>& settings)
{
return _controllerconfig(settings);
return t_controllerconfig(settings);
}
std::pair<uint64_t, uint64_t> core_type::get_bus_map()
{
return _get_bus_map();
return t_get_bus_map();
}
std::list<core_vma_info> core_type::vma_list()
{
return _vma_list();
return t_vma_list();
}
std::set<std::string> core_type::srams()
{
return _srams();
return t_srams();
}
core_sysregion::core_sysregion(const std::string& _name, core_type& _type, core_region& _region)
@ -342,38 +337,13 @@ void core_sysregion::fill_framerate_magic(uint64_t* magic)
core_core::core_core(const core_core_params& params)
: param_register_proxy(*this)
{
_core_identifier = params.core_identifier;
_set_region = params.set_region;
_video_rate = params.video_rate;
_audio_rate = params.audio_rate;
_save_sram = params.save_sram;
_load_sram = params.load_sram;
_serialize = params.serialize;
_unserialize = params.unserialize;
_get_region = params.get_region;
_power = params.power;
_unload_cartridge = params.unload_cartridge;
_get_scale_factors = params.get_scale_factors;
_install_handler = params.install_handler;
_uninstall_handler = params.uninstall_handler;
_emulate = params.emulate;
_runtosave = params.runtosave;
_get_pflag = params.get_pflag;
_set_pflag = params.set_pflag;
port_types = params.port_types;
_draw_cover = params.draw_cover;
_get_core_shortname = params.get_core_shortname;
_pre_emulate_frame = params.pre_emulate_frame;
_execute_action = params.execute_action;
_get_registers = params.get_registers;
hidden = false;
all_cores_set().insert(this);
if(install_handlers_automatically)
install_handler();
new_core_flag = true;
register_queue<core_core::_param_register_proxy, interface_action>::do_ready(param_register_proxy, true);
if(!in_global_ctors())
messages << "Loaded core: " << _core_identifier() << std::endl;
}
core_core::~core_core() throw()
@ -384,27 +354,27 @@ core_core::~core_core() throw()
std::string core_core::get_core_shortname()
{
return _get_core_shortname();
return c_get_core_shortname();
}
bool core_core::set_region(core_region& region)
{
return _set_region(region);
return c_set_region(region);
}
std::pair<uint32_t, uint32_t> core_core::get_video_rate()
{
return _video_rate();
return c_video_rate();
}
std::pair<uint32_t, uint32_t> core_core::get_audio_rate()
{
return _audio_rate();
return c_audio_rate();
}
std::string core_core::get_core_identifier()
{
return _core_identifier();
return c_core_identifier();
}
std::set<core_core*> core_core::all_cores()
@ -428,92 +398,92 @@ void core_core::uninstall_all_handlers()
std::map<std::string, std::vector<char>> core_core::save_sram() throw(std::bad_alloc)
{
return _save_sram();
return c_save_sram();
}
void core_core::load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc)
{
_load_sram(sram);
c_load_sram(sram);
}
void core_core::serialize(std::vector<char>& out)
{
_serialize(out);
c_serialize(out);
}
void core_core::unserialize(const char* in, size_t insize)
{
_unserialize(in, insize);
c_unserialize(in, insize);
}
core_region& core_core::get_region()
{
return _get_region();
return c_get_region();
}
void core_core::power()
{
_power();
c_power();
}
void core_core::unload_cartridge()
{
_unload_cartridge();
c_unload_cartridge();
}
std::pair<uint32_t, uint32_t> core_core::get_scale_factors(uint32_t width, uint32_t height)
{
return _get_scale_factors(width, height);
return c_get_scale_factors(width, height);
}
void core_core::install_handler()
{
_install_handler();
c_install_handler();
}
void core_core::uninstall_handler()
{
_uninstall_handler();
c_uninstall_handler();
}
void core_core::emulate()
{
_emulate();
c_emulate();
}
void core_core::runtosave()
{
_runtosave();
c_runtosave();
}
bool core_core::get_pflag()
{
return _get_pflag();
return c_get_pflag();
}
void core_core::set_pflag(bool pflag)
{
return _set_pflag(pflag);
return c_set_pflag(pflag);
}
framebuffer_raw& core_core::draw_cover()
{
return _draw_cover();
return c_draw_cover();
}
void core_core::pre_emulate_frame(controller_frame& cf)
{
_pre_emulate_frame(cf);
c_pre_emulate_frame(cf);
}
void core_core::execute_action(unsigned id, const std::vector<interface_action_paramval>& p)
{
return _execute_action(id, p);
return c_execute_action(id, p);
}
const struct interface_device_reg* core_core::get_registers()
{
return _get_registers();
return c_get_registers();
}
void core_core::do_register_action(const std::string& key, interface_action& act)