Use virtual methods instead of pointers for core stuff
This commit is contained in:
parent
84faf2f42e
commit
a111afad42
8 changed files with 843 additions and 716 deletions
|
@ -202,24 +202,6 @@ struct core_type_params
|
||||||
* System menu name.
|
* System menu name.
|
||||||
*/
|
*/
|
||||||
const char* sysname;
|
const char* sysname;
|
||||||
/**
|
|
||||||
* Load a ROM slot set. Changes the ROM currently loaded for core.
|
|
||||||
*
|
|
||||||
* Parameter images: The set of images to load.
|
|
||||||
* Parameter settings: The settings to use.
|
|
||||||
* Parameter rtc_sec: The initial RTC seconds value.
|
|
||||||
* Parameter rtc_subsec: The initial RTC subseconds value.
|
|
||||||
* Returns: -1 on failure, 0 on success.
|
|
||||||
*/
|
|
||||||
int (*load_rom)(core_romimage* images, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
|
|
||||||
uint64_t rtc_subsec);
|
|
||||||
/**
|
|
||||||
* Obtain controller config for given settings.
|
|
||||||
*
|
|
||||||
* Parameter settings: The settings to use.
|
|
||||||
* Returns: The controller configuration.
|
|
||||||
*/
|
|
||||||
controller_set (*controllerconfig)(std::map<std::string, std::string>& settings);
|
|
||||||
/**
|
/**
|
||||||
* Semicolon-separated list of extensions this system type uses.
|
* Semicolon-separated list of extensions this system type uses.
|
||||||
*/
|
*/
|
||||||
|
@ -244,24 +226,6 @@ struct core_type_params
|
||||||
* Core this system is emulated by.
|
* Core this system is emulated by.
|
||||||
*/
|
*/
|
||||||
core_core* core;
|
core_core* core;
|
||||||
/**
|
|
||||||
* Get bus mapping.
|
|
||||||
*
|
|
||||||
* Returns: The bus mapping (base,size), or (0,0) if this system does not have bus mapping.
|
|
||||||
*/
|
|
||||||
std::pair<uint64_t, uint64_t> (*get_bus_map)();
|
|
||||||
/**
|
|
||||||
* Get list of valid VMAs. ROM must be loaded.
|
|
||||||
*
|
|
||||||
* Returns: The list of VMAs.
|
|
||||||
*/
|
|
||||||
std::list<core_vma_info> (*vma_list)();
|
|
||||||
/**
|
|
||||||
* Get list of valid SRAM names. ROM must be loaded.
|
|
||||||
*
|
|
||||||
* Returns: The list of SRAMs.
|
|
||||||
*/
|
|
||||||
std::set<std::string> (*srams)();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -271,117 +235,10 @@ struct core_type_params
|
||||||
*/
|
*/
|
||||||
struct core_core_params
|
struct core_core_params
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Get the name of the core.
|
|
||||||
*/
|
|
||||||
std::string (*core_identifier)();
|
|
||||||
/**
|
|
||||||
* Set the current region.
|
|
||||||
*
|
|
||||||
* Parameter region: The new region.
|
|
||||||
* Returns: True on success, false on failure (bad region).
|
|
||||||
*/
|
|
||||||
bool (*set_region)(core_region& region);
|
|
||||||
/**
|
|
||||||
* Get current video frame rate as (numerator, denominator).
|
|
||||||
*/
|
|
||||||
std::pair<uint32_t, uint32_t> (*video_rate)();
|
|
||||||
/**
|
|
||||||
* Get audio sampling rate as (numerator, denominator).
|
|
||||||
*
|
|
||||||
* Note: This value should not be changed while ROM is running, since video dumper may malfunction.
|
|
||||||
*/
|
|
||||||
std::pair<uint32_t, uint32_t> (*audio_rate)();
|
|
||||||
/**
|
|
||||||
* Save all SRAMs.
|
|
||||||
*/
|
|
||||||
std::map<std::string, std::vector<char>> (*save_sram)() throw(std::bad_alloc);
|
|
||||||
/**
|
|
||||||
* Load all SRAMs.
|
|
||||||
*
|
|
||||||
* Note: Must handle SRAM being missing or shorter or longer than expected.
|
|
||||||
*/
|
|
||||||
void (*load_sram)(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc);
|
|
||||||
/**
|
|
||||||
* Serialize the system state.
|
|
||||||
*/
|
|
||||||
void (*serialize)(std::vector<char>& out);
|
|
||||||
/**
|
|
||||||
* Unserialize the system state.
|
|
||||||
*/
|
|
||||||
void (*unserialize)(const char* in, size_t insize);
|
|
||||||
/**
|
|
||||||
* Get current region.
|
|
||||||
*/
|
|
||||||
core_region& (*get_region)();
|
|
||||||
/**
|
|
||||||
* Poweron the console.
|
|
||||||
*/
|
|
||||||
void (*power)();
|
|
||||||
/**
|
|
||||||
* Unload the cartridge from the console.
|
|
||||||
*/
|
|
||||||
void (*unload_cartridge)();
|
|
||||||
/**
|
|
||||||
* Get the current scale factors for screen as (xscale, yscale).
|
|
||||||
*/
|
|
||||||
std::pair<uint32_t, uint32_t> (*get_scale_factors)(uint32_t width, uint32_t height);
|
|
||||||
/**
|
|
||||||
* Do basic core initialization. Called on lsnes startup.
|
|
||||||
*/
|
|
||||||
void (*install_handler)();
|
|
||||||
/**
|
|
||||||
* Do basic core uninitialization. Called on lsnes shutdown.
|
|
||||||
*/
|
|
||||||
void (*uninstall_handler)();
|
|
||||||
/**
|
|
||||||
* Emulate one frame.
|
|
||||||
*/
|
|
||||||
void (*emulate)();
|
|
||||||
/**
|
|
||||||
* Get core into state where saving is possible. Must run less than one frame.
|
|
||||||
*/
|
|
||||||
void (*runtosave)();
|
|
||||||
/**
|
|
||||||
* Get the polled flag.
|
|
||||||
*
|
|
||||||
* The emulator core sets polled flag when the game asks for input.
|
|
||||||
*
|
|
||||||
* If polled flag is clear when frame ends, the frame is marked as lag.
|
|
||||||
*/
|
|
||||||
bool (*get_pflag)();
|
|
||||||
/**
|
|
||||||
* Set the polled flag.
|
|
||||||
*/
|
|
||||||
void (*set_pflag)(bool pflag);
|
|
||||||
/**
|
/**
|
||||||
* Set of valid port types for the core.
|
* Set of valid port types for the core.
|
||||||
*/
|
*/
|
||||||
std::vector<port_type*> port_types;
|
std::vector<port_type*> port_types;
|
||||||
/**
|
|
||||||
* Draw run cover screen.
|
|
||||||
*
|
|
||||||
* Should display information about the ROM loaded.
|
|
||||||
*/
|
|
||||||
framebuffer_raw& (*draw_cover)();
|
|
||||||
/**
|
|
||||||
* Get shortened name of the core.
|
|
||||||
*/
|
|
||||||
std::string (*get_core_shortname)();
|
|
||||||
/**
|
|
||||||
* Set the system controls to appropriate values for next frame.
|
|
||||||
*
|
|
||||||
* E.g. if core supports resetting, set the reset button in the frame to pressed if reset is wanted.
|
|
||||||
*/
|
|
||||||
void (*pre_emulate_frame)(controller_frame& cf);
|
|
||||||
/**
|
|
||||||
* Execute action.
|
|
||||||
*/
|
|
||||||
void (*execute_action)(unsigned id, const std::vector<interface_action_paramval>& p);
|
|
||||||
/**
|
|
||||||
* Get set of interface device registers.
|
|
||||||
*/
|
|
||||||
const struct interface_device_reg* (*get_registers)();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct core_region
|
struct core_region
|
||||||
|
@ -480,31 +337,116 @@ struct core_core
|
||||||
std::set<const interface_action*> get_actions();
|
std::set<const interface_action*> get_actions();
|
||||||
_param_register_proxy param_register_proxy;
|
_param_register_proxy param_register_proxy;
|
||||||
const interface_device_reg* get_registers();
|
const interface_device_reg* get_registers();
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Get the name of the core.
|
||||||
|
*/
|
||||||
|
virtual std::string c_core_identifier() = 0;
|
||||||
|
/**
|
||||||
|
* Set the current region.
|
||||||
|
*
|
||||||
|
* Parameter region: The new region.
|
||||||
|
* Returns: True on success, false on failure (bad region).
|
||||||
|
*/
|
||||||
|
virtual bool c_set_region(core_region& region) = 0;
|
||||||
|
/**
|
||||||
|
* Get current video frame rate as (numerator, denominator).
|
||||||
|
*/
|
||||||
|
virtual std::pair<uint32_t, uint32_t> c_video_rate() = 0;
|
||||||
|
/**
|
||||||
|
* Get audio sampling rate as (numerator, denominator).
|
||||||
|
*
|
||||||
|
* Note: This value should not be changed while ROM is running, since video dumper may malfunction.
|
||||||
|
*/
|
||||||
|
virtual std::pair<uint32_t, uint32_t> c_audio_rate() = 0;
|
||||||
|
/**
|
||||||
|
* Save all SRAMs.
|
||||||
|
*/
|
||||||
|
virtual std::map<std::string, std::vector<char>> c_save_sram() throw(std::bad_alloc) = 0;
|
||||||
|
/**
|
||||||
|
* Load all SRAMs.
|
||||||
|
*
|
||||||
|
* Note: Must handle SRAM being missing or shorter or longer than expected.
|
||||||
|
*/
|
||||||
|
virtual void c_load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc) = 0;
|
||||||
|
/**
|
||||||
|
* Serialize the system state.
|
||||||
|
*/
|
||||||
|
virtual void c_serialize(std::vector<char>& out) = 0;
|
||||||
|
/**
|
||||||
|
* Unserialize the system state.
|
||||||
|
*/
|
||||||
|
virtual void c_unserialize(const char* in, size_t insize) = 0;
|
||||||
|
/**
|
||||||
|
* Get current region.
|
||||||
|
*/
|
||||||
|
virtual core_region& c_get_region() = 0;
|
||||||
|
/**
|
||||||
|
* Poweron the console.
|
||||||
|
*/
|
||||||
|
virtual void c_power() = 0;
|
||||||
|
/**
|
||||||
|
* Unload the cartridge from the console.
|
||||||
|
*/
|
||||||
|
virtual void c_unload_cartridge() = 0;
|
||||||
|
/**
|
||||||
|
* Get the current scale factors for screen as (xscale, yscale).
|
||||||
|
*/
|
||||||
|
virtual std::pair<uint32_t, uint32_t> c_get_scale_factors(uint32_t width, uint32_t height) = 0;
|
||||||
|
/**
|
||||||
|
* Do basic core initialization. Called on lsnes startup.
|
||||||
|
*/
|
||||||
|
virtual void c_install_handler() = 0;
|
||||||
|
/**
|
||||||
|
* Do basic core uninitialization. Called on lsnes shutdown.
|
||||||
|
*/
|
||||||
|
virtual void c_uninstall_handler() = 0;
|
||||||
|
/**
|
||||||
|
* Emulate one frame.
|
||||||
|
*/
|
||||||
|
virtual void c_emulate() = 0;
|
||||||
|
/**
|
||||||
|
* Get core into state where saving is possible. Must run less than one frame.
|
||||||
|
*/
|
||||||
|
virtual void c_runtosave() = 0;
|
||||||
|
/**
|
||||||
|
* Get the polled flag.
|
||||||
|
*
|
||||||
|
* The emulator core sets polled flag when the game asks for input.
|
||||||
|
*
|
||||||
|
* If polled flag is clear when frame ends, the frame is marked as lag.
|
||||||
|
*/
|
||||||
|
virtual bool c_get_pflag() = 0;
|
||||||
|
/**
|
||||||
|
* Set the polled flag.
|
||||||
|
*/
|
||||||
|
virtual void c_set_pflag(bool pflag) = 0;
|
||||||
|
/**
|
||||||
|
* Draw run cover screen.
|
||||||
|
*
|
||||||
|
* Should display information about the ROM loaded.
|
||||||
|
*/
|
||||||
|
virtual framebuffer_raw& c_draw_cover() = 0;
|
||||||
|
/**
|
||||||
|
* Get shortened name of the core.
|
||||||
|
*/
|
||||||
|
virtual std::string c_get_core_shortname() = 0;
|
||||||
|
/**
|
||||||
|
* Set the system controls to appropriate values for next frame.
|
||||||
|
*
|
||||||
|
* E.g. if core supports resetting, set the reset button in the frame to pressed if reset is wanted.
|
||||||
|
*/
|
||||||
|
virtual void c_pre_emulate_frame(controller_frame& cf) = 0;
|
||||||
|
/**
|
||||||
|
* Execute action.
|
||||||
|
*/
|
||||||
|
virtual void c_execute_action(unsigned id, const std::vector<interface_action_paramval>& p) = 0;
|
||||||
|
/**
|
||||||
|
* Get set of interface device registers.
|
||||||
|
*/
|
||||||
|
virtual const struct interface_device_reg* c_get_registers() = 0;
|
||||||
private:
|
private:
|
||||||
std::string (*_core_identifier)();
|
|
||||||
bool (*_set_region)(core_region& region);
|
|
||||||
std::pair<uint32_t, uint32_t> (*_video_rate)();
|
|
||||||
std::pair<uint32_t, uint32_t> (*_audio_rate)();
|
|
||||||
std::map<std::string, std::vector<char>> (*_save_sram)() throw(std::bad_alloc);
|
|
||||||
void (*_load_sram)(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc);
|
|
||||||
void (*_serialize)(std::vector<char>& out);
|
|
||||||
void (*_unserialize)(const char* in, size_t insize);
|
|
||||||
core_region& (*_get_region)();
|
|
||||||
void (*_power)();
|
|
||||||
void (*_unload_cartridge)();
|
|
||||||
std::pair<uint32_t, uint32_t> (*_get_scale_factors)(uint32_t width, uint32_t height);
|
|
||||||
void (*_install_handler)();
|
|
||||||
void (*_uninstall_handler)();
|
|
||||||
void (*_emulate)();
|
|
||||||
void (*_runtosave)();
|
|
||||||
bool (*_get_pflag)();
|
|
||||||
void (*_set_pflag)(bool pflag);
|
|
||||||
std::vector<port_type*> port_types;
|
std::vector<port_type*> port_types;
|
||||||
framebuffer_raw& (*_draw_cover)();
|
|
||||||
std::string (*_get_core_shortname)();
|
|
||||||
void (*_pre_emulate_frame)(controller_frame& cf);
|
|
||||||
void (*_execute_action)(unsigned id, const std::vector<interface_action_paramval>& p);
|
|
||||||
const interface_device_reg* (*_get_registers)();
|
|
||||||
bool hidden;
|
bool hidden;
|
||||||
std::map<std::string, interface_action*> actions;
|
std::map<std::string, interface_action*> actions;
|
||||||
mutex_class actions_lock;
|
mutex_class actions_lock;
|
||||||
|
@ -515,7 +457,7 @@ struct core_type
|
||||||
public:
|
public:
|
||||||
core_type(const core_type_params& params);
|
core_type(const core_type_params& params);
|
||||||
core_type(std::initializer_list<core_type_params> p) : core_type(*p.begin()) {}
|
core_type(std::initializer_list<core_type_params> p) : core_type(*p.begin()) {}
|
||||||
~core_type() throw();
|
virtual ~core_type() throw();
|
||||||
static std::list<core_type*> get_core_types();
|
static std::list<core_type*> get_core_types();
|
||||||
core_region& get_preferred_region();
|
core_region& get_preferred_region();
|
||||||
std::list<core_region*> get_regions();
|
std::list<core_region*> get_regions();
|
||||||
|
@ -572,15 +514,46 @@ public:
|
||||||
void pre_emulate_frame(controller_frame& cf) { return core->pre_emulate_frame(cf); }
|
void pre_emulate_frame(controller_frame& cf) { return core->pre_emulate_frame(cf); }
|
||||||
std::set<const interface_action*> get_actions() { return core->get_actions(); }
|
std::set<const interface_action*> get_actions() { return core->get_actions(); }
|
||||||
const interface_device_reg* get_registers() { return core->get_registers(); }
|
const interface_device_reg* get_registers() { return core->get_registers(); }
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Load a ROM slot set. Changes the ROM currently loaded for core.
|
||||||
|
*
|
||||||
|
* Parameter images: The set of images to load.
|
||||||
|
* Parameter settings: The settings to use.
|
||||||
|
* Parameter rtc_sec: The initial RTC seconds value.
|
||||||
|
* Parameter rtc_subsec: The initial RTC subseconds value.
|
||||||
|
* Returns: -1 on failure, 0 on success.
|
||||||
|
*/
|
||||||
|
virtual int t_load_rom(core_romimage* images, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
|
||||||
|
uint64_t rtc_subsec) = 0;
|
||||||
|
/**
|
||||||
|
* Obtain controller config for given settings.
|
||||||
|
*
|
||||||
|
* Parameter settings: The settings to use.
|
||||||
|
* Returns: The controller configuration.
|
||||||
|
*/
|
||||||
|
virtual controller_set t_controllerconfig(std::map<std::string, std::string>& settings) = 0;
|
||||||
|
/**
|
||||||
|
* Get bus mapping.
|
||||||
|
*
|
||||||
|
* Returns: The bus mapping (base,size), or (0,0) if this system does not have bus mapping.
|
||||||
|
*/
|
||||||
|
virtual std::pair<uint64_t, uint64_t> t_get_bus_map() = 0;
|
||||||
|
/**
|
||||||
|
* Get list of valid VMAs. ROM must be loaded.
|
||||||
|
*
|
||||||
|
* Returns: The list of VMAs.
|
||||||
|
*/
|
||||||
|
virtual std::list<core_vma_info> t_vma_list() = 0;
|
||||||
|
/**
|
||||||
|
* Get list of valid SRAM names. ROM must be loaded.
|
||||||
|
*
|
||||||
|
* Returns: The list of SRAMs.
|
||||||
|
*/
|
||||||
|
virtual std::set<std::string> t_srams() = 0;
|
||||||
private:
|
private:
|
||||||
core_type(const core_type&);
|
core_type(const core_type&);
|
||||||
core_type& operator=(const core_type&);
|
core_type& operator=(const core_type&);
|
||||||
int (*loadimg)(core_romimage* images, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
|
|
||||||
uint64_t rtc_subsec);
|
|
||||||
controller_set (*_controllerconfig)(std::map<std::string, std::string>& settings);
|
|
||||||
std::pair<uint64_t, uint64_t> (*_get_bus_map)();
|
|
||||||
std::list<core_vma_info> (*_vma_list)();
|
|
||||||
std::set<std::string> (*_srams)();
|
|
||||||
unsigned id;
|
unsigned id;
|
||||||
std::string iname;
|
std::string iname;
|
||||||
std::string hname;
|
std::string hname;
|
||||||
|
|
115
src/core/rom.cpp
115
src/core/rom.cpp
|
@ -59,73 +59,80 @@ namespace
|
||||||
|
|
||||||
core_setting_group null_settings;
|
core_setting_group null_settings;
|
||||||
|
|
||||||
core_region null_region{{"null", "(null)", 0, 0, false, {1, 60}, {0}}};
|
struct interface_device_reg null_registers[] = {
|
||||||
core_core core_null{{
|
{NULL, NULL, NULL}
|
||||||
.core_identifier = []() -> std::string { return "null core"; },
|
};
|
||||||
.set_region = [](core_region& reg) -> bool { return true; },
|
|
||||||
.video_rate = []() -> std::pair<unsigned, unsigned> { return std::make_pair(60, 1); },
|
struct _core_null : public core_core, public core_type, public core_region, public core_sysregion
|
||||||
.audio_rate = []() -> std::pair<unsigned, unsigned> { return std::make_pair(48000, 1); },
|
{
|
||||||
.save_sram = []() -> std::map<std::string, std::vector<char>> {
|
_core_null() : core_core({{{}}}), core_type({{
|
||||||
|
.iname = "null",
|
||||||
|
.hname = "(null)",
|
||||||
|
.id = 9999,
|
||||||
|
.sysname = "System",
|
||||||
|
.extensions = "",
|
||||||
|
.bios = NULL,
|
||||||
|
.regions = {this},
|
||||||
|
.images = {},
|
||||||
|
.settings = &null_settings,
|
||||||
|
.core = this,
|
||||||
|
}}), core_region({{"null", "(null)", 0, 0, false, {1, 60}, {0}}}),
|
||||||
|
core_sysregion("null", *this, *this) {}
|
||||||
|
std::string c_core_identifier() { return "null core"; }
|
||||||
|
bool c_set_region(core_region& reg) { return true; }
|
||||||
|
std::pair<unsigned, unsigned> c_video_rate() { return std::make_pair(60, 1); }
|
||||||
|
std::pair<unsigned, unsigned> c_audio_rate() { return std::make_pair(48000, 1); }
|
||||||
|
std::map<std::string, std::vector<char>> c_save_sram() throw (std::bad_alloc) {
|
||||||
std::map<std::string, std::vector<char>> x;
|
std::map<std::string, std::vector<char>> x;
|
||||||
return x;
|
return x;
|
||||||
},
|
}
|
||||||
.load_sram = [](std::map<std::string, std::vector<char>>& sram) -> void {},
|
void c_load_sram(std::map<std::string, std::vector<char>>& sram) throw (std::bad_alloc) {}
|
||||||
.serialize = [](std::vector<char>& out) -> void { out.clear(); },
|
void c_serialize(std::vector<char>& out) { out.clear(); }
|
||||||
.unserialize = [](const char* in, size_t insize) -> void {},
|
void c_unserialize(const char* in, size_t insize) {}
|
||||||
.get_region = []() -> core_region& { return null_region; },
|
core_region& c_get_region() { return *this; }
|
||||||
.power = []() -> void {},
|
void c_power() {}
|
||||||
.unload_cartridge = []() -> void {},
|
void c_unload_cartridge() {}
|
||||||
.get_scale_factors = [](uint32_t width, uint32_t height) -> std::pair<uint32_t, uint32_t> {
|
std::pair<uint32_t, uint32_t> c_get_scale_factors(uint32_t width, uint32_t height) {
|
||||||
return std::make_pair(1, 1);
|
return std::make_pair(1, 1);
|
||||||
},
|
}
|
||||||
.install_handler = []() -> void {},
|
void c_install_handler() {}
|
||||||
.uninstall_handler = []() -> void {},
|
void c_uninstall_handler() {}
|
||||||
.emulate = []() -> void {},
|
void c_emulate() {}
|
||||||
.runtosave = []() -> void {},
|
void c_runtosave() {}
|
||||||
.get_pflag = []() -> bool { return false; },
|
bool c_get_pflag() { return false; }
|
||||||
.set_pflag = [](bool pflag) -> void {},
|
void c_set_pflag(bool pflag) {}
|
||||||
.port_types = {},
|
framebuffer_raw& c_draw_cover() {
|
||||||
.draw_cover = []() -> framebuffer_raw& {
|
|
||||||
static framebuffer_raw x(null_fbinfo);
|
static framebuffer_raw x(null_fbinfo);
|
||||||
for(size_t i = 0; i < sizeof(null_cover_fbmem)/sizeof(null_cover_fbmem[0]); i++)
|
for(size_t i = 0; i < sizeof(null_cover_fbmem)/sizeof(null_cover_fbmem[0]); i++)
|
||||||
null_cover_fbmem[i] = 0x0000;
|
null_cover_fbmem[i] = 0x0000;
|
||||||
std::string message = "NO ROM LOADED";
|
std::string message = "NO ROM LOADED";
|
||||||
cover_render_string(null_cover_fbmem, 204, 220, message, 0xFFFF, 0x0000, 512, 448, 1024, 2);
|
cover_render_string(null_cover_fbmem, 204, 220, message, 0xFFFF, 0x0000, 512, 448, 1024, 2);
|
||||||
return x;
|
return x;
|
||||||
},
|
}
|
||||||
.get_core_shortname = []() -> std::string { return "null"; },
|
std::string c_get_core_shortname() { return "null"; }
|
||||||
.pre_emulate_frame = [](controller_frame& cf) -> void {},
|
void c_pre_emulate_frame(controller_frame& cf) {}
|
||||||
.execute_action = [](unsigned id, const std::vector<interface_action_paramval>& p) -> void {}
|
void c_execute_action(unsigned id, const std::vector<interface_action_paramval>& p) {}
|
||||||
}};
|
const interface_device_reg* c_get_registers() { return null_registers; }
|
||||||
|
int t_load_rom(core_romimage* img, std::map<std::string, std::string>& settings,
|
||||||
core_type type_null{{
|
uint64_t secs, uint64_t subsecs)
|
||||||
"null", "(null)", 9999, "System",
|
{
|
||||||
[](core_romimage* img, std::map<std::string, std::string>& settings,
|
|
||||||
uint64_t secs, uint64_t subsecs) -> int {
|
|
||||||
ecore_callbacks->set_reset_actions(-1, -1);
|
ecore_callbacks->set_reset_actions(-1, -1);
|
||||||
return 0;
|
return 0;
|
||||||
},
|
}
|
||||||
[](std::map<std::string, std::string>& settings) -> controller_set {
|
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
|
||||||
|
{
|
||||||
controller_set x;
|
controller_set x;
|
||||||
x.ports.push_back(&get_default_system_port_type());
|
x.ports.push_back(&get_default_system_port_type());
|
||||||
x.portindex.indices.push_back(sync_triple);
|
x.portindex.indices.push_back(sync_triple);
|
||||||
return x;
|
return x;
|
||||||
},
|
|
||||||
"", NULL, {&null_region}, {}, &null_settings, &core_null,
|
|
||||||
[]() -> std::pair<uint64_t, uint64_t> { return std::make_pair(0ULL, 0ULL); },
|
|
||||||
[]() -> std::list<core_vma_info> {
|
|
||||||
std::list<core_vma_info> x;
|
|
||||||
return x;
|
|
||||||
},
|
|
||||||
[]() -> std::set<std::string> {
|
|
||||||
std::set<std::string> x;
|
|
||||||
return x;
|
|
||||||
}
|
}
|
||||||
}};
|
std::pair<uint64_t, uint64_t> t_get_bus_map() { return std::make_pair(0ULL, 0ULL); }
|
||||||
core_sysregion sysregion_null("null", type_null, null_region);
|
std::list<core_vma_info> t_vma_list() { return std::list<core_vma_info>(); }
|
||||||
|
std::set<std::string> t_srams() { return std::set<std::string>(); }
|
||||||
|
} core_null;
|
||||||
|
|
||||||
core_type* current_rom_type = &type_null;
|
core_type* current_rom_type = &core_null;
|
||||||
core_region* current_region = &null_region;
|
core_region* current_region = &core_null;
|
||||||
|
|
||||||
core_type* find_core_by_extension(const std::string& ext, const std::string& tmpprefer)
|
core_type* find_core_by_extension(const std::string& ext, const std::string& tmpprefer)
|
||||||
{
|
{
|
||||||
|
@ -274,8 +281,8 @@ std::pair<core_type*, core_region*> get_current_rom_info() throw()
|
||||||
|
|
||||||
loaded_rom::loaded_rom() throw()
|
loaded_rom::loaded_rom() throw()
|
||||||
{
|
{
|
||||||
rtype = &type_null;
|
rtype = &core_null;
|
||||||
region = orig_region = &null_region;
|
region = orig_region = &core_null;
|
||||||
}
|
}
|
||||||
|
|
||||||
loaded_rom::loaded_rom(const std::string& file, core_type& ctype) throw(std::bad_alloc, std::runtime_error)
|
loaded_rom::loaded_rom(const std::string& file, core_type& ctype) throw(std::bad_alloc, std::runtime_error)
|
||||||
|
@ -432,8 +439,8 @@ void loaded_rom::load(std::map<std::string, std::string>& settings, uint64_t rtc
|
||||||
throw(std::bad_alloc, std::runtime_error)
|
throw(std::bad_alloc, std::runtime_error)
|
||||||
{
|
{
|
||||||
core_core* old_core = current_rom_type->get_core();
|
core_core* old_core = current_rom_type->get_core();
|
||||||
current_rom_type = &type_null;
|
current_rom_type = &core_null;
|
||||||
if(!orig_region && rtype != &type_null)
|
if(!orig_region && rtype != &core_null)
|
||||||
orig_region = &rtype->get_preferred_region();
|
orig_region = &rtype->get_preferred_region();
|
||||||
if(!region)
|
if(!region)
|
||||||
region = orig_region;
|
region = orig_region;
|
||||||
|
|
|
@ -146,7 +146,10 @@ namespace
|
||||||
|
|
||||||
#include "ports.inc"
|
#include "ports.inc"
|
||||||
#include "slots.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_group bsnes_settings;
|
||||||
core_setting setting_port1(bsnes_settings, "port1", "Port 1 Type", "gamepad", {
|
core_setting setting_port1(bsnes_settings, "port1", "Port 1 Type", "gamepad", {
|
||||||
|
@ -162,7 +165,7 @@ namespace
|
||||||
{"0", "False", 0}, {"1", "True", 1}});
|
{"0", "False", 0}, {"1", "True", 1}});
|
||||||
core_setting setting_randinit(bsnes_settings, "radominit", "Random initial state", "0", {
|
core_setting setting_randinit(bsnes_settings, "radominit", "Random initial state", "0", {
|
||||||
{"0", "False", 0}, {"1", "True", 1}});
|
{"0", "False", 0}, {"1", "True", 1}});
|
||||||
|
|
||||||
////////////////// PORTS COMMON ///////////////////
|
////////////////// PORTS COMMON ///////////////////
|
||||||
port_type* index_to_ptype[] = {
|
port_type* index_to_ptype[] = {
|
||||||
&none, &gamepad, &gamepad16, &multitap, &multitap16, &mouse, &justifier, &justifiers, &superscope
|
&none, &gamepad, &gamepad16, &multitap, &multitap16, &mouse, &justifier, &justifiers, &superscope
|
||||||
|
@ -195,15 +198,6 @@ namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
core_type* internal_rom = NULL;
|
core_type* internal_rom = NULL;
|
||||||
extern core_core bsnes_core;
|
|
||||||
|
|
||||||
interface_action act_reset(bsnes_core, 0, "Soft reset", "reset", {});
|
|
||||||
interface_action act_hreset(bsnes_core, 1, "Hard reset", "hardreset", {});
|
|
||||||
#ifdef BSNES_HAS_DEBUGGER
|
|
||||||
interface_action act_dreset(bsnes_core, 2, "Delayed soft reset", "delayreset", {{"Delay","int:0,99999999"}});
|
|
||||||
interface_action act_dhreset(bsnes_core, 3, "Delayed hard reset", "delayhardreset",
|
|
||||||
{{"Delay","int:0,99999999"}});
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<bool(*T)(const char*,const unsigned char*, unsigned)>
|
template<bool(*T)(const char*,const unsigned char*, unsigned)>
|
||||||
bool load_rom_X1(core_romimage* img)
|
bool load_rom_X1(core_romimage* img)
|
||||||
|
@ -228,9 +222,8 @@ namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<core_type* ctype>
|
int load_rom(core_type* ctype, core_romimage* img, std::map<std::string, std::string>& settings,
|
||||||
int load_rom(core_romimage* img, std::map<std::string, std::string>& settings, uint64_t secs,
|
uint64_t secs, uint64_t subsecs, bool(*fun)(core_romimage*))
|
||||||
uint64_t subsecs, bool(*fun)(core_romimage*))
|
|
||||||
{
|
{
|
||||||
std::map<std::string, std::string> _settings = settings;
|
std::map<std::string, std::string> _settings = settings;
|
||||||
bsnes_settings.fill_defaults(_settings);
|
bsnes_settings.fill_defaults(_settings);
|
||||||
|
@ -284,7 +277,7 @@ namespace
|
||||||
tab.push_back(t(p, i, j, true));
|
tab.push_back(t(p, i, j, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
controller_set _controllerconfig(std::map<std::string, std::string>& settings)
|
controller_set bsnes_controllerconfig(std::map<std::string, std::string>& settings)
|
||||||
{
|
{
|
||||||
std::map<std::string, std::string> _settings = settings;
|
std::map<std::string, std::string> _settings = settings;
|
||||||
bsnes_settings.fill_defaults(_settings);
|
bsnes_settings.fill_defaults(_settings);
|
||||||
|
@ -366,44 +359,7 @@ namespace
|
||||||
return ecore_callbacks->get_randomseed();
|
return ecore_callbacks->get_randomseed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void videoRefresh(const uint32_t* data, bool hires, bool interlace, bool overscan)
|
void videoRefresh(const uint32_t* data, bool hires, bool interlace, bool overscan);
|
||||||
{
|
|
||||||
last_hires = hires;
|
|
||||||
last_interlace = interlace;
|
|
||||||
bool region = (SNES::system.region() == SNES::System::Region::PAL);
|
|
||||||
if(stepping_into_save)
|
|
||||||
messages << "Got video refresh in runtosave, expect desyncs!" << std::endl;
|
|
||||||
video_refresh_done = true;
|
|
||||||
uint32_t fps_n, fps_d;
|
|
||||||
auto fps = bsnes_core.get_video_rate();
|
|
||||||
fps_n = fps.first;
|
|
||||||
fps_d = fps.second;
|
|
||||||
uint32_t g = gcd(fps_n, fps_d);
|
|
||||||
fps_n /= g;
|
|
||||||
fps_d /= g;
|
|
||||||
|
|
||||||
framebuffer_info inf;
|
|
||||||
inf.type = &_pixel_format_lrgb;
|
|
||||||
inf.mem = const_cast<char*>(reinterpret_cast<const char*>(data));
|
|
||||||
inf.physwidth = 512;
|
|
||||||
inf.physheight = 512;
|
|
||||||
inf.physstride = 2048;
|
|
||||||
inf.width = hires ? 512 : 256;
|
|
||||||
inf.height = (region ? 239 : 224) * (interlace ? 2 : 1);
|
|
||||||
inf.stride = interlace ? 2048 : 4096;
|
|
||||||
inf.offset_x = 0;
|
|
||||||
inf.offset_y = (region ? (overscan ? 9 : 1) : (overscan ? 16 : 9)) * 2;
|
|
||||||
|
|
||||||
framebuffer_raw ls(inf);
|
|
||||||
ecore_callbacks->output_frame(ls, fps_n, fps_d);
|
|
||||||
information_dispatch::do_raw_frame(data, hires, interlace, overscan, region ?
|
|
||||||
VIDEO_REGION_PAL : VIDEO_REGION_NTSC);
|
|
||||||
if(soundbuf_fill > 0) {
|
|
||||||
auto freq = SNES::system.apu_frequency();
|
|
||||||
audioapi_submit_buffer(soundbuf, soundbuf_fill / 2, true, freq / 768.0);
|
|
||||||
soundbuf_fill = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void audioSample(int16_t l_sample, int16_t r_sample)
|
void audioSample(int16_t l_sample, int16_t r_sample)
|
||||||
{
|
{
|
||||||
|
@ -574,56 +530,8 @@ namespace
|
||||||
memsize, true, true);
|
memsize, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<core_vma_info> get_VMAlist()
|
std::list<core_vma_info> get_VMAlist();
|
||||||
{
|
std::set<std::string> bsnes_srams()
|
||||||
std::list<core_vma_info> ret;
|
|
||||||
if(!internal_rom)
|
|
||||||
return ret;
|
|
||||||
create_region(ret, "WRAM", 0x007E0000, SNES::cpu.wram, 131072, false);
|
|
||||||
create_region(ret, "APURAM", 0x00000000, SNES::smp.apuram, 65536, false);
|
|
||||||
create_region(ret, "VRAM", 0x00010000, SNES::ppu.vram, 65536, false);
|
|
||||||
create_region(ret, "OAM", 0x00020000, SNES::ppu.oam, 544, false);
|
|
||||||
create_region(ret, "CGRAM", 0x00021000, SNES::ppu.cgram, 512, false);
|
|
||||||
if(SNES::cartridge.has_srtc()) create_region(ret, "RTC", 0x00022000, SNES::srtc.rtc, 20, false);
|
|
||||||
if(SNES::cartridge.has_spc7110rtc()) create_region(ret, "RTC", 0x00022000, SNES::spc7110.rtc, 20,
|
|
||||||
false);
|
|
||||||
if(SNES::cartridge.has_necdsp()) {
|
|
||||||
create_region(ret, "DSPRAM", 0x00023000, reinterpret_cast<uint8_t*>(SNES::necdsp.dataRAM),
|
|
||||||
4096, false, true);
|
|
||||||
create_region(ret, "DSPPROM", 0xF0000000, reinterpret_cast<uint8_t*>(SNES::necdsp.programROM),
|
|
||||||
65536, true, true);
|
|
||||||
create_region(ret, "DSPDROM", 0xF0010000, reinterpret_cast<uint8_t*>(SNES::necdsp.dataROM),
|
|
||||||
4096, true, true);
|
|
||||||
}
|
|
||||||
create_region(ret, "SRAM", 0x10000000, SNES::cartridge.ram, false);
|
|
||||||
create_region(ret, "ROM", 0x80000000, SNES::cartridge.rom, true);
|
|
||||||
create_region(ret, "BUS", 0x1000000, 0x1000000, snes_bus_iospace_rw);
|
|
||||||
create_region(ret, "PTRTABLE", 0x100000000, 0x100000, ptrtable_iospace_rw);
|
|
||||||
map_internal(ret, "CPU_STATE", 0, &SNES::cpu, sizeof(SNES::cpu));
|
|
||||||
map_internal(ret, "PPU_STATE", 1, &SNES::ppu, sizeof(SNES::ppu));
|
|
||||||
map_internal(ret, "SMP_STATE", 2, &SNES::smp, sizeof(SNES::smp));
|
|
||||||
map_internal(ret, "DSP_STATE", 3, &SNES::dsp, sizeof(SNES::dsp));
|
|
||||||
if(internal_rom == &type_bsx || internal_rom == &type_bsxslotted) {
|
|
||||||
create_region(ret, "BSXFLASH", 0x90000000, SNES::bsxflash.memory, true);
|
|
||||||
create_region(ret, "BSX_RAM", 0x20000000, SNES::bsxcartridge.sram, false);
|
|
||||||
create_region(ret, "BSX_PRAM", 0x30000000, SNES::bsxcartridge.psram, false);
|
|
||||||
}
|
|
||||||
if(internal_rom == &type_sufamiturbo) {
|
|
||||||
create_region(ret, "SLOTA_ROM", 0x90000000, SNES::sufamiturbo.slotA.rom, true);
|
|
||||||
create_region(ret, "SLOTB_ROM", 0xA0000000, SNES::sufamiturbo.slotB.rom, true);
|
|
||||||
create_region(ret, "SLOTA_RAM", 0x20000000, SNES::sufamiturbo.slotA.ram, false);
|
|
||||||
create_region(ret, "SLOTB_RAM", 0x30000000, SNES::sufamiturbo.slotB.ram, false);
|
|
||||||
}
|
|
||||||
if(internal_rom == &type_sgb) {
|
|
||||||
create_region(ret, "GBROM", 0x90000000, GameBoy::cartridge.romdata,
|
|
||||||
GameBoy::cartridge.romsize, true);
|
|
||||||
create_region(ret, "GBRAM", 0x20000000, GameBoy::cartridge.ramdata,
|
|
||||||
GameBoy::cartridge.ramsize, false);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::set<std::string> srams()
|
|
||||||
{
|
{
|
||||||
std::set<std::string> r;
|
std::set<std::string> r;
|
||||||
if(!internal_rom)
|
if(!internal_rom)
|
||||||
|
@ -637,35 +545,16 @@ namespace
|
||||||
|
|
||||||
const char* hexes = "0123456789ABCDEF";
|
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{{
|
void redraw_cover_fbinfo();
|
||||||
.core_identifier = []() -> std::string {
|
|
||||||
|
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();
|
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)
|
if(®ion == ®ion_auto)
|
||||||
SNES::config.region = SNES::System::Region::Autodetect;
|
SNES::config.region = SNES::System::Region::Autodetect;
|
||||||
else if(®ion == ®ion_ntsc)
|
else if(®ion == ®ion_ntsc)
|
||||||
|
@ -675,8 +564,8 @@ namespace
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
},
|
}
|
||||||
.video_rate = []() -> std::pair<uint32_t, uint32_t> {
|
std::pair<uint32_t, uint32_t> c_video_rate() {
|
||||||
if(!internal_rom)
|
if(!internal_rom)
|
||||||
return std::make_pair(60, 1);
|
return std::make_pair(60, 1);
|
||||||
uint32_t div;
|
uint32_t div;
|
||||||
|
@ -685,13 +574,13 @@ namespace
|
||||||
else
|
else
|
||||||
div = last_interlace ? DURATION_NTSC_FIELD : DURATION_NTSC_FRAME;
|
div = last_interlace ? DURATION_NTSC_FIELD : DURATION_NTSC_FRAME;
|
||||||
return std::make_pair(SNES::system.cpu_frequency(), div);
|
return std::make_pair(SNES::system.cpu_frequency(), div);
|
||||||
},
|
}
|
||||||
.audio_rate = []() -> std::pair<uint32_t, uint32_t> {
|
std::pair<uint32_t, uint32_t> c_audio_rate() {
|
||||||
if(!internal_rom)
|
if(!internal_rom)
|
||||||
return std::make_pair(64081, 2);
|
return std::make_pair(64081, 2);
|
||||||
return std::make_pair(SNES::system.apu_frequency(), static_cast<uint32_t>(768));
|
return std::make_pair(SNES::system.apu_frequency(), static_cast<uint32_t>(768));
|
||||||
},
|
}
|
||||||
.save_sram = []() -> std::map<std::string, std::vector<char>> {
|
std::map<std::string, std::vector<char>> c_save_sram() throw(std::bad_alloc) {
|
||||||
std::map<std::string, std::vector<char>> out;
|
std::map<std::string, std::vector<char>> out;
|
||||||
if(!internal_rom)
|
if(!internal_rom)
|
||||||
return out;
|
return out;
|
||||||
|
@ -704,8 +593,8 @@ namespace
|
||||||
out[savename] = x;
|
out[savename] = x;
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
},
|
}
|
||||||
.load_sram = [](std::map<std::string, std::vector<char>>& sram) -> void {
|
void c_load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc) {
|
||||||
std::set<std::string> used;
|
std::set<std::string> used;
|
||||||
if(!internal_rom) {
|
if(!internal_rom) {
|
||||||
for(auto i : sram)
|
for(auto i : sram)
|
||||||
|
@ -732,15 +621,15 @@ namespace
|
||||||
if(!used.count(i.first))
|
if(!used.count(i.first))
|
||||||
messages << "WARNING: SRAM '" << i.first << ": Not found on cartridge."
|
messages << "WARNING: SRAM '" << i.first << ": Not found on cartridge."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
},
|
}
|
||||||
.serialize = [](std::vector<char>& out) -> void {
|
void c_serialize(std::vector<char>& out) {
|
||||||
if(!internal_rom)
|
if(!internal_rom)
|
||||||
throw std::runtime_error("No ROM loaded");
|
throw std::runtime_error("No ROM loaded");
|
||||||
serializer s = SNES::system.serialize();
|
serializer s = SNES::system.serialize();
|
||||||
out.resize(s.size());
|
out.resize(s.size());
|
||||||
memcpy(&out[0], s.data(), 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)
|
if(!internal_rom)
|
||||||
throw std::runtime_error("No ROM loaded");
|
throw std::runtime_error("No ROM loaded");
|
||||||
serializer s(reinterpret_cast<const uint8_t*>(in), insize);
|
serializer s(reinterpret_cast<const uint8_t*>(in), insize);
|
||||||
|
@ -748,31 +637,31 @@ namespace
|
||||||
throw std::runtime_error("SNES core rejected savestate");
|
throw std::runtime_error("SNES core rejected savestate");
|
||||||
have_saved_this_frame = true;
|
have_saved_this_frame = true;
|
||||||
do_reset_flag = -1;
|
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;
|
return (SNES::system.region() == SNES::System::Region::PAL) ? region_pal : region_ntsc;
|
||||||
},
|
}
|
||||||
.power = []() -> void {
|
void c_power() {
|
||||||
if(internal_rom) snes_power();
|
if(internal_rom) snes_power();
|
||||||
},
|
}
|
||||||
.unload_cartridge = []() -> void {
|
void c_unload_cartridge() {
|
||||||
if(!internal_rom) return;
|
if(!internal_rom) return;
|
||||||
snes_term();
|
snes_term();
|
||||||
snes_unload_cartridge();
|
snes_unload_cartridge();
|
||||||
internal_rom = NULL;
|
internal_rom = NULL;
|
||||||
},
|
}
|
||||||
.get_scale_factors = [](uint32_t width, uint32_t height) -> std::pair<uint32_t, uint32_t> {
|
std::pair<uint32_t, uint32_t> c_get_scale_factors(uint32_t width, uint32_t height) {
|
||||||
return std::make_pair((width < 400) ? 2 : 1, (height < 400) ? 2 : 1);
|
return std::make_pair((width < 400) ? 2 : 1, (height < 400) ? 2 : 1);
|
||||||
},
|
}
|
||||||
.install_handler = []() -> void {
|
void c_install_handler() {
|
||||||
basic_init();
|
basic_init();
|
||||||
old = SNES::interface;
|
old = SNES::interface;
|
||||||
SNES::interface = &my_interface_obj;
|
SNES::interface = &my_interface_obj;
|
||||||
SNES::system.init();
|
SNES::system.init();
|
||||||
magic_flags |= 1;
|
magic_flags |= 1;
|
||||||
},
|
}
|
||||||
.uninstall_handler = []() -> void { SNES::interface = old; },
|
void c_uninstall_handler() { SNES::interface = old; }
|
||||||
.emulate = []() -> void {
|
void c_emulate() {
|
||||||
if(!internal_rom)
|
if(!internal_rom)
|
||||||
return;
|
return;
|
||||||
bool was_delay_reset = false;
|
bool was_delay_reset = false;
|
||||||
|
@ -856,32 +745,31 @@ again2:
|
||||||
SNES::cpu.step_event = nall::function<bool()>();
|
SNES::cpu.step_event = nall::function<bool()>();
|
||||||
#endif
|
#endif
|
||||||
have_saved_this_frame = false;
|
have_saved_this_frame = false;
|
||||||
},
|
}
|
||||||
.runtosave = []() -> void {
|
void c_runtosave() {
|
||||||
if(!internal_rom)
|
if(!internal_rom)
|
||||||
return;
|
return;
|
||||||
stepping_into_save = true;
|
stepping_into_save = true;
|
||||||
SNES::system.runtosave();
|
SNES::system.runtosave();
|
||||||
have_saved_this_frame = true;
|
have_saved_this_frame = true;
|
||||||
stepping_into_save = false;
|
stepping_into_save = false;
|
||||||
},
|
}
|
||||||
.get_pflag = []() -> bool { return SNES::cpu.controller_flag; },
|
bool c_get_pflag() { return SNES::cpu.controller_flag; }
|
||||||
.set_pflag = [](bool pflag) -> void { SNES::cpu.controller_flag = pflag; },
|
void c_set_pflag(bool pflag) { SNES::cpu.controller_flag = pflag; }
|
||||||
.port_types = port_types,
|
framebuffer_raw& c_draw_cover() {
|
||||||
.draw_cover = []() -> framebuffer_raw& {
|
|
||||||
static framebuffer_raw x(cover_fbinfo);
|
static framebuffer_raw x(cover_fbinfo);
|
||||||
redraw_cover_fbinfo();
|
redraw_cover_fbinfo();
|
||||||
return x;
|
return x;
|
||||||
},
|
}
|
||||||
.get_core_shortname = []() -> std::string
|
std::string c_get_core_shortname()
|
||||||
{
|
{
|
||||||
#ifdef BSNES_IS_COMPAT
|
#ifdef BSNES_IS_COMPAT
|
||||||
return (stringfmt() << "bsnes" << BSNES_VERSION << "c").str();
|
return (stringfmt() << "bsnes" << BSNES_VERSION << "c").str();
|
||||||
#else
|
#else
|
||||||
return (stringfmt() << "bsnes" << BSNES_VERSION << "a").str();
|
return (stringfmt() << "bsnes" << BSNES_VERSION << "a").str();
|
||||||
#endif
|
#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);
|
cf.axis3(0, 0, 1, (do_reset_flag >= 0) ? 1 : 0);
|
||||||
if(support_hreset)
|
if(support_hreset)
|
||||||
|
@ -893,8 +781,8 @@ again2:
|
||||||
cf.axis3(0, 0, 2, 0);
|
cf.axis3(0, 0, 2, 0);
|
||||||
cf.axis3(0, 0, 3, 0);
|
cf.axis3(0, 0, 3, 0);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
.execute_action = [](unsigned id, const std::vector<interface_action_paramval>& p) -> void
|
void c_execute_action(unsigned id, const std::vector<interface_action_paramval>& p)
|
||||||
{
|
{
|
||||||
switch(id) {
|
switch(id) {
|
||||||
case 0: //Soft reset.
|
case 0: //Soft reset.
|
||||||
|
@ -914,67 +802,281 @@ again2:
|
||||||
do_hreset_flag = true;
|
do_hreset_flag = true;
|
||||||
break;
|
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{{
|
interface_action act_reset(bsnes_core, 0, "Soft reset", "reset", {});
|
||||||
.iname = "snes", .hname = "SNES", .id = 0, .sysname = "SNES",
|
interface_action act_hreset(bsnes_core, 1, "Hard reset", "hardreset", {});
|
||||||
.load_rom = [](core_romimage* img, std::map<std::string, std::string>& settings, uint64_t secs,
|
#ifdef BSNES_HAS_DEBUGGER
|
||||||
uint64_t subsecs) -> int {
|
interface_action act_dreset(bsnes_core, 2, "Delayed soft reset", "delayreset", {{"Delay","int:0,99999999"}});
|
||||||
return load_rom<&type_snes>(img, settings, secs, subsecs,
|
interface_action act_dhreset(bsnes_core, 3, "Delayed hard reset", "delayhardreset",
|
||||||
load_rom_X1<snes_load_cartridge_normal>);
|
{{"Delay","int:0,99999999"}});
|
||||||
},
|
#endif
|
||||||
.controllerconfig = _controllerconfig, .extensions = "sfc;smc;swc;fig;ufo;sf2;gd3;gd7;dx2;mgd;mgh",
|
|
||||||
.bios = NULL, .regions = snes_regions, .images = snes_images,
|
struct _type_snes : public core_type
|
||||||
.settings = &bsnes_settings, .core = &bsnes_core, .get_bus_map = bsnes_get_bus_map,
|
{
|
||||||
.vma_list = get_VMAlist, .srams = srams
|
_type_snes() : core_type({{
|
||||||
}};
|
.iname = "snes",
|
||||||
core_type type_bsx{{
|
.hname = "SNES",
|
||||||
.iname = "bsx", .hname = "BS-X (non-slotted)", .id = 1, .sysname = "BS-X",
|
.id = 0,
|
||||||
.load_rom = [](core_romimage* img, std::map<std::string, std::string>& settings, uint64_t secs,
|
.sysname = "SNES",
|
||||||
uint64_t subsecs) -> int {
|
.extensions = "sfc;smc;swc;fig;ufo;sf2;gd3;gd7;dx2;mgd;mgh",
|
||||||
return load_rom<&type_bsx>(img, settings, secs, subsecs,
|
.bios = NULL,
|
||||||
load_rom_X2<snes_load_cartridge_bsx>);
|
.regions = {®ion_auto, ®ion_ntsc, ®ion_pal},
|
||||||
},
|
.images = snes_images,
|
||||||
.controllerconfig = _controllerconfig, .extensions = "bs", .bios = "bsx.sfc", .regions = bsx_regions,
|
.settings = &bsnes_settings,
|
||||||
.images = bsx_images, .settings = &bsnes_settings, .core = &bsnes_core,
|
.core = &bsnes_core,
|
||||||
.get_bus_map = bsnes_get_bus_map, .vma_list = get_VMAlist, .srams = srams
|
}}) {}
|
||||||
}};
|
int t_load_rom(core_romimage* img, std::map<std::string, std::string>& settings,
|
||||||
core_type type_bsxslotted{{
|
uint64_t secs, uint64_t subsecs)
|
||||||
.iname = "bsxslotted", .hname = "BS-X (slotted)", .id = 2, .sysname = "BS-X",
|
|
||||||
.load_rom = [](core_romimage* img, std::map<std::string, std::string>& settings,
|
|
||||||
uint64_t secs, uint64_t subsecs) -> int {
|
|
||||||
return load_rom<&type_bsxslotted>(img, settings, secs, subsecs,
|
|
||||||
load_rom_X2<snes_load_cartridge_bsx_slotted>);
|
|
||||||
},
|
|
||||||
.controllerconfig = _controllerconfig, .extensions = "bss", .bios = "bsxslotted.sfc",
|
|
||||||
.regions = bsxs_regions, .images = bsxs_images, .settings = &bsnes_settings, .core = &bsnes_core,
|
|
||||||
.get_bus_map = bsnes_get_bus_map, .vma_list = get_VMAlist, .srams = srams
|
|
||||||
}};
|
|
||||||
core_type type_sufamiturbo{{
|
|
||||||
.iname = "sufamiturbo", .hname = "Sufami Turbo", .id = 3, .sysname = "SufamiTurbo",
|
|
||||||
.load_rom = [](core_romimage* img, std::map<std::string, std::string>& settings, uint64_t secs,
|
|
||||||
uint64_t subsecs) -> int {
|
|
||||||
return load_rom<&type_sufamiturbo>(img, settings, secs, subsecs,
|
|
||||||
load_rom_X3<snes_load_cartridge_sufami_turbo>);
|
|
||||||
},
|
|
||||||
.controllerconfig = _controllerconfig, .extensions = "st", .bios = "sufamiturbo.sfc",
|
|
||||||
.regions = sufamiturbo_regions, .images = sufamiturbo_images, .settings = &bsnes_settings,
|
|
||||||
.core = &bsnes_core, .get_bus_map = bsnes_get_bus_map, .vma_list = get_VMAlist, .srams = srams
|
|
||||||
}};
|
|
||||||
core_type type_sgb{{
|
|
||||||
.iname = "sgb", .hname = "Super Game Boy", .id = 4, .sysname = "SGB",
|
|
||||||
.load_rom = [](core_romimage* img, std::map<std::string, std::string>& settings, uint64_t secs,
|
|
||||||
uint64_t subsecs) -> int
|
|
||||||
{
|
{
|
||||||
return load_rom<&type_sgb>(img, settings, secs, subsecs,
|
return load_rom(this, img, settings, secs, subsecs,
|
||||||
|
load_rom_X1<snes_load_cartridge_normal>);
|
||||||
|
}
|
||||||
|
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
|
||||||
|
{
|
||||||
|
return bsnes_controllerconfig(settings);
|
||||||
|
}
|
||||||
|
std::pair<uint64_t, uint64_t> t_get_bus_map() { return bsnes_get_bus_map(); }
|
||||||
|
std::list<core_vma_info> t_vma_list() { return get_VMAlist(); }
|
||||||
|
std::set<std::string> t_srams() { return bsnes_srams(); }
|
||||||
|
} type_snes;
|
||||||
|
core_sysregion snes_pal("snes_pal", type_snes, region_pal);
|
||||||
|
core_sysregion snes_ntsc("snes_ntsc", type_snes, region_ntsc);
|
||||||
|
|
||||||
|
struct _type_bsx : public core_type
|
||||||
|
{
|
||||||
|
_type_bsx() : core_type({{
|
||||||
|
.iname = "bsx",
|
||||||
|
.hname = "BS-X (non-slotted)",
|
||||||
|
.id = 1,
|
||||||
|
.sysname = "BS-X",
|
||||||
|
.extensions = "bs",
|
||||||
|
.bios = "bsx.sfc",
|
||||||
|
.regions = {®ion_ntsc},
|
||||||
|
.images = bsx_images,
|
||||||
|
.settings = &bsnes_settings,
|
||||||
|
.core = &bsnes_core,
|
||||||
|
}}) {}
|
||||||
|
int t_load_rom(core_romimage* img, std::map<std::string, std::string>& settings,
|
||||||
|
uint64_t secs, uint64_t subsecs)
|
||||||
|
{
|
||||||
|
return load_rom(this, img, settings, secs, subsecs,
|
||||||
|
load_rom_X2<snes_load_cartridge_bsx>);
|
||||||
|
}
|
||||||
|
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
|
||||||
|
{
|
||||||
|
return bsnes_controllerconfig(settings);
|
||||||
|
}
|
||||||
|
std::pair<uint64_t, uint64_t> t_get_bus_map() { return bsnes_get_bus_map(); }
|
||||||
|
std::list<core_vma_info> t_vma_list() { return get_VMAlist(); }
|
||||||
|
std::set<std::string> t_srams() { return bsnes_srams(); }
|
||||||
|
} type_bsx;
|
||||||
|
core_sysregion bsx_sr("bsx", type_bsx, region_ntsc);
|
||||||
|
|
||||||
|
struct _type_bsxslotted : public core_type
|
||||||
|
{
|
||||||
|
_type_bsxslotted() : core_type({{
|
||||||
|
.iname = "bsxslotted",
|
||||||
|
.hname = "BS-X (slotted)",
|
||||||
|
.id = 2,
|
||||||
|
.sysname = "BS-X",
|
||||||
|
.extensions = "bss",
|
||||||
|
.bios = "bsxslotted.sfc",
|
||||||
|
.regions = {®ion_ntsc},
|
||||||
|
.images = bsxs_images,
|
||||||
|
.settings = &bsnes_settings,
|
||||||
|
.core = &bsnes_core,
|
||||||
|
}}) {}
|
||||||
|
int t_load_rom(core_romimage* img, std::map<std::string, std::string>& settings,
|
||||||
|
uint64_t secs, uint64_t subsecs)
|
||||||
|
{
|
||||||
|
return load_rom(this, img, settings, secs, subsecs,
|
||||||
|
load_rom_X2<snes_load_cartridge_bsx_slotted>);
|
||||||
|
}
|
||||||
|
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
|
||||||
|
{
|
||||||
|
return bsnes_controllerconfig(settings);
|
||||||
|
}
|
||||||
|
std::pair<uint64_t, uint64_t> t_get_bus_map() { return bsnes_get_bus_map(); }
|
||||||
|
std::list<core_vma_info> t_vma_list() { return get_VMAlist(); }
|
||||||
|
std::set<std::string> t_srams() { return bsnes_srams(); }
|
||||||
|
} type_bsxslotted;
|
||||||
|
core_sysregion bsxslotted_sr("bsxslotted", type_bsxslotted, region_ntsc);
|
||||||
|
|
||||||
|
struct _type_sufamiturbo : public core_type
|
||||||
|
{
|
||||||
|
_type_sufamiturbo() : core_type({{
|
||||||
|
.iname = "sufamiturbo",
|
||||||
|
.hname = "Sufami Turbo",
|
||||||
|
.id = 3,
|
||||||
|
.sysname = "SufamiTurbo",
|
||||||
|
.extensions = "st",
|
||||||
|
.bios = "sufamiturbo.sfc",
|
||||||
|
.regions = {®ion_ntsc},
|
||||||
|
.images = sufamiturbo_images,
|
||||||
|
.settings = &bsnes_settings,
|
||||||
|
.core = &bsnes_core,
|
||||||
|
}}) {}
|
||||||
|
int t_load_rom(core_romimage* img, std::map<std::string, std::string>& settings,
|
||||||
|
uint64_t secs, uint64_t subsecs)
|
||||||
|
{
|
||||||
|
return load_rom(this, img, settings, secs, subsecs,
|
||||||
|
load_rom_X3<snes_load_cartridge_sufami_turbo>);
|
||||||
|
}
|
||||||
|
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
|
||||||
|
{
|
||||||
|
return bsnes_controllerconfig(settings);
|
||||||
|
}
|
||||||
|
std::pair<uint64_t, uint64_t> t_get_bus_map() { return bsnes_get_bus_map(); }
|
||||||
|
std::list<core_vma_info> t_vma_list() { return get_VMAlist(); }
|
||||||
|
std::set<std::string> t_srams() { return bsnes_srams(); }
|
||||||
|
} type_sufamiturbo;
|
||||||
|
core_sysregion sufamiturbo_sr("sufamiturbo", type_sufamiturbo, region_ntsc);
|
||||||
|
|
||||||
|
struct _type_sgb : public core_type
|
||||||
|
{
|
||||||
|
_type_sgb() : core_type({{
|
||||||
|
.iname = "sgb",
|
||||||
|
.hname = "Super Game Boy",
|
||||||
|
.id = 4,
|
||||||
|
.sysname = "SGB",
|
||||||
|
.extensions = "gb;dmg;sgb",
|
||||||
|
.bios = "sgb.sfc",
|
||||||
|
.regions = {®ion_auto, ®ion_ntsc, ®ion_pal},
|
||||||
|
.images = sgb_images,
|
||||||
|
.settings = &bsnes_settings,
|
||||||
|
.core = &bsnes_core,
|
||||||
|
}}) {}
|
||||||
|
int t_load_rom(core_romimage* img, std::map<std::string, std::string>& settings,
|
||||||
|
uint64_t secs, uint64_t subsecs)
|
||||||
|
{
|
||||||
|
return load_rom(this, img, settings, secs, subsecs,
|
||||||
load_rom_X2<snes_load_cartridge_super_game_boy>);
|
load_rom_X2<snes_load_cartridge_super_game_boy>);
|
||||||
},
|
}
|
||||||
.controllerconfig = _controllerconfig, .extensions = "gb;dmg;sgb", .bios = "sgb.sfc",
|
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
|
||||||
.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
|
return bsnes_controllerconfig(settings);
|
||||||
}};
|
}
|
||||||
|
std::pair<uint64_t, uint64_t> t_get_bus_map() { return bsnes_get_bus_map(); }
|
||||||
|
std::list<core_vma_info> t_vma_list() { return get_VMAlist(); }
|
||||||
|
std::set<std::string> t_srams() { return bsnes_srams(); }
|
||||||
|
} type_sgb;
|
||||||
|
core_sysregion sgb_pal("sgb_pal", type_sgb, region_pal);
|
||||||
|
core_sysregion sgb_ntsc("sgb_ntsc", type_sgb, region_ntsc);
|
||||||
|
|
||||||
|
void redraw_cover_fbinfo()
|
||||||
|
{
|
||||||
|
for(size_t i = 0; i < sizeof(cover_fbmem) / sizeof(cover_fbmem[0]); i++)
|
||||||
|
cover_fbmem[i] = 0;
|
||||||
|
std::string ident = bsnes_core.get_core_identifier();
|
||||||
|
cover_render_string(cover_fbmem, 0, 0, ident, 0x7FFFF, 0x00000, 512, 448, 2048, 4);
|
||||||
|
std::ostringstream name;
|
||||||
|
name << "Internal ROM name: ";
|
||||||
|
for(unsigned i = 0; i < 21; i++) {
|
||||||
|
unsigned busaddr = 0x00FFC0 + i;
|
||||||
|
unsigned char ch = SNES::bus.read(busaddr);
|
||||||
|
if(ch < 32 || ch > 126)
|
||||||
|
name << "<" << hexes[ch / 16] << hexes[ch % 16] << ">";
|
||||||
|
else
|
||||||
|
name << ch;
|
||||||
|
}
|
||||||
|
cover_render_string(cover_fbmem, 0, 16, name.str(), 0x7FFFF, 0x00000, 512, 448, 2048, 4);
|
||||||
|
unsigned y = 32;
|
||||||
|
for(auto i : cover_information()) {
|
||||||
|
cover_render_string(cover_fbmem, 0, y, i, 0x7FFFF, 0x00000, 512, 448, 2048, 4);
|
||||||
|
y += 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void my_interface::videoRefresh(const uint32_t* data, bool hires, bool interlace, bool overscan)
|
||||||
|
{
|
||||||
|
last_hires = hires;
|
||||||
|
last_interlace = interlace;
|
||||||
|
bool region = (SNES::system.region() == SNES::System::Region::PAL);
|
||||||
|
if(stepping_into_save)
|
||||||
|
messages << "Got video refresh in runtosave, expect desyncs!" << std::endl;
|
||||||
|
video_refresh_done = true;
|
||||||
|
uint32_t fps_n, fps_d;
|
||||||
|
auto fps = bsnes_core.get_video_rate();
|
||||||
|
fps_n = fps.first;
|
||||||
|
fps_d = fps.second;
|
||||||
|
uint32_t g = gcd(fps_n, fps_d);
|
||||||
|
fps_n /= g;
|
||||||
|
fps_d /= g;
|
||||||
|
|
||||||
|
framebuffer_info inf;
|
||||||
|
inf.type = &_pixel_format_lrgb;
|
||||||
|
inf.mem = const_cast<char*>(reinterpret_cast<const char*>(data));
|
||||||
|
inf.physwidth = 512;
|
||||||
|
inf.physheight = 512;
|
||||||
|
inf.physstride = 2048;
|
||||||
|
inf.width = hires ? 512 : 256;
|
||||||
|
inf.height = (region ? 239 : 224) * (interlace ? 2 : 1);
|
||||||
|
inf.stride = interlace ? 2048 : 4096;
|
||||||
|
inf.offset_x = 0;
|
||||||
|
inf.offset_y = (region ? (overscan ? 9 : 1) : (overscan ? 16 : 9)) * 2;
|
||||||
|
framebuffer_raw ls(inf);
|
||||||
|
|
||||||
|
ecore_callbacks->output_frame(ls, fps_n, fps_d);
|
||||||
|
information_dispatch::do_raw_frame(data, hires, interlace, overscan, region ?
|
||||||
|
VIDEO_REGION_PAL : VIDEO_REGION_NTSC);
|
||||||
|
if(soundbuf_fill > 0) {
|
||||||
|
auto freq = SNES::system.apu_frequency();
|
||||||
|
audioapi_submit_buffer(soundbuf, soundbuf_fill / 2, true, freq / 768.0);
|
||||||
|
soundbuf_fill = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<core_vma_info> get_VMAlist()
|
||||||
|
{
|
||||||
|
std::list<core_vma_info> ret;
|
||||||
|
if(!internal_rom)
|
||||||
|
return ret;
|
||||||
|
create_region(ret, "WRAM", 0x007E0000, SNES::cpu.wram, 131072, false);
|
||||||
|
create_region(ret, "APURAM", 0x00000000, SNES::smp.apuram, 65536, false);
|
||||||
|
create_region(ret, "VRAM", 0x00010000, SNES::ppu.vram, 65536, false);
|
||||||
|
create_region(ret, "OAM", 0x00020000, SNES::ppu.oam, 544, false);
|
||||||
|
create_region(ret, "CGRAM", 0x00021000, SNES::ppu.cgram, 512, false);
|
||||||
|
if(SNES::cartridge.has_srtc()) create_region(ret, "RTC", 0x00022000, SNES::srtc.rtc, 20, false);
|
||||||
|
if(SNES::cartridge.has_spc7110rtc()) create_region(ret, "RTC", 0x00022000, SNES::spc7110.rtc, 20,
|
||||||
|
false);
|
||||||
|
if(SNES::cartridge.has_necdsp()) {
|
||||||
|
create_region(ret, "DSPRAM", 0x00023000, reinterpret_cast<uint8_t*>(SNES::necdsp.dataRAM),
|
||||||
|
4096, false, true);
|
||||||
|
create_region(ret, "DSPPROM", 0xF0000000, reinterpret_cast<uint8_t*>(SNES::necdsp.programROM),
|
||||||
|
65536, true, true);
|
||||||
|
create_region(ret, "DSPDROM", 0xF0010000, reinterpret_cast<uint8_t*>(SNES::necdsp.dataROM),
|
||||||
|
4096, true, true);
|
||||||
|
}
|
||||||
|
create_region(ret, "SRAM", 0x10000000, SNES::cartridge.ram, false);
|
||||||
|
create_region(ret, "ROM", 0x80000000, SNES::cartridge.rom, true);
|
||||||
|
create_region(ret, "BUS", 0x1000000, 0x1000000, snes_bus_iospace_rw);
|
||||||
|
create_region(ret, "PTRTABLE", 0x100000000, 0x100000, ptrtable_iospace_rw);
|
||||||
|
map_internal(ret, "CPU_STATE", 0, &SNES::cpu, sizeof(SNES::cpu));
|
||||||
|
map_internal(ret, "PPU_STATE", 1, &SNES::ppu, sizeof(SNES::ppu));
|
||||||
|
map_internal(ret, "SMP_STATE", 2, &SNES::smp, sizeof(SNES::smp));
|
||||||
|
map_internal(ret, "DSP_STATE", 3, &SNES::dsp, sizeof(SNES::dsp));
|
||||||
|
if(internal_rom == &type_bsx || internal_rom == &type_bsxslotted) {
|
||||||
|
create_region(ret, "BSXFLASH", 0x90000000, SNES::bsxflash.memory, true);
|
||||||
|
create_region(ret, "BSX_RAM", 0x20000000, SNES::bsxcartridge.sram, false);
|
||||||
|
create_region(ret, "BSX_PRAM", 0x30000000, SNES::bsxcartridge.psram, false);
|
||||||
|
}
|
||||||
|
if(internal_rom == &type_sufamiturbo) {
|
||||||
|
create_region(ret, "SLOTA_ROM", 0x90000000, SNES::sufamiturbo.slotA.rom, true);
|
||||||
|
create_region(ret, "SLOTB_ROM", 0xA0000000, SNES::sufamiturbo.slotB.rom, true);
|
||||||
|
create_region(ret, "SLOTA_RAM", 0x20000000, SNES::sufamiturbo.slotA.ram, false);
|
||||||
|
create_region(ret, "SLOTB_RAM", 0x30000000, SNES::sufamiturbo.slotB.ram, false);
|
||||||
|
}
|
||||||
|
if(internal_rom == &type_sgb) {
|
||||||
|
create_region(ret, "GBROM", 0x90000000, GameBoy::cartridge.romdata,
|
||||||
|
GameBoy::cartridge.romsize, true);
|
||||||
|
create_region(ret, "GBRAM", 0x20000000, GameBoy::cartridge.ramdata,
|
||||||
|
GameBoy::cartridge.ramsize, false);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
function_ptr_command<arg_filename> dump_core(lsnes_cmd, "dump-core", "No description available",
|
function_ptr_command<arg_filename> dump_core(lsnes_cmd, "dump-core", "No description available",
|
||||||
"No description available\n",
|
"No description available\n",
|
||||||
|
|
|
@ -46,7 +46,6 @@ namespace
|
||||||
{
|
{
|
||||||
bool do_reset_flag = false;
|
bool do_reset_flag = false;
|
||||||
core_type* internal_rom = NULL;
|
core_type* internal_rom = NULL;
|
||||||
extern core_core gambatte_core;
|
|
||||||
bool rtc_fixed;
|
bool rtc_fixed;
|
||||||
time_t rtc_fixed_val;
|
time_t rtc_fixed_val;
|
||||||
gambatte::GB* instance;
|
gambatte::GB* instance;
|
||||||
|
@ -59,7 +58,6 @@ namespace
|
||||||
unsigned accumulator_s = 0;
|
unsigned accumulator_s = 0;
|
||||||
bool pflag = false;
|
bool pflag = false;
|
||||||
|
|
||||||
interface_action act_reset(gambatte_core, 0, "Soft reset", "reset", {});
|
|
||||||
|
|
||||||
struct interface_device_reg gb_registers[] = {
|
struct interface_device_reg gb_registers[] = {
|
||||||
{NULL, NULL, NULL}
|
{NULL, NULL, NULL}
|
||||||
|
@ -76,7 +74,6 @@ namespace
|
||||||
|
|
||||||
#include "ports.inc"
|
#include "ports.inc"
|
||||||
#include "slots.inc"
|
#include "slots.inc"
|
||||||
#include "regions.inc"
|
|
||||||
|
|
||||||
core_setting_group gambatte_settings;
|
core_setting_group gambatte_settings;
|
||||||
|
|
||||||
|
@ -161,7 +158,7 @@ namespace
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
controller_set _controllerconfig(std::map<std::string, std::string>& settings)
|
controller_set gambatte_controllerconfig(std::map<std::string, std::string>& settings)
|
||||||
{
|
{
|
||||||
std::map<std::string, std::string> _settings = settings;
|
std::map<std::string, std::string> _settings = settings;
|
||||||
controller_set r;
|
controller_set r;
|
||||||
|
@ -244,7 +241,7 @@ namespace
|
||||||
return vmas;
|
return vmas;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<std::string> srams()
|
std::set<std::string> gambatte_srams()
|
||||||
{
|
{
|
||||||
std::set<std::string> s;
|
std::set<std::string> s;
|
||||||
if(!internal_rom)
|
if(!internal_rom)
|
||||||
|
@ -270,27 +267,17 @@ namespace
|
||||||
return name.str();
|
return name.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void redraw_cover_fbinfo()
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
core_core gambatte_core{{
|
struct _gambatte_core : public core_core, public core_region
|
||||||
.core_identifier = []() -> std::string { return "libgambatte "+gambatte::GB::version(); },
|
{
|
||||||
.set_region = [](core_region& region) -> bool { return (®ion == ®ion_world); },
|
_gambatte_core() : core_core({{_port_types}}),
|
||||||
.video_rate = []() -> std::pair<uint32_t, uint32_t> { return std::make_pair(262144, 4389); },
|
core_region({{"world", "World", 0, 0, false, {4389, 262144}, {0}}}) {}
|
||||||
.audio_rate = []() -> std::pair<uint32_t, uint32_t> { return std::make_pair(32768, 1); },
|
std::string c_core_identifier() { return "libgambatte "+gambatte::GB::version(); }
|
||||||
.save_sram = []() -> std::map<std::string, std::vector<char>> {
|
bool c_set_region(core_region& region) { return (®ion == this); }
|
||||||
|
std::pair<uint32_t, uint32_t> c_video_rate() { return std::make_pair(262144, 4389); }
|
||||||
|
std::pair<uint32_t, uint32_t> c_audio_rate() { return std::make_pair(32768, 1); }
|
||||||
|
std::map<std::string, std::vector<char>> c_save_sram() throw(std::bad_alloc) {
|
||||||
std::map<std::string, std::vector<char>> s;
|
std::map<std::string, std::vector<char>> s;
|
||||||
if(!internal_rom)
|
if(!internal_rom)
|
||||||
return s;
|
return s;
|
||||||
|
@ -302,8 +289,8 @@ namespace
|
||||||
for(size_t i = 0; i < 8; i++)
|
for(size_t i = 0; i < 8; i++)
|
||||||
s["rtc"][i] = ((unsigned long long)timebase >> (8 * i));
|
s["rtc"][i] = ((unsigned long long)timebase >> (8 * i));
|
||||||
return s;
|
return s;
|
||||||
},
|
}
|
||||||
.load_sram = [](std::map<std::string, std::vector<char>>& sram) -> void {
|
void c_load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc) {
|
||||||
if(!internal_rom)
|
if(!internal_rom)
|
||||||
return;
|
return;
|
||||||
std::vector<char> x = sram.count("main") ? sram["main"] : std::vector<char>();
|
std::vector<char> x = sram.count("main") ? sram["main"] : std::vector<char>();
|
||||||
|
@ -321,8 +308,8 @@ namespace
|
||||||
timebase |= (unsigned long long)(unsigned char)x2[i] << (8 * i);
|
timebase |= (unsigned long long)(unsigned char)x2[i] << (8 * i);
|
||||||
instance->setRtcBase(timebase);
|
instance->setRtcBase(timebase);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
.serialize = [](std::vector<char>& out) -> void {
|
void c_serialize(std::vector<char>& out) {
|
||||||
if(!internal_rom)
|
if(!internal_rom)
|
||||||
throw std::runtime_error("Can't save without ROM");
|
throw std::runtime_error("Can't save without ROM");
|
||||||
instance->saveState(out);
|
instance->saveState(out);
|
||||||
|
@ -332,8 +319,8 @@ namespace
|
||||||
write32ube(&out[osize + 4 * i], primary_framebuffer[i]);
|
write32ube(&out[osize + 4 * i], primary_framebuffer[i]);
|
||||||
out.push_back(frame_overflow >> 8);
|
out.push_back(frame_overflow >> 8);
|
||||||
out.push_back(frame_overflow);
|
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)
|
if(!internal_rom)
|
||||||
throw std::runtime_error("Can't load without ROM");
|
throw std::runtime_error("Can't load without ROM");
|
||||||
size_t foffset = insize - 2 - 4 * sizeof(primary_framebuffer) /
|
size_t foffset = insize - 2 - 4 * sizeof(primary_framebuffer) /
|
||||||
|
@ -349,16 +336,16 @@ namespace
|
||||||
unsigned x2 = (unsigned char)in[insize - 1];
|
unsigned x2 = (unsigned char)in[insize - 1];
|
||||||
frame_overflow = x1 * 256 + x2;
|
frame_overflow = x1 * 256 + x2;
|
||||||
do_reset_flag = false;
|
do_reset_flag = false;
|
||||||
},
|
}
|
||||||
.get_region = []() -> core_region& { return region_world; },
|
core_region& c_get_region() { return *this; }
|
||||||
.power = []() -> void {},
|
void c_power() {}
|
||||||
.unload_cartridge = []() -> void {},
|
void c_unload_cartridge() {}
|
||||||
.get_scale_factors = [](uint32_t width, uint32_t height) -> std::pair<uint32_t, uint32_t> {
|
std::pair<uint32_t, uint32_t> c_get_scale_factors(uint32_t width, uint32_t height) {
|
||||||
return std::make_pair(max(512 / width, (uint32_t)1), max(448 / height, (uint32_t)1));
|
return std::make_pair(max(512 / width, (uint32_t)1), max(448 / height, (uint32_t)1));
|
||||||
},
|
}
|
||||||
.install_handler = []() -> void { magic_flags |= 2; },
|
void c_install_handler() { magic_flags |= 2; }
|
||||||
.uninstall_handler = []() -> void {},
|
void c_uninstall_handler() {}
|
||||||
.emulate = []() -> void {
|
void c_emulate() {
|
||||||
if(!internal_rom)
|
if(!internal_rom)
|
||||||
return;
|
return;
|
||||||
int16_t reset = ecore_callbacks->get_input(0, 0, 1);
|
int16_t reset = ecore_callbacks->get_input(0, 0, 1);
|
||||||
|
@ -412,61 +399,129 @@ namespace
|
||||||
|
|
||||||
framebuffer_raw ls(inf);
|
framebuffer_raw ls(inf);
|
||||||
ecore_callbacks->output_frame(ls, 262144, 4389);
|
ecore_callbacks->output_frame(ls, 262144, 4389);
|
||||||
},
|
}
|
||||||
.runtosave = []() -> void {},
|
void c_runtosave() {}
|
||||||
.get_pflag = []() -> bool { return pflag; },
|
bool c_get_pflag() { return pflag; }
|
||||||
.set_pflag = [](bool _pflag) -> void { pflag = _pflag; },
|
void c_set_pflag(bool _pflag) { pflag = _pflag; }
|
||||||
.port_types = port_types,
|
framebuffer_raw& c_draw_cover() {
|
||||||
.draw_cover = []() -> framebuffer_raw& {
|
|
||||||
static framebuffer_raw x(cover_fbinfo);
|
static framebuffer_raw x(cover_fbinfo);
|
||||||
redraw_cover_fbinfo();
|
redraw_cover_fbinfo();
|
||||||
return x;
|
return x;
|
||||||
},
|
}
|
||||||
.get_core_shortname = []() -> std::string { return "gambatte"+gambatte::GB::version(); },
|
std::string c_get_core_shortname() { return "gambatte"+gambatte::GB::version(); }
|
||||||
.pre_emulate_frame = [](controller_frame& cf) -> void {
|
void c_pre_emulate_frame(controller_frame& cf) {
|
||||||
cf.axis3(0, 0, 1, do_reset_flag ? 1 : 0);
|
cf.axis3(0, 0, 1, do_reset_flag ? 1 : 0);
|
||||||
},
|
}
|
||||||
.execute_action = [](unsigned id, const std::vector<interface_action_paramval>& p) -> void
|
void c_execute_action(unsigned id, const std::vector<interface_action_paramval>& p)
|
||||||
{
|
{
|
||||||
switch(id) {
|
switch(id) {
|
||||||
case 0: //Soft reset.
|
case 0: //Soft reset.
|
||||||
do_reset_flag = true;
|
do_reset_flag = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
.get_registers = []() -> const interface_device_reg* { return gb_registers; },
|
const interface_device_reg* c_get_registers() { return gb_registers; }
|
||||||
}};
|
} gambatte_core;
|
||||||
|
interface_action act_reset(gambatte_core, 0, "Soft reset", "reset", {});
|
||||||
core_type type_dmg{{
|
|
||||||
.iname = "dmg", .hname = "Game Boy", .id = 1, .sysname = "Gameboy",
|
struct _type_dmg : public core_type, public core_sysregion
|
||||||
.load_rom = [](core_romimage* img, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
|
{
|
||||||
uint64_t rtc_subsec) -> int {
|
_type_dmg() : core_type({{
|
||||||
return load_rom_common(img, gambatte::GB::FORCE_DMG, rtc_sec, rtc_subsec, &type_dmg);
|
.iname = "dmg",
|
||||||
},
|
.hname = "Game Boy",
|
||||||
.controllerconfig = _controllerconfig, .extensions = "gb;dmg", .bios = NULL, .regions = dmg_regions,
|
.id = 1,
|
||||||
.images = dmg_images, .settings = &gambatte_settings, .core = &gambatte_core,
|
.sysname = "Gameboy",
|
||||||
.get_bus_map = gambatte_bus_map, .vma_list = get_VMAlist, .srams = srams
|
.extensions = "gb;dmg",
|
||||||
}};
|
.bios = NULL,
|
||||||
core_type type_gbc{{
|
.regions = {&gambatte_core},
|
||||||
.iname = "gbc", .hname = "Game Boy Color", .id = 0, .sysname = "Gameboy",
|
.images = dmg_images,
|
||||||
.load_rom = [](core_romimage* img, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
|
.settings = &gambatte_settings,
|
||||||
uint64_t rtc_subsec) -> int {
|
.core = &gambatte_core,
|
||||||
return load_rom_common(img, 0, rtc_sec, rtc_subsec, &type_gbc);
|
}}), core_sysregion("gdmg", *this, gambatte_core) {}
|
||||||
},
|
int t_load_rom(core_romimage* img, std::map<std::string, std::string>& settings,
|
||||||
.controllerconfig = _controllerconfig, .extensions = "gbc;cgb", .bios = NULL, .regions = gbc_regions,
|
uint64_t secs, uint64_t subsecs)
|
||||||
.images = gbc_images, .settings = &gambatte_settings, .core = &gambatte_core,
|
{
|
||||||
.get_bus_map = gambatte_bus_map, .vma_list = get_VMAlist, .srams = srams
|
return load_rom_common(img, gambatte::GB::FORCE_DMG, secs, subsecs, this);
|
||||||
}};
|
}
|
||||||
core_type type_gbca{{
|
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
|
||||||
.iname = "gbc_gba", .hname = "Game Boy Color (GBA)", .id = 2, .sysname = "Gameboy",
|
{
|
||||||
.load_rom = [](core_romimage* img, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
|
return gambatte_controllerconfig(settings);
|
||||||
uint64_t rtc_subsec) -> int {
|
}
|
||||||
return load_rom_common(img, gambatte::GB::GBA_CGB, rtc_sec, rtc_subsec, &type_gbca);
|
std::pair<uint64_t, uint64_t> t_get_bus_map() { return gambatte_bus_map(); }
|
||||||
},
|
std::list<core_vma_info> t_vma_list() { return get_VMAlist(); }
|
||||||
.controllerconfig = _controllerconfig, .extensions = "", .bios = NULL, .regions = gbca_regions,
|
std::set<std::string> t_srams() { return gambatte_srams(); }
|
||||||
.images = gbca_images, .settings = &gambatte_settings, .core = &gambatte_core,
|
} type_dmg;
|
||||||
.get_bus_map = gambatte_bus_map, .vma_list = get_VMAlist, .srams = srams
|
|
||||||
}};
|
struct _type_gbc : public core_type, public core_sysregion
|
||||||
|
{
|
||||||
|
_type_gbc() : core_type({{
|
||||||
|
.iname = "gbc",
|
||||||
|
.hname = "Game Boy Color",
|
||||||
|
.id = 0,
|
||||||
|
.sysname = "Gameboy",
|
||||||
|
.extensions = "gbc;cgb",
|
||||||
|
.bios = NULL,
|
||||||
|
.regions = {&gambatte_core},
|
||||||
|
.images = gbc_images,
|
||||||
|
.settings = &gambatte_settings,
|
||||||
|
.core = &gambatte_core,
|
||||||
|
}}), core_sysregion("ggbc", *this, gambatte_core) {}
|
||||||
|
int t_load_rom(core_romimage* img, std::map<std::string, std::string>& settings,
|
||||||
|
uint64_t secs, uint64_t subsecs)
|
||||||
|
{
|
||||||
|
return load_rom_common(img, 0, secs, subsecs, this);
|
||||||
|
}
|
||||||
|
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
|
||||||
|
{
|
||||||
|
return gambatte_controllerconfig(settings);
|
||||||
|
}
|
||||||
|
std::pair<uint64_t, uint64_t> t_get_bus_map() { return gambatte_bus_map(); }
|
||||||
|
std::list<core_vma_info> t_vma_list() { return get_VMAlist(); }
|
||||||
|
std::set<std::string> t_srams() { return gambatte_srams(); }
|
||||||
|
} type_gbc;
|
||||||
|
|
||||||
|
struct _type_gbca : public core_type, public core_sysregion
|
||||||
|
{
|
||||||
|
_type_gbca() : core_type({{
|
||||||
|
.iname = "gbc_gba",
|
||||||
|
.hname = "Game Boy Color (GBA)",
|
||||||
|
.id = 2,
|
||||||
|
.sysname = "Gameboy",
|
||||||
|
.extensions = "",
|
||||||
|
.bios = NULL,
|
||||||
|
.regions = {&gambatte_core},
|
||||||
|
.images = gbca_images,
|
||||||
|
.settings = &gambatte_settings,
|
||||||
|
.core = &gambatte_core,
|
||||||
|
}}), core_sysregion("ggbca", *this, gambatte_core) {}
|
||||||
|
int t_load_rom(core_romimage* img, std::map<std::string, std::string>& settings,
|
||||||
|
uint64_t secs, uint64_t subsecs)
|
||||||
|
{
|
||||||
|
return load_rom_common(img, gambatte::GB::GBA_CGB, secs, subsecs, this);
|
||||||
|
}
|
||||||
|
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
|
||||||
|
{
|
||||||
|
return gambatte_controllerconfig(settings);
|
||||||
|
}
|
||||||
|
std::pair<uint64_t, uint64_t> t_get_bus_map() { return gambatte_bus_map(); }
|
||||||
|
std::list<core_vma_info> t_vma_list() { return get_VMAlist(); }
|
||||||
|
std::set<std::string> t_srams() { return gambatte_srams(); }
|
||||||
|
} type_gbca;
|
||||||
|
|
||||||
|
void redraw_cover_fbinfo()
|
||||||
|
{
|
||||||
|
for(size_t i = 0; i < sizeof(cover_fbmem) / sizeof(cover_fbmem[0]); i++)
|
||||||
|
cover_fbmem[i] = 0x00000000;
|
||||||
|
std::string ident = gambatte_core.get_core_identifier();
|
||||||
|
cover_render_string(cover_fbmem, 0, 0, ident, 0xFFFFFF, 0x00000, 480, 432, 1920, 4);
|
||||||
|
cover_render_string(cover_fbmem, 0, 16, "Internal ROM name: " + get_cartridge_name(),
|
||||||
|
0xFFFFFF, 0x00000, 480, 432, 1920, 4);
|
||||||
|
unsigned y = 32;
|
||||||
|
for(auto i : cover_information()) {
|
||||||
|
cover_render_string(cover_fbmem, 0, y, i, 0xFFFFFF, 0x000000, 480, 432, 1920, 4);
|
||||||
|
y += 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<char> cmp_save;
|
std::vector<char> cmp_save;
|
||||||
|
|
||||||
|
|
|
@ -263,7 +263,7 @@ for i = 1,#ports do
|
||||||
print("\t}");
|
print("\t}");
|
||||||
print("} "..port.symbol..";");
|
print("} "..port.symbol..";");
|
||||||
end
|
end
|
||||||
local s = "std::vector<port_type*> port_types{ ";
|
local s = "std::vector<port_type*> _port_types{ ";
|
||||||
for i = 1,#ports do
|
for i = 1,#ports do
|
||||||
s = s .."&"..ports[i].symbol..", ";
|
s = s .."&"..ports[i].symbol..", ";
|
||||||
end
|
end
|
||||||
|
|
|
@ -217,7 +217,7 @@ namespace sky
|
||||||
controller_info = &X2;
|
controller_info = &X2;
|
||||||
}
|
}
|
||||||
} psystem;
|
} psystem;
|
||||||
|
|
||||||
port_index_triple t(unsigned p, unsigned c, unsigned i, bool nl)
|
port_index_triple t(unsigned p, unsigned c, unsigned i, bool nl)
|
||||||
{
|
{
|
||||||
port_index_triple x;
|
port_index_triple x;
|
||||||
|
@ -228,56 +228,87 @@ namespace sky
|
||||||
return x;
|
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;
|
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}};
|
struct core_romimage_info skyzip{{"rom", "skyroads.zip", .mandatory = 1, .pass_mode = 1, .headersize = 0}};
|
||||||
|
|
||||||
extern struct core_core sky_core;
|
struct _sky_core : public core_core, public core_type, public core_region, public core_sysregion
|
||||||
|
{
|
||||||
struct core_core sky_core{{
|
_sky_core() : core_core({{{&psystem}}}), core_type({{
|
||||||
.core_identifier = []() -> std::string { return "Sky"; },
|
.iname = "sky",
|
||||||
.set_region = [](core_region& region) -> bool { return (®ion == &world_region); },
|
.hname = "Sky",
|
||||||
.video_rate = []() -> std::pair<uint32_t, uint32_t> { return std::make_pair(656250, 18227); },
|
.id = 3522,
|
||||||
.audio_rate = []() -> std::pair<uint32_t, uint32_t> { return std::make_pair(48000, 1); },
|
.sysname = "Sky",
|
||||||
.save_sram = []() -> std::map<std::string, std::vector<char>> {
|
.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<uint32_t, uint32_t> c_video_rate() { return std::make_pair(656250, 18227); }
|
||||||
|
std::pair<uint32_t, uint32_t> c_audio_rate() { return std::make_pair(48000, 1); }
|
||||||
|
std::map<std::string, std::vector<char>> c_save_sram() throw(std::bad_alloc) {
|
||||||
std::map<std::string, std::vector<char>> r;
|
std::map<std::string, std::vector<char>> r;
|
||||||
std::vector<char> sram;
|
std::vector<char> sram;
|
||||||
sram.resize(32);
|
sram.resize(32);
|
||||||
memcpy(&sram[0], _gstate.sram, 32);
|
memcpy(&sram[0], _gstate.sram, 32);
|
||||||
r["sram"] = sram;
|
r["sram"] = sram;
|
||||||
return r;
|
return r;
|
||||||
},
|
}
|
||||||
.load_sram = [](std::map<std::string, std::vector<char>>& sram) -> void {
|
void c_load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc) {
|
||||||
if(sram.count("sram") && sram["sram"].size() == 32)
|
if(sram.count("sram") && sram["sram"].size() == 32)
|
||||||
memcpy(_gstate.sram, &sram["sram"][0], 32);
|
memcpy(_gstate.sram, &sram["sram"][0], 32);
|
||||||
else
|
else
|
||||||
memset(_gstate.sram, 0, 32);
|
memset(_gstate.sram, 0, 32);
|
||||||
},
|
}
|
||||||
.serialize = [](std::vector<char>& out) -> void {
|
void c_serialize(std::vector<char>& out) {
|
||||||
auto wram = _gstate.as_ram();
|
auto wram = _gstate.as_ram();
|
||||||
out.resize(wram.second);
|
out.resize(wram.second);
|
||||||
memcpy(&out[0], wram.first, 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();
|
auto wram = _gstate.as_ram();
|
||||||
if(insize != wram.second)
|
if(insize != wram.second)
|
||||||
throw std::runtime_error("Save is of wrong size");
|
throw std::runtime_error("Save is of wrong size");
|
||||||
memcpy(wram.first, in, wram.second);
|
memcpy(wram.first, in, wram.second);
|
||||||
handle_loadstate(_gstate);
|
handle_loadstate(_gstate);
|
||||||
},
|
}
|
||||||
.get_region = []() -> core_region& { return world_region; },
|
core_region& c_get_region() { return *this; }
|
||||||
.power = []() -> void {},
|
void c_power() {}
|
||||||
.unload_cartridge = []() -> void {},
|
void c_unload_cartridge() {}
|
||||||
.get_scale_factors = [](uint32_t w, uint32_t h) -> std::pair<uint32_t, uint32_t> {
|
std::pair<uint32_t, uint32_t> c_get_scale_factors(uint32_t w, uint32_t h) {
|
||||||
return std::make_pair(FB_WIDTH / w, FB_HEIGHT / h);
|
return std::make_pair(FB_WIDTH / w, FB_HEIGHT / h);
|
||||||
},
|
}
|
||||||
.install_handler = []() -> void { sky_core.hide(); },
|
void c_install_handler() { hide(); }
|
||||||
.uninstall_handler = []() -> void {},
|
void c_uninstall_handler() {}
|
||||||
.emulate = []() -> void {
|
void c_emulate() {
|
||||||
static unsigned count[4];
|
static unsigned count[4];
|
||||||
static unsigned tcount[4] = {5, 7, 8, 25};
|
static unsigned tcount[4] = {5, 7, 8, 25};
|
||||||
uint16_t x = 0;
|
uint16_t x = 0;
|
||||||
|
@ -318,41 +349,21 @@ namespace sky
|
||||||
audioapi_submit_buffer(sbuf, samples, true, 48000);
|
audioapi_submit_buffer(sbuf, samples, true, 48000);
|
||||||
for(unsigned i = 0; i < samples; i++)
|
for(unsigned i = 0; i < samples; i++)
|
||||||
information_dispatch::do_sample(sbuf[2 * i + 0], sbuf[2 * i + 1]);
|
information_dispatch::do_sample(sbuf[2 * i + 0], sbuf[2 * i + 1]);
|
||||||
},
|
}
|
||||||
.runtosave = []() -> void {},
|
void c_runtosave() {}
|
||||||
.get_pflag = []() -> bool { return pflag; },
|
bool c_get_pflag() { return pflag; }
|
||||||
.set_pflag = [](bool _pflag) -> void { pflag = _pflag; },
|
void c_set_pflag(bool _pflag) { pflag = _pflag; }
|
||||||
.port_types = {&psystem},
|
framebuffer_raw& c_draw_cover() {
|
||||||
.draw_cover = []() -> framebuffer_raw& {
|
|
||||||
static framebuffer_raw x(cover_fbinfo);
|
static framebuffer_raw x(cover_fbinfo);
|
||||||
return x;
|
return x;
|
||||||
},
|
|
||||||
.get_core_shortname = []() -> std::string { return "sky"; },
|
|
||||||
.pre_emulate_frame = [](controller_frame& cf) -> void {},
|
|
||||||
.execute_action = [](unsigned id, const std::vector<interface_action_paramval>& p) -> void {},
|
|
||||||
.get_registers = []() -> const interface_device_reg* { return sky_registers; },
|
|
||||||
}};
|
|
||||||
|
|
||||||
void controller_magic()
|
|
||||||
{
|
|
||||||
if(magic_flags & 1) {
|
|
||||||
X2.controllers[1] = &A8;
|
|
||||||
cstyle = 1;
|
|
||||||
} else if(magic_flags & 2) {
|
|
||||||
X2.controllers[1] = &B8;
|
|
||||||
cstyle = 2;
|
|
||||||
} else if(magic_flags & 4) {
|
|
||||||
X2.controllers[1] = &C8;
|
|
||||||
cstyle = 2;
|
|
||||||
} else {
|
|
||||||
cstyle = 0;
|
|
||||||
}
|
}
|
||||||
}
|
std::string c_get_core_shortname() { return "sky"; }
|
||||||
|
void c_pre_emulate_frame(controller_frame& cf) {}
|
||||||
core_type skytype{{
|
void c_execute_action(unsigned id, const std::vector<interface_action_paramval>& p) {}
|
||||||
.iname = "sky", .hname = "Sky", .id = 3522, .sysname = "Sky",
|
const interface_device_reg* c_get_registers() { return sky_registers; }
|
||||||
.load_rom = [](core_romimage* images, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
|
int t_load_rom(core_romimage* images, std::map<std::string, std::string>& settings,
|
||||||
uint64_t rtc_subsec) -> int {
|
uint64_t rtc_sec, uint64_t rtc_subsec)
|
||||||
|
{
|
||||||
controller_magic();
|
controller_magic();
|
||||||
const unsigned char* _filename = images[0].data;
|
const unsigned char* _filename = images[0].data;
|
||||||
size_t size = images[0].size;
|
size_t size = images[0].size;
|
||||||
|
@ -366,8 +377,8 @@ namespace sky
|
||||||
rom_boot_vector(_gstate);
|
rom_boot_vector(_gstate);
|
||||||
ecore_callbacks->set_reset_actions(-1, -1);
|
ecore_callbacks->set_reset_actions(-1, -1);
|
||||||
return 0;
|
return 0;
|
||||||
},
|
}
|
||||||
.controllerconfig = [](std::map<std::string, std::string>& settings) -> controller_set
|
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
|
||||||
{
|
{
|
||||||
controller_magic();
|
controller_magic();
|
||||||
controller_set r;
|
controller_set r;
|
||||||
|
@ -378,13 +389,11 @@ namespace sky
|
||||||
r.portindex.logical_map.push_back(std::make_pair(0, 1));
|
r.portindex.logical_map.push_back(std::make_pair(0, 1));
|
||||||
r.portindex.pcid_map.push_back(std::make_pair(0, 1));
|
r.portindex.pcid_map.push_back(std::make_pair(0, 1));
|
||||||
return r;
|
return r;
|
||||||
},
|
}
|
||||||
.extensions = "sky", .bios = NULL, .regions = {&world_region}, .images = {&skyzip},
|
std::pair<uint64_t, uint64_t> t_get_bus_map() { return std::make_pair(0, 0); }
|
||||||
.settings = &sky_settings, .core = &sky_core,
|
std::list<core_vma_info> t_vma_list()
|
||||||
.get_bus_map = []() -> std::pair<uint64_t, uint64_t> { return std::make_pair(0, 0); },
|
{
|
||||||
.vma_list = []() -> std::list<core_vma_info> {
|
|
||||||
std::list<core_vma_info> r;
|
std::list<core_vma_info> r;
|
||||||
|
|
||||||
core_vma_info ram;
|
core_vma_info ram;
|
||||||
ram.name = "RAM";
|
ram.name = "RAM";
|
||||||
ram.backing_ram = _gstate.as_ram().first;
|
ram.backing_ram = _gstate.as_ram().first;
|
||||||
|
@ -394,14 +403,13 @@ namespace sky
|
||||||
ram.endian = 0;
|
ram.endian = 0;
|
||||||
ram.iospace_rw = NULL;
|
ram.iospace_rw = NULL;
|
||||||
r.push_back(ram);
|
r.push_back(ram);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
},
|
}
|
||||||
.srams = []() -> std::set<std::string> {
|
std::set<std::string> t_srams()
|
||||||
|
{
|
||||||
std::set<std::string> r;
|
std::set<std::string> r;
|
||||||
r.insert("sram");
|
r.insert("sram");
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}};
|
} sky_core;
|
||||||
core_sysregion X24("sky", skytype, world_region);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,6 @@ namespace
|
||||||
|
|
||||||
#include "ports.inc"
|
#include "ports.inc"
|
||||||
#include "slots.inc"
|
#include "slots.inc"
|
||||||
#include "regions.inc"
|
|
||||||
|
|
||||||
core_setting_group test_settings;
|
core_setting_group test_settings;
|
||||||
|
|
||||||
|
@ -72,7 +71,7 @@ namespace
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
controller_set _controllerconfig(std::map<std::string, std::string>& settings)
|
controller_set test_controllerconfig(std::map<std::string, std::string>& settings)
|
||||||
{
|
{
|
||||||
std::map<std::string, std::string> _settings = settings;
|
std::map<std::string, std::string> _settings = settings;
|
||||||
controller_set r;
|
controller_set r;
|
||||||
|
@ -125,29 +124,41 @@ namespace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern core_core test_core;
|
struct _test_core : public core_core, public core_type, public core_region, public core_sysregion
|
||||||
|
{
|
||||||
core_core test_core{{
|
_test_core() : core_core({{_port_types}}), core_type({{
|
||||||
.core_identifier = []() -> std::string { return "TEST"; },
|
.iname = "test",
|
||||||
.set_region = [](core_region& region) -> bool { return (®ion == ®ion_world); },
|
.hname = "test",
|
||||||
.video_rate = []() -> std::pair<uint32_t, uint32_t> { return std::make_pair(60, 1); },
|
.id = 0,
|
||||||
.audio_rate = []() -> std::pair<uint32_t, uint32_t> { return std::make_pair(48000, 1); },
|
.sysname = "Test",
|
||||||
.save_sram = []() -> std::map<std::string, std::vector<char>> {
|
.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<uint32_t, uint32_t> c_video_rate() { return std::make_pair(60, 1); }
|
||||||
|
std::pair<uint32_t, uint32_t> c_audio_rate() { return std::make_pair(48000, 1); }
|
||||||
|
std::map<std::string, std::vector<char>> c_save_sram() throw(std::bad_alloc) {
|
||||||
std::map<std::string, std::vector<char>> s;
|
std::map<std::string, std::vector<char>> s;
|
||||||
return s;
|
return s;
|
||||||
},
|
}
|
||||||
.load_sram = [](std::map<std::string, std::vector<char>>& sram) -> void {},
|
void c_load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc) {}
|
||||||
.serialize = [](std::vector<char>& out) -> void { out.clear(); },
|
void c_serialize(std::vector<char>& out) { out.clear(); }
|
||||||
.unserialize = [](const char* in, size_t insize) -> void {},
|
void c_unserialize(const char* in, size_t insize) {}
|
||||||
.get_region = []() -> core_region& { return region_world; },
|
core_region& c_get_region() { return *this; }
|
||||||
.power = []() -> void {},
|
void c_power() {}
|
||||||
.unload_cartridge = []() -> void {},
|
void c_unload_cartridge() {}
|
||||||
.get_scale_factors = [](uint32_t width, uint32_t height) -> std::pair<uint32_t, uint32_t> {
|
std::pair<uint32_t, uint32_t> c_get_scale_factors(uint32_t width, uint32_t height) {
|
||||||
return std::make_pair(max(512 / width, (uint32_t)1), max(448 / height, (uint32_t)1));
|
return std::make_pair(max(512 / width, (uint32_t)1), max(448 / height, (uint32_t)1));
|
||||||
},
|
}
|
||||||
.install_handler = []() -> void { test_core.hide(); },
|
void c_install_handler() { hide(); }
|
||||||
.uninstall_handler = []() -> void {},
|
void c_uninstall_handler() {}
|
||||||
.emulate = []() -> void {
|
void c_emulate() {
|
||||||
pflag = false;
|
pflag = false;
|
||||||
redraw_screen();
|
redraw_screen();
|
||||||
framebuffer_info inf;
|
framebuffer_info inf;
|
||||||
|
@ -163,30 +174,31 @@ namespace
|
||||||
inf.offset_y = 0;
|
inf.offset_y = 0;
|
||||||
framebuffer_raw ls(inf);
|
framebuffer_raw ls(inf);
|
||||||
ecore_callbacks->output_frame(ls, 60,1);
|
ecore_callbacks->output_frame(ls, 60,1);
|
||||||
},
|
}
|
||||||
.runtosave = []() -> void {},
|
void c_runtosave() {}
|
||||||
.get_pflag = []() -> bool { return pflag; },
|
bool c_get_pflag() { return pflag; }
|
||||||
.set_pflag = [](bool _pflag) -> void { pflag = _pflag; },
|
void c_set_pflag(bool _pflag) { pflag = _pflag; }
|
||||||
.port_types = port_types,
|
framebuffer_raw& c_draw_cover() {
|
||||||
.draw_cover = []() -> framebuffer_raw& {
|
|
||||||
static framebuffer_raw x(cover_fbinfo);
|
static framebuffer_raw x(cover_fbinfo);
|
||||||
redraw_cover_fbinfo();
|
redraw_cover_fbinfo();
|
||||||
return x;
|
return x;
|
||||||
},
|
}
|
||||||
.get_core_shortname = []() -> std::string { return "test"; },
|
std::string c_get_core_shortname() { return "test"; }
|
||||||
.pre_emulate_frame = [](controller_frame& cf) -> void {},
|
void c_pre_emulate_frame(controller_frame& cf) {}
|
||||||
.execute_action = [](unsigned id, const std::vector<interface_action_paramval>& p) -> void {},
|
void c_execute_action(unsigned id, const std::vector<interface_action_paramval>& p) {}
|
||||||
.get_registers = []() -> const interface_device_reg* { return test_registers; },
|
const interface_device_reg* c_get_registers() { return test_registers; }
|
||||||
}};
|
int t_load_rom(core_romimage* images, std::map<std::string, std::string>& settings,
|
||||||
|
uint64_t rtc_sec, uint64_t rtc_subsec)
|
||||||
core_type type_test{{
|
{
|
||||||
.iname = "test", .hname = "test", .id = 0, .sysname = "Test",
|
ecore_callbacks->set_reset_actions(-1, -1);
|
||||||
.load_rom = [](core_romimage* img, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
|
return 0;
|
||||||
uint64_t rtc_subsec) -> int { ecore_callbacks->set_reset_actions(-1, -1); return 0; },
|
}
|
||||||
.controllerconfig = _controllerconfig, .extensions = "test", .bios = NULL, .regions = test_regions,
|
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
|
||||||
.images = test_images, .settings = &test_settings, .core = &test_core,
|
{
|
||||||
.get_bus_map = []() -> std::pair<uint64_t, uint64_t> { return std::make_pair(0, 0); },
|
return test_controllerconfig(settings);
|
||||||
.vma_list = []() -> std::list<core_vma_info> { return std::list<core_vma_info>();},
|
}
|
||||||
.srams = []() -> std::set<std::string> { return std::set<std::string>();}
|
std::pair<uint64_t, uint64_t> t_get_bus_map() { return std::make_pair(0, 0); }
|
||||||
}};
|
std::list<core_vma_info> t_vma_list() { return std::list<core_vma_info>(); }
|
||||||
|
std::set<std::string> t_srams() { return std::set<std::string>(); }
|
||||||
|
} test_core;
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,11 +151,6 @@ core_type::core_type(const core_type_params& params)
|
||||||
hname = params.hname;
|
hname = params.hname;
|
||||||
sysname = params.sysname;
|
sysname = params.sysname;
|
||||||
id = params.id;
|
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;
|
core = params.core;
|
||||||
settings = params.settings;
|
settings = params.settings;
|
||||||
if(params.bios)
|
if(params.bios)
|
||||||
|
@ -245,7 +240,7 @@ core_region& core_type::get_preferred_region()
|
||||||
bool core_type::load(core_romimage* images, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
|
bool core_type::load(core_romimage* images, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
|
||||||
uint64_t rtc_subsec)
|
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)
|
core_sysregion& core_type::combine_region(core_region& reg)
|
||||||
|
@ -278,22 +273,22 @@ bool core_type::is_known_extension(const std::string& ext)
|
||||||
|
|
||||||
controller_set core_type::controllerconfig(std::map<std::string, std::string>& settings)
|
controller_set core_type::controllerconfig(std::map<std::string, std::string>& settings)
|
||||||
{
|
{
|
||||||
return _controllerconfig(settings);
|
return t_controllerconfig(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<uint64_t, uint64_t> core_type::get_bus_map()
|
std::pair<uint64_t, uint64_t> core_type::get_bus_map()
|
||||||
{
|
{
|
||||||
return _get_bus_map();
|
return t_get_bus_map();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<core_vma_info> core_type::vma_list()
|
std::list<core_vma_info> core_type::vma_list()
|
||||||
{
|
{
|
||||||
return _vma_list();
|
return t_vma_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<std::string> core_type::srams()
|
std::set<std::string> core_type::srams()
|
||||||
{
|
{
|
||||||
return _srams();
|
return t_srams();
|
||||||
}
|
}
|
||||||
|
|
||||||
core_sysregion::core_sysregion(const std::string& _name, core_type& _type, core_region& _region)
|
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)
|
core_core::core_core(const core_core_params& params)
|
||||||
: param_register_proxy(*this)
|
: 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;
|
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;
|
hidden = false;
|
||||||
all_cores_set().insert(this);
|
all_cores_set().insert(this);
|
||||||
if(install_handlers_automatically)
|
if(install_handlers_automatically)
|
||||||
install_handler();
|
install_handler();
|
||||||
new_core_flag = true;
|
new_core_flag = true;
|
||||||
register_queue<core_core::_param_register_proxy, interface_action>::do_ready(param_register_proxy, true);
|
register_queue<core_core::_param_register_proxy, interface_action>::do_ready(param_register_proxy, true);
|
||||||
if(!in_global_ctors())
|
|
||||||
messages << "Loaded core: " << _core_identifier() << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
core_core::~core_core() throw()
|
core_core::~core_core() throw()
|
||||||
|
@ -384,27 +354,27 @@ core_core::~core_core() throw()
|
||||||
|
|
||||||
std::string core_core::get_core_shortname()
|
std::string core_core::get_core_shortname()
|
||||||
{
|
{
|
||||||
return _get_core_shortname();
|
return c_get_core_shortname();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool core_core::set_region(core_region& region)
|
bool core_core::set_region(core_region& region)
|
||||||
{
|
{
|
||||||
return _set_region(region);
|
return c_set_region(region);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<uint32_t, uint32_t> core_core::get_video_rate()
|
std::pair<uint32_t, uint32_t> core_core::get_video_rate()
|
||||||
{
|
{
|
||||||
return _video_rate();
|
return c_video_rate();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<uint32_t, uint32_t> core_core::get_audio_rate()
|
std::pair<uint32_t, uint32_t> core_core::get_audio_rate()
|
||||||
{
|
{
|
||||||
return _audio_rate();
|
return c_audio_rate();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string core_core::get_core_identifier()
|
std::string core_core::get_core_identifier()
|
||||||
{
|
{
|
||||||
return _core_identifier();
|
return c_core_identifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<core_core*> core_core::all_cores()
|
std::set<core_core*> core_core::all_cores()
|
||||||
|
@ -428,92 +398,92 @@ void core_core::uninstall_all_handlers()
|
||||||
|
|
||||||
std::map<std::string, std::vector<char>> core_core::save_sram() throw(std::bad_alloc)
|
std::map<std::string, std::vector<char>> core_core::save_sram() throw(std::bad_alloc)
|
||||||
{
|
{
|
||||||
return _save_sram();
|
return c_save_sram();
|
||||||
}
|
}
|
||||||
|
|
||||||
void core_core::load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc)
|
void core_core::load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc)
|
||||||
{
|
{
|
||||||
_load_sram(sram);
|
c_load_sram(sram);
|
||||||
}
|
}
|
||||||
|
|
||||||
void core_core::serialize(std::vector<char>& out)
|
void core_core::serialize(std::vector<char>& out)
|
||||||
{
|
{
|
||||||
_serialize(out);
|
c_serialize(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void core_core::unserialize(const char* in, size_t insize)
|
void core_core::unserialize(const char* in, size_t insize)
|
||||||
{
|
{
|
||||||
_unserialize(in, insize);
|
c_unserialize(in, insize);
|
||||||
}
|
}
|
||||||
|
|
||||||
core_region& core_core::get_region()
|
core_region& core_core::get_region()
|
||||||
{
|
{
|
||||||
return _get_region();
|
return c_get_region();
|
||||||
}
|
}
|
||||||
|
|
||||||
void core_core::power()
|
void core_core::power()
|
||||||
{
|
{
|
||||||
_power();
|
c_power();
|
||||||
}
|
}
|
||||||
|
|
||||||
void core_core::unload_cartridge()
|
void core_core::unload_cartridge()
|
||||||
{
|
{
|
||||||
_unload_cartridge();
|
c_unload_cartridge();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<uint32_t, uint32_t> core_core::get_scale_factors(uint32_t width, uint32_t height)
|
std::pair<uint32_t, uint32_t> core_core::get_scale_factors(uint32_t width, uint32_t height)
|
||||||
{
|
{
|
||||||
return _get_scale_factors(width, height);
|
return c_get_scale_factors(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void core_core::install_handler()
|
void core_core::install_handler()
|
||||||
{
|
{
|
||||||
_install_handler();
|
c_install_handler();
|
||||||
}
|
}
|
||||||
|
|
||||||
void core_core::uninstall_handler()
|
void core_core::uninstall_handler()
|
||||||
{
|
{
|
||||||
_uninstall_handler();
|
c_uninstall_handler();
|
||||||
}
|
}
|
||||||
|
|
||||||
void core_core::emulate()
|
void core_core::emulate()
|
||||||
{
|
{
|
||||||
_emulate();
|
c_emulate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void core_core::runtosave()
|
void core_core::runtosave()
|
||||||
{
|
{
|
||||||
_runtosave();
|
c_runtosave();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool core_core::get_pflag()
|
bool core_core::get_pflag()
|
||||||
{
|
{
|
||||||
return _get_pflag();
|
return c_get_pflag();
|
||||||
}
|
}
|
||||||
|
|
||||||
void core_core::set_pflag(bool pflag)
|
void core_core::set_pflag(bool pflag)
|
||||||
{
|
{
|
||||||
return _set_pflag(pflag);
|
return c_set_pflag(pflag);
|
||||||
}
|
}
|
||||||
|
|
||||||
framebuffer_raw& core_core::draw_cover()
|
framebuffer_raw& core_core::draw_cover()
|
||||||
{
|
{
|
||||||
return _draw_cover();
|
return c_draw_cover();
|
||||||
}
|
}
|
||||||
|
|
||||||
void core_core::pre_emulate_frame(controller_frame& cf)
|
void core_core::pre_emulate_frame(controller_frame& cf)
|
||||||
{
|
{
|
||||||
_pre_emulate_frame(cf);
|
c_pre_emulate_frame(cf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void core_core::execute_action(unsigned id, const std::vector<interface_action_paramval>& p)
|
void core_core::execute_action(unsigned id, const std::vector<interface_action_paramval>& p)
|
||||||
{
|
{
|
||||||
return _execute_action(id, p);
|
return c_execute_action(id, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct interface_device_reg* core_core::get_registers()
|
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)
|
void core_core::do_register_action(const std::string& key, interface_action& act)
|
||||||
|
|
Loading…
Add table
Reference in a new issue