3 #include "core/command.hpp"
4 #include "core/dispatch.hpp"
5 #include "core/framerate.hpp"
6 #include "core/mainloop.hpp"
7 #include "core/memorymanip.hpp"
8 #include "core/misc.hpp"
9 #include "core/rom.hpp"
10 #include "core/romguess.hpp"
11 #include "core/settings.hpp"
12 #include "core/window.hpp"
13 #include "interface/cover.hpp"
14 #include "interface/romtype.hpp"
15 #include "interface/callbacks.hpp"
16 #include "library/framebuffer-pixfmt-rgb16.hpp"
17 #include "library/controller-data.hpp"
18 #include "library/fileimage-patch.hpp"
19 #include "library/sha256.hpp"
20 #include "library/string.hpp"
21 #include "library/zip.hpp"
29 #include <boost/iostreams/categories.hpp>
30 #include <boost/iostreams/copy.hpp>
31 #include <boost/iostreams/stream.hpp>
32 #include <boost/iostreams/stream_buffer.hpp>
33 #include <boost/iostreams/filter/symmetric.hpp>
34 #include <boost/iostreams/filter/zlib.hpp>
35 #include <boost/iostreams/filtering_stream.hpp>
36 #include <boost/iostreams/device/back_inserter.hpp>
38 #ifdef USE_LIBGCRYPT_SHA256
44 const char* null_chars
= "F";
45 uint16_t null_cover_fbmem
[512 * 448];
47 settingvar::variable
<settingvar::model_bool
<settingvar::yes_no
>> savestate_no_check(lsnes_vset
,
48 "dont-check-savestate", "Movie‣Loading‣Don't check savestates", false);
51 struct framebuffer::info null_fbinfo
= {
52 &framebuffer::pixfmt_bgr16
, //Format.
53 (char*)null_cover_fbmem
, //Memory.
54 512, 448, 1024, //Physical size.
55 512, 448, 1024, //Logical size.
59 port_index_triple sync_triple
= {true, 0, 0, 0 };
61 struct interface_device_reg null_registers
[] = {
65 struct _core_null
: public core_core
, public core_type
, public core_region
, public core_sysregion
67 _core_null() : core_core({}, {}), core_type({{
77 }}), core_region({{"null", "(null)", 0, 0, false, {1, 60}, {0}}}),
78 core_sysregion("null", *this, *this) { hide(); }
79 std::string
c_core_identifier() { return "null core"; }
80 bool c_set_region(core_region
& reg
) { return true; }
81 std::pair
<unsigned, unsigned> c_video_rate() { return std::make_pair(60, 1); }
82 double c_get_PAR() { return 1.0; }
83 std::pair
<unsigned, unsigned> c_audio_rate() { return std::make_pair(48000, 1); }
84 std::map
<std::string
, std::vector
<char>> c_save_sram() throw (std::bad_alloc
) {
85 std::map
<std::string
, std::vector
<char>> x
;
88 void c_load_sram(std::map
<std::string
, std::vector
<char>>& sram
) throw (std::bad_alloc
) {}
89 void c_serialize(std::vector
<char>& out
) { out
.clear(); }
90 void c_unserialize(const char* in
, size_t insize
) {}
91 core_region
& c_get_region() { return *this; }
93 void c_unload_cartridge() {}
94 std::pair
<uint32_t, uint32_t> c_get_scale_factors(uint32_t width
, uint32_t height
) {
95 return std::make_pair(1, 1);
97 void c_install_handler() {}
98 void c_uninstall_handler() {}
100 void c_runtosave() {}
101 bool c_get_pflag() { return false; }
102 void c_set_pflag(bool pflag
) {}
103 framebuffer::raw
& c_draw_cover() {
104 static framebuffer::raw
x(null_fbinfo
);
105 for(size_t i
= 0; i
< sizeof(null_cover_fbmem
)/sizeof(null_cover_fbmem
[0]); i
++)
106 null_cover_fbmem
[i
] = 0x0000;
107 std::string message
= "NO ROM LOADED";
108 cover_render_string(null_cover_fbmem
, 204, 220, message
, 0xFFFF, 0x0000, 512, 448, 1024, 2);
111 std::string
c_get_core_shortname() { return "null"; }
112 void c_pre_emulate_frame(controller_frame
& cf
) {}
113 void c_execute_action(unsigned id
, const std::vector
<interface_action_paramval
>& p
) {}
114 const interface_device_reg
* c_get_registers() { return null_registers
; }
115 int t_load_rom(core_romimage
* img
, std::map
<std::string
, std::string
>& settings
,
116 uint64_t secs
, uint64_t subsecs
)
120 controller_set
t_controllerconfig(std::map
<std::string
, std::string
>& settings
)
123 x
.ports
.push_back(&get_default_system_port_type());
126 std::pair
<uint64_t, uint64_t> c_get_bus_map() { return std::make_pair(0ULL, 0ULL); }
127 std::list
<core_vma_info
> c_vma_list() { return std::list
<core_vma_info
>(); }
128 std::set
<std::string
> c_srams() { return std::set
<std::string
>(); }
129 unsigned c_action_flags(unsigned id
) { return 0; }
130 int c_reset_action(bool hard
) { return -1; }
131 bool c_isnull() { return true; }
132 void c_set_debug_flags(uint64_t addr
, unsigned int sflags
, unsigned int cflags
) {}
133 void c_set_cheat(uint64_t addr
, uint64_t value
, bool set
) {}
134 void c_debug_reset() {}
135 std::vector
<std::string
> c_get_trace_cpus()
137 return std::vector
<std::string
>();
141 core_type
* current_rom_type
= &core_null
;
142 core_region
* current_region
= &core_null
;
144 core_type
* find_core_by_extension(const std::string
& ext
, const std::string
& tmpprefer
)
146 std::string key
= "ext:" + ext
;
147 std::list
<core_type
*> possible
= core_type::get_core_types();
148 core_type
* fallback
= NULL
;
149 core_type
* preferred
= preferred_core
.count(key
) ? preferred_core
[key
] : NULL
;
150 //Tmpprefer overrides normal preferred core.
152 for(auto i
: possible
)
153 if(i
->is_known_extension(ext
) && i
->get_core_identifier() == tmpprefer
)
155 for(auto i
: possible
)
156 if(i
->is_known_extension(ext
)) {
158 if(!preferred
&& i
->get_core_shortname() == preferred_core_default
)
166 core_type
* find_core_by_name(const std::string
& name
, const std::string
& tmpprefer
)
168 std::string key
= "type:" + name
;
169 std::list
<core_type
*> possible
= core_type::get_core_types();
170 core_type
* fallback
= NULL
;
171 core_type
* preferred
= preferred_core
.count(key
) ? preferred_core
[key
] : NULL
;
172 //Tmpprefer overrides normal preferred core.
174 for(auto i
: possible
)
175 if(i
->get_iname() == tmpprefer
)
177 for(auto i
: possible
)
178 if(i
->get_iname() == name
) {
180 if(!preferred
&& i
->get_core_shortname() == preferred_core_default
)
188 struct fileimage::image::info
get_xml_info()
190 fileimage::image::info i
;
191 i
.type
= fileimage::image::info::IT_MARKUP
;
196 struct fileimage::image::info
xlate_info(core_romimage_info ri
)
198 fileimage::image::info i
;
199 if(ri
.pass_mode
== 0) i
.type
= fileimage::image::info::IT_MEMORY
;
200 if(ri
.pass_mode
== 1) i
.type
= fileimage::image::info::IT_FILE
;
201 i
.headersize
= ri
.headersize
;
205 void record_files(loaded_rom
& rom
)
207 for(unsigned i
= 0; i
< ROM_SLOT_COUNT
; i
++) {
209 record_filehash(rom
.romimg
[i
].filename
, rom
.romimg
[i
].stripped
,
210 rom
.romimg
[i
].sha_256
.read());
213 record_filehash(rom
.romxml
[i
].filename
, rom
.romxml
[i
].stripped
,
214 rom
.romxml
[i
].sha_256
.read());
220 fileimage::hash lsnes_image_hasher
;
222 std::pair
<core_type
*, core_region
*> get_current_rom_info() throw()
224 return std::make_pair(current_rom_type
, current_region
);
227 loaded_rom::loaded_rom() throw()
230 region
= orig_region
= &core_null
;
233 loaded_rom::loaded_rom(const std::string
& file
, core_type
& ctype
) throw(std::bad_alloc
, std::runtime_error
)
236 region
= orig_region
= &rtype
->get_preferred_region();
239 unsigned pmand
= 0, tmand
= 0;
240 for(unsigned i
= 0; i
< ctype
.get_image_count(); i
++)
241 tmand
|= ctype
.get_image_info(i
).mandatory
;
242 if((bios
= ctype
.get_biosname()) != "") {
243 //This thing has a BIOS.
245 std::string basename
= lsnes_vset
["firmwarepath"].str() + "/" + bios
;
246 romimg
[0] = fileimage::image(lsnes_image_hasher
, basename
, "", xlate_info(ctype
.get_image_info(0)));
247 if(zip::file_exists(basename
+ ".xml"))
248 romxml
[0] = fileimage::image(lsnes_image_hasher
, basename
+ ".xml", "", get_xml_info());
249 pmand
|= ctype
.get_image_info(0).mandatory
;
251 romimg
[romidx
] = fileimage::image(lsnes_image_hasher
, file
, "", xlate_info(ctype
.get_image_info(romidx
)));
252 if(zip::file_exists(file
+ ".xml"))
253 romxml
[romidx
] = fileimage::image(lsnes_image_hasher
, file
+ ".xml", "", get_xml_info());
254 pmand
|= ctype
.get_image_info(romidx
).mandatory
;
255 msu1_base
= zip::resolverel(file
, "");
258 throw std::runtime_error("Required ROM images missing");
262 loaded_rom::loaded_rom(const std::string
& file
, const std::string
& tmpprefer
) throw(std::bad_alloc
,
265 std::istream
& spec
= zip::openrel(file
, "");
267 std::getline(spec
, s
);
269 if(!spec
|| s
!= "[GAMEPACK FILE]") {
270 //This is a Raw ROM image.
272 std::string ext
= regex(".*\\.([^.]*)?", file
, "Can't read file extension")[1];
273 core_type
* coretype
= find_core_by_extension(ext
, tmpprefer
);
275 (stringfmt() << "Extension '" << ext
<< "' unknown").throwex();
277 region
= orig_region
= &rtype
->get_preferred_region();
280 unsigned pmand
= 0, tmand
= 0;
281 for(unsigned i
= 0; i
< rtype
->get_image_count(); i
++)
282 tmand
|= rtype
->get_image_info(i
).mandatory
;
283 if((bios
= coretype
->get_biosname()) != "") {
284 //This thing has a BIOS.
286 std::string basename
= lsnes_vset
["firmwarepath"].str() + "/" + bios
;
287 romimg
[0] = fileimage::image(lsnes_image_hasher
, basename
, "",
288 xlate_info(coretype
->get_image_info(0)));
289 if(zip::file_exists(basename
+ ".xml"))
290 romxml
[0] = fileimage::image(lsnes_image_hasher
, basename
+ ".xml", "",
292 pmand
|= rtype
->get_image_info(0).mandatory
;
294 romimg
[romidx
] = fileimage::image(lsnes_image_hasher
, file
, "",
295 xlate_info(coretype
->get_image_info(romidx
)));
296 if(zip::file_exists(file
+ ".xml"))
297 romxml
[romidx
] = fileimage::image(lsnes_image_hasher
, file
+ ".xml", "", get_xml_info());
298 pmand
|= rtype
->get_image_info(romidx
).mandatory
;
299 msu1_base
= zip::resolverel(file
, "");
302 throw std::runtime_error("Required ROM images missing");
305 load_filename
= file
;
306 std::vector
<std::string
> lines
;
307 while(std::getline(spec
, s
))
308 lines
.push_back(strip_CR(s
));
309 std::string platname
= "";
310 std::string platreg
= "";
311 for(auto i
: lines
) {
313 if(tmp
= regex("type[ \t]+(.+)", i
))
315 if(tmp
= regex("region[ \t]+(.+)", i
))
320 rtype
= find_core_by_name(platname
, tmpprefer
);
322 (stringfmt() << "Not a valid system type '" << platname
<< "'").throwex();
325 bool goodreg
= false;
326 orig_region
= &rtype
->get_preferred_region();
327 for(auto i
: rtype
->get_regions())
328 if(i
->get_iname() == platreg
) {
332 if(!goodreg
&& platreg
!= "")
333 (stringfmt() << "Not a valid system region '" << platreg
<< "'").throwex();
334 region
= orig_region
;
337 std::string cromimg
[ROM_SLOT_COUNT
];
338 std::string cromxml
[ROM_SLOT_COUNT
];
339 for(auto i
: lines
) {
341 if(!(tmp
= regex("(rom|xml)[ \t]+([^ \t]+)[ \t]+(.*)", i
)))
343 size_t idxs
= rtype
->get_image_count();
345 for(size_t i
= 0; i
< idxs
; i
++)
346 if(rtype
->get_image_info(i
).iname
== tmp
[2])
349 (stringfmt() << "Not a valid ROM name '" << tmp
[2] << "'").throwex();
351 cromimg
[idx
] = tmp
[3];
353 cromxml
[idx
] = tmp
[3];
357 unsigned mask1
= 0, mask2
= 0;
358 for(size_t i
= 0; i
< rtype
->get_image_count(); i
++) {
359 auto ii
= rtype
->get_image_info(i
);
360 mask1
|= ii
.mandatory
;
362 mask2
|= ii
.mandatory
;
363 if(cromimg
[i
] == "" && cromxml
[i
] != "") {
364 messages
<< "WARNING: Slot " << ii
.iname
<< ": XML without ROM." << std::endl
;
369 throw std::runtime_error("Required ROM missing");
372 for(size_t i
= 0; i
< rtype
->get_image_count(); i
++) {
373 romimg
[i
] = fileimage::image(lsnes_image_hasher
, cromimg
[i
], file
,
374 xlate_info(rtype
->get_image_info(i
)));
375 romxml
[i
] = fileimage::image(lsnes_image_hasher
, cromxml
[i
], file
, get_xml_info());
377 record_files(*this); //Have to do this before patching.
380 for(auto i
: lines
) {
382 if(!(tmp
= regex("patch([+-][0-9]+)?[ \t]+([^ \t]+)[ \t]+(.*)", i
)))
384 size_t idxs
= rtype
->get_image_count();
386 for(size_t i
= 0; i
< idxs
; i
++)
387 if(rtype
->get_image_info(i
).iname
== tmp
[2])
390 (stringfmt() << "Not a valid ROM name '" << tmp
[2] << "'").throwex();
393 offset
= parse_value
<int32_t>(tmp
[1]);
394 romimg
[idx
].patch(zip::readrel(tmp
[3], file
), offset
);
399 msu1_base
= zip::resolverel(cromimg
[1], file
);
401 msu1_base
= zip::resolverel(cromimg
[0], file
);
406 bool filter_by_core(core_type
& ctype
, const std::string
& core
)
408 return (core
== "" || ctype
.get_core_identifier() == core
);
411 bool filter_by_type(core_type
& ctype
, const std::string
& type
)
413 return (type
== "" || ctype
.get_iname() == type
);
416 bool filter_by_region(core_type
& ctype
, const std::string
& region
)
420 for(auto i
: ctype
.get_regions())
421 if(i
->get_iname() == region
)
426 bool filter_by_extension(core_type
& ctype
, const std::string
& file
)
428 regex_results tmp
= regex(".*\\.([^.]*)", file
);
431 std::string ext
= tmp
[1];
432 return ctype
.is_known_extension(ext
);
435 bool filter_by_fileset(core_type
& ctype
, const std::string file
[ROM_SLOT_COUNT
])
437 uint32_t m
= 0, t
= 0;
438 for(unsigned i
= 0; i
< ROM_SLOT_COUNT
; i
++) {
439 if(i
>= ctype
.get_image_count() && file
[i
] != "")
441 auto s
= ctype
.get_image_info(i
);
449 core_region
* detect_region(core_type
* t
, const std::string
& region
)
451 core_region
* r
= NULL
;
452 for(auto i
: t
->get_regions())
453 if(i
->get_iname() == region
)
455 if(!r
&& region
!= "")
456 (stringfmt() << "Not a valid system region '" << region
<< "'").throwex();
457 if(!r
) r
= &t
->get_preferred_region(); //Default region.
462 loaded_rom::loaded_rom(const std::string
& file
, const std::string
& core
, const std::string
& type
,
463 const std::string
& _region
)
466 core_region
* r
= NULL
;
467 bool fullspec
= (core
!= "" && type
!= "");
468 for(auto i
: core_type::get_core_types()) {
469 if(!filter_by_core(*i
, core
))
471 if(!filter_by_type(*i
, type
))
473 if(!fullspec
&& !filter_by_region(*i
, _region
))
475 if(!fullspec
&& !filter_by_extension(*i
, file
))
479 if(!t
) throw std::runtime_error("No matching core found");
480 r
= detect_region(t
, _region
);
481 unsigned pmand
= 0, tmand
= 0;
482 for(unsigned i
= 0; i
< t
->get_image_count(); i
++)
483 tmand
|= t
->get_image_info(i
).mandatory
;
484 std::string bios
= t
->get_biosname();
485 unsigned romidx
= (bios
!= "") ? 1 : 0;
487 std::string basename
= lsnes_vset
["firmwarepath"].str() + "/" + bios
;
488 romimg
[0] = fileimage::image(lsnes_image_hasher
, basename
, "", xlate_info(t
->get_image_info(0)));
489 if(zip::file_exists(basename
+ ".xml"))
490 romxml
[0] = fileimage::image(lsnes_image_hasher
, basename
+ ".xml", "", get_xml_info());
491 pmand
|= t
->get_image_info(0).mandatory
;
493 romimg
[romidx
] = fileimage::image(lsnes_image_hasher
, file
, "", xlate_info(t
->get_image_info(romidx
)));
494 if(zip::file_exists(file
+ ".xml"))
495 romxml
[romidx
] = fileimage::image(lsnes_image_hasher
, file
+ ".xml", "", get_xml_info());
496 pmand
|= t
->get_image_info(romidx
).mandatory
;
497 msu1_base
= zip::resolverel(file
, "");
500 throw std::runtime_error("Required ROM images missing");
502 orig_region
= region
= r
;
505 loaded_rom::loaded_rom(const std::string file
[ROM_SLOT_COUNT
], const std::string
& core
, const std::string
& type
,
506 const std::string
& _region
)
509 core_region
* r
= NULL
;
510 bool fullspec
= (core
!= "" && type
!= "");
511 for(auto i
: core_type::get_core_types()) {
512 if(!filter_by_core(*i
, core
)) {
515 if(!filter_by_type(*i
, type
)) {
518 if(!fullspec
&& !filter_by_region(*i
, _region
)) {
521 if(!fullspec
&& !filter_by_fileset(*i
, file
)) {
526 if(!t
) throw std::runtime_error("No matching core found");
527 r
= detect_region(t
, _region
);
528 std::string bios
= t
->get_biosname();
529 unsigned romidx
= (bios
!= "") ? 1 : 0;
530 unsigned pmand
= 0, tmand
= 0;
531 for(unsigned i
= 0; i
< 27; i
++) {
532 if(i
>= t
->get_image_count())
535 pmand
|= t
->get_image_info(i
).mandatory
;
536 tmand
|= t
->get_image_info(i
).mandatory
;
537 romimg
[i
] = fileimage::image(lsnes_image_hasher
, file
[i
], "", xlate_info(t
->get_image_info(i
)));
538 if(zip::file_exists(file
[i
] + ".xml"))
539 romxml
[i
] = fileimage::image(lsnes_image_hasher
, file
[i
] + ".xml", "", get_xml_info());
541 msu1_base
= zip::resolverel(file
[romidx
], "");
544 throw std::runtime_error("Required ROM images missing");
546 orig_region
= region
= r
;
549 void loaded_rom::load(std::map
<std::string
, std::string
>& settings
, uint64_t rtc_sec
, uint64_t rtc_subsec
)
550 throw(std::bad_alloc
, std::runtime_error
)
552 core_type
* old_type
= current_rom_type
;
553 core_core
* old_core
= current_rom_type
->get_core();
554 current_rom_type
= &core_null
;
555 if(!orig_region
&& rtype
!= &core_null
)
556 orig_region
= &rtype
->get_preferred_region();
558 region
= orig_region
;
559 if(rtype
&& !orig_region
->compatible_with(*region
))
560 throw std::runtime_error("Trying to force incompatible region");
561 if(rtype
&& !rtype
->set_region(*region
))
562 throw std::runtime_error("Trying to force unknown region");
564 core_romimage images
[ROM_SLOT_COUNT
];
565 for(size_t i
= 0; i
< ROM_SLOT_COUNT
; i
++) {
566 images
[i
].markup
= (const char*)romxml
[i
];
567 images
[i
].data
= (const unsigned char*)romimg
[i
];
568 images
[i
].size
= (size_t)romimg
[i
];
570 if(!rtype
->load(images
, settings
, rtc_sec
, rtc_subsec
))
571 throw std::runtime_error("Can't load cartridge ROM");
573 region
= &rtype
->get_region();
575 auto nominal_fps
= rtype
->get_video_rate();
576 auto nominal_hz
= rtype
->get_audio_rate();
577 set_nominal_framerate(1.0 * nominal_fps
.first
/ nominal_fps
.second
);
578 information_dispatch::do_sound_rate(nominal_hz
.first
, nominal_hz
.second
);
579 current_rom_type
= rtype
;
580 current_region
= region
;
581 //If core changes, unload the cartridge.
582 if(old_core
!= current_rom_type
->get_core())
584 old_core
->debug_reset();
585 old_core
->unload_cartridge();
587 refresh_cart_mappings();
588 notify_core_changed(old_type
!= current_rom_type
);
591 std::map
<std::string
, std::vector
<char>> load_sram_commandline(const std::vector
<std::string
>& cmdline
)
592 throw(std::bad_alloc
, std::runtime_error
)
594 std::map
<std::string
, std::vector
<char>> ret
;
596 for(auto i
: cmdline
) {
597 if(opt
= regex("--continue=(.+)", i
)) {
598 zip::reader
r(opt
[1]);
600 auto sramname
= regex("sram\\.(.*)", j
);
603 std::istream
& x
= r
[j
];
605 std::vector
<char> out
;
606 boost::iostreams::back_insert_device
<std::vector
<char>> rd(out
);
607 boost::iostreams::copy(x
, rd
);
609 ret
[sramname
[1]] = out
;
616 } else if(opt
= regex("--sram-([^=]+)=(.+)", i
)) {
618 ret
[opt
[1]] = zip::readrel(opt
[2], "");
619 } catch(std::bad_alloc
& e
) {
621 } catch(std::runtime_error
& e
) {
622 throw std::runtime_error("Can't load SRAM '" + opt
[1] + "': " + e
.what());
629 std::vector
<char> loaded_rom::save_core_state(bool nochecksum
) throw(std::bad_alloc
, std::runtime_error
)
631 std::vector
<char> ret
;
632 rtype
->serialize(ret
);
635 size_t offset
= ret
.size();
636 unsigned char tmp
[32];
637 #ifdef USE_LIBGCRYPT_SHA256
638 gcry_md_hash_buffer(GCRY_MD_SHA256
, tmp
, &ret
[0], offset
);
640 sha256::hash(tmp
, ret
);
642 ret
.resize(offset
+ 32);
643 memcpy(&ret
[offset
], tmp
, 32);
647 void loaded_rom::load_core_state(const std::vector
<char>& buf
, bool nochecksum
) throw(std::runtime_error
)
650 rtype
->unserialize(&buf
[0], buf
.size());
655 throw std::runtime_error("Savestate corrupt");
656 if(!savestate_no_check
) {
657 unsigned char tmp
[32];
658 #ifdef USE_LIBGCRYPT_SHA256
659 gcry_md_hash_buffer(GCRY_MD_SHA256
, tmp
, &buf
[0], buf
.size() - 32);
661 sha256::hash(tmp
, reinterpret_cast<const uint8_t*>(&buf
[0]), buf
.size() - 32);
663 if(memcmp(tmp
, &buf
[buf
.size() - 32], 32))
664 throw std::runtime_error("Savestate corrupt");
666 rtype
->unserialize(&buf
[0], buf
.size() - 32);
669 void set_hasher_callback(std::function
<void(uint64_t, uint64_t)> cb
)
671 lsnes_image_hasher
.set_callback(cb
);
674 std::map
<std::string
, core_type
*> preferred_core
;
675 std::string preferred_core_default
;