From 7f41254b27a87a8d5bfeb7fa22211119976c486d Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Sun, 6 Jan 2013 19:59:45 +0200 Subject: [PATCH] More making core functions into methods --- include/core/emucore.hpp | 14 - include/interface/romtype.hpp | 28 ++ src/core/bsnes-legacy.cpp | 595 +++++++++++++++++++----------------------- src/core/gambatte.cpp | 211 +++++---------- src/core/mainloop.cpp | 17 +- src/core/moviedata.cpp | 8 +- src/core/rom.cpp | 18 +- src/interface/romtype.cpp | 43 +++ 8 files changed, 443 insertions(+), 491 deletions(-) diff --git a/include/core/emucore.hpp b/include/core/emucore.hpp index 58dc4f41..0379469a 100644 --- a/include/core/emucore.hpp +++ b/include/core/emucore.hpp @@ -12,22 +12,8 @@ #include "interface/romtype.hpp" -//Install handler. -void core_install_handler(); -//Uninstall handler. -void core_uninstall_handler(); -//Emulate a frame. -void core_emulate_frame(); -//Run to point save. -void core_runtosave(); //Get set of SRAMs. std::set get_sram_set(); -//Get poll flag (set to 1 on each real poll, except if 2. -unsigned core_get_poll_flag(); -//Set poll flag (set to 1 on each real poll, except if 2. -void core_set_poll_flag(unsigned pflag); -//Request reset on next frame. -void core_request_reset(long delay); //Valid port types. extern port_type* core_port_types[]; //Emulator core. diff --git a/include/interface/romtype.hpp b/include/interface/romtype.hpp index 25fa7f5e..c1d7ae0d 100644 --- a/include/interface/romtype.hpp +++ b/include/interface/romtype.hpp @@ -69,6 +69,13 @@ struct core_core_params 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)(); + unsigned (*get_pflag)(); + void (*set_pflag)(unsigned pflag); + void (*request_reset)(long delay); }; @@ -130,6 +137,13 @@ struct core_core 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(); + unsigned get_pflag(); + void set_pflag(unsigned pflag); + void request_reset(long delay); private: std::string (*_core_identifier)(); bool (*_set_region)(core_region& region); @@ -144,6 +158,13 @@ private: 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)(); + unsigned (*_get_pflag)(); + void (*_set_pflag)(unsigned pflag); + void (*_request_reset)(long delay); }; struct core_type @@ -187,6 +208,13 @@ public: { return core->get_scale_factors(width, height); } + void install_handler() { core->install_handler(); } + void uninstall_handler() { core->uninstall_handler(); } + void emulate() { core->emulate(); } + void runtosave() { core->runtosave(); } + unsigned get_pflag() { return core->get_pflag(); } + void set_pflag(unsigned pflag) { core->set_pflag(pflag); } + void request_reset(long delay) { core->request_reset(delay); } private: core_type(const core_type&); core_type& operator=(const core_type&); diff --git a/src/core/bsnes-legacy.cpp b/src/core/bsnes-legacy.cpp index 3064ad83..6fb265b2 100644 --- a/src/core/bsnes-legacy.cpp +++ b/src/core/bsnes-legacy.cpp @@ -51,7 +51,6 @@ namespace bool pollflag_active = true; boolean_setting allow_inconsistent_saves(lsnes_set, "allow-inconsistent-saves", false); boolean_setting save_every_frame(lsnes_set, "save-every-frame", false); - uint32_t norom_frame[512 * 448]; bool have_saved_this_frame = false; int16_t blanksound[1070] = {0}; int16_t soundbuf[8192] = {0}; @@ -61,6 +60,13 @@ namespace uint64_t trace_counter; std::ofstream trace_output; bool trace_output_enable; + SNES::Interface* old; + bool stepping_into_save; + bool video_refresh_done; + bool forced_hook = false; + //Delay reset. + unsigned long long delayreset_cycles_run; + unsigned long long delayreset_cycles_target; core_setting_group bsnes_settings; @@ -446,22 +452,13 @@ namespace SNES::interface = &i; } - void init_norom_frame() - { - static bool done = false; - if(done) - return; - done = true; - for(size_t i = 0; i < 512 * 448; i++) - norom_frame[i] = 0x7C21F; - } - core_type* internal_rom = NULL; extern core_type type_snes; extern core_type type_bsx; extern core_type type_bsxslotted; extern core_type type_sufamiturbo; extern core_type type_sgb; + extern core_core_params _bsnes_core; template bool load_rom_X1(core_romimage* img) @@ -501,12 +498,13 @@ namespace SNES::config.random = false; SNES::config.expansion_port = SNES::System::ExpansionPortDevice::None; bool r = fun(img); - if(r) + if(r) { internal_rom = ctype; - snes_set_controller_port_device(false, index_to_bsnes_type[type1]); - snes_set_controller_port_device(true, index_to_bsnes_type[type2]); - have_saved_this_frame = false; - do_reset_flag = -1; + snes_set_controller_port_device(false, index_to_bsnes_type[type1]); + snes_set_controller_port_device(true, index_to_bsnes_type[type2]); + have_saved_this_frame = false; + do_reset_flag = -1; + } return r ? 0 : -1; } @@ -633,6 +631,167 @@ namespace #define BSNES_RESET_LEVEL 1 #endif + class my_interface : public SNES::Interface + { + string path(SNES::Cartridge::Slot slot, const string &hint) + { + const char* _hint = hint; + std::string _hint2 = _hint; + std::string fwp = ecore_callbacks->get_firmware_path(); + regex_results r; + std::string msubase = ecore_callbacks->get_base_path(); + if(regex_match(".*\\.sfc", msubase)) + msubase = msubase.substr(0, msubase.length() - 4); + + if(_hint2 == "msu1.rom" || _hint2 == ".msu") { + //MSU-1 main ROM. + std::string x = msubase + ".msu"; + messages << "MSU main data file: " << x << std::endl; + return x.c_str(); + } + if(r = regex("(track)?(-([0-9])+\\.pcm)", _hint2)) { + //MSU track. + std::string x = msubase + r[2]; + messages << "MSU track " << r[3] << "': " << x << std::endl; + return x.c_str(); + } + std::string finalpath = fwp + "/" + _hint2; + return finalpath.c_str(); + } + + time_t currentTime() + { + return ecore_callbacks->get_time(); + } + + time_t randomSeed() + { + return ecore_callbacks->get_randomseed(); + } + + void videoRefresh(const uint32_t* data, bool hires, bool interlace, bool overscan) + { + last_hires = hires; + last_interlace = interlace; + bool region = (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.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 audioSample(int16_t l_sample, int16_t r_sample) + { + uint16_t _l = l_sample; + uint16_t _r = r_sample; + soundbuf[soundbuf_fill++] = l_sample; + soundbuf[soundbuf_fill++] = r_sample; + information_dispatch::do_sample(l_sample, r_sample); + //The SMP emits a sample every 768 ticks of its clock. Use this in order to keep track of + //time. + ecore_callbacks->timer_tick(768, SNES::system.apu_frequency()); + } + + int16_t inputPoll(bool port, SNES::Input::Device device, unsigned index, unsigned id) + { + int16_t offset = 0; + //The superscope/justifier handling is nuts. + if(port && SNES::input.port2) { + SNES::SuperScope* ss = dynamic_cast(SNES::input.port2); + SNES::Justifier* js = dynamic_cast(SNES::input.port2); + if(ss && index == 0) { + if(id == 0) + offset = ss->x; + if(id == 1) + offset = ss->y; + } + if(js && index == 0) { + if(id == 0) + offset = js->player1.x; + if(id == 1) + offset = js->player1.y; + } + if(js && js->chained && index == 1) { + if(id == 0) + offset = js->player2.x; + if(id == 1) + offset = js->player2.y; + } + } + return ecore_callbacks->get_input(port ? 2 : 1, index, id) - offset; + } + } my_interface_obj; + + bool trace_fn() + { +#ifdef BSNES_HAS_DEBUGGER + if(trace_counter && !--trace_counter) { + //Trace counter did transition 1->0. Call the hook. + snesdbg_on_trace(); + } + if(trace_output_enable) { + char buffer[1024]; + SNES::cpu.disassemble_opcode(buffer, SNES::cpu.regs.pc); + trace_output << buffer << std::endl; + } + return false; +#endif + } + bool delayreset_fn() + { + trace_fn(); //Call this also. + if(delayreset_cycles_run == delayreset_cycles_target || video_refresh_done) + return true; + delayreset_cycles_run++; + return false; + } + + + bool trace_enabled() + { + return (trace_counter || !!trace_output_enable); + } + + void update_trace_hook_state() + { + if(forced_hook) + return; +#ifdef BSNES_HAS_DEBUGGER + if(!trace_enabled()) + SNES::cpu.step_event = nall::function(); + else + SNES::cpu.step_event = trace_fn; +#endif + } + std::string sram_name(const nall::string& _id, SNES::Cartridge::Slot slotname) { std::string id(_id, _id.length()); @@ -772,7 +931,106 @@ namespace //Get scale factors. [](uint32_t width, uint32_t height) -> std::pair { return std::make_pair((width < 400) ? 2 : 1, (height < 400) ? 2 : 1); - } + }, + //Install handler + []() -> void { + basic_init(); + old = SNES::interface; + SNES::interface = &my_interface_obj; + SNES::system.init(); + }, + //Uninstall handler + []() -> void { SNES::interface = old; }, + //Emulate frame. + []() -> void { + if(!internal_rom) + return; + bool was_delay_reset = false; + int16_t reset = ecore_callbacks->set_input(0, 0, 1, (do_reset_flag >= 0) ? 1 : 0); + if(reset) { + long hi = ecore_callbacks->set_input(0, 0, 2, do_reset_flag / 10000); + long lo = ecore_callbacks->set_input(0, 0, 3, do_reset_flag % 10000); + long delay = 10000 * hi + lo; + if(delay > 0) { + was_delay_reset = true; +#ifdef BSNES_HAS_DEBUGGER + messages << "Executing delayed reset... This can take some time!" + << std::endl; + video_refresh_done = false; + delayreset_cycles_run = 0; + delayreset_cycles_target = delay; + forced_hook = true; + SNES::cpu.step_event = delayreset_fn; +again: + SNES::system.run(); + if(SNES::scheduler.exit_reason() == SNES::Scheduler::ExitReason::DebuggerEvent + && SNES::debugger.break_event == + SNES::Debugger::BreakEvent::BreakpointHit) { + snesdbg_on_break(); + goto again; + } + SNES::cpu.step_event = nall::function(); + forced_hook = false; + if(video_refresh_done) { + //Force the reset here. + do_reset_flag = -1; + messages << "SNES reset (forced at " << delayreset_cycles_run << ")" + << std::endl; + SNES::system.reset(); + return; + } + SNES::system.reset(); + messages << "SNES reset (delayed " << delayreset_cycles_run << ")" + << std::endl; +#else + messages << "Delayresets not supported on this bsnes version " + "(needs v084 or v085)" << std::endl; + SNES::system.reset(); +#endif + } else if(delay == 0) { + SNES::system.reset(); + messages << "SNES reset" << std::endl; + } + } + do_reset_flag = -1; + + if(!have_saved_this_frame && save_every_frame && !was_delay_reset) + SNES::system.runtosave(); +#ifdef BSNES_HAS_DEBUGGER + if(trace_enabled()) + SNES::cpu.step_event = trace_fn; +#endif +again2: + SNES::system.run(); + if(SNES::scheduler.exit_reason() == SNES::Scheduler::ExitReason::DebuggerEvent && + SNES::debugger.break_event == SNES::Debugger::BreakEvent::BreakpointHit) { + snesdbg_on_break(); + goto again2; + } +#ifdef BSNES_HAS_DEBUGGER + SNES::cpu.step_event = nall::function(); +#endif + have_saved_this_frame = false; + }, + //Run to save. + []() -> void { + if(!internal_rom) + return; + stepping_into_save = true; + if(!allow_inconsistent_saves) + SNES::system.runtosave(); + have_saved_this_frame = true; + stepping_into_save = false; + }, + //Get poll flag. + []() -> unsigned { return pollflag_active ? (SNES::cpu.controller_flag ? 1 : 0) : 2; }, + //Set poll flag. + [](unsigned pflag) -> void { + SNES::cpu.controller_flag = (pflag != 0); + pollflag_active = (pflag < 2); + }, + //Request reset. + [](long delay) -> void { do_reset_flag = delay; } }; core_core bsnes_core(_bsnes_core); @@ -842,11 +1100,6 @@ namespace core_sysregion sr6("sgb_ntsc", type_sgb, region_ntsc); core_sysregion sr7("sgb_pal", type_sgb, region_pal); - bool stepping_into_save; - bool video_refresh_done; - //Delay reset. - unsigned long long delayreset_cycles_run; - unsigned long long delayreset_cycles_target; std::map> ptrmap; @@ -913,170 +1166,6 @@ namespace create_region(inf, name, 0x101000000 + index * 0x1000000, reinterpret_cast(memory), memsize, true, true); } - - bool trace_enabled() - { - return (trace_counter || !!trace_output_enable); - } - - bool forced_hook = false; - - bool trace_fn() - { - if(trace_counter && !--trace_counter) { - //Trace counter did transition 1->0. Call the hook. - snesdbg_on_trace(); - } - if(trace_output_enable) { - char buffer[1024]; - SNES::cpu.disassemble_opcode(buffer, SNES::cpu.regs.pc); - trace_output << buffer << std::endl; - } - return false; - } - - void update_trace_hook_state() - { - if(forced_hook) - return; -#ifdef BSNES_HAS_DEBUGGER - if(!trace_enabled()) - SNES::cpu.step_event = nall::function(); - else - SNES::cpu.step_event = trace_fn; -#endif - } - - bool delayreset_fn() - { - trace_fn(); //Call this also. - if(delayreset_cycles_run == delayreset_cycles_target || video_refresh_done) - return true; - delayreset_cycles_run++; - return false; - } - - class my_interface : public SNES::Interface - { - string path(SNES::Cartridge::Slot slot, const string &hint) - { - const char* _hint = hint; - std::string _hint2 = _hint; - std::string fwp = ecore_callbacks->get_firmware_path(); - regex_results r; - std::string msubase = ecore_callbacks->get_base_path(); - if(regex_match(".*\\.sfc", msubase)) - msubase = msubase.substr(0, msubase.length() - 4); - - if(_hint2 == "msu1.rom" || _hint2 == ".msu") { - //MSU-1 main ROM. - std::string x = msubase + ".msu"; - messages << "MSU main data file: " << x << std::endl; - return x.c_str(); - } - if(r = regex("(track)?(-([0-9])+\\.pcm)", _hint2)) { - //MSU track. - std::string x = msubase + r[2]; - messages << "MSU track " << r[3] << "': " << x << std::endl; - return x.c_str(); - } - std::string finalpath = fwp + "/" + _hint2; - return finalpath.c_str(); - } - - time_t currentTime() - { - return ecore_callbacks->get_time(); - } - - time_t randomSeed() - { - return ecore_callbacks->get_randomseed(); - } - - void videoRefresh(const uint32_t* data, bool hires, bool interlace, bool overscan) - { - last_hires = hires; - last_interlace = interlace; - bool region = (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.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 audioSample(int16_t l_sample, int16_t r_sample) - { - uint16_t _l = l_sample; - uint16_t _r = r_sample; - soundbuf[soundbuf_fill++] = l_sample; - soundbuf[soundbuf_fill++] = r_sample; - information_dispatch::do_sample(l_sample, r_sample); - //The SMP emits a sample every 768 ticks of its clock. Use this in order to keep track of - //time. - ecore_callbacks->timer_tick(768, SNES::system.apu_frequency()); - } - - int16_t inputPoll(bool port, SNES::Input::Device device, unsigned index, unsigned id) - { - int16_t offset = 0; - //The superscope/justifier handling is nuts. - if(port && SNES::input.port2) { - SNES::SuperScope* ss = dynamic_cast(SNES::input.port2); - SNES::Justifier* js = dynamic_cast(SNES::input.port2); - if(ss && index == 0) { - if(id == 0) - offset = ss->x; - if(id == 1) - offset = ss->y; - } - if(js && index == 0) { - if(id == 0) - offset = js->player1.x; - if(id == 1) - offset = js->player1.y; - } - if(js && js->chained && index == 1) { - if(id == 0) - offset = js->player2.x; - if(id == 1) - offset = js->player2.y; - } - } - return ecore_callbacks->get_input(port ? 2 : 1, index, id) - offset; - } - }; - - my_interface my_interface_obj; - SNES::Interface* old; } core_core* emulator_core = &bsnes_core; @@ -1086,18 +1175,6 @@ port_type* core_port_types[] = { &superscope, NULL }; -void core_install_handler() -{ - basic_init(); - old = SNES::interface; - SNES::interface = &my_interface_obj; - SNES::system.init(); -} - -void core_uninstall_handler() -{ - SNES::interface = old; -} std::set get_sram_set() { @@ -1111,118 +1188,7 @@ std::set get_sram_set() return r; } -void core_request_reset(long delay) -{ - do_reset_flag = delay; -} - -void core_emulate_frame() -{ - static unsigned frame_modulus = 0; - if(!internal_rom) { - do_reset_flag = -1; - init_norom_frame(); - framebuffer_info inf; - inf.type = &_pixel_format_lrgb; - inf.mem = const_cast(reinterpret_cast(norom_frame)); - inf.physwidth = 512; - inf.physheight = 448; - inf.physstride = 2048; - inf.width = 512; - inf.height = 448; - inf.stride = 2048; - inf.offset_x = 0; - inf.offset_y = 0; - - framebuffer_raw ls(inf); - ecore_callbacks->output_frame(ls, 60, 1); - - audioapi_submit_buffer(blanksound, frame_modulus ? 534 : 535, true, 32040.5); - for(unsigned i = 0; i < 534; i++) - information_dispatch::do_sample(0, 0); - if(!frame_modulus) - information_dispatch::do_sample(0, 0); - frame_modulus++; - frame_modulus %= 120; - ecore_callbacks->timer_tick(1, 60); - return; - } - - bool was_delay_reset = false; - int16_t reset = ecore_callbacks->set_input(0, 0, 1, (do_reset_flag >= 0) ? 1 : 0); - if(reset) { - long hi = ecore_callbacks->set_input(0, 0, 2, do_reset_flag / 10000); - long lo = ecore_callbacks->set_input(0, 0, 3, do_reset_flag % 10000); - long delay = 10000 * hi + lo; - if(delay > 0) { - was_delay_reset = true; -#ifdef BSNES_HAS_DEBUGGER - messages << "Executing delayed reset... This can take some time!" << std::endl; - video_refresh_done = false; - delayreset_cycles_run = 0; - delayreset_cycles_target = delay; - forced_hook = true; - SNES::cpu.step_event = delayreset_fn; -again: - SNES::system.run(); - if(SNES::scheduler.exit_reason() == SNES::Scheduler::ExitReason::DebuggerEvent && - SNES::debugger.break_event == SNES::Debugger::BreakEvent::BreakpointHit) { - snesdbg_on_break(); - goto again; - } - SNES::cpu.step_event = nall::function(); - forced_hook = false; - if(video_refresh_done) { - //Force the reset here. - do_reset_flag = -1; - messages << "SNES reset (forced at " << delayreset_cycles_run << ")" << std::endl; - SNES::system.reset(); - return; - } - SNES::system.reset(); - messages << "SNES reset (delayed " << delayreset_cycles_run << ")" << std::endl; -#else - messages << "Delayresets not supported on this bsnes version (needs v084 or v085)" - << std::endl; - SNES::system.reset(); -#endif - } else if(delay == 0) { - SNES::system.reset(); - messages << "SNES reset" << std::endl; - } - } - do_reset_flag = -1; - - - if(!have_saved_this_frame && save_every_frame && !was_delay_reset) - SNES::system.runtosave(); -#ifdef BSNES_HAS_DEBUGGER - if(trace_enabled()) - SNES::cpu.step_event = trace_fn; -#endif -again2: - SNES::system.run(); - if(SNES::scheduler.exit_reason() == SNES::Scheduler::ExitReason::DebuggerEvent && - SNES::debugger.break_event == SNES::Debugger::BreakEvent::BreakpointHit) { - snesdbg_on_break(); - goto again2; - } -#ifdef BSNES_HAS_DEBUGGER - SNES::cpu.step_event = nall::function(); -#endif - have_saved_this_frame = false; -} -void core_runtosave() -{ - if(!internal_rom) - return; - stepping_into_save = true; - if(!allow_inconsistent_saves) - SNES::system.runtosave(); - have_saved_this_frame = true; - stepping_into_save = false; -} std::list get_vma_list() { @@ -1270,17 +1236,6 @@ std::list get_vma_list() return ret; } -unsigned core_get_poll_flag() -{ - return pollflag_active ? (SNES::cpu.controller_flag ? 1 : 0) : 2; -} - -void core_set_poll_flag(unsigned pflag) -{ - SNES::cpu.controller_flag = (pflag != 0); - pollflag_active = (pflag < 2); -} - emucore_callbacks::~emucore_callbacks() throw() { } diff --git a/src/core/gambatte.cpp b/src/core/gambatte.cpp index f22ada33..f6e16c5a 100644 --- a/src/core/gambatte.cpp +++ b/src/core/gambatte.cpp @@ -47,7 +47,6 @@ namespace unsigned frame_overflow = 0; std::vector romdata; uint32_t primary_framebuffer[160*144]; - uint32_t norom_framebuffer[160*144]; uint32_t accumulator_l = 0; uint32_t accumulator_r = 0; unsigned accumulator_s = 0; @@ -141,16 +140,6 @@ namespace - void init_norom_framebuffer() - { - static bool done = false; - if(done) - return; - done = true; - for(size_t i = 0; i < 160 * 144; i++) - norom_framebuffer[i] = 0xFF8080; - } - time_t walltime_fn() { if(rtc_fixed) @@ -249,7 +238,6 @@ namespace return std::make_pair(0, 0); } - unsigned world_compatible[] = {0, UINT_MAX}; core_region_params _region_world = { "world", "World", 1, 0, false, {35112, 2097152, 16742706, 626688}, world_compatible @@ -353,7 +341,75 @@ namespace //Get scale factors [](uint32_t width, uint32_t height) -> std::pair { return std::make_pair(max(512 / width, (uint32_t)1), max(448 / height, (uint32_t)1)); - } + }, + //Install handler + []() -> void {}, + //Uninstall handler. + []() -> void {}, + //Emulate frame. + []() -> void { + if(!internal_rom) + return; + int16_t reset = ecore_callbacks->set_input(0, 0, 1, do_reset_flag ? 1 : 0); + if(reset) { + instance->reset(); + messages << "GB(C) reset" << std::endl; + } + do_reset_flag = false; + + uint32_t samplebuffer[SAMPLES_PER_FRAME + 2064]; + while(true) { + int16_t soundbuf[(SAMPLES_PER_FRAME + 63) / 32 + 66]; + size_t emitted = 0; + unsigned samples_emitted = SAMPLES_PER_FRAME - frame_overflow; + long ret = instance->runFor(primary_framebuffer, 160, samplebuffer, samples_emitted); + for(unsigned i = 0; i < samples_emitted; i++) { + uint32_t l = (int32_t)(int16_t)(samplebuffer[i]) + 32768; + uint32_t r = (int32_t)(int16_t)(samplebuffer[i] >> 16) + 32768; + accumulator_l += l; + accumulator_r += r; + accumulator_s++; + if((accumulator_s & 63) == 0) { + int16_t l2 = (accumulator_l >> 6) - 32768; + int16_t r2 = (accumulator_r >> 6) - 32768; + soundbuf[emitted++] = l2; + soundbuf[emitted++] = r2; + information_dispatch::do_sample(l2, r2); + accumulator_l = accumulator_r = 0; + accumulator_s = 0; + } + } + audioapi_submit_buffer(soundbuf, emitted / 2, true, 32768); + ecore_callbacks->timer_tick(samples_emitted, 2097152); + frame_overflow += samples_emitted; + if(frame_overflow >= SAMPLES_PER_FRAME) { + frame_overflow -= SAMPLES_PER_FRAME; + break; + } + } + framebuffer_info inf; + inf.type = &_pixel_format_rgb32; + inf.mem = const_cast(reinterpret_cast(primary_framebuffer)); + inf.physwidth = 160; + inf.physheight = 144; + inf.physstride = 640; + inf.width = 160; + inf.height = 144; + inf.stride = 640; + inf.offset_x = 0; + inf.offset_y = 0; + + framebuffer_raw ls(inf); + ecore_callbacks->output_frame(ls, 262144, 4389); + }, + //Run to save. + []() -> void {}, + //Get poll flag. + []() -> unsigned { return 2; }, + //Set poll flag. + [](unsigned pflag) -> void {}, + //Request reset. + [](long delay) -> void { do_reset_flag = true; } }; core_core gambatte_core(_gambatte_core); @@ -401,125 +457,7 @@ port_type* core_port_types[] = { }; -void core_runtosave() -{ -} - -void core_install_handler() -{ -} -void core_uninstall_handler() -{ -} - -void core_emulate_frame_nocore() -{ - do_reset_flag = -1; - init_norom_framebuffer(); - while(true) { - int16_t soundbuf[(SAMPLES_PER_FRAME + 63) / 32]; - size_t emitted = 0; - unsigned samples_emitted = SAMPLES_PER_FRAME - frame_overflow; - for(unsigned i = 0; i < samples_emitted; i++) { - accumulator_l += 32768; - accumulator_r += 32768; - accumulator_s++; - if((accumulator_s & 63) == 0) { - int16_t l2 = (accumulator_l >> 6) - 32768; - int16_t r2 = (accumulator_r >> 6) - 32768; - soundbuf[emitted++] = l2; - soundbuf[emitted++] = r2; - information_dispatch::do_sample(l2, r2); - accumulator_l = accumulator_r = 0; - accumulator_s = 0; - } - } - audioapi_submit_buffer(soundbuf, emitted / 2, true, 32768); - ecore_callbacks->timer_tick(samples_emitted, 2097152); - frame_overflow = 0; - break; - } - framebuffer_info inf; - inf.type = &_pixel_format_rgb32; - inf.mem = const_cast(reinterpret_cast(norom_framebuffer)); - inf.physwidth = 160; - inf.physheight = 144; - inf.physstride = 640; - inf.width = 160; - inf.height = 144; - inf.stride = 640; - inf.offset_x = 0; - inf.offset_y = 0; - - framebuffer_raw ls(inf); - ecore_callbacks->output_frame(ls, 262144, 4389); -} - -void core_request_reset(long delay) -{ - do_reset_flag = true; -} - -void core_emulate_frame() -{ - if(!internal_rom) { - core_emulate_frame_nocore(); - return; - } - - int16_t reset = ecore_callbacks->set_input(0, 0, 1, do_reset_flag ? 1 : 0); - if(reset) { - instance->reset(); - messages << "GB(C) reset" << std::endl; - } - do_reset_flag = false; - - uint32_t samplebuffer[SAMPLES_PER_FRAME + 2064]; - while(true) { - int16_t soundbuf[(SAMPLES_PER_FRAME + 63) / 32 + 66]; - size_t emitted = 0; - unsigned samples_emitted = SAMPLES_PER_FRAME - frame_overflow; - long ret = instance->runFor(primary_framebuffer, 160, samplebuffer, samples_emitted); - for(unsigned i = 0; i < samples_emitted; i++) { - uint32_t l = (int32_t)(int16_t)(samplebuffer[i]) + 32768; - uint32_t r = (int32_t)(int16_t)(samplebuffer[i] >> 16) + 32768; - accumulator_l += l; - accumulator_r += r; - accumulator_s++; - if((accumulator_s & 63) == 0) { - int16_t l2 = (accumulator_l >> 6) - 32768; - int16_t r2 = (accumulator_r >> 6) - 32768; - soundbuf[emitted++] = l2; - soundbuf[emitted++] = r2; - information_dispatch::do_sample(l2, r2); - accumulator_l = accumulator_r = 0; - accumulator_s = 0; - } - } - audioapi_submit_buffer(soundbuf, emitted / 2, true, 32768); - ecore_callbacks->timer_tick(samples_emitted, 2097152); - frame_overflow += samples_emitted; - if(frame_overflow >= SAMPLES_PER_FRAME) { - frame_overflow -= SAMPLES_PER_FRAME; - break; - } - } - framebuffer_info inf; - inf.type = &_pixel_format_rgb32; - inf.mem = const_cast(reinterpret_cast(primary_framebuffer)); - inf.physwidth = 160; - inf.physheight = 144; - inf.physstride = 640; - inf.width = 160; - inf.height = 144; - inf.stride = 640; - inf.offset_x = 0; - inf.offset_y = 0; - - framebuffer_raw ls(inf); - ecore_callbacks->output_frame(ls, 262144, 4389); -} std::list get_vma_list() { @@ -597,15 +535,6 @@ std::set get_sram_set() return s; } -unsigned core_get_poll_flag() -{ - return 2; -} - -void core_set_poll_flag(unsigned pflag) -{ -} - std::vector cmp_save; function_ptr_command<> cmp_save1(lsnes_cmd, "set-cmp-save", "", "\n", []() throw(std::bad_alloc, std::runtime_error) { @@ -621,8 +550,6 @@ function_ptr_command<> cmp_save2(lsnes_cmd, "do-cmp-save", "", "\n", []() throw( instance->saveState(x, cmp_save); }); - - emucore_callbacks::~emucore_callbacks() throw() {} struct emucore_callbacks* ecore_callbacks; diff --git a/src/core/mainloop.cpp b/src/core/mainloop.cpp index ecaedf36..9f8b7b0e 100644 --- a/src/core/mainloop.cpp +++ b/src/core/mainloop.cpp @@ -94,14 +94,13 @@ namespace } int get_pflag() { - return core_get_poll_flag(); + return our_rom->rtype->get_pflag(); } void set_pflag(int flag) { - core_set_poll_flag(flag); + our_rom->rtype->set_pflag(flag); } } lsnes_pflag_handler; - } path_setting firmwarepath_setting(lsnes_set, "firmwarepath"); @@ -537,9 +536,9 @@ namespace return; } if(x == "") - core_request_reset(0); + our_rom->rtype->request_reset(0); else - core_request_reset(parse_value(x)); + our_rom->rtype->request_reset(parse_value(x)); }); function_ptr_command load_c(lsnes_cmd, "load", "Load savestate (current mode)", @@ -835,7 +834,7 @@ namespace void handle_saves() { if(!queued_saves.empty() || (do_unsafe_rewind && !unsafe_rewind_obj)) { - core_runtosave(); + our_rom->rtype->runtosave(); for(auto i : queued_saves) do_save_state(i); if(do_unsafe_rewind && !unsafe_rewind_obj) { @@ -879,7 +878,7 @@ void main_loop(struct loaded_rom& rom, struct moviefile& initial, bool load_has_ lsnes_callbacks lsnes_callbacks_obj; ecore_callbacks = &lsnes_callbacks_obj; movb.get_movie().set_pflag_handler(&lsnes_pflag_handler); - core_install_handler(); + emulator_core->install_handler(); //Load our given movie. bool first_round = false; @@ -954,7 +953,7 @@ void main_loop(struct loaded_rom& rom, struct moviefile& initial, bool load_has_ just_did_loadstate = false; } frame_irq_time = get_utime() - time_x; - core_emulate_frame(); + our_rom->rtype->emulate(); time_x = get_utime(); if(amode == ADVANCE_AUTO) platform::wait(to_wait_frame(get_utime())); @@ -962,6 +961,6 @@ void main_loop(struct loaded_rom& rom, struct moviefile& initial, bool load_has_ lua_callback_do_frame(); } information_dispatch::do_dump_end(); - core_uninstall_handler(); + emulator_core->uninstall_handler(); voicethread_kill(); } diff --git a/src/core/moviedata.cpp b/src/core/moviedata.cpp index 1ae47bc9..763a52c7 100644 --- a/src/core/moviedata.cpp +++ b/src/core/moviedata.cpp @@ -187,7 +187,7 @@ void do_save_state(const std::string& filename) throw(std::bad_alloc, our_movie.pollcounters); our_movie.input = movb.get_movie().save(); our_movie.save(filename2, savecompression); - our_movie.poll_flag = core_get_poll_flag(); + our_movie.poll_flag = our_rom->rtype->get_pflag(); uint64_t took = get_utime() - origtime; messages << "Saved state '" << filename2 << "' in " << took << " microseconds." << std::endl; lua_callback_post_save(filename2, true); @@ -268,7 +268,7 @@ void do_load_beginning(bool reload) throw(std::bad_alloc, std::runtime_error) our_movie.rtc_subsecond = our_movie.movie_rtc_subsecond; if(!our_movie.anchor_savestate.empty()) our_rom->load_core_state(our_movie.anchor_savestate); - core_set_poll_flag(0); + our_rom->rtype->set_pflag(0); redraw_framebuffer(screen_nosignal); lua_callback_do_rewind(); } catch(std::bad_alloc& e) { @@ -351,7 +351,7 @@ void do_load_state(struct moviefile& _movie, int lmode) //Set the core ports in order to avoid port state being reinitialized when loading. controls.set_ports(portset); our_rom->load_core_state(_movie.savestate); - core_set_poll_flag(_movie.poll_flag); + our_rom->rtype->set_pflag(_movie.poll_flag); } else { our_rom->rtype->load_sram(_movie.movie_sram); controls.set_ports(portset); @@ -359,7 +359,7 @@ void do_load_state(struct moviefile& _movie, int lmode) _movie.rtc_subsecond = _movie.movie_rtc_subsecond; if(!_movie.anchor_savestate.empty()) our_rom->load_core_state(_movie.anchor_savestate); - core_set_poll_flag(0); + our_rom->rtype->set_pflag(0); } } catch(std::bad_alloc& e) { OOM_panic(); diff --git a/src/core/rom.cpp b/src/core/rom.cpp index 9a83b118..070804d6 100644 --- a/src/core/rom.cpp +++ b/src/core/rom.cpp @@ -103,10 +103,24 @@ namespace //Unload the cartridge. []() -> void {}, //Get scale factors. - [](uint32_t width, uint32_t height) -> std::pair { return std::make_pair(1, 1); } + [](uint32_t width, uint32_t height) -> std::pair { return std::make_pair(1, 1); }, + //Install handler. + []() -> void {}, + //Uninstall handler. + []() -> void {}, + //Emulate frame. + []() -> void {}, + //Run to save. + []() -> void {}, + //Get poll flag. + []() -> unsigned { return 2; }, + //Set poll flag. + [](unsigned pflag) -> void {}, + //Request reset. + [](long delay) -> void {} }; core_core core_null(_core_null); - + core_type_params _type_null = { "null", "(null)", 9999, 0, [](core_romimage* img, std::map& settings, diff --git a/src/interface/romtype.cpp b/src/interface/romtype.cpp index 6273a25c..acdedf94 100644 --- a/src/interface/romtype.cpp +++ b/src/interface/romtype.cpp @@ -304,6 +304,13 @@ core_core::core_core(core_core_params& params) _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; + _request_reset = params.request_reset; } bool core_core::set_region(core_region& region) @@ -373,3 +380,39 @@ std::pair core_core::get_scale_factors(uint32_t width, uint3 { return _get_scale_factors(width, height); } + +void core_core::install_handler() +{ + _install_handler(); +} + +void core_core::uninstall_handler() +{ + _uninstall_handler(); +} + +void core_core::emulate() +{ + _emulate(); +} + +void core_core::runtosave() +{ + _runtosave(); +} + +unsigned core_core::get_pflag() +{ + return _get_pflag(); +} + +void core_core::set_pflag(unsigned pflag) +{ + return _set_pflag(pflag); +} + +void core_core::request_reset(long delay) +{ + if(_request_reset) + _request_reset(delay); +} -- 2.11.4.GIT