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