From b05b31a538db52ab2a0262282125c764e29a53ae Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Sat, 7 Apr 2012 19:12:14 +0300 Subject: [PATCH] Rework jukebox - Remove explicit setting for jukebox names - Add setting for number of saves in jukebox - Add path for save slots. --- include/core/moviedata.hpp | 2 +- manual.lyx | 8 --- manual.txt | 8 +-- src/core/mainloop.cpp | 72 ++++++++++++++------------- src/core/moviedata.cpp | 58 ++++++++++++++++++--- src/platform/win32mm/joystick.cpp | 6 +-- src/platform/wxwidgets/main.cpp | 3 -- src/platform/wxwidgets/mainwindow.cpp | 29 ----------- src/platform/wxwidgets/settings.cpp | 39 ++++++++++++--- 9 files changed, 125 insertions(+), 100 deletions(-) diff --git a/include/core/moviedata.hpp b/include/core/moviedata.hpp index 571d45ff..e17e5856 100644 --- a/include/core/moviedata.hpp +++ b/include/core/moviedata.hpp @@ -28,7 +28,7 @@ void do_save_movie(const std::string& filename) throw(std::bad_alloc, std::runti void do_load_beginning() throw(std::bad_alloc, std::runtime_error); void do_load_state(struct moviefile& _movie, int lmode); bool do_load_state(const std::string& filename, int lmode); -std::string translate_name_mprefix(std::string original); +std::string translate_name_mprefix(std::string original, bool forio = false); extern std::string last_save; extern movie_logic movb; diff --git a/manual.lyx b/manual.lyx index a6f9fb54..7a2f3bc1 100644 --- a/manual.lyx +++ b/manual.lyx @@ -1654,14 +1654,6 @@ cycle-jukebox-forward Cycle save jukebox forwards \end_layout -\begin_layout Subsubsection -add-jukebox-save -\end_layout - -\begin_layout Standard -Add to jukebox saves. -\end_layout - \begin_layout Subsubsection load-jukebox \end_layout diff --git a/manual.txt b/manual.txt index 647cda0a..4478743f 100644 --- a/manual.txt +++ b/manual.txt @@ -794,15 +794,11 @@ Cycle save jukebox backwards. Cycle save jukebox forwards -6.8.3 add-jukebox-save - -Add to jukebox saves. - -6.8.4 load-jukebox +6.8.3 load-jukebox Do load from jukebox (current mode). -6.8.5 save-jukebox +6.8.4 save-jukebox Do state save to jukebox. diff --git a/src/core/mainloop.cpp b/src/core/mainloop.cpp index 6cb5abba..e058b415 100644 --- a/src/core/mainloop.cpp +++ b/src/core/mainloop.cpp @@ -6,6 +6,7 @@ #include "core/framebuffer.hpp" #include "core/framerate.hpp" #include "lua/lua.hpp" +#include "library/string.hpp" #include "core/mainloop.hpp" #include "core/movie.hpp" #include "core/moviedata.hpp" @@ -61,7 +62,7 @@ namespace std::set queued_saves; bool stepping_into_save; //Save jukebox. - std::vector save_jukebox; + numeric_setting jukebox_size("jukebox-size", 0, 999, 12); size_t save_jukebox_pointer; //Pending reset cycles. -1 if no reset pending, otherwise, cycle count for reset. long pending_reset_cycles = -1; @@ -75,6 +76,11 @@ namespace //Last frame params. bool last_hires = false; bool last_interlace = false; + + std::string save_jukebox_name(size_t i) + { + return (stringfmt() << "${project}" << (i + 1) << ".lsmv").str(); + } } class firmware_path_setting : public setting @@ -272,8 +278,8 @@ void update_movie_state() x << "F"; _status.set("Flags", x.str()); } - if(save_jukebox.size() > 0) - _status.set("Saveslot", translate_name_mprefix(save_jukebox[save_jukebox_pointer])); + if(jukebox_size > 0) + _status.set("Saveslot", translate_name_mprefix(save_jukebox_name(save_jukebox_pointer))); else _status.erase("Saveslot"); { @@ -399,6 +405,20 @@ class my_interface : public SNES::Interface namespace { + class jukebox_size_listener : public information_dispatch + { + public: + jukebox_size_listener() : information_dispatch("jukebox-size-listener") {}; + void on_setting_change(const std::string& setting, const std::string& value) + { + if(setting == "jukebox-size") { + if(save_jukebox_pointer >= jukebox_size) + save_jukebox_pointer = 0; + update_movie_state(); + } + } + } _jukebox_size_listener; + function_ptr_command<> count_rerecords("count-rerecords", "Count rerecords", "Syntax: count-rerecords\nCounts rerecords.\n", []() throw(std::bad_alloc, std::runtime_error) { @@ -434,11 +454,13 @@ namespace function_ptr_command<> save_jukebox_prev("cycle-jukebox-backward", "Cycle save jukebox backwards", "Syntax: cycle-jukebox-backward\nCycle save jukebox backwards\n", []() throw(std::bad_alloc, std::runtime_error) { + if(jukebox_size == 0) + return; if(save_jukebox_pointer == 0) - save_jukebox_pointer = save_jukebox.size() - 1; + save_jukebox_pointer = jukebox_size - 1; else save_jukebox_pointer--; - if(save_jukebox_pointer >= save_jukebox.size()) + if(save_jukebox_pointer >= jukebox_size) save_jukebox_pointer = 0; update_movie_state(); information_dispatch::do_status_update(); @@ -447,38 +469,32 @@ namespace function_ptr_command<> save_jukebox_next("cycle-jukebox-forward", "Cycle save jukebox forwards", "Syntax: cycle-jukebox-forward\nCycle save jukebox forwards\n", []() throw(std::bad_alloc, std::runtime_error) { - if(save_jukebox_pointer == save_jukebox.size() - 1) + if(jukebox_size == 0) + return; + if(save_jukebox_pointer == jukebox_size - 1) save_jukebox_pointer = 0; else save_jukebox_pointer++; - if(save_jukebox_pointer >= save_jukebox.size()) + if(save_jukebox_pointer >= jukebox_size) save_jukebox_pointer = 0; update_movie_state(); information_dispatch::do_status_update(); }); - function_ptr_command add_jukebox("add-jukebox-save", "Add save to jukebox", - "Syntax: add-jukebox-save\nAdd save to jukebox\n", - [](arg_filename filename) throw(std::bad_alloc, std::runtime_error) { - save_jukebox.push_back(filename); - update_movie_state(); - information_dispatch::do_status_update(); - }); - function_ptr_command<> load_jukebox("load-jukebox", "Load save from jukebox", "Syntax: load-jukebox\nLoad save from jukebox\n", []() throw(std::bad_alloc, std::runtime_error) { - if(!save_jukebox.size()) - throw std::runtime_error("No saves in jukebox"); - mark_pending_load(save_jukebox[save_jukebox_pointer], LOAD_STATE_CURRENT); + if(jukebox_size == 0) + throw std::runtime_error("No slot selected"); + mark_pending_load(save_jukebox_name(save_jukebox_pointer), LOAD_STATE_CURRENT); }); function_ptr_command<> save_jukebox_c("save-jukebox", "Save save to jukebox", "Syntax: save-jukebox\nSave save to jukebox\n", []() throw(std::bad_alloc, std::runtime_error) { - if(!save_jukebox.size()) - throw std::runtime_error("No saves in jukebox"); - mark_pending_save(save_jukebox[save_jukebox_pointer], SAVE_STATE); + if(jukebox_size == 0) + throw std::runtime_error("No slot selected"); + mark_pending_save(save_jukebox_name(save_jukebox_pointer), SAVE_STATE); }); function_ptr_command<> padvance_frame("+advance-frame", "Advance one frame", @@ -646,7 +662,6 @@ namespace while(1); }); - inverse_key ipause_emulator("pause-emulator", "(Un)pause"); inverse_key ijback("cycle-jukebox-backward", "Cycle slot backwards"); inverse_key ijforward("cycle-jukebox-forward", "Cycle slot forwards"); @@ -853,19 +868,6 @@ namespace } } -std::vector get_jukebox_names() -{ - return save_jukebox; -} - -void set_jukebox_names(const std::vector& newj) -{ - save_jukebox = newj; - if(save_jukebox_pointer >= save_jukebox.size()) - save_jukebox_pointer = 0; - update_movie_state(); -} - void main_loop(struct loaded_rom& rom, struct moviefile& initial, bool load_has_to_succeed) throw(std::bad_alloc, std::runtime_error) { diff --git a/src/core/moviedata.cpp b/src/core/moviedata.cpp index 621b73c0..d270c73c 100644 --- a/src/core/moviedata.cpp +++ b/src/core/moviedata.cpp @@ -48,6 +48,44 @@ namespace { numeric_setting savecompression("savecompression", 0, 9, 7); + class slot_path_setting : public setting + { + public: + slot_path_setting() : setting("slotpath") { _slotpath = "."; default_slot = true; } + void blank() throw(std::bad_alloc, std::runtime_error) + { + _slotpath = "."; + default_slot = true; + } + + bool is_set() throw() + { + return !default_slot; + } + + void set(const std::string& value) throw(std::bad_alloc, std::runtime_error) + { + if(value != "") { + _slotpath = value; + default_slot = false; + } else + blank(); + } + + std::string get() throw(std::bad_alloc) + { + return _slotpath; + } + + operator std::string() throw(std::bad_alloc) + { + return _slotpath; + } + private: + std::string _slotpath; + bool default_slot; + } slotpath_setting; + class projectprefix_setting : public setting { public: @@ -168,13 +206,17 @@ namespace } } -std::string translate_name_mprefix(std::string original) +std::string translate_name_mprefix(std::string original, bool forio) { size_t prefixloc = original.find("${project}"); - if(prefixloc < original.length()) - return original.substr(0, prefixloc) + static_cast(mprefix) + - original.substr(prefixloc + 10); - else + if(prefixloc < original.length()) { + std::string pprf = forio ? (slotpath_setting.get() + "/") : std::string(""); + if(prefixloc == 0) + return pprf + static_cast(mprefix) + original.substr(prefixloc + 10); + else + return original.substr(0, prefixloc) + static_cast(mprefix) + + original.substr(prefixloc + 10); + } else return original; } @@ -201,7 +243,7 @@ std::pair split_author(const std::string& author) thro void do_save_state(const std::string& filename) throw(std::bad_alloc, std::runtime_error) { - std::string filename2 = translate_name_mprefix(filename); + std::string filename2 = translate_name_mprefix(filename, true); lua_callback_pre_save(filename2, true); try { uint64_t origtime = get_utime(); @@ -236,7 +278,7 @@ void do_save_state(const std::string& filename) throw(std::bad_alloc, //Save movie. void do_save_movie(const std::string& filename) throw(std::bad_alloc, std::runtime_error) { - std::string filename2 = translate_name_mprefix(filename); + std::string filename2 = translate_name_mprefix(filename, true); lua_callback_pre_save(filename2, false); try { uint64_t origtime = get_utime(); @@ -457,7 +499,7 @@ void do_load_state(struct moviefile& _movie, int lmode) //Load state bool do_load_state(const std::string& filename, int lmode) { - std::string filename2 = translate_name_mprefix(filename); + std::string filename2 = translate_name_mprefix(filename, true); uint64_t origtime = get_utime(); lua_callback_pre_load(filename2); struct moviefile mfile; diff --git a/src/platform/win32mm/joystick.cpp b/src/platform/win32mm/joystick.cpp index 67f44606..92c069c8 100644 --- a/src/platform/win32mm/joystick.cpp +++ b/src/platform/win32mm/joystick.cpp @@ -33,14 +33,14 @@ namespace void create_hat(unsigned i) { std::string n = (stringfmt() << "joystick" << i << "hat").str(); - keygroup* k = new keygroup(n, keygroup::KT_HAT); + keygroup* k = new keygroup(n, "joystick", keygroup::KT_HAT); hats[i] = k; } void create_button(unsigned i, unsigned j) { std::string n = (stringfmt() << "joystick" << i << "button" << j).str(); - keygroup* k = new keygroup(n, keygroup::KT_KEY); + keygroup* k = new keygroup(n, "joystick", keygroup::KT_KEY); buttons[std::make_pair(i, j)] = k; } @@ -48,7 +48,7 @@ namespace { std::string n = (stringfmt() << "joystick" << i << "axis" << j).str(); keygroup* k; - k = new keygroup(n, keygroup::KT_AXIS_PAIR); + k = new keygroup(n, "joystick", keygroup::KT_AXIS_PAIR); axes[std::make_pair(i, j)] = k; } diff --git a/src/platform/wxwidgets/main.cpp b/src/platform/wxwidgets/main.cpp index 444809bc..8f0072c1 100644 --- a/src/platform/wxwidgets/main.cpp +++ b/src/platform/wxwidgets/main.cpp @@ -166,9 +166,6 @@ end: { std::string cfg = get_config_path() + "/lsneswxw.rc"; std::ofstream cfgfile(cfg.c_str()); - //Jukebox. - for(auto i : get_jukebox_names()) - cfgfile << "add-jukebox-save " << i << std::endl; //Joystick axis. for(auto i : keygroup::get_axis_set()) { keygroup* k = keygroup::lookup_by_name(i); diff --git a/src/platform/wxwidgets/mainwindow.cpp b/src/platform/wxwidgets/mainwindow.cpp index f845b1ed..fd14cf57 100644 --- a/src/platform/wxwidgets/mainwindow.cpp +++ b/src/platform/wxwidgets/mainwindow.cpp @@ -72,7 +72,6 @@ enum wxID_DUMP_FIRST, wxID_DUMP_LAST = wxID_DUMP_FIRST + 1023, wxID_REWIND_MOVIE, - wxID_EDIT_JUKEBOX, wxID_MEMORY_SEARCH, wxID_CANCEL_SAVES, wxID_EDIT_HOTKEYS, @@ -771,7 +770,6 @@ wxwin_mainwindow::wxwin_mainwindow() menu_entry(wxID_EDIT_SETTINGS, wxT("Configure settings...")); menu_entry(wxID_EDIT_KEYBINDINGS, wxT("Configure keybindings...")); menu_entry(wxID_EDIT_ALIAS, wxT("Configure aliases...")); - menu_entry(wxID_EDIT_JUKEBOX, wxT("Configure jukebox...")); menu_separator(); menu_entry(wxID_EDIT_HOTKEYS, wxT("Configure hotkeys...")); } @@ -975,33 +973,6 @@ void wxwin_mainwindow::handle_menu_click_cancelable(wxCommandEvent& e) runemufn([alias, newcmd]() { command::set_alias_for(alias, newcmd); }); return; } - case wxID_EDIT_JUKEBOX: { - modal_pause_holder hld; - std::vector new_jukebox; - std::string x; - runemufn([&x]() { - for(auto i : get_jukebox_names()) - x = x + i + "\n"; - }); - x = pick_text(this, "Configure jukebox", "List jukebox entries", x, true); - while(x != "") { - size_t split = x.find_first_of("\n"); - std::string l; - if(split < x.length()) { - l = x.substr(0, split); - x = x.substr(split + 1); - } else { - l = x; - x = ""; - } - istrip_CR(l); - if(l != "") - new_jukebox.push_back(l); - } - runemufn([&new_jukebox]() { set_jukebox_names(new_jukebox); }); - notify_update_status(); - return; - } case wxID_EDIT_MEMORYWATCH: { modal_pause_holder hld; std::set bind; diff --git a/src/platform/wxwidgets/settings.cpp b/src/platform/wxwidgets/settings.cpp index ea4fea4e..3978ff7c 100644 --- a/src/platform/wxwidgets/settings.cpp +++ b/src/platform/wxwidgets/settings.cpp @@ -33,6 +33,8 @@ extern "C" #define FIRMWAREPATH "firmwarepath" #define ROMPATH "rompath" #define MOVIEPATH "moviepath" +#define SLOTPATH "slotpath" +#define SAVESLOTS "jukebox-size" @@ -327,6 +329,8 @@ private: wxStaticText* rompath; wxStaticText* firmpath; wxStaticText* savepath; + wxStaticText* slotpath; + wxStaticText* slots; wxFlexGridSizer* top_s; }; @@ -334,21 +338,31 @@ wxeditor_esettings_paths::wxeditor_esettings_paths(wxWindow* parent) : wxPanel(parent, -1) { wxButton* tmp; - top_s = new wxFlexGridSizer(3, 3, 0, 0); + top_s = new wxFlexGridSizer(5, 3, 0, 0); SetSizer(top_s); - top_s->Add(new wxStaticText(this, -1, wxT("ROM path")), 0, wxGROW); + top_s->Add(new wxStaticText(this, -1, wxT("ROM path: ")), 0, wxGROW); top_s->Add(rompath = new wxStaticText(this, -1, wxT("")), 1, wxGROW); top_s->Add(tmp = new wxButton(this, wxID_HIGHEST + 1, wxT("Change...")), 0, wxGROW); tmp->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(wxeditor_esettings_paths::on_configure), NULL, this); - top_s->Add(new wxStaticText(this, -1, wxT("Firmware path")), 0, wxGROW); + top_s->Add(new wxStaticText(this, -1, wxT("Firmware path: ")), 0, wxGROW); top_s->Add(firmpath = new wxStaticText(this, -1, wxT("")), 1, wxGROW); top_s->Add(tmp = new wxButton(this, wxID_HIGHEST + 2, wxT("Change...")), 0, wxGROW); tmp->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(wxeditor_esettings_paths::on_configure), NULL, this); - top_s->Add(new wxStaticText(this, -1, wxT("Save path")), 0, wxGROW); + top_s->Add(new wxStaticText(this, -1, wxT("Movie path: ")), 0, wxGROW); top_s->Add(savepath = new wxStaticText(this, -1, wxT("")), 1, wxGROW); top_s->Add(tmp = new wxButton(this, wxID_HIGHEST + 3, wxT("Change...")), 0, wxGROW); + tmp->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(wxeditor_esettings_paths::on_configure), NULL, + this); + top_s->Add(new wxStaticText(this, -1, wxT("Slot path: ")), 0, wxGROW); + top_s->Add(slotpath = new wxStaticText(this, -1, wxT("")), 1, wxGROW); + top_s->Add(tmp = new wxButton(this, wxID_HIGHEST + 5, wxT("Change...")), 0, wxGROW); + tmp->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(wxeditor_esettings_paths::on_configure), NULL, + this); + top_s->Add(new wxStaticText(this, -1, wxT("Save slots: ")), 0, wxGROW); + top_s->Add(slots = new wxStaticText(this, -1, wxT("")), 1, wxGROW); + top_s->Add(tmp = new wxButton(this, wxID_HIGHEST + 4, wxT("Change...")), 0, wxGROW); tmp->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(wxeditor_esettings_paths::on_configure), NULL, this); refresh(); @@ -368,6 +382,10 @@ void wxeditor_esettings_paths::on_configure(wxCommandEvent& e) name = FIRMWAREPATH; else if(e.GetId() == wxID_HIGHEST + 3) name = MOVIEPATH; + else if(e.GetId() == wxID_HIGHEST + 4) + name = SAVESLOTS; + else if(e.GetId() == wxID_HIGHEST + 5) + name = SLOTPATH; else return; std::string val; @@ -378,21 +396,28 @@ void wxeditor_esettings_paths::on_configure(wxCommandEvent& e) refresh(); return; } - runemufn([val, name]() { setting::set(name, val); }); + std::string err; + runemufn([val, name, &err]() { try { setting::set(name, val); } catch(std::exception& e) { err = e.what(); }}); + if(err != "") + wxMessageBox(wxT("Invalid value"), wxT("Can't change value"), wxICON_EXCLAMATION | wxOK); refresh(); } void wxeditor_esettings_paths::refresh() { - std::string rpath, fpath, spath; - runemufn([&rpath, &fpath, &spath]() { + std::string rpath, fpath, spath, nslot, lpath; + runemufn([&rpath, &fpath, &spath, &nslot, &lpath]() { fpath = setting::get(FIRMWAREPATH); rpath = setting::get(ROMPATH); spath = setting::get(MOVIEPATH); + nslot = setting::get(SAVESLOTS); + lpath = setting::get(SLOTPATH); }); rompath->SetLabel(towxstring(rpath)); firmpath->SetLabel(towxstring(fpath)); savepath->SetLabel(towxstring(spath)); + slots->SetLabel(towxstring(nslot)); + slotpath->SetLabel(towxstring(lpath)); top_s->Layout(); Fit(); }