3 #include "core/advdumper.hpp"
4 #include "core/dispatch.hpp"
5 #include "core/framerate.hpp"
6 #include "core/instance.hpp"
7 #include "core/memorymanip.hpp"
8 #include "core/messages.hpp"
9 #include "core/nullcore.hpp"
10 #include "core/rom.hpp"
11 #include "core/settings.hpp"
12 #include "core/window.hpp"
13 #include "interface/callbacks.hpp"
14 #include "interface/cover.hpp"
15 #include "interface/romtype.hpp"
16 #include "library/portctrl-data.hpp"
17 #include "library/fileimage-patch.hpp"
18 #include "library/sha256.hpp"
19 #include "library/string.hpp"
20 #include "library/zip.hpp"
27 #include <boost/iostreams/categories.hpp>
28 #include <boost/iostreams/copy.hpp>
29 #include <boost/iostreams/stream.hpp>
30 #include <boost/iostreams/stream_buffer.hpp>
31 #include <boost/iostreams/filter/symmetric.hpp>
32 #include <boost/iostreams/filter/zlib.hpp>
33 #include <boost/iostreams/filtering_stream.hpp>
34 #include <boost/iostreams/device/back_inserter.hpp>
36 #ifdef USE_LIBGCRYPT_SHA256
42 settingvar::supervariable
<settingvar::model_bool
<settingvar::yes_no
>> savestate_no_check(lsnes_setgrp
,
43 "dont-check-savestate", "Movie‣Loading‣Don't check savestates", false);
45 core_type
* current_rom_type
= &get_null_type();
46 core_region
* current_region
= &get_null_region();
49 std::pair
<core_type
*, core_region
*> get_current_rom_info() throw()
51 return std::make_pair(current_rom_type
, current_region
);
54 loaded_rom::loaded_rom() throw()
56 region
= &image
->get_region();
59 loaded_rom::loaded_rom(rom_image_handle _image
) throw(std::bad_alloc
, std::runtime_error
)
62 region
= &image
->get_region();
65 void loaded_rom::load(std::map
<std::string
, std::string
>& settings
, uint64_t rtc_sec
, uint64_t rtc_subsec
)
66 throw(std::bad_alloc
, std::runtime_error
)
69 core_type
* old_type
= current_rom_type
;
70 core_core
* old_core
= current_rom_type
->get_core();
71 current_rom_type
= &get_null_type();
72 if(&rtype() != &get_null_type())
73 image
->setup_region(rtype().get_preferred_region());
75 region
= &image
->get_region();
76 if(!image
->get_region().compatible_with(*region
))
77 throw std::runtime_error("Trying to force incompatible region");
78 if(!rtype().set_region(*region
))
79 throw std::runtime_error("Trying to force unknown region");
81 core_romimage images
[ROM_SLOT_COUNT
];
82 for(size_t i
= 0; i
< ROM_SLOT_COUNT
; i
++) {
83 auto& img
= image
->get_image(i
, false);
84 auto& xml
= image
->get_image(i
, true);
85 images
[i
].markup
= (const char*)xml
;
86 images
[i
].data
= (const unsigned char*)img
;
87 images
[i
].size
= (size_t)img
;
89 if(!rtype().load(images
, settings
, rtc_sec
, rtc_subsec
))
90 throw std::runtime_error("Can't load cartridge ROM");
92 region
= &rtype().get_region();
94 auto nominal_fps
= rtype().get_video_rate();
95 auto nominal_hz
= rtype().get_audio_rate();
96 core
.framerate
->set_nominal_framerate(1.0 * nominal_fps
.first
/ nominal_fps
.second
);
97 core
.mdumper
->on_rate_change(nominal_hz
.first
, nominal_hz
.second
);
99 current_rom_type
= &rtype();
100 current_region
= region
;
101 //If core changes, unload the cartridge.
102 if(old_core
!= current_rom_type
->get_core())
104 old_core
->debug_reset();
105 old_core
->unload_cartridge();
108 core
.dispatch
->core_changed(old_type
!= current_rom_type
);
111 std::map
<std::string
, std::vector
<char>> load_sram_commandline(const std::vector
<std::string
>& cmdline
)
112 throw(std::bad_alloc
, std::runtime_error
)
114 std::map
<std::string
, std::vector
<char>> ret
;
116 for(auto i
: cmdline
) {
117 if(opt
= regex("--continue=(.+)", i
)) {
118 zip::reader
r(opt
[1]);
120 auto sramname
= regex("sram\\.(.*)", j
);
123 std::istream
& x
= r
[j
];
125 std::vector
<char> out
;
126 boost::iostreams::back_insert_device
<std::vector
<char>> rd(out
);
127 boost::iostreams::copy(x
, rd
);
129 ret
[sramname
[1]] = out
;
136 } else if(opt
= regex("--sram-([^=]+)=(.+)", i
)) {
138 ret
[opt
[1]] = zip::readrel(opt
[2], "");
139 } catch(std::bad_alloc
& e
) {
141 } catch(std::runtime_error
& e
) {
142 throw std::runtime_error("Can't load SRAM '" + opt
[1] + "': " + e
.what());
149 std::vector
<char> loaded_rom::save_core_state(bool nochecksum
) throw(std::bad_alloc
, std::runtime_error
)
151 std::vector
<char> ret
;
152 rtype().serialize(ret
);
155 size_t offset
= ret
.size();
156 unsigned char tmp
[32];
157 #ifdef USE_LIBGCRYPT_SHA256
158 gcry_md_hash_buffer(GCRY_MD_SHA256
, tmp
, &ret
[0], offset
);
160 sha256::hash(tmp
, ret
);
162 ret
.resize(offset
+ 32);
163 memcpy(&ret
[offset
], tmp
, 32);
167 void loaded_rom::load_core_state(const std::vector
<char>& buf
, bool nochecksum
) throw(std::runtime_error
)
170 rtype().unserialize(&buf
[0], buf
.size());
175 throw std::runtime_error("Savestate corrupt");
176 if(!savestate_no_check(*CORE().settings
)) {
177 unsigned char tmp
[32];
178 #ifdef USE_LIBGCRYPT_SHA256
179 gcry_md_hash_buffer(GCRY_MD_SHA256
, tmp
, &buf
[0], buf
.size() - 32);
181 sha256::hash(tmp
, reinterpret_cast<const uint8_t*>(&buf
[0]), buf
.size() - 32);
183 if(memcmp(tmp
, &buf
[buf
.size() - 32], 32))
184 throw std::runtime_error("Savestate corrupt");
186 rtype().unserialize(&buf
[0], buf
.size() - 32);