1 #include "core/misc.hpp"
2 #include "interface/romtype.hpp"
3 #include "interface/callbacks.hpp"
4 #include "library/minmax.hpp"
5 #include "library/string.hpp"
17 bool install_handlers_automatically
;
19 std::map
<std::string
, std::string
>& sysreg_mapping()
21 static std::map
<std::string
, std::string
> x
;
25 std::set
<core_core
*>& all_cores_set()
27 static std::set
<core_core
*> x
;
31 std::set
<core_core
*>& uninitialized_cores_set()
33 static std::set
<core_core
*> x
;
37 std::multimap
<std::string
, core_sysregion
*>& sysregions()
39 static std::multimap
<std::string
, core_sysregion
*> x
;
43 std::set
<core_type
*>& types()
45 static std::set
<core_type
*> x
;
49 bool compare_coretype(core_type
* a
, core_type
* b
)
51 return (a
->get_id() < b
->get_id());
54 bool compare_regions(core_region
* a
, core_region
* b
)
56 return (a
->get_handle() < b
->get_handle());
60 bool interface_action::is_toggle() const
63 if(!strcmp(i
.model
, "toggle"))
68 core_region::core_region(const core_region_params
& params
)
73 handle
= params
.handle
;
74 priority
= params
.priority
;
75 magic
[0] = params
.framemagic
[0];
76 magic
[1] = params
.framemagic
[1];
77 magic
[2] = 1000 * params
.framemagic
[0] / params
.framemagic
[1];
78 magic
[3] = 1000 * params
.framemagic
[0] % params
.framemagic
[1];
79 compatible
= params
.compatible_runs
;
83 bool core_region::compatible_with(core_region
& run
)
85 for(auto i
: compatible
)
91 bool core_region::is_multi()
96 const std::string
& core_region::get_iname()
101 const std::string
& core_region::get_hname()
106 unsigned core_region::get_priority()
111 unsigned core_region:: get_handle()
116 void core_region::fill_framerate_magic(uint64_t* _magic
)
118 for(size_t i
= 0; i
< 4; i
++)
119 _magic
[i
] = magic
[i
];
122 double core_region::approx_framerate()
124 return (double)magic
[1] / magic
[0];
127 core_romimage_info::core_romimage_info(const core_romimage_info_params
& params
)
129 iname
= params
.iname
;
130 hname
= params
.hname
;
131 mandatory
= params
.mandatory
;
132 pass_mode
= params
.pass_mode
;
133 headersize
= params
.headersize
;
134 if(params
.extensions
) {
135 std::string tmp
= params
.extensions
;
136 for(auto& ext
: token_iterator_foreach(tmp
, {";"}))
137 extensions
.insert(ext
);
141 size_t core_romimage_info::get_headnersize(size_t imagesize
)
143 if(headersize
&& imagesize
% (2 * headersize
) == headersize
)
148 core_type::core_type(const core_type_params
& params
)
149 : settings(params
.settings
)
151 iname
= params
.iname
;
152 hname
= params
.hname
;
153 sysname
= params
.sysname
;
157 biosname
= params
.bios
;
158 for(auto i
: params
.regions
)
159 regions
.push_back(i
);
160 imageinfo
= params
.images
.get();
161 types().insert(this);
164 core_type::~core_type() throw()
169 unsigned core_type::get_id()
174 const std::string
& core_type::get_iname()
179 const std::string
& core_type::get_hname()
184 unsigned core_type::get_image_count()
186 return imageinfo
.size();
189 core_setting_group
& core_type::get_settings()
194 core_romimage_info
core_type::get_image_info(unsigned index
)
196 if(index
>= imageinfo
.size())
197 throw std::runtime_error("Requested invalid image index");
198 return imageinfo
[index
];
201 std::list
<core_type
*> core_type::get_core_types()
203 std::list
<core_type
*> ret
;
204 for(auto i
: types())
206 ret
.sort(compare_coretype
);
210 std::list
<core_region
*> core_type::get_regions()
212 std::list
<core_region
*> ret
= regions
;
213 ret
.sort(compare_regions
);
217 core_region
& core_type::get_preferred_region()
219 core_region
* p
= NULL
;
221 for(auto i
: regions
) {
222 unsigned pri
= i
->get_priority();
224 cutoff
= max(pri
+ 1, pri
);
231 bool core_type::load(core_romimage
* images
, std::map
<std::string
, std::string
>& settings
, uint64_t rtc_sec
,
234 return (t_load_rom(images
, settings
, rtc_sec
, rtc_subsec
) >= 0);
237 core_sysregion
& core_type::combine_region(core_region
& reg
)
239 for(auto i
: sysregions())
240 if(&(i
.second
->get_type()) == this && &(i
.second
->get_region()) == ®
)
242 throw std::runtime_error("Invalid region for system type");
245 std::list
<std::string
> core_type::get_extensions()
247 static std::list
<std::string
> empty
;
248 unsigned base
= (biosname
!= "") ? 1 : 0;
249 if(imageinfo
.size() <= base
)
251 auto s
= imageinfo
[base
].extensions
;
252 std::list
<std::string
> ret
;
258 std::string
core_type::get_biosname()
263 bool core_type::is_known_extension(const std::string
& ext
)
265 std::string _ext
= ext
;
266 std::transform(_ext
.begin(), _ext
.end(), _ext
.begin(), ::tolower
);
267 for(auto i
: get_extensions())
273 controller_set
core_type::controllerconfig(std::map
<std::string
, std::string
>& settings
)
275 return t_controllerconfig(settings
);
278 std::pair
<uint64_t, uint64_t> core_core::get_bus_map()
280 return c_get_bus_map();
283 double core_core::get_PAR()
288 std::list
<core_vma_info
> core_core::vma_list()
293 std::set
<std::string
> core_core::srams()
298 bool core_core::isnull()
303 std::pair
<unsigned, unsigned> core_core::lightgun_scale()
305 return c_lightgun_scale();
308 std::pair
<unsigned, unsigned> core_core::c_lightgun_scale()
310 return std::make_pair(0, 0);
313 void core_core::debug_reset()
315 return c_debug_reset();
318 bool core_core::c_isnull()
323 core_sysregion::core_sysregion(const std::string
& _name
, core_type
& _type
, core_region
& _region
)
324 : name(_name
), type(_type
), region(_region
)
326 sysregions().insert(std::make_pair(_name
, this));
329 core_sysregion::~core_sysregion() throw()
331 for(auto i
= sysregions().begin(); i
!= sysregions().end(); i
++)
332 if(i
->second
== this) {
333 sysregions().erase(i
);
338 core_sysregion
& core_type::lookup_sysregion(const std::string
& sysreg
)
340 for(auto i
: sysregions())
341 if(i
.first
== sysreg
&& &i
.second
->get_type() == this)
343 throw std::runtime_error("Bad system-region type");
346 const std::string
& core_sysregion::get_name()
351 core_region
& core_sysregion::get_region()
356 core_type
& core_sysregion::get_type()
361 void core_sysregion::fill_framerate_magic(uint64_t* magic
)
363 region
.fill_framerate_magic(magic
);
366 core_core::core_core(std::initializer_list
<port_type
*> ports
, std::initializer_list
<interface_action
> x_actions
)
369 port_types
.push_back(i
);
370 for(auto i
: x_actions
)
371 actions
[i
._symbol
] = i
;
374 uninitialized_cores_set().insert(this);
375 all_cores_set().insert(this);
376 new_core_flag
= true;
379 core_core::core_core(std::vector
<port_type
*> ports
, std::vector
<interface_action
> x_actions
)
382 port_types
.push_back(i
);
383 for(auto i
: x_actions
)
384 actions
[i
._symbol
] = i
;
387 uninitialized_cores_set().insert(this);
388 all_cores_set().insert(this);
389 new_core_flag
= true;
392 core_core::~core_core() throw()
394 all_cores().erase(this);
397 void core_core::initialize_new_cores()
399 for(auto i
: uninitialized_cores_set())
400 i
->install_handler();
401 uninitialized_cores_set().clear();
404 std::string
core_core::get_core_shortname()
406 return c_get_core_shortname();
409 bool core_core::set_region(core_region
& region
)
411 return c_set_region(region
);
414 std::pair
<uint32_t, uint32_t> core_core::get_video_rate()
416 return c_video_rate();
419 std::pair
<uint32_t, uint32_t> core_core::get_audio_rate()
421 return c_audio_rate();
424 std::string
core_core::get_core_identifier()
426 return c_core_identifier();
429 std::set
<core_core
*> core_core::all_cores()
431 return all_cores_set();
434 void core_core::install_all_handlers()
436 install_handlers_automatically
= true;
437 for(auto i
: all_cores_set())
438 i
->install_handler();
441 void core_core::uninstall_all_handlers()
443 install_handlers_automatically
= false;
444 for(auto i
: all_cores_set())
445 i
->uninstall_handler();
448 std::map
<std::string
, std::vector
<char>> core_core::save_sram() throw(std::bad_alloc
)
450 return c_save_sram();
453 void core_core::load_sram(std::map
<std::string
, std::vector
<char>>& sram
) throw(std::bad_alloc
)
458 void core_core::serialize(std::vector
<char>& out
)
463 void core_core::unserialize(const char* in
, size_t insize
)
465 c_unserialize(in
, insize
);
468 core_region
& core_core::get_region()
470 return c_get_region();
473 void core_core::power()
478 void core_core::unload_cartridge()
480 c_unload_cartridge();
483 std::pair
<uint32_t, uint32_t> core_core::get_scale_factors(uint32_t width
, uint32_t height
)
485 return c_get_scale_factors(width
, height
);
488 void core_core::install_handler()
493 void core_core::uninstall_handler()
495 c_uninstall_handler();
498 void core_core::emulate()
503 void core_core::runtosave()
508 bool core_core::get_pflag()
510 return c_get_pflag();
513 void core_core::set_pflag(bool pflag
)
515 return c_set_pflag(pflag
);
518 framebuffer::raw
& core_core::draw_cover()
520 return c_draw_cover();
523 void core_core::pre_emulate_frame(controller_frame
& cf
)
525 c_pre_emulate_frame(cf
);
528 void core_core::execute_action(unsigned id
, const std::vector
<interface_action_paramval
>& p
)
530 return c_execute_action(id
, p
);
533 const struct interface_device_reg
* core_core::get_registers()
535 return c_get_registers();
538 unsigned core_core::action_flags(unsigned id
)
540 return c_action_flags(id
);
543 std::set
<const interface_action
*> core_core::get_actions()
545 threads::alock
h(actions_lock
);
546 std::set
<const interface_action
*> r
;
547 for(auto& i
: actions
)
552 int core_core::reset_action(bool hard
)
554 return c_reset_action(hard
);
557 void core_core::set_debug_flags(uint64_t addr
, unsigned flags_set
, unsigned flags_clear
)
559 return c_set_debug_flags(addr
, flags_set
, flags_clear
);
562 void core_core::set_cheat(uint64_t addr
, uint64_t value
, bool set
)
564 return c_set_cheat(addr
, value
, set
);
567 std::vector
<std::string
> core_core::get_trace_cpus()
569 return c_get_trace_cpus();
572 emucore_callbacks::~emucore_callbacks() throw()
576 core_romimage_info_collection::core_romimage_info_collection()
580 core_romimage_info_collection::core_romimage_info_collection(std::initializer_list
<core_romimage_info_params
> idata
)
583 data
.push_back(core_romimage_info(i
));
586 core_romimage_info_collection::core_romimage_info_collection(std::vector
<core_romimage_info_params
> idata
)
589 data
.push_back(core_romimage_info(i
));
592 std::set
<core_sysregion
*> core_sysregion::find_matching(const std::string
& name
)
594 std::set
<core_sysregion
*> ret
;
595 auto u
= sysregions().upper_bound(name
);
596 for(auto i
= sysregions().lower_bound(name
); i
!= u
; ++i
)
597 ret
.insert(i
->second
);
601 void register_sysregion_mapping(std::string from
, std::string to
)
603 sysreg_mapping()[from
] = to
;
606 std::string
lookup_sysregion_mapping(std::string from
)
608 if(sysreg_mapping().count(from
))
609 return sysreg_mapping()[from
];
614 struct emucore_callbacks
* ecore_callbacks
;
616 bool new_core_flag
= false;
617 uint32_t magic_flags
= 0;