From a111afad42a3d2dedd0dfb0d1f7f71ea22dbec57 Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Wed, 3 Jul 2013 18:21:16 +0300 Subject: [PATCH] Use virtual methods instead of pointers for core stuff --- include/interface/romtype.hpp | 319 ++++++++-------- src/core/rom.cpp | 115 +++--- src/emulation/bsnes-legacy/core.cpp | 554 ++++++++++++++++------------ src/emulation/gambatte/core.cpp | 225 ++++++----- src/emulation/make-ports.lua | 2 +- src/emulation/sky/sky.cpp | 156 ++++---- src/emulation/test/test.cpp | 102 ++--- src/interface/romtype.cpp | 86 ++--- 8 files changed, 843 insertions(+), 716 deletions(-) diff --git a/include/interface/romtype.hpp b/include/interface/romtype.hpp index 3562e990..d2598df1 100644 --- a/include/interface/romtype.hpp +++ b/include/interface/romtype.hpp @@ -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& 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& 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 (*get_bus_map)(); -/** - * Get list of valid VMAs. ROM must be loaded. - * - * Returns: The list of VMAs. - */ - std::list (*vma_list)(); -/** - * Get list of valid SRAM names. ROM must be loaded. - * - * Returns: The list of SRAMs. - */ - std::set (*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 (*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 (*audio_rate)(); -/** - * Save all SRAMs. - */ - std::map> (*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>& sram) throw(std::bad_alloc); -/** - * Serialize the system state. - */ - void (*serialize)(std::vector& 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 (*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_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& 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 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 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 c_audio_rate() = 0; +/** + * Save all SRAMs. + */ + virtual std::map> 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>& sram) throw(std::bad_alloc) = 0; +/** + * Serialize the system state. + */ + virtual void c_serialize(std::vector& 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 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& 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 (*_video_rate)(); - std::pair (*_audio_rate)(); - std::map> (*_save_sram)() throw(std::bad_alloc); - void (*_load_sram)(std::map>& sram) throw(std::bad_alloc); - void (*_serialize)(std::vector& out); - void (*_unserialize)(const char* in, size_t insize); - core_region& (*_get_region)(); - void (*_power)(); - void (*_unload_cartridge)(); - std::pair (*_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_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& p); - const interface_device_reg* (*_get_registers)(); bool hidden; std::map 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 p) : core_type(*p.begin()) {} - ~core_type() throw(); + virtual ~core_type() throw(); static std::list get_core_types(); core_region& get_preferred_region(); std::list get_regions(); @@ -572,15 +514,46 @@ public: void pre_emulate_frame(controller_frame& cf) { return core->pre_emulate_frame(cf); } std::set 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& 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& 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 t_get_bus_map() = 0; +/** + * Get list of valid VMAs. ROM must be loaded. + * + * Returns: The list of VMAs. + */ + virtual std::list t_vma_list() = 0; +/** + * Get list of valid SRAM names. ROM must be loaded. + * + * Returns: The list of SRAMs. + */ + virtual std::set t_srams() = 0; private: core_type(const core_type&); core_type& operator=(const core_type&); - int (*loadimg)(core_romimage* images, std::map& settings, uint64_t rtc_sec, - uint64_t rtc_subsec); - controller_set (*_controllerconfig)(std::map& settings); - std::pair (*_get_bus_map)(); - std::list (*_vma_list)(); - std::set (*_srams)(); unsigned id; std::string iname; std::string hname; diff --git a/src/core/rom.cpp b/src/core/rom.cpp index 6450a094..5d4dfb73 100644 --- a/src/core/rom.cpp +++ b/src/core/rom.cpp @@ -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 { return std::make_pair(60, 1); }, - .audio_rate = []() -> std::pair { return std::make_pair(48000, 1); }, - .save_sram = []() -> std::map> { + 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 c_video_rate() { return std::make_pair(60, 1); } + std::pair c_audio_rate() { return std::make_pair(48000, 1); } + std::map> c_save_sram() throw (std::bad_alloc) { std::map> x; return x; - }, - .load_sram = [](std::map>& sram) -> void {}, - .serialize = [](std::vector& 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 { + } + void c_load_sram(std::map>& sram) throw (std::bad_alloc) {} + void c_serialize(std::vector& 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 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& p) -> void {} - }}; - - core_type type_null{{ - "null", "(null)", 9999, "System", - [](core_romimage* img, std::map& 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& p) {} + const interface_device_reg* c_get_registers() { return null_registers; } + int t_load_rom(core_romimage* img, std::map& settings, + uint64_t secs, uint64_t subsecs) + { ecore_callbacks->set_reset_actions(-1, -1); return 0; - }, - [](std::map& settings) -> controller_set { + } + controller_set t_controllerconfig(std::map& 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 { return std::make_pair(0ULL, 0ULL); }, - []() -> std::list { - std::list x; - return x; - }, - []() -> std::set { - std::set x; - return x; } - }}; - core_sysregion sysregion_null("null", type_null, null_region); + std::pair t_get_bus_map() { return std::make_pair(0ULL, 0ULL); } + std::list t_vma_list() { return std::list(); } + std::set t_srams() { return std::set(); } + } 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 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& 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; diff --git a/src/emulation/bsnes-legacy/core.cpp b/src/emulation/bsnes-legacy/core.cpp index ecfa1308..2b95637a 100644 --- a/src/emulation/bsnes-legacy/core.cpp +++ b/src/emulation/bsnes-legacy/core.cpp @@ -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 load_rom_X1(core_romimage* img) @@ -228,9 +222,8 @@ namespace } - template - int load_rom(core_romimage* img, std::map& settings, uint64_t secs, - uint64_t subsecs, bool(*fun)(core_romimage*)) + int load_rom(core_type* ctype, core_romimage* img, std::map& settings, + uint64_t secs, uint64_t subsecs, bool(*fun)(core_romimage*)) { std::map _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& settings) + controller_set bsnes_controllerconfig(std::map& settings) { std::map _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(reinterpret_cast(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 get_VMAlist() - { - std::list 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(SNES::necdsp.dataRAM), - 4096, false, true); - create_region(ret, "DSPPROM", 0xF0000000, reinterpret_cast(SNES::necdsp.programROM), - 65536, true, true); - create_region(ret, "DSPDROM", 0xF0010000, reinterpret_cast(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 srams() + std::list get_VMAlist(); + std::set bsnes_srams() { std::set 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(®ion == ®ion_auto) SNES::config.region = SNES::System::Region::Autodetect; else if(®ion == ®ion_ntsc) @@ -675,8 +564,8 @@ namespace else return false; return true; - }, - .video_rate = []() -> std::pair { + } + std::pair 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 { + } + std::pair c_audio_rate() { if(!internal_rom) return std::make_pair(64081, 2); return std::make_pair(SNES::system.apu_frequency(), static_cast(768)); - }, - .save_sram = []() -> std::map> { + } + std::map> c_save_sram() throw(std::bad_alloc) { std::map> out; if(!internal_rom) return out; @@ -704,8 +593,8 @@ namespace out[savename] = x; } return out; - }, - .load_sram = [](std::map>& sram) -> void { + } + void c_load_sram(std::map>& sram) throw(std::bad_alloc) { std::set 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& out) -> void { + } + void c_serialize(std::vector& 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(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 { + } + std::pair 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(); #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& p) -> void + } + void c_execute_action(unsigned id, const std::vector& 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& settings, uint64_t secs, - uint64_t subsecs) -> int { - return load_rom<&type_snes>(img, settings, secs, subsecs, - load_rom_X1); - }, - .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& settings, uint64_t secs, - uint64_t subsecs) -> int { - return load_rom<&type_bsx>(img, settings, secs, subsecs, - load_rom_X2); - }, - .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& settings, - uint64_t secs, uint64_t subsecs) -> int { - return load_rom<&type_bsxslotted>(img, settings, secs, subsecs, - load_rom_X2); - }, - .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& settings, uint64_t secs, - uint64_t subsecs) -> int { - return load_rom<&type_sufamiturbo>(img, settings, secs, subsecs, - load_rom_X3); - }, - .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& 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 = {®ion_auto, ®ion_ntsc, ®ion_pal}, + .images = snes_images, + .settings = &bsnes_settings, + .core = &bsnes_core, + }}) {} + int t_load_rom(core_romimage* img, std::map& 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); + } + controller_set t_controllerconfig(std::map& settings) + { + return bsnes_controllerconfig(settings); + } + std::pair t_get_bus_map() { return bsnes_get_bus_map(); } + std::list t_vma_list() { return get_VMAlist(); } + std::set 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 = {®ion_ntsc}, + .images = bsx_images, + .settings = &bsnes_settings, + .core = &bsnes_core, + }}) {} + int t_load_rom(core_romimage* img, std::map& settings, + uint64_t secs, uint64_t subsecs) + { + return load_rom(this, img, settings, secs, subsecs, + load_rom_X2); + } + controller_set t_controllerconfig(std::map& settings) + { + return bsnes_controllerconfig(settings); + } + std::pair t_get_bus_map() { return bsnes_get_bus_map(); } + std::list t_vma_list() { return get_VMAlist(); } + std::set 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 = {®ion_ntsc}, + .images = bsxs_images, + .settings = &bsnes_settings, + .core = &bsnes_core, + }}) {} + int t_load_rom(core_romimage* img, std::map& settings, + uint64_t secs, uint64_t subsecs) + { + return load_rom(this, img, settings, secs, subsecs, + load_rom_X2); + } + controller_set t_controllerconfig(std::map& settings) + { + return bsnes_controllerconfig(settings); + } + std::pair t_get_bus_map() { return bsnes_get_bus_map(); } + std::list t_vma_list() { return get_VMAlist(); } + std::set 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 = {®ion_ntsc}, + .images = sufamiturbo_images, + .settings = &bsnes_settings, + .core = &bsnes_core, + }}) {} + int t_load_rom(core_romimage* img, std::map& settings, + uint64_t secs, uint64_t subsecs) + { + return load_rom(this, img, settings, secs, subsecs, + load_rom_X3); + } + controller_set t_controllerconfig(std::map& settings) + { + return bsnes_controllerconfig(settings); + } + std::pair t_get_bus_map() { return bsnes_get_bus_map(); } + std::list t_vma_list() { return get_VMAlist(); } + std::set 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 = {®ion_auto, ®ion_ntsc, ®ion_pal}, + .images = sgb_images, + .settings = &bsnes_settings, + .core = &bsnes_core, + }}) {} + int t_load_rom(core_romimage* img, std::map& settings, + uint64_t secs, uint64_t subsecs) + { + return load_rom(this, img, settings, secs, subsecs, load_rom_X2); - }, - .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& settings) + { + return bsnes_controllerconfig(settings); + } + std::pair t_get_bus_map() { return bsnes_get_bus_map(); } + std::list t_vma_list() { return get_VMAlist(); } + std::set 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(reinterpret_cast(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 get_VMAlist() + { + std::list 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(SNES::necdsp.dataRAM), + 4096, false, true); + create_region(ret, "DSPPROM", 0xF0000000, reinterpret_cast(SNES::necdsp.programROM), + 65536, true, true); + create_region(ret, "DSPDROM", 0xF0010000, reinterpret_cast(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 dump_core(lsnes_cmd, "dump-core", "No description available", "No description available\n", diff --git a/src/emulation/gambatte/core.cpp b/src/emulation/gambatte/core.cpp index 0c7edf18..94c30ecb 100644 --- a/src/emulation/gambatte/core.cpp +++ b/src/emulation/gambatte/core.cpp @@ -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& settings) + controller_set gambatte_controllerconfig(std::map& settings) { std::map _settings = settings; controller_set r; @@ -244,7 +241,7 @@ namespace return vmas; } - std::set srams() + std::set gambatte_srams() { std::set 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 (®ion == ®ion_world); }, - .video_rate = []() -> std::pair { return std::make_pair(262144, 4389); }, - .audio_rate = []() -> std::pair { return std::make_pair(32768, 1); }, - .save_sram = []() -> std::map> { + 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 (®ion == this); } + std::pair c_video_rate() { return std::make_pair(262144, 4389); } + std::pair c_audio_rate() { return std::make_pair(32768, 1); } + std::map> c_save_sram() throw(std::bad_alloc) { std::map> 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>& sram) -> void { + } + void c_load_sram(std::map>& sram) throw(std::bad_alloc) { if(!internal_rom) return; std::vector x = sram.count("main") ? sram["main"] : std::vector(); @@ -321,8 +308,8 @@ namespace timebase |= (unsigned long long)(unsigned char)x2[i] << (8 * i); instance->setRtcBase(timebase); } - }, - .serialize = [](std::vector& out) -> void { + } + void c_serialize(std::vector& 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 { + } + core_region& c_get_region() { return *this; } + void c_power() {} + void c_unload_cartridge() {} + std::pair 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& p) -> void + } + void c_execute_action(unsigned id, const std::vector& 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& 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& 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& 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& 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& settings) + { + return gambatte_controllerconfig(settings); + } + std::pair t_get_bus_map() { return gambatte_bus_map(); } + std::list t_vma_list() { return get_VMAlist(); } + std::set 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& settings, + uint64_t secs, uint64_t subsecs) + { + return load_rom_common(img, 0, secs, subsecs, this); + } + controller_set t_controllerconfig(std::map& settings) + { + return gambatte_controllerconfig(settings); + } + std::pair t_get_bus_map() { return gambatte_bus_map(); } + std::list t_vma_list() { return get_VMAlist(); } + std::set 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& 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& settings) + { + return gambatte_controllerconfig(settings); + } + std::pair t_get_bus_map() { return gambatte_bus_map(); } + std::list t_vma_list() { return get_VMAlist(); } + std::set 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 cmp_save; diff --git a/src/emulation/make-ports.lua b/src/emulation/make-ports.lua index 6e7520a7..ed7a04cc 100644 --- a/src/emulation/make-ports.lua +++ b/src/emulation/make-ports.lua @@ -263,7 +263,7 @@ for i = 1,#ports do print("\t}"); print("} "..port.symbol..";"); end -local s = "std::vector port_types{ "; +local s = "std::vector _port_types{ "; for i = 1,#ports do s = s .."&"..ports[i].symbol..", "; end diff --git a/src/emulation/sky/sky.cpp b/src/emulation/sky/sky.cpp index bced793c..1db77bf0 100644 --- a/src/emulation/sky/sky.cpp +++ b/src/emulation/sky/sky.cpp @@ -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 (®ion == &world_region); }, - .video_rate = []() -> std::pair { return std::make_pair(656250, 18227); }, - .audio_rate = []() -> std::pair { return std::make_pair(48000, 1); }, - .save_sram = []() -> std::map> { + 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 (®ion == this); } + std::pair c_video_rate() { return std::make_pair(656250, 18227); } + std::pair c_audio_rate() { return std::make_pair(48000, 1); } + std::map> c_save_sram() throw(std::bad_alloc) { std::map> r; std::vector sram; sram.resize(32); memcpy(&sram[0], _gstate.sram, 32); r["sram"] = sram; return r; - }, - .load_sram = [](std::map>& sram) -> void { + } + void c_load_sram(std::map>& 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& out) -> void { + } + void c_serialize(std::vector& 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 { + } + core_region& c_get_region() { return *this; } + void c_power() {} + void c_unload_cartridge() {} + std::pair 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& 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& 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& p) {} + const interface_device_reg* c_get_registers() { return sky_registers; } + int t_load_rom(core_romimage* images, std::map& 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& settings) -> controller_set + } + controller_set t_controllerconfig(std::map& 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 { return std::make_pair(0, 0); }, - .vma_list = []() -> std::list { + } + std::pair t_get_bus_map() { return std::make_pair(0, 0); } + std::list t_vma_list() + { std::list 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::set t_srams() + { std::set r; r.insert("sram"); return r; } - }}; - core_sysregion X24("sky", skytype, world_region); + } sky_core; } diff --git a/src/emulation/test/test.cpp b/src/emulation/test/test.cpp index b9ec21af..178b7b95 100644 --- a/src/emulation/test/test.cpp +++ b/src/emulation/test/test.cpp @@ -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& settings) + controller_set test_controllerconfig(std::map& settings) { std::map _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 (®ion == ®ion_world); }, - .video_rate = []() -> std::pair { return std::make_pair(60, 1); }, - .audio_rate = []() -> std::pair { return std::make_pair(48000, 1); }, - .save_sram = []() -> std::map> { + 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 (®ion == this); } + std::pair c_video_rate() { return std::make_pair(60, 1); } + std::pair c_audio_rate() { return std::make_pair(48000, 1); } + std::map> c_save_sram() throw(std::bad_alloc) { std::map> s; return s; - }, - .load_sram = [](std::map>& sram) -> void {}, - .serialize = [](std::vector& 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 { + } + void c_load_sram(std::map>& sram) throw(std::bad_alloc) {} + void c_serialize(std::vector& 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 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& 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& 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 { return std::make_pair(0, 0); }, - .vma_list = []() -> std::list { return std::list();}, - .srams = []() -> std::set { return std::set();} - }}; + } + 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& p) {} + const interface_device_reg* c_get_registers() { return test_registers; } + int t_load_rom(core_romimage* images, std::map& settings, + uint64_t rtc_sec, uint64_t rtc_subsec) + { + ecore_callbacks->set_reset_actions(-1, -1); + return 0; + } + controller_set t_controllerconfig(std::map& settings) + { + return test_controllerconfig(settings); + } + std::pair t_get_bus_map() { return std::make_pair(0, 0); } + std::list t_vma_list() { return std::list(); } + std::set t_srams() { return std::set(); } + } test_core; } diff --git a/src/interface/romtype.cpp b/src/interface/romtype.cpp index 500ad660..f5559940 100644 --- a/src/interface/romtype.cpp +++ b/src/interface/romtype.cpp @@ -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& 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& settings) { - return _controllerconfig(settings); + return t_controllerconfig(settings); } std::pair core_type::get_bus_map() { - return _get_bus_map(); + return t_get_bus_map(); } std::list core_type::vma_list() { - return _vma_list(); + return t_vma_list(); } std::set 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::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 core_core::get_video_rate() { - return _video_rate(); + return c_video_rate(); } std::pair 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::all_cores() @@ -428,92 +398,92 @@ void core_core::uninstall_all_handlers() std::map> core_core::save_sram() throw(std::bad_alloc) { - return _save_sram(); + return c_save_sram(); } void core_core::load_sram(std::map>& sram) throw(std::bad_alloc) { - _load_sram(sram); + c_load_sram(sram); } void core_core::serialize(std::vector& 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 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& 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)