Fix build on GCC 4.9
[lsnes.git] / src / interface / romtype.cpp
blobe4436edf10383e4099c0a0c7206929df9d9c9b5e
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"
6 #include <set>
7 #include <map>
8 #include <string>
9 #include <algorithm>
10 #include <cctype>
11 #include <stdexcept>
12 #include <list>
13 #include <limits>
15 namespace
17 bool install_handlers_automatically;
19 std::map<std::string, std::string>& sysreg_mapping()
21 static std::map<std::string, std::string> x;
22 return x;
25 std::set<core_core*>& all_cores_set()
27 static std::set<core_core*> x;
28 return x;
31 std::set<core_core*>& uninitialized_cores_set()
33 static std::set<core_core*> x;
34 return x;
37 std::multimap<std::string, core_sysregion*>& sysregions()
39 static std::multimap<std::string, core_sysregion*> x;
40 return x;
43 std::set<core_type*>& types()
45 static std::set<core_type*> x;
46 return 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
62 for(auto i : params)
63 if(!strcmp(i.model, "toggle"))
64 return true;
65 return false;
68 core_region::core_region(const core_region_params& params)
70 iname = params.iname;
71 hname = params.hname;
72 multi = params.multi;
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)
86 if(i == run.handle)
87 return true;
88 return false;
91 bool core_region::is_multi()
93 return multi;
96 const std::string& core_region::get_iname()
98 return iname;
101 const std::string& core_region::get_hname()
103 return hname;
106 unsigned core_region::get_priority()
108 return priority;
111 unsigned core_region:: get_handle()
113 return 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)
144 return headersize;
145 return 0;
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;
154 id = params.id;
155 core = params.core;
156 if(params.bios)
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()
166 types().erase(this);
169 unsigned core_type::get_id()
171 return id;
174 const std::string& core_type::get_iname()
176 return iname;
179 const std::string& core_type::get_hname()
181 return hname;
184 unsigned core_type::get_image_count()
186 return imageinfo.size();
189 core_setting_group& core_type::get_settings()
191 return 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())
205 ret.push_back(i);
206 ret.sort(compare_coretype);
207 return ret;
210 std::list<core_region*> core_type::get_regions()
212 std::list<core_region*> ret = regions;
213 ret.sort(compare_regions);
214 return ret;
217 core_region& core_type::get_preferred_region()
219 core_region* p = NULL;
220 unsigned cutoff = 0;
221 for(auto i : regions) {
222 unsigned pri = i->get_priority();
223 if(pri >= cutoff) {
224 cutoff = max(pri + 1, pri);
225 p = i;
228 return *p;
231 bool core_type::load(core_romimage* images, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
232 uint64_t rtc_subsec)
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()) == &reg)
241 return *(i.second);
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)
250 return empty;
251 auto s = imageinfo[base].extensions;
252 std::list<std::string> ret;
253 for(auto i : s)
254 ret.push_back(i);
255 return ret;
258 std::string core_type::get_biosname()
260 return 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())
268 if(i == _ext)
269 return true;
270 return false;
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()
285 return c_get_PAR();
288 std::list<core_vma_info> core_core::vma_list()
290 return c_vma_list();
293 std::set<std::string> core_core::srams()
295 return c_srams();
298 bool core_core::isnull()
300 return c_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()
320 return false;
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);
334 break;
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)
342 return *i.second;
343 throw std::runtime_error("Bad system-region type");
346 const std::string& core_sysregion::get_name()
348 return name;
351 core_region& core_sysregion::get_region()
353 return region;
356 core_type& core_sysregion::get_type()
358 return 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)
368 for(auto i : ports)
369 port_types.push_back(i);
370 for(auto i : x_actions)
371 actions[i._symbol] = i;
373 hidden = false;
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)
381 for(auto i : ports)
382 port_types.push_back(i);
383 for(auto i : x_actions)
384 actions[i._symbol] = i;
386 hidden = false;
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)
455 c_load_sram(sram);
458 void core_core::serialize(std::vector<char>& out)
460 c_serialize(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()
475 c_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()
490 c_install_handler();
493 void core_core::uninstall_handler()
495 c_uninstall_handler();
498 void core_core::emulate()
500 c_emulate();
503 void core_core::runtosave()
505 c_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)
548 r.insert(&i.second);
549 return r;
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)
582 for(auto i : 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)
588 for(auto i : 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);
598 return ret;
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];
610 else
611 return "";
614 struct emucore_callbacks* ecore_callbacks;
616 bool new_core_flag = false;
617 uint32_t magic_flags = 0;