From 83dcbee83a1fb482845364d43ccd392cd602f033 Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Fri, 13 Sep 2013 21:34:59 +0300 Subject: [PATCH 1/2] Save ROM name hints --- include/core/moviefile.hpp | 10 +++++++--- include/core/rom.hpp | 11 +++++++++-- src/core/mainloop.cpp | 3 ++- src/core/moviedata.cpp | 4 +++- src/core/moviefile.cpp | 22 ++++++++++++++-------- src/core/rom.cpp | 11 +++++++++++ src/platform/sdl/main.cpp | 3 ++- src/platform/wxwidgets/main.cpp | 3 ++- src/platform/wxwidgets/romselect.cpp | 3 ++- src/util/movieinfo.cpp | 5 ++++- 10 files changed, 56 insertions(+), 19 deletions(-) diff --git a/include/core/moviefile.hpp b/include/core/moviefile.hpp index d6a09168..771e2660 100644 --- a/include/core/moviefile.hpp +++ b/include/core/moviefile.hpp @@ -7,9 +7,9 @@ #include #include "core/controllerframe.hpp" #include "core/rom.hpp" +#include "core/romtype.hpp" #include "core/subtitles.hpp" - /** * This structure gives parsed representationg of movie file, as result of decoding or for encoding. */ @@ -76,11 +76,15 @@ struct moviefile /** * SHA-256 of ROM (empty string if none). */ - std::string romimg_sha256[27]; + std::string romimg_sha256[ROM_SLOT_COUNT]; /** * SHA-256 of ROM XML (empty string if none). */ - std::string romxml_sha256[27]; + std::string romxml_sha256[ROM_SLOT_COUNT]; +/** + * ROM hints (empty string if none). + */ + std::string romname_hint[ROM_SLOT_COUNT]; /** * Authors of the run, first in each pair is full name, second is nickname. */ diff --git a/include/core/rom.hpp b/include/core/rom.hpp index bcdda2b9..a27f6da7 100644 --- a/include/core/rom.hpp +++ b/include/core/rom.hpp @@ -1,11 +1,14 @@ #ifndef _rom__hpp__included__ #define _rom__hpp__included__ +#define ROM_SLOT_COUNT 27 + #include #include #include #include #include "core/misc.hpp" +#include "core/moviefile.hpp" #include "core/romtype.hpp" /** @@ -60,6 +63,10 @@ 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; +/** + * Name hint. Only for non-XML slots. + */ + std::string namehint; /** * Get pointer to loaded data * @@ -121,11 +128,11 @@ struct loaded_rom /** * Loaded main ROM */ - loaded_slot romimg[27]; + loaded_slot romimg[ROM_SLOT_COUNT]; /** * Loaded main ROM XML */ - loaded_slot romxml[27]; + loaded_slot romxml[ROM_SLOT_COUNT]; /** * MSU-1 base. */ diff --git a/src/core/mainloop.cpp b/src/core/mainloop.cpp index d228a053..0f4b056c 100644 --- a/src/core/mainloop.cpp +++ b/src/core/mainloop.cpp @@ -278,9 +278,10 @@ namespace messages << "Loading ROM " << filenam << std::endl; loaded_rom newrom(filenam); *our_rom = newrom; - for(size_t i = 0; i < sizeof(our_rom->romimg)/sizeof(our_rom->romimg[0]); i++) { + for(size_t i = 0; i < ROM_SLOT_COUNT; i++) { our_movie.romimg_sha256[i] = our_rom->romimg[i].sha256; our_movie.romxml_sha256[i] = our_rom->romxml[i].sha256; + our_movie.romname_hint[i] = our_rom->romxml[i].namehint; } } catch(std::exception& e) { messages << "Can't reload ROM: " << e.what() << std::endl; diff --git a/src/core/moviedata.cpp b/src/core/moviedata.cpp index 38ed8e05..da550477 100644 --- a/src/core/moviedata.cpp +++ b/src/core/moviedata.cpp @@ -420,7 +420,9 @@ void do_load_state(struct moviefile& _movie, int lmode) << "\tFile is from: " << _movie.coreversion << std::endl; } bool rom_ok = true; - for(size_t i = 0; i < sizeof(our_rom->romimg)/sizeof(our_rom->romimg[0]); i++) { + for(size_t i = 0; i < ROM_SLOT_COUNT; i++) { + if(_movie.romname_hint[i] == "") + _movie.romname_hint[i] = our_rom->romimg[i].namehint; rom_ok = rom_ok & warn_hash_mismatch(_movie.romimg_sha256[i], our_rom->romimg[i], (stringfmt() << "ROM #" << (i + 1)).str(), will_load_state); rom_ok = rom_ok & warn_hash_mismatch(_movie.romxml_sha256[i], our_rom->romxml[i], diff --git a/src/core/moviefile.cpp b/src/core/moviefile.cpp index 75cfadaf..bb79f790 100644 --- a/src/core/moviefile.cpp +++ b/src/core/moviefile.cpp @@ -387,14 +387,17 @@ moviefile::moviefile(const std::string& movie) throw(std::bad_alloc, std::runtim read_linefile(r, "coreversion", coreversion); read_linefile(r, "rom.sha256", romimg_sha256[0], true); read_linefile(r, "romxml.sha256", romxml_sha256[0], true); + read_linefile(r, "rom.hint", romname_hint[0], true); unsigned base = 97; if(r.has_member("slot`.sha256")) base = 96; - for(size_t i = 0; i < 26; i++) { - read_linefile(r, (stringfmt() << "slot" << (char)(base + i) << ".sha256").str(), romimg_sha256[i + 1], + for(size_t i = 1; i < ROM_SLOT_COUNT; i++) { + read_linefile(r, (stringfmt() << "slot" << (char)(base + i - 1) << ".sha256").str(), romimg_sha256[i], true); - read_linefile(r, (stringfmt() << "slot" << (char)(base + i) << "xml.sha256").str(), - romxml_sha256[i + 1], true); + read_linefile(r, (stringfmt() << "slot" << (char)(base + i - 1) << "xml.sha256").str(), + romxml_sha256[i], true); + read_linefile(r, (stringfmt() << "slot" << (char)(base + i - 1) << ".hint").str(), + romname_hint[i], true); } read_linefile(r, "prefix", prefix, true); read_subtitles(r, "subtitles", subtitles); @@ -458,11 +461,14 @@ void moviefile::save(const std::string& movie, unsigned compression) throw(std:: write_rrdata(w); write_linefile(w, "rom.sha256", romimg_sha256[0], true); write_linefile(w, "romxml.sha256", romxml_sha256[0], true); - for(size_t i = 0; i < 26; i++) { - write_linefile(w, (stringfmt() << "slot" << (char)(97 + i) << ".sha256").str(), romimg_sha256[i + 1], + write_linefile(w, "rom.hint", romname_hint[0], true); + for(size_t i = 1; i < ROM_SLOT_COUNT; i++) { + write_linefile(w, (stringfmt() << "slot" << (char)(96 + i) << ".sha256").str(), romimg_sha256[i], true); - write_linefile(w, (stringfmt() << "slot" << (char)(97 + i) << "xml.sha256").str(), - romxml_sha256[i + 1], true); + write_linefile(w, (stringfmt() << "slot" << (char)(96 + i) << "xml.sha256").str(), + romxml_sha256[i], true); + write_linefile(w, (stringfmt() << "slot" << (char)(96 + i) << ".hint").str(), + romname_hint[i], true); } write_subtitles(w, "subtitles", subtitles); write_linefile(w, "prefix", prefix, true); diff --git a/src/core/rom.cpp b/src/core/rom.cpp index 2540a54c..9dc747da 100644 --- a/src/core/rom.cpp +++ b/src/core/rom.cpp @@ -63,6 +63,17 @@ loaded_slot::loaded_slot(const std::string& filename, const std::string& base, return; } valid = true; + std::string _filename = filename; +#if defined(_WIN32) || defined(_WIN64) + const char* split = "/\\"; +#else + const char* split = "/"; +#endif + size_t s1 = _filename.find_last_of(split); + size_t s2 = _filename.find_last_of("."); + if(s1 < _filename.length()) s1 = s1 + 1; else s1 = 0; + if(s2 <= s1 || s2 >= _filename.length()) s2 = _filename.length(); + namehint = _filename.substr(s1, s2 - s1); data = read_file_relative(filename, base); if(!xml) headered = imginfo.headersize(data.size()); diff --git a/src/platform/sdl/main.cpp b/src/platform/sdl/main.cpp index 805d303b..46f1cd5c 100644 --- a/src/platform/sdl/main.cpp +++ b/src/platform/sdl/main.cpp @@ -36,9 +36,10 @@ struct moviefile generate_movie_template(std::vector cmdline, loade movie.coreversion = bsnes_core_version; 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++) { + for(size_t i = 0; i < ROM_SLOT_COUNT; i++) { movie.romimg_sha256[i] = r.romimg[i].sha256; movie.romxml_sha256[i] = r.romxml[i].sha256; + movie.romname_hint[i] = r.romimg[i].namehint; } 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 1245ac4d..072f11ea 100644 --- a/src/platform/wxwidgets/main.cpp +++ b/src/platform/wxwidgets/main.cpp @@ -459,9 +459,10 @@ bool lsnes_app::OnInit() //Initialize the remainder. mov->coreversion = bsnes_core_version; mov->rerecords = "0"; - for(size_t i = 0; i < sizeof(rom->romimg)/sizeof(rom->romimg[0]); i++) { + for(size_t i = 0; i < ROM_SLOT_COUNT; i++) { mov->romimg_sha256[i] = rom->romimg[i].sha256; mov->romxml_sha256[i] = rom->romxml[i].sha256; + mov->romname_hint[i] = rom->romimg[i].namehint; } mov->gametype = &rom->rtype->combine_region(*rom->region); } diff --git a/src/platform/wxwidgets/romselect.cpp b/src/platform/wxwidgets/romselect.cpp index d44e2577..05aa75a9 100644 --- a/src/platform/wxwidgets/romselect.cpp +++ b/src/platform/wxwidgets/romselect.cpp @@ -374,9 +374,10 @@ struct moviefile wxwin_project::make_movie() f.prefix = sanitize_prefix(tostdstring(prefix->GetValue())); 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++) { + for(size_t i = 0; i < ROM_SLOT_COUNT; i++) { f.romimg_sha256[i] = our_rom->romimg[i].sha256; f.romxml_sha256[i] = our_rom->romxml[i].sha256; + f.romname_hint[i] = our_rom->romimg[i].namehint; } size_t lines = authors->GetNumberOfLines(); for(size_t i = 0; i < lines; i++) { diff --git a/src/util/movieinfo.cpp b/src/util/movieinfo.cpp index 8e3cf30d..df97d8bc 100644 --- a/src/util/movieinfo.cpp +++ b/src/util/movieinfo.cpp @@ -56,8 +56,11 @@ int main(int argc, char** argv) else std::cout << "No game name available" << std::endl; std::cout << "Project ID: " << escape_string(m.projectid) << std::endl; - for(size_t i = 0; i < sizeof(m.romimg_sha256)/sizeof(m.romimg_sha256[0]); i++) { + for(size_t i = 0; i < ROM_SLOT_COUNT; i++) { if(m.romimg_sha256[i] != "") { + if(m.romname_hint[i] != "") + std::cout << name_subrom(*rtype, 2 * i + 0) << " namehint: " + << escape_string(m.romname_hint[i]) << std::endl; std::cout << name_subrom(*rtype, 2 * i + 0) << " checksum: " << escape_string(m.romimg_sha256[i]) << std::endl; if(m.romxml_sha256[i] != "") { From 702a4b8c4bd2897cbdc6f9677bfe77a23994b478 Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Sat, 14 Sep 2013 15:26:20 +0300 Subject: [PATCH 2/2] Use hints for default filename on ROM load request --- include/core/rom.hpp | 5 ++++ include/core/window.hpp | 2 +- .../platform/wxwidgets/window_mainwindow.hpp | 2 +- src/core/moviedata.cpp | 23 ++++++++++++++----- src/core/rom.cpp | 20 ++++++++-------- src/dummy/graphics.cpp | 2 +- src/platform/sdl/graphicsfn.cpp | 2 +- src/platform/wxwidgets/main.cpp | 7 +++--- src/platform/wxwidgets/mainwindow.cpp | 8 ++++++- 9 files changed, 47 insertions(+), 24 deletions(-) diff --git a/include/core/rom.hpp b/include/core/rom.hpp index a27f6da7..ca7d1202 100644 --- a/include/core/rom.hpp +++ b/include/core/rom.hpp @@ -201,4 +201,9 @@ std::vector save_core_state(bool nochecksum = false) throw(std::bad_alloc) */ void load_core_state(const std::vector& buf, bool nochecksum = false) throw(std::runtime_error); +/** + * Does specified file exist? + */ +bool file_exists(const std::string& name); + #endif diff --git a/include/core/window.hpp b/include/core/window.hpp index 0bb91a15..74d02cd4 100644 --- a/include/core/window.hpp +++ b/include/core/window.hpp @@ -225,7 +225,7 @@ struct graphics_plugin /** * Request filename for ROM load. */ - static std::string request_rom(core_type& coretype); + static std::string request_rom(core_type& coretype, const std::string& hint); /** * Identification for graphics plugin. */ diff --git a/include/platform/wxwidgets/window_mainwindow.hpp b/include/platform/wxwidgets/window_mainwindow.hpp index 57f99869..06626dff 100644 --- a/include/platform/wxwidgets/window_mainwindow.hpp +++ b/include/platform/wxwidgets/window_mainwindow.hpp @@ -41,7 +41,7 @@ public: void menu_check(int id, bool newstate); void menu_separator(); void handle_menu_click(wxCommandEvent& e); - void request_rom(std::string& filename, core_type& coretype); + void request_rom(std::string& filename, core_type& coretype, const std::string& hint); recent_menu* recent_roms; recent_menu* recent_movies; private: diff --git a/src/core/moviedata.cpp b/src/core/moviedata.cpp index da550477..ca749a1f 100644 --- a/src/core/moviedata.cpp +++ b/src/core/moviedata.cpp @@ -183,6 +183,15 @@ namespace return false; } } + + std::string getline(const std::vector& v) + { + std::string t(v.begin(), v.end()); + size_t ptr = t.find_first_of("\r\n"); + if(ptr < t.size()) + t = t.substr(0, ptr); + return t; + } } std::string translate_name_mprefix(std::string original, bool forio) @@ -376,18 +385,20 @@ void do_load_beginning(bool reload) throw(std::bad_alloc, std::runtime_error) void try_request_rom(const std::string& moviefile) { - auto sysreg_content = read_file_relative(moviefile + "/gametype", ""); - std::string sysreg_name(sysreg_content.begin(), sysreg_content.end()); - size_t ptr = sysreg_name.find_first_of("\r\n"); - if(ptr < sysreg_name.size()) - sysreg_name = sysreg_name.substr(0, ptr); + std::string sysreg_name = getline(read_file_relative(moviefile + "/gametype", "")); core_sysregion* sysreg; try { sysreg = &core_sysregion::lookup(sysreg_name); } catch(...) { throw std::runtime_error("The movie is for unsupported system type"); } - std::string rname = graphics_plugin::request_rom(sysreg->get_type()); + std::string hintfile = (sysreg->get_type().get_biosname() != "") ? "slota.hint" : "rom.hint"; + std::string hint; + try { + hint = getline(read_file_relative(moviefile + "/" + hintfile, "")); + } catch(...) { + } + std::string rname = graphics_plugin::request_rom(sysreg->get_type(), hint); if(rname == "") throw std::runtime_error("Canceled loading ROM"); loaded_rom newrom(rname); diff --git a/src/core/rom.cpp b/src/core/rom.cpp index 9dc747da..82248d15 100644 --- a/src/core/rom.cpp +++ b/src/core/rom.cpp @@ -29,20 +29,20 @@ #include #include +bool file_exists(const std::string& name) +{ + try { + delete &open_file_relative(name, ""); + return true; + } catch(...) { + return false; + } +} + namespace { core_type* current_rom_type = NULL; core_region* current_region = NULL; - - bool file_exists(const std::string& name) - { - try { - delete &open_file_relative(name, ""); - return true; - } catch(...) { - return false; - } - } } loaded_slot::loaded_slot() throw(std::bad_alloc) diff --git a/src/dummy/graphics.cpp b/src/dummy/graphics.cpp index 2f6764c5..39acdff7 100644 --- a/src/dummy/graphics.cpp +++ b/src/dummy/graphics.cpp @@ -49,7 +49,7 @@ void graphics_plugin::fatal_error() throw() std::cerr << "Exiting on fatal error." << std::endl; } -std::string graphics_plugin::request_rom(core_type& coretype) +std::string graphics_plugin::request_rom(core_type& coretype, const std::string& hint) { throw std::runtime_error("Headless does not support ROM preloading"); } diff --git a/src/platform/sdl/graphicsfn.cpp b/src/platform/sdl/graphicsfn.cpp index 10695460..09ad8329 100644 --- a/src/platform/sdl/graphicsfn.cpp +++ b/src/platform/sdl/graphicsfn.cpp @@ -613,7 +613,7 @@ void graphics_plugin::fatal_error() throw() } } -std::string graphics_plugin::request_rom(core_type& coretype) +std::string graphics_plugin::request_rom(core_type& coretype, const std::string& hint) { throw std::runtime_error("SDL version does not support ROM preloading"); } diff --git a/src/platform/wxwidgets/main.cpp b/src/platform/wxwidgets/main.cpp index 072f11ea..e8124076 100644 --- a/src/platform/wxwidgets/main.cpp +++ b/src/platform/wxwidgets/main.cpp @@ -535,19 +535,20 @@ void graphics_plugin::fatal_error() throw() } } -std::string graphics_plugin::request_rom(core_type& coretype) +std::string graphics_plugin::request_rom(core_type& coretype, const std::string& hint) { core_type* ctype = &coretype; std::string outname; + std::string _hint = hint; mutex_class lock; cv_class cv; bool done = false; umutex_class h(lock); - runuifun([ctype, &outname, &lock, &cv, &done]() -> void { + runuifun([ctype, hint, &outname, &lock, &cv, &done]() -> void { if(done) return; try { - main_window->request_rom(outname, *ctype); + main_window->request_rom(outname, *ctype, hint); } catch(...) { } umutex_class h(lock); diff --git a/src/platform/wxwidgets/mainwindow.cpp b/src/platform/wxwidgets/mainwindow.cpp index 0e9de282..02b1b562 100644 --- a/src/platform/wxwidgets/mainwindow.cpp +++ b/src/platform/wxwidgets/mainwindow.cpp @@ -1000,12 +1000,16 @@ void wxwin_mainwindow::notify_exit() throw() Destroy(); } -void wxwin_mainwindow::request_rom(std::string& filename, core_type& coretype) +void wxwin_mainwindow::request_rom(std::string& filename, core_type& coretype, const std::string& hint) { const std::list& exts = coretype.get_extensions(); std::string filter = coretype.get_hname() + " ROMs|"; bool first = true; + std::string defaultname = ""; for(auto i : exts) { + std::string hinted_file = hint + "." + i; + if(file_exists(rom_path() + "/" + hinted_file)) + defaultname = hinted_file; if(!first) filter = filter + ";"; first = false; @@ -1014,6 +1018,8 @@ void wxwin_mainwindow::request_rom(std::string& filename, core_type& coretype) filter = filter + "|All files|*.*"; wxFileDialog* fdiag = new wxFileDialog(this, wxT("Load ROM"), towxstring(rom_path()), wxT(""), towxstring(filter), wxFD_OPEN); + if(defaultname != "") + fdiag->SetFilename(defaultname); if(fdiag->ShowModal() != wxID_OK) { delete fdiag; return;