If loading movie/savestate without ROM, prompt for one

This commit is contained in:
Ilari Liusvaara 2013-09-03 22:27:42 +03:00
parent f9e0abd0bd
commit 61482629ee
12 changed files with 143 additions and 2 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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