diff --git a/include/core/rom.hpp b/include/core/rom.hpp index bcdda2b9..e3da87c9 100644 --- a/include/core/rom.hpp +++ b/include/core/rom.hpp @@ -42,7 +42,10 @@ struct loaded_slot * throws std::runtime_error: Bad IPS patch. */ void patch(const std::vector& 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 * diff --git a/include/core/romtype.hpp b/include/core/romtype.hpp index bc648010..cd4b7ac7 100644 --- a/include/core/romtype.hpp +++ b/include/core/romtype.hpp @@ -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); }; diff --git a/src/core/gambatte.cpp b/src/core/gambatte.cpp index 1bf09ce8..8f80f7fb 100644 --- a/src/core/gambatte.cpp +++ b/src/core/gambatte.cpp @@ -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, ""); diff --git a/src/core/mainloop.cpp b/src/core/mainloop.cpp index 118bc19b..6f0b7e3e 100644 --- a/src/core/mainloop.cpp +++ b/src/core/mainloop.cpp @@ -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; diff --git a/src/core/misc.cpp b/src/core/misc.cpp index 0d9b69ac..ef257025 100644 --- a/src/core/misc.cpp +++ b/src/core/misc.cpp @@ -135,8 +135,8 @@ struct loaded_rom load_rom_from_commandline(std::vector 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; } diff --git a/src/core/moviedata.cpp b/src/core/moviedata.cpp index 419c1215..5b4cb42e 100644 --- a/src/core/moviedata.cpp +++ b/src/core/moviedata.cpp @@ -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); diff --git a/src/core/rom.cpp b/src/core/rom.cpp index cc365255..adf46422 100644 --- a/src/core/rom.cpp +++ b/src/core/rom.cpp @@ -16,6 +16,7 @@ #include "library/zip.hpp" #include + #include #include #include @@ -28,6 +29,13 @@ #include #include #include +#include + +#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& 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 data2 = data; size_t poffset = 0; @@ -89,14 +123,12 @@ void loaded_slot::patch(const std::vector& patch, int32_t offset) throw(st data2[osize] = 0; } data = data2; - sha256 = new_sha256; + sha_256 = new_sha256; } catch(...) { throw; } } - - std::pair get_current_rom_info() throw() { return std::make_pair(current_rom_type, current_region); diff --git a/src/core/romtype.cpp b/src/core/romtype.cpp index 47b7e97b..59fc2f84 100644 --- a/src/core/romtype.cpp +++ b/src/core/romtype.cpp @@ -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) { } diff --git a/src/platform/sdl/main.cpp b/src/platform/sdl/main.cpp index 0b81a460..324816bd 100644 --- a/src/platform/sdl/main.cpp +++ b/src/platform/sdl/main.cpp @@ -39,8 +39,8 @@ struct moviefile generate_movie_template(std::vector 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++) { diff --git a/src/platform/wxwidgets/main.cpp b/src/platform/wxwidgets/main.cpp index 53f1e296..9ecce963 100644 --- a/src/platform/wxwidgets/main.cpp +++ b/src/platform/wxwidgets/main.cpp @@ -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); } diff --git a/src/platform/wxwidgets/romselect.cpp b/src/platform/wxwidgets/romselect.cpp index 2dda8f46..75314fee 100644 --- a/src/platform/wxwidgets/romselect.cpp +++ b/src/platform/wxwidgets/romselect.cpp @@ -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++) {