Allow passing ROMs by filename instead by data
This is useful later if loading multi-hundred MB CD images.
This commit is contained in:
parent
adea6ff6cb
commit
5936385ac7
11 changed files with 77 additions and 32 deletions
|
@ -42,7 +42,10 @@ struct loaded_slot
|
|||
* throws std::runtime_error: Bad IPS patch.
|
||||
*/
|
||||
void patch(const std::vector<char>& patch, int32_t offset) throw(std::bad_alloc, std::runtime_error);
|
||||
|
||||
/**
|
||||
* Is this filename?
|
||||
*/
|
||||
bool filename_flag;
|
||||
/**
|
||||
* Is this slot XML slot?
|
||||
*/
|
||||
|
@ -59,7 +62,7 @@ struct loaded_slot
|
|||
/**
|
||||
* SHA-256 for the data in this slot if data is valid. If no valid data, this field is "".
|
||||
*/
|
||||
std::string sha256;
|
||||
std::string sha_256;
|
||||
/**
|
||||
* Get pointer to loaded data
|
||||
*
|
||||
|
|
|
@ -38,11 +38,15 @@ private:
|
|||
|
||||
struct core_romimage_info
|
||||
{
|
||||
//If headersize is NULL, always use 0.
|
||||
core_romimage_info(const std::string& iname, const std::string& hname, unsigned mandatory,
|
||||
unsigned (*headersize)(size_t imagesize));
|
||||
//This sets pass_by_filename!
|
||||
core_romimage_info(const std::string& iname, const std::string& hname, unsigned mandatory);
|
||||
std::string iname;
|
||||
std::string hname;
|
||||
unsigned mandatory;
|
||||
bool pass_by_filename;
|
||||
unsigned (*headersize)(size_t imagesize);
|
||||
};
|
||||
|
||||
|
|
|
@ -47,11 +47,6 @@ namespace
|
|||
return 1;
|
||||
}
|
||||
|
||||
unsigned header_fn(size_t r)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool do_reset_flag = false;
|
||||
core_type* internal_rom = NULL;
|
||||
extern core_type type_dmg;
|
||||
|
@ -153,9 +148,9 @@ namespace
|
|||
uint64_t magic[4] = {35112, 2097152, 16742706, 626688};
|
||||
|
||||
core_region region_world("world", "World", 0, 0, false, magic, regions_compatible);
|
||||
core_romimage_info image_rom_dmg("rom", "Cartridge ROM", 1, header_fn);
|
||||
core_romimage_info image_rom_gbc("rom", "Cartridge ROM", 1, header_fn);
|
||||
core_romimage_info image_rom_gbca("rom", "Cartridge ROM", 1, header_fn);
|
||||
core_romimage_info image_rom_dmg("rom", "Cartridge ROM", 1, NULL);
|
||||
core_romimage_info image_rom_gbc("rom", "Cartridge ROM", 1, NULL);
|
||||
core_romimage_info image_rom_gbca("rom", "Cartridge ROM", 1, NULL);
|
||||
core_type type_dmg("dmg", "Game Boy", 1, load_rom_dmg, "gb;dmg");
|
||||
core_type type_gbc("gbc", "Game Boy Color", 0, load_rom_gbc, "gbc;cgb");
|
||||
core_type type_gbc_gba("gbc_gba", "Game Boy Color (GBA)", 2, load_rom_gbc_gba, "");
|
||||
|
|
|
@ -215,8 +215,8 @@ namespace
|
|||
loaded_rom newrom(filenam);
|
||||
*our_rom = newrom;
|
||||
for(size_t i = 0; i < sizeof(our_rom->romimg)/sizeof(our_rom->romimg[0]); i++) {
|
||||
our_movie.romimg_sha256[i] = our_rom->romimg[i].sha256;
|
||||
our_movie.romxml_sha256[i] = our_rom->romxml[i].sha256;
|
||||
our_movie.romimg_sha256[i] = our_rom->romimg[i].sha_256;
|
||||
our_movie.romxml_sha256[i] = our_rom->romxml[i].sha_256;
|
||||
}
|
||||
} catch(std::exception& e) {
|
||||
messages << "Can't reload ROM: " << e.what() << std::endl;
|
||||
|
|
|
@ -135,8 +135,8 @@ struct loaded_rom load_rom_from_commandline(std::vector<std::string> cmdline) th
|
|||
(r.rtype->get_image_info(i).hname + " ROM");
|
||||
xmlname = r.rtype->get_image_info(i).hname + " XML";
|
||||
}
|
||||
if(r.romimg[i].valid) messages << romname << " hash: " << r.romimg[i].sha256 << std::endl;
|
||||
if(r.romxml[i].valid) messages << xmlname << " hash: " << r.romxml[i].sha256 << std::endl;
|
||||
if(r.romimg[i].valid) messages << romname << " hash: " << r.romimg[i].sha_256 << std::endl;
|
||||
if(r.romxml[i].valid) messages << xmlname << " hash: " << r.romxml[i].sha_256 << std::endl;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -166,17 +166,17 @@ namespace
|
|||
bool warn_hash_mismatch(const std::string& mhash, const loaded_slot& slot,
|
||||
const std::string& name, bool fatal)
|
||||
{
|
||||
if(mhash == slot.sha256)
|
||||
if(mhash == slot.sha_256)
|
||||
return true;
|
||||
if(!fatal) {
|
||||
messages << "WARNING: " << name << " hash mismatch!" << std::endl
|
||||
<< "\tMovie: " << mhash << std::endl
|
||||
<< "\tOur ROM: " << slot.sha256 << std::endl;
|
||||
<< "\tOur ROM: " << slot.sha_256 << std::endl;
|
||||
return true;
|
||||
} else {
|
||||
messages << "ERROR: " << name << " hash mismatch!" << std::endl
|
||||
<< "\tMovie: " << mhash << std::endl
|
||||
<< "\tOur ROM: " << slot.sha256 << std::endl;
|
||||
<< "\tOur ROM: " << slot.sha_256 << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -232,8 +232,8 @@ void do_save_state(const std::string& filename) throw(std::bad_alloc,
|
|||
our_movie.is_savestate = true;
|
||||
our_movie.sram = save_sram();
|
||||
for(size_t i = 0; i < sizeof(our_rom->romimg)/sizeof(our_rom->romimg[0]); i++) {
|
||||
our_movie.romimg_sha256[i] = our_rom->romimg[i].sha256;
|
||||
our_movie.romxml_sha256[i] = our_rom->romxml[i].sha256;
|
||||
our_movie.romimg_sha256[i] = our_rom->romimg[i].sha_256;
|
||||
our_movie.romxml_sha256[i] = our_rom->romxml[i].sha_256;
|
||||
}
|
||||
our_movie.savestate = save_core_state();
|
||||
get_framebuffer().save(our_movie.screenshot);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "library/zip.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <cstdint>
|
||||
|
@ -28,6 +29,13 @@
|
|||
#include <boost/iostreams/filter/zlib.hpp>
|
||||
#include <boost/iostreams/filtering_stream.hpp>
|
||||
#include <boost/iostreams/device/back_inserter.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#ifdef BOOST_FILESYSTEM3
|
||||
namespace boost_fs = boost::filesystem3;
|
||||
#else
|
||||
namespace boost_fs = boost::filesystem;
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -39,7 +47,8 @@ loaded_slot::loaded_slot() throw(std::bad_alloc)
|
|||
{
|
||||
valid = false;
|
||||
xml = false;
|
||||
sha256 = "";
|
||||
sha_256 = "";
|
||||
filename_flag = false;
|
||||
}
|
||||
|
||||
loaded_slot::loaded_slot(const std::string& filename, const std::string& base,
|
||||
|
@ -49,9 +58,32 @@ loaded_slot::loaded_slot(const std::string& filename, const std::string& base,
|
|||
xml = xml_flag;
|
||||
if(filename == "") {
|
||||
valid = false;
|
||||
sha256 = "";
|
||||
sha_256 = "";
|
||||
filename_flag = (!xml && imginfo.pass_by_filename);
|
||||
return;
|
||||
}
|
||||
//XMLs are always loaded, no matter what.
|
||||
if(!xml && imginfo.pass_by_filename) {
|
||||
std::string _filename = filename;
|
||||
//Translate the passed filename to absolute one.
|
||||
_filename = resolve_file_relative(_filename, base);
|
||||
_filename = boost_fs::absolute(boost_fs::path(_filename)).string();
|
||||
filename_flag = true;
|
||||
data.resize(_filename.length());
|
||||
std::copy(_filename.begin(), _filename.end(), data.begin());
|
||||
//Compute the SHA-256.
|
||||
std::istream& s = open_file_relative(filename, "");
|
||||
sha256 hash;
|
||||
char buffer[8192];
|
||||
size_t block;
|
||||
while(block = s.readsome(buffer, 8192))
|
||||
hash.write(buffer, block);
|
||||
sha_256 = hash.read();
|
||||
delete &s;
|
||||
valid = true;
|
||||
return;
|
||||
}
|
||||
filename_flag = false;
|
||||
valid = true;
|
||||
data = read_file_relative(filename, base);
|
||||
if(!xml)
|
||||
|
@ -64,7 +96,7 @@ loaded_slot::loaded_slot(const std::string& filename, const std::string& base,
|
|||
data.resize(0);
|
||||
}
|
||||
}
|
||||
sha256 = sha256::hash(data);
|
||||
sha_256 = sha256::hash(data);
|
||||
if(xml) {
|
||||
size_t osize = data.size();
|
||||
data.resize(osize + 1);
|
||||
|
@ -74,6 +106,8 @@ loaded_slot::loaded_slot(const std::string& filename, const std::string& base,
|
|||
|
||||
void loaded_slot::patch(const std::vector<char>& patch, int32_t offset) throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
if(filename_flag)
|
||||
throw std::runtime_error("CD images can't be patched on the fly");
|
||||
try {
|
||||
std::vector<char> data2 = data;
|
||||
size_t poffset = 0;
|
||||
|
@ -89,14 +123,12 @@ void loaded_slot::patch(const std::vector<char>& patch, int32_t offset) throw(st
|
|||
data2[osize] = 0;
|
||||
}
|
||||
data = data2;
|
||||
sha256 = new_sha256;
|
||||
sha_256 = new_sha256;
|
||||
} catch(...) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::pair<core_type*, core_region*> get_current_rom_info() throw()
|
||||
{
|
||||
return std::make_pair(current_rom_type, current_region);
|
||||
|
|
|
@ -83,6 +83,11 @@ namespace
|
|||
{
|
||||
return (a->get_handle() < b->get_handle());
|
||||
}
|
||||
|
||||
unsigned default_headersize(size_t imagesize)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
core_region::core_region(const std::string& _iname, const std::string& _hname, unsigned _priority, unsigned _handle,
|
||||
|
@ -212,7 +217,13 @@ unsigned core_type::get_image_count()
|
|||
|
||||
core_romimage_info::core_romimage_info(const std::string& _iname, const std::string& _hname, unsigned _mandatory,
|
||||
unsigned (*_headersize)(size_t imagesize))
|
||||
: iname(_iname), hname(_hname), headersize(_headersize), mandatory(_mandatory)
|
||||
: iname(_iname), hname(_hname), headersize(_headersize ? _headersize : default_headersize),
|
||||
mandatory(_mandatory), pass_by_filename(false)
|
||||
{
|
||||
}
|
||||
|
||||
core_romimage_info::core_romimage_info(const std::string& _iname, const std::string& _hname, unsigned _mandatory)
|
||||
: iname(_iname), hname(_hname), headersize(NULL), mandatory(_mandatory), pass_by_filename(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -39,8 +39,8 @@ struct moviefile generate_movie_template(std::vector<std::string> cmdline, loade
|
|||
movie.projectid = get_random_hexstring(40);
|
||||
movie.gametype = &r.rtype->combine_region(*r.region);
|
||||
for(size_t i = 0; i < sizeof(r.romimg)/sizeof(r.romimg[0]); i++) {
|
||||
movie.romimg_sha256[i] = r.romimg[i].sha256;
|
||||
movie.romxml_sha256[i] = r.romxml[i].sha256;
|
||||
movie.romimg_sha256[i] = r.romimg[i].sha_256;
|
||||
movie.romxml_sha256[i] = r.romxml[i].sha_256;
|
||||
}
|
||||
movie.movie_sram = load_sram_commandline(cmdline);
|
||||
for(auto i = cmdline.begin(); i != cmdline.end(); i++) {
|
||||
|
|
|
@ -435,8 +435,8 @@ bool lsnes_app::OnInit()
|
|||
mov->projectid = get_random_hexstring(40);
|
||||
mov->rerecords = "0";
|
||||
for(size_t i = 0; i < sizeof(rom->romimg)/sizeof(rom->romimg[0]); i++) {
|
||||
mov->romimg_sha256[i] = rom->romimg[i].sha256;
|
||||
mov->romxml_sha256[i] = rom->romxml[i].sha256;
|
||||
mov->romimg_sha256[i] = rom->romimg[i].sha_256;
|
||||
mov->romxml_sha256[i] = rom->romxml[i].sha_256;
|
||||
}
|
||||
mov->gametype = &rom->rtype->combine_region(*rom->region);
|
||||
}
|
||||
|
|
|
@ -378,8 +378,8 @@ struct moviefile wxwin_project::make_movie()
|
|||
f.projectid = get_random_hexstring(40);
|
||||
f.rerecords = "0";
|
||||
for(size_t i = 0; i < sizeof(our_rom->romimg)/sizeof(our_rom->romimg[0]); i++) {
|
||||
f.romimg_sha256[i] = our_rom->romimg[i].sha256;
|
||||
f.romxml_sha256[i] = our_rom->romxml[i].sha256;
|
||||
f.romimg_sha256[i] = our_rom->romimg[i].sha_256;
|
||||
f.romxml_sha256[i] = our_rom->romxml[i].sha_256;
|
||||
}
|
||||
size_t lines = authors->GetNumberOfLines();
|
||||
for(size_t i = 0; i < lines; i++) {
|
||||
|
|
Loading…
Add table
Reference in a new issue