If loading movie/savestate without ROM, prompt for one
This commit is contained in:
parent
f9e0abd0bd
commit
61482629ee
12 changed files with 143 additions and 2 deletions
|
@ -71,6 +71,8 @@ std::pair<uint64_t, uint64_t> core_get_bus_map();
|
|||
unsigned core_get_poll_flag();
|
||||
//Set poll flag (set to 1 on each real poll, except if 2.
|
||||
void core_set_poll_flag(unsigned pflag);
|
||||
//Is a cartridge loaded?
|
||||
bool core_rom_loaded();
|
||||
|
||||
/**
|
||||
* Get name of logical button.
|
||||
|
|
|
@ -24,5 +24,6 @@ extern std::string msu1_base_path;
|
|||
void mainloop_signal_need_rewind(void* ptr);
|
||||
|
||||
void set_stop_at_frame(uint64_t frame = 0);
|
||||
void force_pause();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "core/keymapper.hpp"
|
||||
#include "core/messagebuffer.hpp"
|
||||
#include "core/status.hpp"
|
||||
#include "core/romtype.hpp"
|
||||
#include "library/framebuffer.hpp"
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
@ -221,6 +222,10 @@ struct graphics_plugin
|
|||
* - The call can occur in any thread.
|
||||
*/
|
||||
static void fatal_error() throw();
|
||||
/**
|
||||
* Request filename for ROM load.
|
||||
*/
|
||||
static std::string request_rom(core_type& coretype);
|
||||
/**
|
||||
* Identification for graphics plugin.
|
||||
*/
|
||||
|
|
|
@ -41,6 +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);
|
||||
recent_menu* recent_roms;
|
||||
recent_menu* recent_movies;
|
||||
private:
|
||||
|
|
|
@ -1175,6 +1175,11 @@ void core_set_poll_flag(unsigned pflag)
|
|||
pollflag_active = (pflag < 2);
|
||||
}
|
||||
|
||||
bool core_rom_loaded()
|
||||
{
|
||||
return (internal_rom != NULL);
|
||||
}
|
||||
|
||||
emucore_callbacks::~emucore_callbacks() throw()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -323,6 +323,11 @@ void core_power()
|
|||
|
||||
void core_unload_cartridge()
|
||||
{
|
||||
if(!internal_rom)
|
||||
return;
|
||||
instance->~GB();
|
||||
new(instance) gambatte::GB;
|
||||
internal_rom = NULL;
|
||||
}
|
||||
|
||||
void set_preload_settings()
|
||||
|
@ -607,6 +612,11 @@ std::pair<uint64_t, uint64_t> core_get_bus_map()
|
|||
return std::make_pair(0, 0);
|
||||
}
|
||||
|
||||
bool core_rom_loaded()
|
||||
{
|
||||
return (internal_rom != NULL);
|
||||
}
|
||||
|
||||
emucore_callbacks::~emucore_callbacks() throw() {}
|
||||
|
||||
struct emucore_callbacks* ecore_callbacks;
|
||||
|
|
|
@ -288,6 +288,11 @@ namespace
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void close_rom()
|
||||
{
|
||||
our_rom->rtype = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void update_movie_state()
|
||||
|
@ -731,6 +736,13 @@ namespace
|
|||
mark_pending_load("SOME NONBLANK NAME", LOAD_STATE_ROMRELOAD);
|
||||
});
|
||||
|
||||
function_ptr_command<> close_rom2("close-rom", "Close the ROM image",
|
||||
"Syntax: close-rom\nClose the ROM image\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
close_rom();
|
||||
mark_pending_load("SOME NONBLANK NAME", LOAD_STATE_ROMRELOAD);
|
||||
});
|
||||
|
||||
function_ptr_command<> cancel_save("cancel-saves", "Cancel all pending saves", "Syntax: cancel-save\n"
|
||||
"Cancel pending saves\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
|
@ -1084,7 +1096,8 @@ void main_loop(struct loaded_rom& rom, struct moviefile& initial, bool load_has_
|
|||
just_did_loadstate = false;
|
||||
}
|
||||
frame_irq_time = get_utime() - time_x;
|
||||
core_emulate_frame();
|
||||
if(core_rom_loaded())
|
||||
core_emulate_frame();
|
||||
time_x = get_utime();
|
||||
if(amode == ADVANCE_AUTO)
|
||||
platform::wait(to_wait_frame(get_utime()));
|
||||
|
@ -1103,3 +1116,9 @@ void set_stop_at_frame(uint64_t frame)
|
|||
amode = ADVANCE_AUTO;
|
||||
platform::set_paused(false);
|
||||
}
|
||||
|
||||
void force_pause()
|
||||
{
|
||||
amode = ADVANCE_PAUSE;
|
||||
platform::set_paused(true);
|
||||
}
|
|
@ -7,11 +7,14 @@
|
|||
#include "core/framebuffer.hpp"
|
||||
#include "core/framerate.hpp"
|
||||
#include "lua/lua.hpp"
|
||||
#include "core/mainloop.hpp"
|
||||
#include "core/memorymanip.hpp"
|
||||
#include "core/misc.hpp"
|
||||
#include "core/moviedata.hpp"
|
||||
#include "core/rrdata.hpp"
|
||||
#include "core/settings.hpp"
|
||||
#include "library/string.hpp"
|
||||
#include "library/zip.hpp"
|
||||
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
|
@ -295,6 +298,14 @@ extern time_t random_seed_value;
|
|||
|
||||
void do_load_beginning(bool reload) throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
if(!our_rom->rtype) {
|
||||
core_unload_cartridge();
|
||||
refresh_cart_mappings();
|
||||
redraw_framebuffer(screen_nosignal);
|
||||
force_pause();
|
||||
messages << "ROM closed" << std::endl;
|
||||
return;
|
||||
}
|
||||
if(!our_movie.gametype && !reload) {
|
||||
messages << "Can't load movie without a ROM" << std::endl;
|
||||
return;
|
||||
|
@ -346,6 +357,26 @@ void do_load_beginning(bool reload) throw(std::bad_alloc, std::runtime_error)
|
|||
messages << "Movie rewound to beginning." << std::endl;
|
||||
}
|
||||
|
||||
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);
|
||||
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());
|
||||
if(rname == "")
|
||||
throw std::runtime_error("Canceled loading ROM");
|
||||
loaded_rom newrom(rname);
|
||||
*our_rom = newrom;
|
||||
}
|
||||
|
||||
//Load state from loaded movie file (does not catch errors).
|
||||
void do_load_state(struct moviefile& _movie, int lmode)
|
||||
{
|
||||
|
@ -510,6 +541,8 @@ bool do_load_state(const std::string& filename, int lmode)
|
|||
lua_callback_pre_load(filename2);
|
||||
struct moviefile mfile;
|
||||
try {
|
||||
if(!core_rom_loaded())
|
||||
try_request_rom(filename2);
|
||||
mfile = moviefile(filename2);
|
||||
} catch(std::bad_alloc& e) {
|
||||
OOM_panic();
|
||||
|
|
|
@ -49,4 +49,9 @@ void graphics_plugin::fatal_error() throw()
|
|||
std::cerr << "Exiting on fatal error." << std::endl;
|
||||
}
|
||||
|
||||
std::string graphics_plugin::request_rom(core_type& coretype)
|
||||
{
|
||||
throw std::runtime_error("Headless does not support ROM preloading");
|
||||
}
|
||||
|
||||
const char* graphics_plugin::name = "Dummy graphics plugin";
|
||||
|
|
|
@ -613,4 +613,10 @@ void graphics_plugin::fatal_error() throw()
|
|||
}
|
||||
}
|
||||
|
||||
std::string graphics_plugin::request_rom(core_type& coretype)
|
||||
{
|
||||
throw std::runtime_error("SDL version does not support ROM preloading");
|
||||
}
|
||||
|
||||
|
||||
const char* graphics_plugin::name = "SDL graphics plugin";
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "core/rrdata.hpp"
|
||||
#include "core/settings.hpp"
|
||||
#include "core/window.hpp"
|
||||
#include "library/workthread.hpp"
|
||||
#include "library/string.hpp"
|
||||
#include "library/zip.hpp"
|
||||
|
||||
|
@ -533,6 +534,30 @@ void graphics_plugin::fatal_error() throw()
|
|||
}
|
||||
}
|
||||
|
||||
std::string graphics_plugin::request_rom(core_type& coretype)
|
||||
{
|
||||
core_type* ctype = &coretype;
|
||||
std::string outname;
|
||||
mutex_class lock;
|
||||
cv_class cv;
|
||||
bool done = false;
|
||||
umutex_class h(lock);
|
||||
runuifun([ctype, &outname, &lock, &cv, &done]() -> void {
|
||||
if(done)
|
||||
return;
|
||||
try {
|
||||
main_window->request_rom(outname, *ctype);
|
||||
} catch(...) {
|
||||
}
|
||||
umutex_class h(lock);
|
||||
done = true;
|
||||
cv.notify_all();
|
||||
});
|
||||
while(!done)
|
||||
cv.wait(h);
|
||||
return outname;
|
||||
}
|
||||
|
||||
void _runuifun_async(void (*fn)(void*), void* arg)
|
||||
{
|
||||
mutex::holder h(*ui_mutex);
|
||||
|
|
|
@ -107,7 +107,8 @@ enum
|
|||
wxID_RROM_FIRST,
|
||||
wxID_RROM_LAST = wxID_RROM_FIRST + 16,
|
||||
wxID_VUDISPLAY,
|
||||
wxID_MOVIE_EDIT
|
||||
wxID_MOVIE_EDIT,
|
||||
wxID_CLOSE_ROM
|
||||
};
|
||||
|
||||
|
||||
|
@ -867,6 +868,9 @@ wxwin_mainwindow::wxwin_mainwindow()
|
|||
menu_entry(wxID_SAVE_SUBTITLES, wxT("Subtitles..."));
|
||||
menu_entry(wxID_CANCEL_SAVES, wxT("Cancel pending saves"));
|
||||
menu_end_sub();
|
||||
menu_start_sub(wxT("Close"));
|
||||
menu_entry(wxID_CLOSE_ROM, wxT("ROM"));
|
||||
menu_end_sub();
|
||||
menu_separator();
|
||||
menu_entry(wxID_EXIT, wxT("Quit"));
|
||||
|
||||
|
@ -996,6 +1000,28 @@ void wxwin_mainwindow::notify_exit() throw()
|
|||
Destroy();
|
||||
}
|
||||
|
||||
void wxwin_mainwindow::request_rom(std::string& filename, core_type& coretype)
|
||||
{
|
||||
const std::list<std::string>& exts = coretype.get_extensions();
|
||||
std::string filter = coretype.get_hname() + " ROMs|";
|
||||
bool first = true;
|
||||
for(auto i : exts) {
|
||||
if(!first)
|
||||
filter = filter + ";";
|
||||
first = false;
|
||||
filter = filter + "*." + i;
|
||||
}
|
||||
filter = filter + "|All files|*.*";
|
||||
wxFileDialog* fdiag = new wxFileDialog(this, wxT("Load ROM"), towxstring(rom_path()), "", towxstring(filter),
|
||||
wxFD_OPEN);
|
||||
if(fdiag->ShowModal() != wxID_OK) {
|
||||
delete fdiag;
|
||||
return;
|
||||
}
|
||||
filename = fdiag->GetPath();
|
||||
delete fdiag;
|
||||
}
|
||||
|
||||
#define NEW_KEYBINDING "A new binding..."
|
||||
#define NEW_ALIAS "A new alias..."
|
||||
#define NEW_WATCH "A new watch..."
|
||||
|
@ -1300,5 +1326,8 @@ void wxwin_mainwindow::handle_menu_click_cancelable(wxCommandEvent& e)
|
|||
case wxID_MOVIE_EDIT:
|
||||
wxeditor_movie_display(this);
|
||||
return;
|
||||
case wxID_CLOSE_ROM:
|
||||
platform::queue("close-rom");
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue