Handle project switch as special kind of loadstate

This avoids all manner of special cases.
This commit is contained in:
Ilari Liusvaara 2013-05-23 00:31:28 +03:00
parent 1be1d0ff72
commit b404184412
4 changed files with 36 additions and 13 deletions

View file

@ -24,6 +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 switch_projects(const std::string& newproj);
#endif

View file

@ -75,6 +75,7 @@ namespace
//Mode and filename of pending load, one of LOAD_* constants.
int loadmode;
std::string pending_load;
std::string pending_new_project;
//Queued saves (all savestates).
std::set<std::string> queued_saves;
//Save jukebox.
@ -943,6 +944,29 @@ namespace
messages << "Rewind done in " << (get_utime() - t) << " usec." << std::endl;
return 1;
}
if(pending_new_project != "") {
std::string id = pending_new_project;
pending_new_project = "";
project_info* old = project_get();
if(old && old->id == id)
goto nothing_to_do;
try {
auto& p = project_load(id);
project_set(&p);
if(project_get() != old)
delete old;
flush_slotinfo(); //Wrong movie may be stale.
return 1;
} catch(std::exception& e) {
messages << "Can't switch projects: " << e.what() << std::endl;
goto nothing_to_do;
}
nothing_to_do:
amode = old_mode;
platform::set_paused(amode == ADVANCE_PAUSE);
platform::flush_command_queue();
return 0;
}
if(pending_load != "") {
std::string old_project = our_movie.projectid;
system_corrupt = false;
@ -963,7 +987,6 @@ namespace
movb.get_movie().set_pflag_handler(&lsnes_pflag_handler);
pending_load = "";
amode = ADVANCE_AUTO;
platform::cancel_wait();
platform::set_paused(false);
if(!system_corrupt) {
location_special = SPECIAL_SAVEPOINT;
@ -1005,7 +1028,6 @@ namespace
if(!system_corrupt)
return false;
while(system_corrupt) {
platform::cancel_wait();
platform::set_paused(true);
platform::flush_command_queue();
handle_load();
@ -1098,7 +1120,6 @@ void main_loop(struct loaded_rom& rom, struct moviefile& initial, bool load_has_
//If we just loadstated, we are up to date.
if(amode == ADVANCE_QUIT)
break;
platform::cancel_wait();
platform::set_paused(amode == ADVANCE_PAUSE);
platform::flush_command_queue();
//We already have done the reset this frame if we are going to do one at all.
@ -1131,3 +1152,12 @@ void do_flush_slotinfo()
{
flush_slotinfo();
}
void switch_projects(const std::string& newproj)
{
pending_new_project = newproj;
amode = ADVANCE_LOAD;
old_mode = ADVANCE_PAUSE;
platform::cancel_wait();
platform::set_paused(false);
}

View file

@ -375,9 +375,6 @@ bool project_set(project_info* p, bool current)
delete newrom;
newrom = NULL;
do_load_state(newmovie, LOAD_STATE_DEFAULT);
//If the thing is movie, we have to load the first frame to avoid desyncs.
if(movb.get_movie().get_current_frame() == 0)
movb.get_movie().next_frame();
skip_rom_movie:
active_project = p;
switched = true;

View file

@ -1294,13 +1294,9 @@ void wxwin_mainwindow::handle_menu_click_cancelable(wxCommandEvent& e)
}
std::string id = a[d2->GetSelection()];
runemufn([id]() -> void {
project_info* old_proj = project_get();
if(old_proj && old_proj->id == id)
return;
try {
project_info& proj = project_load(id);
if(project_set(&proj))
delete old_proj;
delete &project_load(id); //Check.
switch_projects(id);
} catch(std::exception& e) {
messages << "Failed to change project: " << e.what() << std::endl;
}