Refactor unsafe rewinding a bit now that state is its own subobject
This commit is contained in:
parent
653f44e353
commit
39286f820a
7 changed files with 29 additions and 43 deletions
|
@ -51,7 +51,7 @@ extern std::string last_save;
|
|||
* Parameter secs: The seconds counter.
|
||||
* Parameter ssecs: The subsecond counter.
|
||||
*/
|
||||
void mainloop_restore_state(const std::vector<char>& state, uint64_t secs, uint64_t ssecs);
|
||||
void mainloop_restore_state(const dynamic_state& state);
|
||||
|
||||
std::string get_mprefix_for_project();
|
||||
void set_mprefix_for_project(const std::string& pfx);
|
||||
|
|
|
@ -73,8 +73,7 @@ struct lua_state
|
|||
void callback_snoop_input(uint32_t port, uint32_t controller, uint32_t index, short value) throw();
|
||||
void callback_quit() throw();
|
||||
void callback_keyhook(const std::string& key, keyboard::key& p) throw();
|
||||
void callback_do_unsafe_rewind(const std::vector<char>& save, uint64_t secs, uint64_t ssecs, movie& mov,
|
||||
void* u);
|
||||
void callback_do_unsafe_rewind(movie& mov, void* u);
|
||||
bool callback_do_button(uint32_t port, uint32_t controller, uint32_t index, const char* type);
|
||||
void callback_movie_lost(const char* what);
|
||||
void callback_do_latch(std::list<std::string>& args);
|
||||
|
|
|
@ -3,22 +3,19 @@
|
|||
|
||||
#include "library/lua-base.hpp"
|
||||
#include "library/string.hpp"
|
||||
#include "core/moviefile.hpp"
|
||||
|
||||
struct lua_unsaferewind
|
||||
{
|
||||
lua_unsaferewind(lua::state& L);
|
||||
static size_t overcommit() { return 0; }
|
||||
std::vector<char> state;
|
||||
uint64_t frame;
|
||||
uint64_t lag;
|
||||
//The console state.
|
||||
dynamic_state console_state;
|
||||
//Extra state variable involved in fast movie restore. It is not part of normal console state.
|
||||
uint64_t ptr;
|
||||
uint64_t secs;
|
||||
uint64_t ssecs;
|
||||
std::vector<uint32_t> pollcounters;
|
||||
std::vector<char> hostmemory;
|
||||
std::string print()
|
||||
{
|
||||
return (stringfmt() << "to frame " << frame).str();
|
||||
return (stringfmt() << "to frame " << console_state.save_frame).str();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -712,8 +712,7 @@ jumpback:
|
|||
if(!*core.mlogic)
|
||||
return 0;
|
||||
uint64_t t = framerate_regulator::get_utime();
|
||||
std::vector<char> s;
|
||||
core.lua2->callback_do_unsafe_rewind(s, 0, 0, core.mlogic->get_movie(), unsafe_rewind_obj);
|
||||
core.lua2->callback_do_unsafe_rewind(core.mlogic->get_movie(), unsafe_rewind_obj);
|
||||
core.dispatch->mode_change(false);
|
||||
do_unsafe_rewind = false;
|
||||
core.mlogic->get_mfile().dyn.is_savestate = true;
|
||||
|
@ -805,11 +804,8 @@ nothing_to_do:
|
|||
}
|
||||
if(do_unsafe_rewind && !unsafe_rewind_obj) {
|
||||
uint64_t t = framerate_regulator::get_utime();
|
||||
std::vector<char> s = core.rom->save_core_state(true);
|
||||
uint64_t secs = core.mlogic->get_mfile().dyn.rtc_second;
|
||||
uint64_t ssecs = core.mlogic->get_mfile().dyn.rtc_subsecond;
|
||||
core.lua2->callback_do_unsafe_rewind(s, secs, ssecs, core.mlogic->get_movie(),
|
||||
NULL);
|
||||
core.mlogic->get_mfile().dyn.savestate = core.rom->save_core_state(true);
|
||||
core.lua2->callback_do_unsafe_rewind(core.mlogic->get_movie(), NULL);
|
||||
do_unsafe_rewind = false;
|
||||
messages << "Rewind point set in " << (framerate_regulator::get_utime() - t)
|
||||
<< " usec." << std::endl;
|
||||
|
|
|
@ -885,16 +885,14 @@ bool do_load_state(const std::string& filename, int lmode)
|
|||
return true;
|
||||
}
|
||||
|
||||
void mainloop_restore_state(const std::vector<char>& state, uint64_t secs, uint64_t ssecs)
|
||||
void mainloop_restore_state(const dynamic_state& state)
|
||||
{
|
||||
auto& core = CORE();
|
||||
//Force unlazy rrdata.
|
||||
core.mlogic->get_rrdata().read_base(rrdata::filename(core.mlogic->get_mfile().projectid),
|
||||
false);
|
||||
core.mlogic->get_rrdata().add((*core.nrrdata)());
|
||||
core.mlogic->get_mfile().dyn.rtc_second = secs;
|
||||
core.mlogic->get_mfile().dyn.rtc_subsecond = ssecs;
|
||||
core.rom->load_core_state(state, true);
|
||||
core.rom->load_core_state(state.savestate, true);
|
||||
}
|
||||
|
||||
rrdata::rrdata()
|
||||
|
|
|
@ -418,8 +418,7 @@ uint64_t lua_state::timed_hook(int timer) throw()
|
|||
return 0;
|
||||
}
|
||||
|
||||
void lua_state::callback_do_unsafe_rewind(const std::vector<char>& save, uint64_t secs, uint64_t ssecs, movie& mov,
|
||||
void* u)
|
||||
void lua_state::callback_do_unsafe_rewind(movie& mov, void* u)
|
||||
{
|
||||
auto& core = CORE();
|
||||
if(u) {
|
||||
|
@ -428,24 +427,26 @@ void lua_state::callback_do_unsafe_rewind(const std::vector<char>& save, uint64_
|
|||
try {
|
||||
run_callback(*on_pre_rewind);
|
||||
run_callback(*on_movie_lost, "unsaferewind");
|
||||
mainloop_restore_state(u2->state, u2->secs, u2->ssecs);
|
||||
mov.fast_load(u2->frame, u2->ptr, u2->lag, u2->pollcounters);
|
||||
try { core.mlogic->get_mfile().dyn.host_memory = u2->hostmemory; } catch(...) {}
|
||||
mainloop_restore_state(u2->console_state);
|
||||
mov.fast_load(u2->console_state.save_frame, u2->ptr, u2->console_state.lagged_frames,
|
||||
u2->console_state.pollcounters);
|
||||
core.mlogic->get_mfile().dyn = u2->console_state;
|
||||
run_callback(*on_post_rewind);
|
||||
delete reinterpret_cast<lua::objpin<lua_unsaferewind>*>(u);
|
||||
} catch(std::bad_alloc& e) {
|
||||
OOM_panic();
|
||||
} catch(...) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
//Save
|
||||
run_callback(*on_set_rewind, lua::state::fn_tag([&core, save, secs, ssecs, &mov](lua::state& L) ->
|
||||
run_callback(*on_set_rewind, lua::state::fn_tag([&core, &mov](lua::state& L) ->
|
||||
int {
|
||||
lua_unsaferewind* u2 = lua::_class<lua_unsaferewind>::create(*core.lua);
|
||||
u2->state = save;
|
||||
u2->secs = secs,
|
||||
u2->ssecs = ssecs;
|
||||
u2->hostmemory = core.mlogic->get_mfile().dyn.host_memory;
|
||||
mov.fast_save(u2->frame, u2->ptr, u2->lag, u2->pollcounters);
|
||||
u2->console_state = core.mlogic->get_mfile().dyn;
|
||||
u2->console_state.is_savestate = true;
|
||||
mov.fast_save(u2->console_state.save_frame, u2->ptr, u2->console_state.lagged_frames,
|
||||
u2->console_state.pollcounters);
|
||||
return 1;
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -112,20 +112,15 @@ namespace
|
|||
if(!mfile.dyn.is_savestate)
|
||||
throw std::runtime_error("movie.to_rewind only allows savestates");
|
||||
lua_unsaferewind* u2 = lua::_class<lua_unsaferewind>::create(L);
|
||||
u2->state = mfile.dyn.savestate;
|
||||
if(u2->state.size() >= 32)
|
||||
u2->state.resize(u2->state.size() - 32);
|
||||
u2->secs = mfile.dyn.rtc_second;
|
||||
u2->ssecs = mfile.dyn.rtc_subsecond;
|
||||
u2->pollcounters = mfile.dyn.pollcounters;
|
||||
u2->lag = mfile.dyn.lagged_frames;
|
||||
u2->frame = mfile.dyn.save_frame;
|
||||
u2->hostmemory = mfile.dyn.host_memory;
|
||||
u2->console_state = mfile.dyn;
|
||||
//Cut off the hash.
|
||||
if(u2->console_state.savestate.size() >= 32)
|
||||
u2->console_state.savestate.resize(u2->console_state.savestate.size() - 32);
|
||||
//Now the remaining field ptr is somewhat nastier.
|
||||
uint64_t f = 0;
|
||||
uint64_t s = mfile.input->size();
|
||||
u2->ptr = 0;
|
||||
while(++f < u2->frame) {
|
||||
while(++f < u2->console_state.save_frame) {
|
||||
if(u2->ptr < s)
|
||||
u2->ptr++;
|
||||
while(u2->ptr < s && !(*mfile.input)[u2->ptr].sync())
|
||||
|
|
Loading…
Add table
Reference in a new issue