Core cleanups
[lsnes.git] / src / interface / romtype.cpp
blob63664a70bb0e6bb3218c64e9c4314c3ef4fc426e
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 "library/register-queue.hpp"
7 #include <set>
8 #include <map>
9 #include <string>
10 #include <algorithm>
11 #include <cctype>
12 #include <stdexcept>
13 #include <list>
14 #include <limits>
16 namespace
18 bool install_handlers_automatically;
20 std::set<core_core*>& all_cores_set()
22 static std::set<core_core*> x;
23 return x;
26 std::multimap<std::string, core_sysregion*>& sysregions()
28 static std::multimap<std::string, core_sysregion*> x;
29 return x;
32 std::set<core_type*>& types()
34 static std::set<core_type*> x;
35 return x;
38 bool compare_coretype(core_type* a, core_type* b)
40 return (a->get_id() < b->get_id());
43 bool compare_regions(core_region* a, core_region* b)
45 return (a->get_handle() < b->get_handle());
48 unsigned default_headersize(size_t imagesize)
50 return 0;
54 bool interface_action::is_toggle() const
56 for(auto i : params)
57 if(!strcmp(i.model, "toggle"))
58 return true;
59 return false;
62 core_region::core_region(const core_region_params& params)
64 iname = params.iname;
65 hname = params.hname;
66 multi = params.multi;
67 handle = params.handle;
68 priority = params.priority;
69 magic[0] = params.framemagic[0];
70 magic[1] = params.framemagic[1];
71 magic[2] = 1000000000 * params.framemagic[0] / params.framemagic[1];
72 magic[3] = 1000000000 * params.framemagic[0] % params.framemagic[1];
73 compatible = params.compatible_runs;
77 bool core_region::compatible_with(core_region& run)
79 for(auto i : compatible)
80 if(i == run.handle)
81 return true;
82 return false;
85 bool core_region::is_multi()
87 return multi;
90 const std::string& core_region::get_iname()
92 return iname;
95 const std::string& core_region::get_hname()
97 return hname;
100 unsigned core_region::get_priority()
102 return priority;
105 unsigned core_region:: get_handle()
107 return handle;
110 void core_region::fill_framerate_magic(uint64_t* _magic)
112 for(size_t i = 0; i < 4; i++)
113 _magic[i] = magic[i];
116 double core_region::approx_framerate()
118 return (double)magic[1] / magic[0];
121 core_romimage_info::core_romimage_info(const core_romimage_info_params& params)
123 iname = params.iname;
124 hname = params.hname;
125 mandatory = params.mandatory;
126 pass_mode = params.pass_mode;
127 headersize = params.headersize;
130 size_t core_romimage_info::get_headnersize(size_t imagesize)
132 if(headersize && imagesize % (2 * headersize) == headersize)
133 return headersize;
134 return 0;
137 core_type::core_type(const core_type_params& params)
138 : settings(params.settings)
140 iname = params.iname;
141 hname = params.hname;
142 sysname = params.sysname;
143 id = params.id;
144 core = params.core;
145 if(params.bios)
146 biosname = params.bios;
147 for(auto i : params.regions)
148 regions.push_back(i);
149 imageinfo = params.images.get();
150 if(params.extensions) {
151 std::string tmp = params.extensions;
152 while(tmp != "") {
153 std::string ext;
154 extract_token(tmp, ext, ";");
155 extensions.push_back(ext);
158 types().insert(this);
161 core_type::~core_type() throw()
163 types().erase(this);
166 unsigned core_type::get_id()
168 return id;
171 const std::string& core_type::get_iname()
173 return iname;
176 const std::string& core_type::get_hname()
178 return hname;
181 unsigned core_type::get_image_count()
183 return imageinfo.size();
186 core_setting_group& core_type::get_settings()
188 return settings;
191 core_romimage_info core_type::get_image_info(unsigned index)
193 if(index >= imageinfo.size())
194 throw std::runtime_error("Requested invalid image index");
195 return imageinfo[index];
198 std::list<core_type*> core_type::get_core_types()
200 std::list<core_type*> ret;
201 for(auto i : types())
202 ret.push_back(i);
203 ret.sort(compare_coretype);
204 return ret;
207 std::list<core_region*> core_type::get_regions()
209 std::list<core_region*> ret = regions;
210 ret.sort(compare_regions);
211 return ret;
214 core_region& core_type::get_preferred_region()
216 core_region* p = NULL;
217 unsigned cutoff = 0;
218 for(auto i : regions) {
219 unsigned pri = i->get_priority();
220 if(pri >= cutoff) {
221 cutoff = max(pri + 1, pri);
222 p = i;
225 return *p;
228 bool core_type::load(core_romimage* images, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
229 uint64_t rtc_subsec)
231 return (t_load_rom(images, settings, rtc_sec, rtc_subsec) >= 0);
234 core_sysregion& core_type::combine_region(core_region& reg)
236 for(auto i : sysregions())
237 if(&(i.second->get_type()) == this && &(i.second->get_region()) == &reg)
238 return *(i.second);
239 throw std::runtime_error("Invalid region for system type");
242 const std::list<std::string>& core_type::get_extensions()
244 return extensions;
247 std::string core_type::get_biosname()
249 return biosname;
252 bool core_type::is_known_extension(const std::string& ext)
254 std::string _ext = ext;
255 std::transform(_ext.begin(), _ext.end(), _ext.begin(), ::tolower);
256 for(auto i : extensions)
257 if(i == _ext)
258 return true;
259 return false;
262 controller_set core_type::controllerconfig(std::map<std::string, std::string>& settings)
264 return t_controllerconfig(settings);
267 std::pair<uint64_t, uint64_t> core_core::get_bus_map()
269 return c_get_bus_map();
272 std::list<core_vma_info> core_core::vma_list()
274 return c_vma_list();
277 std::set<std::string> core_core::srams()
279 return c_srams();
282 core_sysregion::core_sysregion(const std::string& _name, core_type& _type, core_region& _region)
283 : name(_name), type(_type), region(_region)
285 sysregions().insert(std::make_pair(_name, this));
288 core_sysregion::~core_sysregion() throw()
290 for(auto i = sysregions().begin(); i != sysregions().end(); i++)
291 if(i->second == this) {
292 sysregions().erase(i);
293 break;
297 core_sysregion& core_type::lookup_sysregion(const std::string& sysreg)
299 for(auto i : sysregions())
300 if(i.first == sysreg && &i.second->get_type() == this)
301 return *i.second;
302 throw std::runtime_error("Bad system-region type");
305 const std::string& core_sysregion::get_name()
307 return name;
310 core_region& core_sysregion::get_region()
312 return region;
315 core_type& core_sysregion::get_type()
317 return type;
320 void core_sysregion::fill_framerate_magic(uint64_t* magic)
322 region.fill_framerate_magic(magic);
325 core_core::core_core(std::initializer_list<port_type*> ports, std::initializer_list<interface_action> x_actions)
327 for(auto i : ports)
328 port_types.push_back(i);
329 for(auto i : x_actions)
330 actions[i._symbol] = i;
332 hidden = false;
333 all_cores_set().insert(this);
334 if(install_handlers_automatically)
335 install_handler();
336 new_core_flag = true;
339 core_core::~core_core() throw()
341 all_cores().erase(this);
344 std::string core_core::get_core_shortname()
346 return c_get_core_shortname();
349 bool core_core::set_region(core_region& region)
351 return c_set_region(region);
354 std::pair<uint32_t, uint32_t> core_core::get_video_rate()
356 return c_video_rate();
359 std::pair<uint32_t, uint32_t> core_core::get_audio_rate()
361 return c_audio_rate();
364 std::string core_core::get_core_identifier()
366 return c_core_identifier();
369 std::set<core_core*> core_core::all_cores()
371 return all_cores_set();
374 void core_core::install_all_handlers()
376 install_handlers_automatically = true;
377 for(auto i : all_cores_set())
378 i->install_handler();
381 void core_core::uninstall_all_handlers()
383 install_handlers_automatically = false;
384 for(auto i : all_cores_set())
385 i->uninstall_handler();
388 std::map<std::string, std::vector<char>> core_core::save_sram() throw(std::bad_alloc)
390 return c_save_sram();
393 void core_core::load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc)
395 c_load_sram(sram);
398 void core_core::serialize(std::vector<char>& out)
400 c_serialize(out);
403 void core_core::unserialize(const char* in, size_t insize)
405 c_unserialize(in, insize);
408 core_region& core_core::get_region()
410 return c_get_region();
413 void core_core::power()
415 c_power();
418 void core_core::unload_cartridge()
420 c_unload_cartridge();
423 std::pair<uint32_t, uint32_t> core_core::get_scale_factors(uint32_t width, uint32_t height)
425 return c_get_scale_factors(width, height);
428 void core_core::install_handler()
430 c_install_handler();
433 void core_core::uninstall_handler()
435 c_uninstall_handler();
438 void core_core::emulate()
440 c_emulate();
443 void core_core::runtosave()
445 c_runtosave();
448 bool core_core::get_pflag()
450 return c_get_pflag();
453 void core_core::set_pflag(bool pflag)
455 return c_set_pflag(pflag);
458 framebuffer_raw& core_core::draw_cover()
460 return c_draw_cover();
463 void core_core::pre_emulate_frame(controller_frame& cf)
465 c_pre_emulate_frame(cf);
468 void core_core::execute_action(unsigned id, const std::vector<interface_action_paramval>& p)
470 return c_execute_action(id, p);
473 const struct interface_device_reg* core_core::get_registers()
475 return c_get_registers();
478 unsigned core_core::action_flags(unsigned id)
480 return c_action_flags(id);
483 std::set<const interface_action*> core_core::get_actions()
485 umutex_class h(actions_lock);
486 std::set<const interface_action*> r;
487 for(auto& i : actions)
488 r.insert(&i.second);
489 return r;
492 int core_core::reset_action(bool hard)
494 return c_reset_action(hard);
497 emucore_callbacks::~emucore_callbacks() throw()
501 core_romimage_info_collection::core_romimage_info_collection(std::initializer_list<core_romimage_info_params> idata)
503 for(auto i : idata)
504 data.push_back(core_romimage_info(i));
507 struct emucore_callbacks* ecore_callbacks;
509 bool new_core_flag = false;
510 uint32_t magic_flags = 0;