Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
|
77ee92e7c4 |
8 changed files with 421 additions and 382 deletions
|
@ -19,7 +19,7 @@ struct file_download
|
|||
file_download();
|
||||
~file_download();
|
||||
//Lauch.
|
||||
void do_async(loaded_rom& rom);
|
||||
void do_async(loadable_rom& rom);
|
||||
void cancel();
|
||||
//Status.
|
||||
volatile bool finished; //This signals download finishing, call finish().
|
||||
|
@ -29,7 +29,7 @@ struct file_download
|
|||
threads::cv cond;
|
||||
threads::lock m;
|
||||
//Internal.
|
||||
void _do_async(loaded_rom& rom);
|
||||
void _do_async(loadable_rom& rom);
|
||||
std::string tempname;
|
||||
std::string tempname2;
|
||||
};
|
||||
|
|
|
@ -123,7 +123,7 @@ struct emulator_instance
|
|||
master_dumper* mdumper;
|
||||
slotinfo_cache* slotcache;
|
||||
audioapi_instance* audio;
|
||||
loaded_rom* rom;
|
||||
loadable_rom* rom;
|
||||
save_jukebox* jukebox;
|
||||
emulator_runmode* runmode;
|
||||
status_updater* supdater;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
/**
|
||||
* \brief Emulator main loop.
|
||||
*/
|
||||
void main_loop(struct loaded_rom& rom, struct moviefile& settings, bool load_has_to_succeed = false)
|
||||
void main_loop(struct loadable_rom& rom, struct moviefile& settings, bool load_has_to_succeed = false)
|
||||
throw(std::bad_alloc, std::runtime_error);
|
||||
std::vector<std::string> get_jukebox_names();
|
||||
void set_jukebox_names(const std::vector<std::string>& newj);
|
||||
|
|
|
@ -28,15 +28,113 @@ struct rom_request
|
|||
bool canceled;
|
||||
};
|
||||
|
||||
struct loadable_rom;
|
||||
|
||||
/**
|
||||
* ROM loaded into memory.
|
||||
* An in-core emulation instance.
|
||||
*/
|
||||
struct loaded_rom
|
||||
struct incore_rom
|
||||
{
|
||||
/**
|
||||
* Saves core state into buffer. WARNING: This takes emulated time.
|
||||
*
|
||||
* returns: The saved state.
|
||||
* throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
std::vector<char> save_core_state(bool nochecksum = false) throw(std::bad_alloc, std::runtime_error);
|
||||
|
||||
/**
|
||||
* Loads core state from buffer.
|
||||
*
|
||||
* parameter buf: The buffer containing the state.
|
||||
* throws std::runtime_error: Loading state failed.
|
||||
*/
|
||||
void load_core_state(const std::vector<char>& buf, bool nochecksum = false) throw(std::runtime_error);
|
||||
/**
|
||||
* Get gametype of this ROM.
|
||||
*/
|
||||
core_sysregion& get_sysregion() { return cinst->from_type().combine_region(*region); }
|
||||
/**
|
||||
* Get internal region representation.
|
||||
*/
|
||||
core_region& get_internal_region() { return *region; }
|
||||
/**
|
||||
* Set internal region representation.
|
||||
*/
|
||||
//ROM methods.
|
||||
void set_internal_region(core_region& reg) { region = ® }
|
||||
std::map<std::string, std::vector<char>> save_sram() throw(std::bad_alloc) { return cinst->save_sram(); }
|
||||
void load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc)
|
||||
{
|
||||
cinst->load_sram(sram);
|
||||
}
|
||||
std::list<core_vma_info> vma_list() { return cinst->vma_list(); }
|
||||
framebuffer::raw& draw_cover() { return cinst->draw_cover(); }
|
||||
int reset_action(bool hard) { return cinst->reset_action(hard); }
|
||||
void pre_emulate_frame(portctrl::frame& cf) { return cinst->pre_emulate_frame(cf); }
|
||||
void emulate() { cinst->emulate(); }
|
||||
void runtosave() { cinst->runtosave(); }
|
||||
std::pair<uint32_t, uint32_t> get_audio_rate() { return cinst->get_audio_rate(); }
|
||||
void set_debug_flags(uint64_t addr, unsigned flags_set, unsigned flags_clear)
|
||||
{
|
||||
return cinst->set_debug_flags(addr, flags_set, flags_clear);
|
||||
}
|
||||
void set_cheat(uint64_t addr, uint64_t value, bool set)
|
||||
{
|
||||
return cinst->set_cheat(addr, value, set);
|
||||
}
|
||||
void debug_reset()
|
||||
{
|
||||
cinst->debug_reset();
|
||||
}
|
||||
std::pair<uint32_t, uint32_t> get_scale_factors(uint32_t width, uint32_t height)
|
||||
{
|
||||
return cinst->get_scale_factors(width, height);
|
||||
}
|
||||
std::vector<std::string> get_trace_cpus() { return cinst->get_trace_cpus(); }
|
||||
std::set<std::string> srams() { return cinst->srams(); }
|
||||
double get_PAR() { return cinst->get_PAR(); }
|
||||
unsigned action_flags(unsigned id) { return cinst->action_flags(id); }
|
||||
std::set<const interface_action*> get_actions() { return cinst->get_actions(); }
|
||||
void execute_action(unsigned id, const std::vector<interface_action_paramval>& p)
|
||||
{
|
||||
return cinst->execute_action(id, p);
|
||||
}
|
||||
std::pair<unsigned, unsigned> lightgun_scale() { return cinst->lightgun_scale(); }
|
||||
const interface_device_reg* get_registers() { return cinst->get_registers(); }
|
||||
bool get_pflag() { return cinst->get_pflag(); }
|
||||
void set_pflag(bool pflag) { cinst->set_pflag(pflag); }
|
||||
std::pair<uint64_t, uint64_t> get_bus_map() { return cinst->get_bus_map(); }
|
||||
const std::string& region_get_iname() { return region->get_iname(); }
|
||||
const std::string& region_get_hname() { return region->get_hname(); }
|
||||
double region_approx_framerate() { return region->approx_framerate(); }
|
||||
void region_fill_framerate_magic(uint64_t* magic) { region->fill_framerate_magic(magic); }
|
||||
void destroy();
|
||||
loadable_rom& orig_rom() { return *lrom; }
|
||||
private:
|
||||
/**
|
||||
* Loaded ROM this has been created from.
|
||||
*/
|
||||
loadable_rom* lrom;
|
||||
/**
|
||||
* ROM instance
|
||||
*/
|
||||
core_instance* cinst;
|
||||
/**
|
||||
* ROM region (this is the currently active region).
|
||||
*/
|
||||
core_region* region;
|
||||
};
|
||||
|
||||
/**
|
||||
* A Loadable ROM
|
||||
*/
|
||||
struct loadable_rom
|
||||
{
|
||||
/**
|
||||
* Create blank ROM
|
||||
*/
|
||||
loaded_rom() throw();
|
||||
loadable_rom() throw();
|
||||
/**
|
||||
* Take in ROM filename (or a bundle) and load it to memory.
|
||||
*
|
||||
|
@ -45,17 +143,17 @@ struct loaded_rom
|
|||
* throws std::bad_alloc: Not enough memory.
|
||||
* throws std::runtime_error: Loading ROM file failed.
|
||||
*/
|
||||
loaded_rom(const std::string& file, const std::string& tmpprefer = "") throw(std::bad_alloc,
|
||||
loadable_rom(const std::string& file, const std::string& tmpprefer = "") throw(std::bad_alloc,
|
||||
std::runtime_error);
|
||||
/**
|
||||
* Take a ROM and load it.
|
||||
*/
|
||||
loaded_rom(const std::string& file, const std::string& core, const std::string& type,
|
||||
loadable_rom(const std::string& file, const std::string& core, const std::string& type,
|
||||
const std::string& region);
|
||||
/**
|
||||
* Load a multi-file ROM.
|
||||
*/
|
||||
loaded_rom(const std::string file[ROM_SLOT_COUNT], const std::string& core, const std::string& type,
|
||||
loadable_rom(const std::string file[ROM_SLOT_COUNT], const std::string& core, const std::string& type,
|
||||
const std::string& region);
|
||||
/**
|
||||
* Take in ROM filename and load it to memory with specified type.
|
||||
|
@ -65,7 +163,7 @@ struct loaded_rom
|
|||
* throws std::bad_alloc: Not enough memory.
|
||||
* throws std::runtime_error: Loading ROM file failed.
|
||||
*/
|
||||
loaded_rom(const std::string& file, core_type& ctype) throw(std::bad_alloc, std::runtime_error);
|
||||
loadable_rom(const std::string& file, core_type& ctype) throw(std::bad_alloc, std::runtime_error);
|
||||
/**
|
||||
* Loaded main ROM
|
||||
*/
|
||||
|
@ -86,27 +184,12 @@ struct loaded_rom
|
|||
* Switches the active cartridge to this cartridge. The compatiblity between selected region and original region
|
||||
* is checked. Region is updated after cartridge has been loaded.
|
||||
*
|
||||
* returns: The incore ROM.
|
||||
* throws std::bad_alloc: Not enough memory
|
||||
* throws std::runtime_error: Switching cartridges failed.
|
||||
*/
|
||||
void load(std::map<std::string, std::string>& settings, uint64_t rtc_sec, uint64_t rtc_subsec)
|
||||
incore_rom& load(std::map<std::string, std::string>& settings, uint64_t rtc_sec, uint64_t rtc_subsec)
|
||||
throw(std::bad_alloc, std::runtime_error);
|
||||
/**
|
||||
* Saves core state into buffer. WARNING: This takes emulated time.
|
||||
*
|
||||
* returns: The saved state.
|
||||
* throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
std::vector<char> save_core_state(bool nochecksum = false) throw(std::bad_alloc, std::runtime_error);
|
||||
|
||||
/**
|
||||
* Loads core state from buffer.
|
||||
*
|
||||
* parameter buf: The buffer containing the state.
|
||||
* throws std::runtime_error: Loading state failed.
|
||||
*/
|
||||
void load_core_state(const std::vector<char>& buf, bool nochecksum = false) throw(std::runtime_error);
|
||||
|
||||
/**
|
||||
* Is file a gamepak?
|
||||
*
|
||||
|
@ -121,97 +204,39 @@ struct loaded_rom
|
|||
*/
|
||||
core_type& get_internal_rom_type() { return *rtype; }
|
||||
/**
|
||||
* Get internal region representation.
|
||||
* Is multicore capable?
|
||||
*/
|
||||
core_region& get_internal_region() { return *region; }
|
||||
bool multicore_capable() { return rtype->multicore_capable(); }
|
||||
/**
|
||||
* Is same ROM type?
|
||||
*/
|
||||
bool is_of_type(core_type& type) { return (rtype == &type); }
|
||||
/**
|
||||
* Get gametype of this ROM.
|
||||
*/
|
||||
core_sysregion& get_sysregion() { return rtype->combine_region(*region); }
|
||||
/**
|
||||
* Set internal region representation.
|
||||
*/
|
||||
void set_internal_region(core_region& reg) { region = ® }
|
||||
|
||||
//ROM methods.
|
||||
std::string get_core_identifier() { return rtype->get_core_identifier(); }
|
||||
std::pair<uint32_t, uint32_t> get_scale_factors(uint32_t width, uint32_t height)
|
||||
{
|
||||
return rtype->get_scale_factors(width, height);
|
||||
}
|
||||
const std::string& get_hname() { return rtype->get_hname(); }
|
||||
core_sysregion& combine_region(core_region& reg) { return rtype->combine_region(reg); }
|
||||
bool isnull() { return !rtype || rtype->isnull(); }
|
||||
std::vector<std::string> get_trace_cpus() { return rtype->get_trace_cpus(); }
|
||||
bool isnull() { return rtype->isnull(); }
|
||||
controller_set controllerconfig(std::map<std::string, std::string>& settings)
|
||||
{
|
||||
return rtype->controllerconfig(settings);
|
||||
}
|
||||
core_setting_group& get_settings() { return rtype->get_settings(); }
|
||||
std::set<std::string> srams() { return rtype->srams(); }
|
||||
double get_PAR() { return rtype->get_PAR(); }
|
||||
std::string get_systemmenu_name() { return rtype->get_systemmenu_name(); }
|
||||
unsigned action_flags(unsigned id) { return rtype->action_flags(id); }
|
||||
std::set<const interface_action*> get_actions() { return rtype->get_actions(); }
|
||||
void execute_action(unsigned id, const std::vector<interface_action_paramval>& p)
|
||||
{
|
||||
return rtype->execute_action(id, p);
|
||||
}
|
||||
std::pair<unsigned, unsigned> lightgun_scale() { return rtype->lightgun_scale(); }
|
||||
const interface_device_reg* get_registers() { return rtype->get_registers(); }
|
||||
bool get_pflag() { return rtype->get_pflag(); }
|
||||
void set_pflag(bool pflag) { rtype->set_pflag(pflag); }
|
||||
std::pair<uint64_t, uint64_t> get_bus_map() { return rtype->get_bus_map(); }
|
||||
std::list<core_region*> get_regions() { return rtype->get_regions(); }
|
||||
const std::string& get_iname() { return rtype->get_iname(); }
|
||||
std::map<std::string, std::vector<char>> save_sram() throw(std::bad_alloc) { return rtype->save_sram(); }
|
||||
void load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc)
|
||||
{
|
||||
rtype->load_sram(sram);
|
||||
}
|
||||
std::list<core_vma_info> vma_list() { return rtype->vma_list(); }
|
||||
framebuffer::raw& draw_cover() { return rtype->draw_cover(); }
|
||||
int reset_action(bool hard) { return rtype->reset_action(hard); }
|
||||
void pre_emulate_frame(portctrl::frame& cf) { return rtype->pre_emulate_frame(cf); }
|
||||
void emulate() { rtype->emulate(); }
|
||||
void runtosave() { rtype->runtosave(); }
|
||||
std::pair<uint32_t, uint32_t> get_audio_rate() { return rtype->get_audio_rate(); }
|
||||
void set_debug_flags(uint64_t addr, unsigned flags_set, unsigned flags_clear)
|
||||
{
|
||||
return rtype->set_debug_flags(addr, flags_set, flags_clear);
|
||||
}
|
||||
void set_cheat(uint64_t addr, uint64_t value, bool set)
|
||||
{
|
||||
return rtype->set_cheat(addr, value, set);
|
||||
}
|
||||
void debug_reset()
|
||||
{
|
||||
rtype->debug_reset();
|
||||
}
|
||||
//Region methods.
|
||||
const std::string& orig_region_get_iname() { return orig_region->get_iname(); }
|
||||
const std::string& orig_region_get_hname() { return orig_region->get_hname(); }
|
||||
const std::string& region_get_iname() { return region->get_iname(); }
|
||||
const std::string& region_get_hname() { return region->get_hname(); }
|
||||
double region_approx_framerate() { return region->approx_framerate(); }
|
||||
void region_fill_framerate_magic(uint64_t* magic) { region->fill_framerate_magic(magic); }
|
||||
bool region_compatible_with(core_region& run)
|
||||
{
|
||||
return orig_region && orig_region->compatible_with(run);
|
||||
}
|
||||
private:
|
||||
/**
|
||||
* ROM type
|
||||
* The ROM type.
|
||||
*/
|
||||
core_type* rtype;
|
||||
/**
|
||||
* ROM region (this is the currently active region).
|
||||
*/
|
||||
core_region* region;
|
||||
/**
|
||||
* ROM original region (this is the region ROM is loaded as).
|
||||
*/
|
||||
|
@ -260,7 +285,7 @@ bool _load_new_rom(const romload_request& req);
|
|||
bool reload_active_rom();
|
||||
regex_results get_argument(const std::vector<std::string>& cmdline, const std::string& regexp);
|
||||
std::string get_requested_core(const std::vector<std::string>& cmdline);
|
||||
loaded_rom construct_rom(const std::string& movie_filename, const std::vector<std::string>& cmdline);
|
||||
loadable_rom construct_rom(const std::string& movie_filename, const std::vector<std::string>& cmdline);
|
||||
void try_guess_roms(rom_request& req);
|
||||
void record_filehash(const std::string& file, uint64_t prefix, const std::string& hash);
|
||||
std::string try_to_guess_rom(const std::string& hint, const std::string& hash, const std::string& xhash,
|
||||
|
|
|
@ -109,8 +109,9 @@ extern "C" {
|
|||
#define LSNES_CORE_CAP1_MEMWATCH 0x00010000U
|
||||
//Core supports lightguns (By setting lightgun_height/lightgun_width in LSNES_CORE_GET_AV_STATE).
|
||||
#define LSNES_CORE_CAP1_LIGHTGUN 0x00020000U
|
||||
//Core supports multicore (By supporting LSNES_CORE_LOAD_ROM2).
|
||||
#define LSNES_CORE_CAP1_MULTICORE 0x00040000U
|
||||
//Reserved capabilities.
|
||||
#define LSNES_CORE_CAP1_RESERVED18 0x00040000U
|
||||
#define LSNES_CORE_CAP1_RESERVED19 0x00080000U
|
||||
#define LSNES_CORE_CAP1_RESERVED20 0x00100000U
|
||||
#define LSNES_CORE_CAP1_RESERVED21 0x00200000U
|
||||
|
@ -423,7 +424,7 @@ struct lsnes_core_get_sysregion_info
|
|||
|
||||
|
||||
//Request 5: Get current A/V state.
|
||||
//Item: Core ID.
|
||||
//Item: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: (required)
|
||||
//Fill the structure with current A/V state.
|
||||
#define LSNES_CORE_GET_AV_STATE 5
|
||||
|
@ -440,7 +441,7 @@ struct lsnes_core_get_av_state
|
|||
|
||||
|
||||
//Request 6: Emulate a frame
|
||||
//Item: Core ID.
|
||||
//Item: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: (required).
|
||||
//Emulate a frame and output the video and audio data resulting.
|
||||
#define LSNES_CORE_EMULATE 6
|
||||
|
@ -449,7 +450,7 @@ struct lsnes_core_emulate
|
|||
};
|
||||
|
||||
//Request 7: Save state.
|
||||
//Item: Core ID.
|
||||
//Item: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: (required).
|
||||
//Save core state.
|
||||
#define LSNES_CORE_SAVESTATE 7
|
||||
|
@ -462,7 +463,7 @@ struct lsnes_core_savestate
|
|||
};
|
||||
|
||||
//Request 8: Load state.
|
||||
//Item: Core ID.
|
||||
//Item: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: (required).
|
||||
//Load core state.
|
||||
#define LSNES_CORE_LOADSTATE 8
|
||||
|
@ -523,7 +524,7 @@ struct lsnes_core_load_rom
|
|||
};
|
||||
|
||||
//Request 11: Get region.
|
||||
//Item: Core ID.
|
||||
//Item: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: Fill region 0.
|
||||
//Return the current region.
|
||||
#define LSNES_CORE_GET_REGION 11
|
||||
|
@ -534,7 +535,7 @@ struct lsnes_core_get_region
|
|||
};
|
||||
|
||||
//Request 12: Set region.
|
||||
//Item: Core ID.
|
||||
//Item: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: If region is 0, succeed, otherwise fail.
|
||||
//Set current region.
|
||||
#define LSNES_CORE_SET_REGION 12
|
||||
|
@ -554,7 +555,7 @@ struct lsnes_core_deinitialize
|
|||
};
|
||||
|
||||
//Request 14: Get poll flag state.
|
||||
//Item: Core ID.
|
||||
//Item: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: Return flag inferred from polls.
|
||||
//Return the poll flag state.
|
||||
//The poll flag gets automatically set to 1 if core reads controllers.
|
||||
|
@ -566,7 +567,7 @@ struct lsnes_core_get_pflag
|
|||
};
|
||||
|
||||
//Request 15: Set poll flag state.
|
||||
//Item: Core ID.
|
||||
//Item: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: Set flag inferred from polls.
|
||||
//Sets the poll flag state.
|
||||
#define LSNES_CORE_SET_PFLAG 15
|
||||
|
@ -577,7 +578,7 @@ struct lsnes_core_set_pflag
|
|||
};
|
||||
|
||||
//Request 16: Get action flags.
|
||||
//Item: Core ID.
|
||||
//Item: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: Act as if flags was 1.
|
||||
//Get flags for given action.
|
||||
#define LSNES_CORE_GET_ACTION_FLAGS 16
|
||||
|
@ -592,7 +593,7 @@ struct lsnes_core_get_action_flags
|
|||
};
|
||||
|
||||
//Request 17: Execute action.
|
||||
//Item: Core ID.
|
||||
//Item: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: Do nothing.
|
||||
//Execute given action.
|
||||
#define LSNES_CORE_EXECUTE_ACTION 17
|
||||
|
@ -616,7 +617,7 @@ struct lsnes_core_execute_action
|
|||
};
|
||||
|
||||
//Request 18: Get bus mapping.
|
||||
//Item: Core ID.
|
||||
//Item: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: base=0, size=0 (no mapping).
|
||||
//Get the base and size of bus mapping.
|
||||
#define LSNES_CORE_GET_BUS_MAPPING 18
|
||||
|
@ -629,7 +630,7 @@ struct lsnes_core_get_bus_mapping
|
|||
};
|
||||
|
||||
//Request 19: Enumerate SRAMs.
|
||||
//Item iD: Core ID.
|
||||
//Item iD: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: Return empty set.
|
||||
//Get the set of SRAMs available.
|
||||
#define LSNES_CORE_ENUMERATE_SRAM 19
|
||||
|
@ -640,7 +641,7 @@ struct lsnes_core_enumerate_sram
|
|||
};
|
||||
|
||||
//Request 20: Save SRAMs.
|
||||
//Item id: Core ID.
|
||||
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: Return empty set.
|
||||
//Save the contents of SRAMs.
|
||||
#define LSNES_CORE_SAVE_SRAM 20
|
||||
|
@ -651,7 +652,7 @@ struct lsnes_core_save_sram
|
|||
};
|
||||
|
||||
//Request 21: Load SRAMs.
|
||||
//Item id: Core ID.
|
||||
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: Warn about any SRAMs present.
|
||||
//Load the contents of SRAMs.
|
||||
#define LSNES_CORE_LOAD_SRAM 21
|
||||
|
@ -662,7 +663,7 @@ struct lsnes_core_load_sram
|
|||
};
|
||||
|
||||
//Request 22: Get reset action number.
|
||||
//Item id: Core ID.
|
||||
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: Return -1 for both (not supported).
|
||||
//Return the IDs for reset actions.
|
||||
#define LSNES_CORE_GET_RESET_ACTION 22
|
||||
|
@ -675,7 +676,7 @@ struct lsnes_core_get_reset_action
|
|||
};
|
||||
|
||||
//Request 23: Get scale factors.
|
||||
//Item id: Core ID.
|
||||
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: Scale to at least 360 width, 320 height.
|
||||
//Compute scale factors for given resolution.
|
||||
#define LSNES_CORE_COMPUTE_SCALE 23
|
||||
|
@ -692,7 +693,7 @@ struct lsnes_core_compute_scale
|
|||
};
|
||||
|
||||
//Request 24: Run to save.
|
||||
//Item id: Core ID.
|
||||
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: Do nothing.
|
||||
//Run to next save point (can be at most frame).
|
||||
#define LSNES_CORE_RUNTOSAVE 24
|
||||
|
@ -701,7 +702,7 @@ struct lsnes_core_runtosave
|
|||
};
|
||||
|
||||
//Request 25: Poweron the system
|
||||
//Item id: Core ID.
|
||||
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: Do nothing.
|
||||
//Powers on the emulate system.
|
||||
#define LSNES_CORE_POWERON 25
|
||||
|
@ -710,16 +711,16 @@ struct lsnes_core_poweron
|
|||
};
|
||||
|
||||
//Request 26: Unload the ROM.
|
||||
//Item id: Core ID.
|
||||
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: Do nothing.
|
||||
//Signals that the ROM is no longer needed and can be unloaded.
|
||||
//Signals that the ROM is no longer needed and can be unloaded. Destroys the instance of LSNES_CORE_CAP1_MULTICORE.
|
||||
#define LSNES_CORE_UNLOAD_CARTRIDGE 26
|
||||
struct lsnes_core_unload_cartridge
|
||||
{
|
||||
};
|
||||
|
||||
//Request 27: Reset debugging.
|
||||
//Item id: Core ID.
|
||||
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: Do nothing.
|
||||
//Signals that debugging system should discard all breakpoints, cheats and tracks.
|
||||
#define LSNES_CORE_DEBUG_RESET 27
|
||||
|
@ -728,7 +729,7 @@ struct lsnes_core_debug_reset
|
|||
};
|
||||
|
||||
//Request 28: Set debug flags.
|
||||
//Item id: Core ID.
|
||||
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: Do nothing.
|
||||
//Set debugging flags.
|
||||
#define LSNES_CORE_SET_DEBUG_FLAGS 28
|
||||
|
@ -747,7 +748,7 @@ struct lsnes_core_set_debug_flags
|
|||
};
|
||||
|
||||
//Request 29: Set cheat.
|
||||
//Item id: Core ID.
|
||||
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: Do nothing.
|
||||
//Set or clear cheat.
|
||||
#define LSNES_CORE_SET_CHEAT 29
|
||||
|
@ -762,7 +763,7 @@ struct lsnes_core_set_cheat
|
|||
};
|
||||
|
||||
//Request 30: Draw cover page.
|
||||
//Item id: Core ID.
|
||||
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: Draw black screen.
|
||||
//Draw the cover page.
|
||||
#define LSNES_CORE_DRAW_COVER 30
|
||||
|
@ -773,7 +774,7 @@ struct lsnes_core_draw_cover
|
|||
};
|
||||
|
||||
//Request 31: Set system controls before emulating frame.
|
||||
//Item id: Core ID.
|
||||
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: Do nothing.
|
||||
//Set the system controls before frame is emulated.
|
||||
#define LSNES_CORE_PRE_EMULATE 31
|
||||
|
@ -786,7 +787,7 @@ struct lsnes_core_pre_emulate
|
|||
};
|
||||
|
||||
//Request 32: Get list of device registers.
|
||||
//Item id: Core ID.
|
||||
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: Return no registers.
|
||||
//Return list of device registers.
|
||||
#define LSNES_CORE_GET_DEVICE_REGS 32
|
||||
|
@ -808,7 +809,7 @@ struct lsnes_core_get_device_regs
|
|||
};
|
||||
|
||||
//Request 33: Get VMA list.
|
||||
//Item id: Core ID.
|
||||
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
|
||||
//Default action: Return no VMAs.
|
||||
//Get the list of VMAs.
|
||||
#define LSNES_CORE_GET_VMA_LIST 33
|
||||
|
@ -838,6 +839,25 @@ struct lsnes_core_get_vma_list
|
|||
struct lsnes_core_get_vma_list_vma** vmas;
|
||||
};
|
||||
|
||||
//Request 34: Load ROM and allocate instance ID. Only for emu_flags1 >= 3.
|
||||
//Item id: Type ID.
|
||||
//Default action: Not used.
|
||||
//Load given ROM, allocating instance ID.
|
||||
#define LSNES_CORE_LOAD_ROM2 34
|
||||
struct lsnes_core_load_rom2
|
||||
{
|
||||
//Input: The image set.
|
||||
struct lsnes_core_load_rom_image* images;
|
||||
//Input: System settings. Ended by entry with NULL name.
|
||||
struct lsnes_core_system_setting* settings;
|
||||
//Input: RTC second.
|
||||
uint64_t rtc_sec;
|
||||
//Input: RTC subsecond.
|
||||
uint64_t rtc_subsec;
|
||||
//Output: The instance ID.
|
||||
unsigned instance_id;
|
||||
};
|
||||
|
||||
|
||||
#ifdef LSNES_BUILD_AS_BUILTIN_CORE
|
||||
void lsnes_register_builtin_core(lsnes_core_func_t fn);
|
||||
|
|
|
@ -319,48 +319,16 @@ struct core_core
|
|||
core_core(std::initializer_list<portctrl::type*> ports, std::initializer_list<interface_action> actions);
|
||||
core_core(std::vector<portctrl::type*> ports, std::vector<interface_action> actions);
|
||||
virtual ~core_core() throw();
|
||||
bool set_region(core_region& region);
|
||||
std::pair<uint32_t, uint32_t> get_video_rate();
|
||||
double get_PAR();
|
||||
std::pair<uint32_t, uint32_t> get_audio_rate();
|
||||
std::string get_core_identifier();
|
||||
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);
|
||||
framebuffer::raw& draw_cover();
|
||||
std::vector<portctrl::type*> get_port_types() { return port_types; }
|
||||
std::string get_core_shortname();
|
||||
void pre_emulate_frame(portctrl::frame& cf);
|
||||
void execute_action(unsigned id, const std::vector<interface_action_paramval>& p);
|
||||
unsigned action_flags(unsigned id);
|
||||
std::pair<uint64_t, uint64_t> get_bus_map();
|
||||
std::list<core_vma_info> vma_list();
|
||||
std::set<std::string> srams();
|
||||
static std::set<core_core*> all_cores();
|
||||
static void install_all_handlers();
|
||||
static void uninstall_all_handlers();
|
||||
static void initialize_new_cores();
|
||||
void hide() { hidden = true; }
|
||||
bool is_hidden() { return hidden; }
|
||||
std::set<const interface_action*> get_actions();
|
||||
const interface_device_reg* get_registers();
|
||||
int reset_action(bool hard);
|
||||
std::pair<unsigned, unsigned> lightgun_scale();
|
||||
void set_debug_flags(uint64_t addr, unsigned flags_set, unsigned flags_clear);
|
||||
void set_cheat(uint64_t addr, uint64_t value, bool set);
|
||||
std::vector<std::string> get_trace_cpus();
|
||||
void debug_reset();
|
||||
bool isnull();
|
||||
bool safe_to_unload(loadlib::module& mod) { return !mod.is_marked(this); }
|
||||
protected:
|
||||
|
@ -368,6 +336,195 @@ protected:
|
|||
* Get the name of the core.
|
||||
*/
|
||||
virtual std::string c_core_identifier() = 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;
|
||||
/**
|
||||
* Get shortened name of the core.
|
||||
*/
|
||||
virtual std::string c_get_core_shortname() = 0;
|
||||
/**
|
||||
* Is null core (only NULL core should define this).
|
||||
*/
|
||||
virtual bool c_isnull();
|
||||
private:
|
||||
bool hidden;
|
||||
};
|
||||
|
||||
struct core_instance;
|
||||
|
||||
struct core_type
|
||||
{
|
||||
public:
|
||||
core_type(const core_type_params& params);
|
||||
core_type(std::initializer_list<core_type_params> p) : core_type(*p.begin()) {}
|
||||
virtual ~core_type() throw();
|
||||
static std::list<core_type*> get_core_types();
|
||||
core_region& get_preferred_region();
|
||||
std::list<core_region*> get_regions();
|
||||
core_sysregion& combine_region(core_region& reg);
|
||||
const std::string& get_iname();
|
||||
const std::string& get_hname();
|
||||
std::list<std::string> get_extensions();
|
||||
bool is_known_extension(const std::string& ext);
|
||||
core_sysregion& lookup_sysregion(const std::string& sysreg);
|
||||
std::string get_biosname();
|
||||
unsigned get_id();
|
||||
unsigned get_image_count();
|
||||
core_romimage_info get_image_info(unsigned index);
|
||||
core_instance& load(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);
|
||||
core_setting_group& get_settings();
|
||||
core_core* get_core() { return core; }
|
||||
void install_handler() { core->install_handler(); }
|
||||
void uninstall_handler() { core->uninstall_handler(); }
|
||||
std::string get_systemmenu_name() { return sysname; }
|
||||
bool is_hidden() { return core->is_hidden(); }
|
||||
std::string get_core_identifier() { return core->get_core_identifier(); }
|
||||
std::string get_core_shortname() { return core->get_core_shortname(); }
|
||||
bool isnull() { return core->isnull(); }
|
||||
bool safe_to_unload(loadlib::module& mod) { return core->safe_to_unload(mod); }
|
||||
bool multicore_capable() { return t_multicore_capable(); }
|
||||
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: The new instance, or NULL on failure.
|
||||
*/
|
||||
virtual core_instance* 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;
|
||||
/**
|
||||
* Is multicore capable?
|
||||
*/
|
||||
virtual bool t_multicore_capable() const;
|
||||
private:
|
||||
core_type(const core_type&);
|
||||
core_type& operator=(const core_type&);
|
||||
unsigned id;
|
||||
std::string iname;
|
||||
std::string hname;
|
||||
std::string biosname;
|
||||
std::string sysname;
|
||||
std::list<core_region*> regions;
|
||||
std::vector<core_romimage_info> imageinfo;
|
||||
core_setting_group settings;
|
||||
core_core* core;
|
||||
};
|
||||
|
||||
/**
|
||||
* System type / region pair.
|
||||
*
|
||||
* All run regions for given system must have valid pairs.
|
||||
*/
|
||||
struct core_sysregion
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create a new system type / region pair.
|
||||
*
|
||||
* Parameter name: The internal name of the pair.
|
||||
* Parameter type: The system.
|
||||
* Parameter region: The region.
|
||||
*/
|
||||
core_sysregion(const std::string& name, core_type& type, core_region& region);
|
||||
~core_sysregion() throw();
|
||||
const std::string& get_name();
|
||||
core_region& get_region();
|
||||
core_type& get_type();
|
||||
void fill_framerate_magic(uint64_t* magic); //4 elements filled.
|
||||
/**
|
||||
* Find all sysregions matching specified name.
|
||||
*
|
||||
* Parameter name: The name of system region.
|
||||
* Returns: Sysregions matching the specified.
|
||||
*/
|
||||
static std::set<core_sysregion*> find_matching(const std::string& name);
|
||||
private:
|
||||
core_sysregion(const core_sysregion&);
|
||||
core_sysregion& operator=(const core_sysregion&);
|
||||
std::string name;
|
||||
core_type& type;
|
||||
core_region& region;
|
||||
};
|
||||
|
||||
/**
|
||||
* A core instance.
|
||||
*/
|
||||
struct core_instance
|
||||
{
|
||||
public:
|
||||
virtual ~core_instance();
|
||||
void serialize(std::vector<char>& out) { c_serialize(out); }
|
||||
void unserialize(const char* in, size_t insize) { c_unserialize(in, insize); }
|
||||
core_type& from_type() { return *type; }
|
||||
bool set_region(core_region& region) { return c_set_region(region); }
|
||||
std::pair<uint32_t, uint32_t> get_video_rate() { return c_video_rate(); }
|
||||
double get_PAR() { return c_get_PAR(); }
|
||||
std::pair<uint32_t, uint32_t> get_audio_rate() { return c_audio_rate(); }
|
||||
std::map<std::string, std::vector<char>> save_sram() throw(std::bad_alloc) { return c_save_sram(); }
|
||||
void load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc) { c_load_sram(sram); }
|
||||
core_region& get_region() { return c_get_region(); }
|
||||
void power() { return c_power(); }
|
||||
std::pair<uint32_t, uint32_t> get_scale_factors(uint32_t width, uint32_t height)
|
||||
{
|
||||
return c_get_scale_factors(width, height);
|
||||
}
|
||||
void emulate() { c_emulate(); }
|
||||
void runtosave() { c_runtosave(); }
|
||||
bool get_pflag() { return c_get_pflag(); }
|
||||
void set_pflag(bool pflag) { return c_set_pflag(pflag); }
|
||||
framebuffer::raw& draw_cover() { return c_draw_cover(); }
|
||||
std::vector<portctrl::type*> get_port_types() { return port_types; }
|
||||
void pre_emulate_frame(portctrl::frame& cf) { c_pre_emulate_frame(cf); }
|
||||
void execute_action(unsigned id, const std::vector<interface_action_paramval>& p)
|
||||
{
|
||||
c_execute_action(id, p);
|
||||
}
|
||||
unsigned action_flags(unsigned id) { return c_action_flags(id); }
|
||||
std::pair<uint64_t, uint64_t> get_bus_map() { return c_get_bus_map(); }
|
||||
std::list<core_vma_info> vma_list() { return c_vma_list(); }
|
||||
std::set<std::string> srams() { return c_srams(); }
|
||||
std::set<const interface_action*> get_actions();
|
||||
const interface_device_reg* get_registers() { return c_get_registers(); }
|
||||
int reset_action(bool hard) { return c_reset_action(hard); }
|
||||
std::pair<unsigned, unsigned> lightgun_scale() { return c_lightgun_scale(); }
|
||||
void set_debug_flags(uint64_t addr, unsigned flags_set, unsigned flags_clear)
|
||||
{
|
||||
c_set_debug_flags(addr, flags_set, flags_clear);
|
||||
}
|
||||
void set_cheat(uint64_t addr, uint64_t value, bool set) { return c_set_cheat(addr, value, set); }
|
||||
std::vector<std::string> get_trace_cpus() { return c_get_trace_cpus(); }
|
||||
void debug_reset() { return c_debug_reset(); }
|
||||
bool unload_destroys_instance() { return type->multicore_capable(); }
|
||||
//If multicore, capable, DESTROYS the instance.
|
||||
void unload_cartridge();
|
||||
protected:
|
||||
core_type* type;
|
||||
/**
|
||||
* 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;
|
||||
/**
|
||||
* Set the current region.
|
||||
*
|
||||
|
@ -399,14 +556,6 @@ protected:
|
|||
* 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.
|
||||
*/
|
||||
|
@ -415,22 +564,6 @@ protected:
|
|||
* 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.
|
||||
*/
|
||||
|
@ -457,10 +590,6 @@ protected:
|
|||
* 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.
|
||||
*
|
||||
|
@ -531,163 +660,19 @@ protected:
|
|||
*/
|
||||
virtual void c_debug_reset() = 0;
|
||||
/**
|
||||
* Is null core (only NULL core should define this).
|
||||
* Unload the cartridge from the console (prepare instance to be destroyed).
|
||||
*/
|
||||
virtual bool c_isnull();
|
||||
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;
|
||||
private:
|
||||
std::vector<portctrl::type*> port_types;
|
||||
bool hidden;
|
||||
std::map<std::string, interface_action> actions;
|
||||
threads::lock actions_lock;
|
||||
};
|
||||
|
||||
struct core_type
|
||||
{
|
||||
public:
|
||||
core_type(const core_type_params& params);
|
||||
core_type(std::initializer_list<core_type_params> p) : core_type(*p.begin()) {}
|
||||
virtual ~core_type() throw();
|
||||
static std::list<core_type*> get_core_types();
|
||||
core_region& get_preferred_region();
|
||||
std::list<core_region*> get_regions();
|
||||
core_sysregion& combine_region(core_region& reg);
|
||||
const std::string& get_iname();
|
||||
const std::string& get_hname();
|
||||
std::list<std::string> get_extensions();
|
||||
bool is_known_extension(const std::string& ext);
|
||||
core_sysregion& lookup_sysregion(const std::string& sysreg);
|
||||
std::string get_biosname();
|
||||
unsigned get_id();
|
||||
unsigned get_image_count();
|
||||
core_romimage_info get_image_info(unsigned index);
|
||||
bool load(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);
|
||||
core_setting_group& get_settings();
|
||||
std::pair<uint64_t, uint64_t> get_bus_map() { return core->get_bus_map(); }
|
||||
std::list<core_vma_info> vma_list() { return core->vma_list(); }
|
||||
std::set<std::string> srams() { return core->srams(); }
|
||||
core_core* get_core() { return core; }
|
||||
bool set_region(core_region& region) { return core->set_region(region); }
|
||||
std::pair<uint32_t, uint32_t> get_video_rate() { return core->get_video_rate(); }
|
||||
std::pair<uint32_t, uint32_t> get_audio_rate() { return core->get_audio_rate(); }
|
||||
std::string get_core_identifier() { return core->get_core_identifier(); }
|
||||
std::string get_core_shortname() { return core->get_core_shortname(); }
|
||||
std::map<std::string, std::vector<char>> save_sram() throw(std::bad_alloc) { return core->save_sram(); }
|
||||
void load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc)
|
||||
{
|
||||
core->load_sram(sram);
|
||||
}
|
||||
void serialize(std::vector<char>& out) { core->serialize(out); }
|
||||
void unserialize(const char* in, size_t insize) { core->unserialize(in, insize); }
|
||||
core_region& get_region() { return core->get_region(); }
|
||||
void power() { core->power(); }
|
||||
void unload_cartridge() { core->unload_cartridge(); }
|
||||
std::pair<uint32_t, uint32_t> get_scale_factors(uint32_t width, uint32_t height)
|
||||
{
|
||||
return core->get_scale_factors(width, height);
|
||||
}
|
||||
void install_handler() { core->install_handler(); }
|
||||
void uninstall_handler() { core->uninstall_handler(); }
|
||||
void emulate() { core->emulate(); }
|
||||
void runtosave() { core->runtosave(); }
|
||||
bool get_pflag() { return core->get_pflag(); }
|
||||
void set_pflag(bool pflag) { core->set_pflag(pflag); }
|
||||
framebuffer::raw& draw_cover() { return core->draw_cover(); }
|
||||
std::string get_systemmenu_name() { return sysname; }
|
||||
void execute_action(unsigned id, const std::vector<interface_action_paramval>& p)
|
||||
{
|
||||
return core->execute_action(id, p);
|
||||
}
|
||||
unsigned action_flags(unsigned id) { return core->action_flags(id); }
|
||||
bool is_hidden() { return core->is_hidden(); }
|
||||
double get_PAR() { return core->get_PAR(); }
|
||||
void pre_emulate_frame(portctrl::frame& cf) { return core->pre_emulate_frame(cf); }
|
||||
std::set<const interface_action*> get_actions() { return core->get_actions(); }
|
||||
const interface_device_reg* get_registers() { return core->get_registers(); }
|
||||
int reset_action(bool hard) { return core->reset_action(hard); }
|
||||
std::pair<unsigned, unsigned> lightgun_scale() { return core->lightgun_scale(); }
|
||||
void set_debug_flags(uint64_t addr, unsigned flags_set, unsigned flags_clear)
|
||||
{
|
||||
return core->set_debug_flags(addr, flags_set, flags_clear);
|
||||
}
|
||||
void set_cheat(uint64_t addr, uint64_t value, bool set)
|
||||
{
|
||||
return core->set_cheat(addr, value, set);
|
||||
}
|
||||
std::vector<std::string> get_trace_cpus() { return core->get_trace_cpus(); }
|
||||
void debug_reset() { core->debug_reset(); }
|
||||
bool isnull() { return core->isnull(); }
|
||||
bool safe_to_unload(loadlib::module& mod) { return core->safe_to_unload(mod); }
|
||||
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;
|
||||
private:
|
||||
core_type(const core_type&);
|
||||
core_type& operator=(const core_type&);
|
||||
unsigned id;
|
||||
std::string iname;
|
||||
std::string hname;
|
||||
std::string biosname;
|
||||
std::string sysname;
|
||||
std::list<core_region*> regions;
|
||||
std::vector<core_romimage_info> imageinfo;
|
||||
core_setting_group settings;
|
||||
core_core* core;
|
||||
};
|
||||
|
||||
/**
|
||||
* System type / region pair.
|
||||
*
|
||||
* All run regions for given system must have valid pairs.
|
||||
*/
|
||||
struct core_sysregion
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create a new system type / region pair.
|
||||
*
|
||||
* Parameter name: The internal name of the pair.
|
||||
* Parameter type: The system.
|
||||
* Parameter region: The region.
|
||||
*/
|
||||
core_sysregion(const std::string& name, core_type& type, core_region& region);
|
||||
~core_sysregion() throw();
|
||||
const std::string& get_name();
|
||||
core_region& get_region();
|
||||
core_type& get_type();
|
||||
void fill_framerate_magic(uint64_t* magic); //4 elements filled.
|
||||
/**
|
||||
* Find all sysregions matching specified name.
|
||||
*
|
||||
* Parameter name: The name of system region.
|
||||
* Returns: Sysregions matching the specified.
|
||||
*/
|
||||
static std::set<core_sysregion*> find_matching(const std::string& name);
|
||||
private:
|
||||
core_sysregion(const core_sysregion&);
|
||||
core_sysregion& operator=(const core_sysregion&);
|
||||
std::string name;
|
||||
core_type& type;
|
||||
core_region& region;
|
||||
};
|
||||
|
||||
//Register a sysregion to name mapping.
|
||||
void register_sysregion_mapping(std::string from, std::string to);
|
||||
std::string lookup_sysregion_mapping(std::string from);
|
||||
|
|
105
src/core/rom.cpp
105
src/core/rom.cpp
|
@ -57,6 +57,54 @@ namespace
|
|||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
struct _core_null_instance : public core_instance
|
||||
{
|
||||
bool c_set_region(core_region& reg) { return true; }
|
||||
std::pair<unsigned, unsigned> c_video_rate() { return std::make_pair(60, 1); }
|
||||
double c_get_PAR() { return 1.0; }
|
||||
std::pair<unsigned, unsigned> c_audio_rate() { return std::make_pair(48000, 1); }
|
||||
std::map<std::string, std::vector<char>> c_save_sram() throw (std::bad_alloc) {
|
||||
std::map<std::string, std::vector<char>> x;
|
||||
return x;
|
||||
}
|
||||
std::pair<uint32_t, uint32_t> c_get_scale_factors(uint32_t width, uint32_t height) {
|
||||
return std::make_pair(1, 1);
|
||||
}
|
||||
void c_load_sram(std::map<std::string, std::vector<char>>& sram) throw (std::bad_alloc) {}
|
||||
void c_serialize(std::vector<char>& out) { out.clear(); }
|
||||
void c_unserialize(const char* in, size_t insize) {}
|
||||
core_region& c_get_region();
|
||||
void c_power() {}
|
||||
void c_unload_cartridge() {}
|
||||
void c_emulate() {}
|
||||
void c_runtosave() {}
|
||||
bool c_get_pflag() { return false; }
|
||||
void c_set_pflag(bool pflag) {}
|
||||
framebuffer::raw& c_draw_cover() {
|
||||
static framebuffer::raw x(null_fbinfo);
|
||||
for(size_t i = 0; i < sizeof(null_cover_fbmem)/sizeof(null_cover_fbmem[0]); i++)
|
||||
null_cover_fbmem[i] = 0x0000;
|
||||
std::string message = "NO ROM LOADED";
|
||||
cover_render_string(null_cover_fbmem, 204, 220, message, 0xFFFF, 0x0000, 512, 448, 1024, 2);
|
||||
return x;
|
||||
}
|
||||
void c_pre_emulate_frame(portctrl::frame& cf) {}
|
||||
void c_execute_action(unsigned id, const std::vector<interface_action_paramval>& p) {}
|
||||
const interface_device_reg* c_get_registers() { return null_registers; }
|
||||
std::pair<uint64_t, uint64_t> c_get_bus_map() { return std::make_pair(0ULL, 0ULL); }
|
||||
std::list<core_vma_info> c_vma_list() { return std::list<core_vma_info>(); }
|
||||
std::set<std::string> c_srams() { return std::set<std::string>(); }
|
||||
unsigned c_action_flags(unsigned id) { return 0; }
|
||||
int c_reset_action(bool hard) { return -1; }
|
||||
void c_set_debug_flags(uint64_t addr, unsigned int sflags, unsigned int cflags) {}
|
||||
void c_set_cheat(uint64_t addr, uint64_t value, bool set) {}
|
||||
void c_debug_reset() {}
|
||||
std::vector<std::string> c_get_trace_cpus()
|
||||
{
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
};
|
||||
|
||||
struct _core_null : public core_core, public core_type, public core_region, public core_sysregion
|
||||
{
|
||||
_core_null() : core_core({}, {}), core_type({{
|
||||
|
@ -72,45 +120,13 @@ namespace
|
|||
}}), core_region({{"null", "(null)", 0, 0, false, {1, 60}, {0}}}),
|
||||
core_sysregion("null", *this, *this) { hide(); }
|
||||
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); }
|
||||
double c_get_PAR() { return 1.0; }
|
||||
std::pair<unsigned, unsigned> c_audio_rate() { return std::make_pair(48000, 1); }
|
||||
std::map<std::string, std::vector<char>> c_save_sram() throw (std::bad_alloc) {
|
||||
std::map<std::string, std::vector<char>> x;
|
||||
return x;
|
||||
}
|
||||
void c_load_sram(std::map<std::string, std::vector<char>>& sram) throw (std::bad_alloc) {}
|
||||
void c_serialize(std::vector<char>& out) { out.clear(); }
|
||||
void c_unserialize(const char* in, size_t insize) {}
|
||||
core_region& c_get_region() { return *this; }
|
||||
void c_power() {}
|
||||
void c_unload_cartridge() {}
|
||||
std::pair<uint32_t, uint32_t> c_get_scale_factors(uint32_t width, uint32_t height) {
|
||||
return std::make_pair(1, 1);
|
||||
}
|
||||
void c_install_handler() {}
|
||||
void c_uninstall_handler() {}
|
||||
void c_emulate() {}
|
||||
void c_runtosave() {}
|
||||
bool c_get_pflag() { return false; }
|
||||
void c_set_pflag(bool pflag) {}
|
||||
framebuffer::raw& c_draw_cover() {
|
||||
static framebuffer::raw x(null_fbinfo);
|
||||
for(size_t i = 0; i < sizeof(null_cover_fbmem)/sizeof(null_cover_fbmem[0]); i++)
|
||||
null_cover_fbmem[i] = 0x0000;
|
||||
std::string message = "NO ROM LOADED";
|
||||
cover_render_string(null_cover_fbmem, 204, 220, message, 0xFFFF, 0x0000, 512, 448, 1024, 2);
|
||||
return x;
|
||||
}
|
||||
std::string c_get_core_shortname() { return "null"; }
|
||||
void c_pre_emulate_frame(portctrl::frame& cf) {}
|
||||
void c_execute_action(unsigned id, const std::vector<interface_action_paramval>& p) {}
|
||||
const interface_device_reg* c_get_registers() { return null_registers; }
|
||||
int t_load_rom(core_romimage* img, std::map<std::string, std::string>& settings,
|
||||
core_instance* t_load_rom(core_romimage* img, std::map<std::string, std::string>& settings,
|
||||
uint64_t secs, uint64_t subsecs)
|
||||
{
|
||||
return 0;
|
||||
return new _core_null_instance;
|
||||
}
|
||||
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
|
||||
{
|
||||
|
@ -118,21 +134,12 @@ namespace
|
|||
x.ports.push_back(&portctrl::get_default_system_port_type());
|
||||
return x;
|
||||
}
|
||||
std::pair<uint64_t, uint64_t> c_get_bus_map() { return std::make_pair(0ULL, 0ULL); }
|
||||
std::list<core_vma_info> c_vma_list() { return std::list<core_vma_info>(); }
|
||||
std::set<std::string> c_srams() { return std::set<std::string>(); }
|
||||
unsigned c_action_flags(unsigned id) { return 0; }
|
||||
int c_reset_action(bool hard) { return -1; }
|
||||
bool c_isnull() { return true; }
|
||||
void c_set_debug_flags(uint64_t addr, unsigned int sflags, unsigned int cflags) {}
|
||||
void c_set_cheat(uint64_t addr, uint64_t value, bool set) {}
|
||||
void c_debug_reset() {}
|
||||
std::vector<std::string> c_get_trace_cpus()
|
||||
{
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
bool t_multirom_capable() const { return true; }
|
||||
} core_null;
|
||||
|
||||
core_region& _core_null_instance::c_get_region() { return core_null; }
|
||||
|
||||
core_type* current_rom_type = &core_null;
|
||||
core_region* current_region = &core_null;
|
||||
|
||||
|
@ -650,7 +657,7 @@ std::map<std::string, std::vector<char>> load_sram_commandline(const std::vector
|
|||
std::vector<char> loaded_rom::save_core_state(bool nochecksum) throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
std::vector<char> ret;
|
||||
rtype->serialize(ret);
|
||||
cinst->serialize(ret);
|
||||
if(nochecksum)
|
||||
return ret;
|
||||
size_t offset = ret.size();
|
||||
|
@ -668,7 +675,7 @@ std::vector<char> loaded_rom::save_core_state(bool nochecksum) throw(std::bad_al
|
|||
void loaded_rom::load_core_state(const std::vector<char>& buf, bool nochecksum) throw(std::runtime_error)
|
||||
{
|
||||
if(nochecksum) {
|
||||
rtype->unserialize(&buf[0], buf.size());
|
||||
cinst->unserialize(&buf[0], buf.size());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -684,7 +691,7 @@ void loaded_rom::load_core_state(const std::vector<char>& buf, bool nochecksum)
|
|||
if(memcmp(tmp, &buf[buf.size() - 32], 32))
|
||||
throw std::runtime_error("Savestate corrupt");
|
||||
}
|
||||
rtype->unserialize(&buf[0], buf.size() - 32);
|
||||
cinst->unserialize(&buf[0], buf.size() - 32);
|
||||
}
|
||||
|
||||
bool loaded_rom::is_gamepak(const std::string& filename) throw(std::bad_alloc, std::runtime_error)
|
||||
|
|
|
@ -394,11 +394,12 @@ int main(int argc, char** argv)
|
|||
|
||||
init_main_callbacks();
|
||||
messages << "--- Loading ROM ---" << std::endl;
|
||||
struct loaded_rom r;
|
||||
struct loadable_rom r;
|
||||
struct incore_rom* icrom = NULL;
|
||||
try {
|
||||
std::map<std::string, std::string> tmp;
|
||||
r = construct_rom(movfn, cmdline);
|
||||
r.load(tmp, 1000000000, 0);
|
||||
icrom = &r.load(tmp, 1000000000, 0);
|
||||
messages << "Using core: " << r.get_core_identifier() << std::endl;
|
||||
} catch(std::bad_alloc& e) {
|
||||
OOM_panic();
|
||||
|
@ -408,8 +409,8 @@ int main(int argc, char** argv)
|
|||
fatal_error();
|
||||
exit(1);
|
||||
}
|
||||
messages << "Detected region: " << r.get_sysregion().get_name() << std::endl;
|
||||
lsnes_instance.framerate->set_nominal_framerate(r.region_approx_framerate());
|
||||
messages << "Detected region: " << icrom->get_sysregion().get_name() << std::endl;
|
||||
lsnes_instance.framerate->set_nominal_framerate(icrom->region_approx_framerate());
|
||||
|
||||
messages << "--- End of Startup --- " << std::endl;
|
||||
|
||||
|
@ -434,6 +435,7 @@ int main(int argc, char** argv)
|
|||
fatal_error();
|
||||
return 1;
|
||||
}
|
||||
icrom->destroy();
|
||||
quit_lua();
|
||||
lsnes_instance.mlogic->release_memory();
|
||||
lsnes_instance.buttons->cleanup();
|
||||
|
|
Loading…
Add table
Reference in a new issue