Allow passing ROMs by filename instead by data

This is useful later if loading multi-hundred MB CD images.
This commit is contained in:
Ilari Liusvaara 2012-11-27 00:53:32 +02:00
parent adea6ff6cb
commit 5936385ac7
11 changed files with 77 additions and 32 deletions

View file

@ -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
*

View file

@ -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);
};

View file

@ -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, "");

View file

@ -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;

View file

@ -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;
}

View file

@ -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);

View file

@ -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);

View file

@ -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)
{
}

View file

@ -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++) {

View file

@ -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);
}

View file

@ -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++) {