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/pixfmt-rgb16.hpp"
17 #include "library/controller-data.hpp"
18 #include "library/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>
37 #include <boost/filesystem.hpp>
39 #ifdef USE_LIBGCRYPT_SHA256
43 #ifdef BOOST_FILESYSTEM3
44 namespace boost_fs
= boost::filesystem3
;
46 namespace boost_fs
= boost::filesystem
;
51 const char* null_chars
= "F";
52 uint16_t null_cover_fbmem
[512 * 448];
54 setting_var
<setting_var_model_bool
<setting_yes_no
>> savestate_no_check(lsnes_vset
, "dont-check-savestate",
55 "Movie‣Loading‣Don't check savestates", false);
58 struct framebuffer_info null_fbinfo
= {
59 &_pixel_format_bgr16
, //Format.
60 (char*)null_cover_fbmem
, //Memory.
61 512, 448, 1024, //Physical size.
62 512, 448, 1024, //Logical size.
66 port_index_triple sync_triple
= {true, 0, 0, 0 };
68 struct interface_device_reg null_registers
[] = {
72 struct _core_null
: public core_core
, public core_type
, public core_region
, public core_sysregion
74 _core_null() : core_core({}, {}), core_type({{
84 }}), core_region({{"null", "(null)", 0, 0, false, {1, 60}, {0}}}),
85 core_sysregion("null", *this, *this) {}
86 std::string
c_core_identifier() { return "null core"; }
87 bool c_set_region(core_region
& reg
) { return true; }
88 std::pair
<unsigned, unsigned> c_video_rate() { return std::make_pair(60, 1); }
89 double c_get_PAR() { return 1.0; }
90 std::pair
<unsigned, unsigned> c_audio_rate() { return std::make_pair(48000, 1); }
91 std::map
<std::string
, std::vector
<char>> c_save_sram() throw (std::bad_alloc
) {
92 std::map
<std::string
, std::vector
<char>> x
;
95 void c_load_sram(std::map
<std::string
, std::vector
<char>>& sram
) throw (std::bad_alloc
) {}
96 void c_serialize(std::vector
<char>& out
) { out
.clear(); }
97 void c_unserialize(const char* in
, size_t insize
) {}
98 core_region
& c_get_region() { return *this; }
100 void c_unload_cartridge() {}
101 std::pair
<uint32_t, uint32_t> c_get_scale_factors(uint32_t width
, uint32_t height
) {
102 return std::make_pair(1, 1);
104 void c_install_handler() {}
105 void c_uninstall_handler() {}
107 void c_runtosave() {}
108 bool c_get_pflag() { return false; }
109 void c_set_pflag(bool pflag
) {}
110 framebuffer_raw
& c_draw_cover() {
111 static framebuffer_raw
x(null_fbinfo
);
112 for(size_t i
= 0; i
< sizeof(null_cover_fbmem
)/sizeof(null_cover_fbmem
[0]); i
++)
113 null_cover_fbmem
[i
] = 0x0000;
114 std::string message
= "NO ROM LOADED";
115 cover_render_string(null_cover_fbmem
, 204, 220, message
, 0xFFFF, 0x0000, 512, 448, 1024, 2);
118 std::string
c_get_core_shortname() { return "null"; }
119 void c_pre_emulate_frame(controller_frame
& cf
) {}
120 void c_execute_action(unsigned id
, const std::vector
<interface_action_paramval
>& p
) {}
121 const interface_device_reg
* c_get_registers() { return null_registers
; }
122 int t_load_rom(core_romimage
* img
, std::map
<std::string
, std::string
>& settings
,
123 uint64_t secs
, uint64_t subsecs
)
127 controller_set
t_controllerconfig(std::map
<std::string
, std::string
>& settings
)
130 x
.ports
.push_back(&get_default_system_port_type());
133 std::pair
<uint64_t, uint64_t> c_get_bus_map() { return std::make_pair(0ULL, 0ULL); }
134 std::list
<core_vma_info
> c_vma_list() { return std::list
<core_vma_info
>(); }
135 std::set
<std::string
> c_srams() { return std::set
<std::string
>(); }
136 unsigned c_action_flags(unsigned id
) { return 0; }
137 int c_reset_action(bool hard
) { return -1; }
138 bool c_isnull() { return true; }
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
->get_iname() == 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 loaded_image::info
get_xml_info()
190 loaded_image::info i
;
191 i
.type
= loaded_image::info::IT_MARKUP
;
196 struct loaded_image::info
xlate_info(core_romimage_info ri
)
198 loaded_image::info i
;
199 if(ri
.pass_mode
== 0) i
.type
= loaded_image::info::IT_MEMORY
;
200 if(ri
.pass_mode
== 1) i
.type
= loaded_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 sha256_hasher 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] = loaded_image(lsnes_image_hasher
, basename
, "", xlate_info(ctype
.get_image_info(0)));
247 if(file_exists_zip(basename
+ ".xml"))
248 romxml
[0] = loaded_image(lsnes_image_hasher
, basename
+ ".xml", "", get_xml_info());
249 pmand
|= ctype
.get_image_info(0).mandatory
;
251 romimg
[romidx
] = loaded_image(lsnes_image_hasher
, file
, "", xlate_info(ctype
.get_image_info(romidx
)));
252 if(file_exists_zip(file
+ ".xml"))
253 romxml
[romidx
] = loaded_image(lsnes_image_hasher
, file
+ ".xml", "", get_xml_info());
254 pmand
|= ctype
.get_image_info(romidx
).mandatory
;
255 msu1_base
= resolve_file_relative(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
= open_file_relative(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] = loaded_image(lsnes_image_hasher
, basename
, "",
288 xlate_info(coretype
->get_image_info(0)));
289 if(file_exists_zip(basename
+ ".xml"))
290 romxml
[0] = loaded_image(lsnes_image_hasher
, basename
+ ".xml", "", get_xml_info());
291 pmand
|= rtype
->get_image_info(0).mandatory
;
293 romimg
[romidx
] = loaded_image(lsnes_image_hasher
, file
, "",
294 xlate_info(coretype
->get_image_info(romidx
)));
295 if(file_exists_zip(file
+ ".xml"))
296 romxml
[romidx
] = loaded_image(lsnes_image_hasher
, file
+ ".xml", "", get_xml_info());
297 pmand
|= rtype
->get_image_info(romidx
).mandatory
;
298 msu1_base
= resolve_file_relative(file
, "");
301 throw std::runtime_error("Required ROM images missing");
304 load_filename
= file
;
305 std::vector
<std::string
> lines
;
306 while(std::getline(spec
, s
))
307 lines
.push_back(strip_CR(s
));
308 std::string platname
= "";
309 std::string platreg
= "";
310 for(auto i
: lines
) {
312 if(tmp
= regex("type[ \t]+(.+)", i
))
314 if(tmp
= regex("region[ \t]+(.+)", i
))
319 rtype
= find_core_by_name(platname
, tmpprefer
);
321 (stringfmt() << "Not a valid system type '" << platname
<< "'").throwex();
324 bool goodreg
= false;
325 orig_region
= &rtype
->get_preferred_region();
326 for(auto i
: rtype
->get_regions())
327 if(i
->get_iname() == platreg
) {
331 if(!goodreg
&& platreg
!= "")
332 (stringfmt() << "Not a valid system region '" << platreg
<< "'").throwex();
333 region
= orig_region
;
336 std::string cromimg
[ROM_SLOT_COUNT
];
337 std::string cromxml
[ROM_SLOT_COUNT
];
338 for(auto i
: lines
) {
340 if(!(tmp
= regex("(rom|xml)[ \t]+([^ \t]+)[ \t]+(.*)", i
)))
342 size_t idxs
= rtype
->get_image_count();
344 for(size_t i
= 0; i
< idxs
; i
++)
345 if(rtype
->get_image_info(i
).iname
== tmp
[2])
348 (stringfmt() << "Not a valid ROM name '" << tmp
[2] << "'").throwex();
350 cromimg
[idx
] = tmp
[3];
352 cromxml
[idx
] = tmp
[3];
356 unsigned mask1
= 0, mask2
= 0;
357 for(size_t i
= 0; i
< rtype
->get_image_count(); i
++) {
358 auto ii
= rtype
->get_image_info(i
);
359 mask1
|= ii
.mandatory
;
361 mask2
|= ii
.mandatory
;
362 if(cromimg
[i
] == "" && cromxml
[i
] != "") {
363 messages
<< "WARNING: Slot " << ii
.iname
<< ": XML without ROM." << std::endl
;
368 throw std::runtime_error("Required ROM missing");
371 for(size_t i
= 0; i
< rtype
->get_image_count(); i
++) {
372 romimg
[i
] = loaded_image(lsnes_image_hasher
, cromimg
[i
], file
, xlate_info(rtype
->get_image_info(i
)));
373 romxml
[i
] = loaded_image(lsnes_image_hasher
, cromxml
[i
], file
, get_xml_info());
375 record_files(*this); //Have to do this before patching.
378 for(auto i
: lines
) {
380 if(!(tmp
= regex("patch([+-][0-9]+)?[ \t]+([^ \t]+)[ \t]+(.*)", i
)))
382 size_t idxs
= rtype
->get_image_count();
384 for(size_t i
= 0; i
< idxs
; i
++)
385 if(rtype
->get_image_info(i
).iname
== tmp
[2])
388 (stringfmt() << "Not a valid ROM name '" << tmp
[2] << "'").throwex();
391 offset
= parse_value
<int32_t>(tmp
[1]);
392 romimg
[idx
].patch(read_file_relative(tmp
[3], file
), offset
);
397 msu1_base
= resolve_file_relative(cromimg
[1], file
);
399 msu1_base
= resolve_file_relative(cromimg
[0], file
);
404 bool filter_by_core(core_type
& ctype
, const std::string
& core
)
406 return (core
== "" || ctype
.get_core_identifier() == core
);
409 bool filter_by_type(core_type
& ctype
, const std::string
& type
)
411 return (type
== "" || ctype
.get_iname() == type
);
414 bool filter_by_region(core_type
& ctype
, const std::string
& region
)
418 for(auto i
: ctype
.get_regions())
419 if(i
->get_iname() == region
)
424 bool filter_by_extension(core_type
& ctype
, const std::string
& file
)
426 regex_results tmp
= regex(".*\\.([^.]*)", file
);
429 std::string ext
= tmp
[1];
430 return ctype
.is_known_extension(ext
);
433 bool filter_by_fileset(core_type
& ctype
, const std::string file
[ROM_SLOT_COUNT
])
435 uint32_t m
= 0, t
= 0;
436 for(unsigned i
= 0; i
< ROM_SLOT_COUNT
; i
++) {
437 if(i
>= ctype
.get_image_count() && file
[i
] != "")
439 auto s
= ctype
.get_image_info(i
);
447 core_region
* detect_region(core_type
* t
, const std::string
& region
)
449 core_region
* r
= NULL
;
450 for(auto i
: t
->get_regions())
451 if(i
->get_iname() == region
)
453 if(!r
&& region
!= "")
454 (stringfmt() << "Not a valid system region '" << region
<< "'").throwex();
455 if(!r
) r
= &t
->get_preferred_region(); //Default region.
460 loaded_rom::loaded_rom(const std::string
& file
, const std::string
& core
, const std::string
& type
,
461 const std::string
& _region
)
464 core_region
* r
= NULL
;
465 bool fullspec
= (core
!= "" && type
!= "");
466 for(auto i
: core_type::get_core_types()) {
467 if(!filter_by_core(*i
, core
))
469 if(!filter_by_type(*i
, type
))
471 if(!fullspec
&& !filter_by_region(*i
, _region
))
473 if(!fullspec
&& !filter_by_extension(*i
, file
))
477 if(!t
) throw std::runtime_error("No matching core found");
478 r
= detect_region(t
, _region
);
479 unsigned pmand
= 0, tmand
= 0;
480 for(unsigned i
= 0; i
< t
->get_image_count(); i
++)
481 tmand
|= t
->get_image_info(i
).mandatory
;
482 std::string bios
= t
->get_biosname();
483 unsigned romidx
= (bios
!= "") ? 1 : 0;
485 std::string basename
= lsnes_vset
["firmwarepath"].str() + "/" + bios
;
486 romimg
[0] = loaded_image(lsnes_image_hasher
, basename
, "", xlate_info(t
->get_image_info(0)));
487 if(file_exists_zip(basename
+ ".xml"))
488 romxml
[0] = loaded_image(lsnes_image_hasher
, basename
+ ".xml", "", get_xml_info());
489 pmand
|= t
->get_image_info(0).mandatory
;
491 romimg
[romidx
] = loaded_image(lsnes_image_hasher
, file
, "", xlate_info(t
->get_image_info(romidx
)));
492 if(file_exists_zip(file
+ ".xml"))
493 romxml
[romidx
] = loaded_image(lsnes_image_hasher
, file
+ ".xml", "", get_xml_info());
494 pmand
|= t
->get_image_info(romidx
).mandatory
;
495 msu1_base
= resolve_file_relative(file
, "");
498 throw std::runtime_error("Required ROM images missing");
500 orig_region
= region
= r
;
503 loaded_rom::loaded_rom(const std::string file
[ROM_SLOT_COUNT
], const std::string
& core
, const std::string
& type
,
504 const std::string
& _region
)
507 core_region
* r
= NULL
;
508 bool fullspec
= (core
!= "" && type
!= "");
509 for(auto i
: core_type::get_core_types()) {
510 if(!filter_by_core(*i
, core
)) {
513 if(!filter_by_type(*i
, type
)) {
516 if(!fullspec
&& !filter_by_region(*i
, _region
)) {
519 if(!fullspec
&& !filter_by_fileset(*i
, file
)) {
524 if(!t
) throw std::runtime_error("No matching core found");
525 r
= detect_region(t
, _region
);
526 std::string bios
= t
->get_biosname();
527 unsigned romidx
= (bios
!= "") ? 1 : 0;
528 unsigned pmand
= 0, tmand
= 0;
529 for(unsigned i
= 0; i
< 27; i
++) {
530 if(i
>= t
->get_image_count())
533 pmand
|= t
->get_image_info(i
).mandatory
;
534 tmand
|= t
->get_image_info(i
).mandatory
;
535 romimg
[i
] = loaded_image(lsnes_image_hasher
, file
[i
], "", xlate_info(t
->get_image_info(i
)));
536 if(file_exists_zip(file
[i
] + ".xml"))
537 romxml
[i
] = loaded_image(lsnes_image_hasher
, file
[i
] + ".xml", "", get_xml_info());
539 msu1_base
= resolve_file_relative(file
[romidx
], "");
542 throw std::runtime_error("Required ROM images missing");
544 orig_region
= region
= r
;
547 void loaded_rom::load(std::map
<std::string
, std::string
>& settings
, uint64_t rtc_sec
, uint64_t rtc_subsec
)
548 throw(std::bad_alloc
, std::runtime_error
)
550 core_type
* old_type
= current_rom_type
;
551 core_core
* old_core
= current_rom_type
->get_core();
552 current_rom_type
= &core_null
;
553 if(!orig_region
&& rtype
!= &core_null
)
554 orig_region
= &rtype
->get_preferred_region();
556 region
= orig_region
;
557 if(rtype
&& !orig_region
->compatible_with(*region
))
558 throw std::runtime_error("Trying to force incompatible region");
559 if(rtype
&& !rtype
->set_region(*region
))
560 throw std::runtime_error("Trying to force unknown region");
562 core_romimage images
[ROM_SLOT_COUNT
];
563 for(size_t i
= 0; i
< ROM_SLOT_COUNT
; i
++) {
564 images
[i
].markup
= (const char*)romxml
[i
];
565 images
[i
].data
= (const unsigned char*)romimg
[i
];
566 images
[i
].size
= (size_t)romimg
[i
];
568 if(!rtype
->load(images
, settings
, rtc_sec
, rtc_subsec
))
569 throw std::runtime_error("Can't load cartridge ROM");
571 region
= &rtype
->get_region();
573 auto nominal_fps
= rtype
->get_video_rate();
574 auto nominal_hz
= rtype
->get_audio_rate();
575 set_nominal_framerate(1.0 * nominal_fps
.first
/ nominal_fps
.second
);
576 information_dispatch::do_sound_rate(nominal_hz
.first
, nominal_hz
.second
);
577 current_rom_type
= rtype
;
578 current_region
= region
;
579 //If core changes, unload the cartridge.
580 if(old_core
!= current_rom_type
->get_core())
581 try { old_core
->unload_cartridge(); } catch(...) {}
582 refresh_cart_mappings();
583 notify_core_changed(old_type
!= current_rom_type
);
586 std::map
<std::string
, std::vector
<char>> load_sram_commandline(const std::vector
<std::string
>& cmdline
)
587 throw(std::bad_alloc
, std::runtime_error
)
589 std::map
<std::string
, std::vector
<char>> ret
;
591 for(auto i
: cmdline
) {
592 if(opt
= regex("--continue=(.+)", i
)) {
593 zip_reader
r(opt
[1]);
595 auto sramname
= regex("sram\\.(.*)", j
);
598 std::istream
& x
= r
[j
];
600 std::vector
<char> out
;
601 boost::iostreams::back_insert_device
<std::vector
<char>> rd(out
);
602 boost::iostreams::copy(x
, rd
);
604 ret
[sramname
[1]] = out
;
611 } else if(opt
= regex("--sram-([^=]+)=(.+)", i
)) {
613 ret
[opt
[1]] = read_file_relative(opt
[2], "");
614 } catch(std::bad_alloc
& e
) {
616 } catch(std::runtime_error
& e
) {
617 throw std::runtime_error("Can't load SRAM '" + opt
[1] + "': " + e
.what());
624 std::vector
<char> loaded_rom::save_core_state(bool nochecksum
) throw(std::bad_alloc
)
626 std::vector
<char> ret
;
627 rtype
->serialize(ret
);
630 size_t offset
= ret
.size();
631 unsigned char tmp
[32];
632 #ifdef USE_LIBGCRYPT_SHA256
633 gcry_md_hash_buffer(GCRY_MD_SHA256
, tmp
, &ret
[0], offset
);
635 sha256::hash(tmp
, ret
);
637 ret
.resize(offset
+ 32);
638 memcpy(&ret
[offset
], tmp
, 32);
642 void loaded_rom::load_core_state(const std::vector
<char>& buf
, bool nochecksum
) throw(std::runtime_error
)
645 rtype
->unserialize(&buf
[0], buf
.size());
650 throw std::runtime_error("Savestate corrupt");
651 if(!savestate_no_check
) {
652 unsigned char tmp
[32];
653 #ifdef USE_LIBGCRYPT_SHA256
654 gcry_md_hash_buffer(GCRY_MD_SHA256
, tmp
, &buf
[0], buf
.size() - 32);
656 sha256::hash(tmp
, reinterpret_cast<const uint8_t*>(&buf
[0]), buf
.size() - 32);
658 if(memcmp(tmp
, &buf
[buf
.size() - 32], 32))
659 throw std::runtime_error("Savestate corrupt");
661 rtype
->unserialize(&buf
[0], buf
.size() - 32);
664 void set_hasher_callback(std::function
<void(uint64_t, uint64_t)> cb
)
666 lsnes_image_hasher
.set_callback(cb
);
669 std::map
<std::string
, core_type
*> preferred_core
;
670 std::string preferred_core_default
;