Compare commits
1 commit
master
...
movie-relo
Author | SHA1 | Date | |
---|---|---|---|
|
3a80e18300 |
5 changed files with 101 additions and 3 deletions
|
@ -268,6 +268,18 @@ public:
|
||||||
* Adjust frame count.
|
* Adjust frame count.
|
||||||
*/
|
*/
|
||||||
void adjust_frame_count(int64_t adjust) { frames_in_movie += adjust; }
|
void adjust_frame_count(int64_t adjust) { frames_in_movie += adjust; }
|
||||||
|
/**
|
||||||
|
* Set reload mode flag (only effective in readonly mode).
|
||||||
|
*/
|
||||||
|
void set_reload_mode(bool newstate) throw() { reload_mode = newstate; }
|
||||||
|
/**
|
||||||
|
* Get reload mode flag.
|
||||||
|
*/
|
||||||
|
bool get_reload_mode() const throw() { return reload_mode; }
|
||||||
|
/**
|
||||||
|
* Read the current subframe.
|
||||||
|
*/
|
||||||
|
controller_frame current_subframe() throw(std::bad_alloc);
|
||||||
private:
|
private:
|
||||||
//TRUE if readonly mode is active.
|
//TRUE if readonly mode is active.
|
||||||
bool readonly;
|
bool readonly;
|
||||||
|
@ -296,6 +308,8 @@ private:
|
||||||
uint32_t count_changes(uint64_t first_subframe) throw();
|
uint32_t count_changes(uint64_t first_subframe) throw();
|
||||||
//Sequence number.
|
//Sequence number.
|
||||||
uint64_t seqno;
|
uint64_t seqno;
|
||||||
|
//Reload mode flag.
|
||||||
|
bool reload_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -173,7 +173,14 @@ controller_frame movie_logic::update_controls(bool subframe) throw(std::bad_allo
|
||||||
controls.reset(pending_reset_cycles);
|
controls.reset(pending_reset_cycles);
|
||||||
else if(!subframe)
|
else if(!subframe)
|
||||||
controls.reset(-1);
|
controls.reset(-1);
|
||||||
controller_frame tmp = controls.commit(movb.get_movie().get_current_frame());
|
auto& mov = movb.get_movie();
|
||||||
|
controller_frame tmp = controls.commit(mov.get_current_frame());
|
||||||
|
if(mov.get_reload_mode() && mov.readonly_mode()) {
|
||||||
|
//In reload mode, read the present frame and XOR it.
|
||||||
|
controller_frame pframe;
|
||||||
|
pframe = mov.current_subframe();
|
||||||
|
tmp = tmp ^ pframe;
|
||||||
|
}
|
||||||
lua_callback_do_input(tmp, subframe);
|
lua_callback_do_input(tmp, subframe);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
@ -270,6 +277,8 @@ void update_movie_state()
|
||||||
x << "C";
|
x << "C";
|
||||||
else if(!mo.readonly_mode())
|
else if(!mo.readonly_mode())
|
||||||
x << "R";
|
x << "R";
|
||||||
|
else if(mo.get_reload_mode())
|
||||||
|
x << "L";
|
||||||
else if(mo.get_frame_count() >= mo.get_current_frame())
|
else if(mo.get_frame_count() >= mo.get_current_frame())
|
||||||
x << "P";
|
x << "P";
|
||||||
else
|
else
|
||||||
|
@ -636,6 +645,20 @@ namespace
|
||||||
information_dispatch::do_status_update();
|
information_dispatch::do_status_update();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function_ptr_command<> toggle_rlmode("toggle-rlmode", "Toggle reload mode",
|
||||||
|
"Syntax: toggle-rlmode\nToggles reload mode\n",
|
||||||
|
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||||
|
bool c = movb.get_movie().get_reload_mode();
|
||||||
|
if(!c && !movb.get_movie().readonly_mode()) {
|
||||||
|
//If in read-write mode, set readonly mode.
|
||||||
|
movb.get_movie().readonly_mode(true);
|
||||||
|
information_dispatch::do_mode_change(true);
|
||||||
|
}
|
||||||
|
movb.get_movie().set_reload_mode(!c);
|
||||||
|
update_movie_state();
|
||||||
|
information_dispatch::do_status_update();
|
||||||
|
});
|
||||||
|
|
||||||
function_ptr_command<> repaint("repaint", "Redraw the screen",
|
function_ptr_command<> repaint("repaint", "Redraw the screen",
|
||||||
"Syntax: repaint\nRedraws the screen\n",
|
"Syntax: repaint\nRedraws the screen\n",
|
||||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||||
|
@ -700,6 +723,7 @@ namespace
|
||||||
inverse_key iset_rwmode("set-rwmode", "Movie‣Switch to read/write");
|
inverse_key iset_rwmode("set-rwmode", "Movie‣Switch to read/write");
|
||||||
inverse_key itoggle_romode("set-romode", "Movie‣Switch to read-only");
|
inverse_key itoggle_romode("set-romode", "Movie‣Switch to read-only");
|
||||||
inverse_key itoggle_rwmode("toggle-rwmode", "Movie‣Toggle read-only");
|
inverse_key itoggle_rwmode("toggle-rwmode", "Movie‣Toggle read-only");
|
||||||
|
inverse_key itoggle_rlmode("toggle-rlmode", "Movie‣Toggle reload mode");
|
||||||
inverse_key irepaint("repaint", "System‣Repaint screen");
|
inverse_key irepaint("repaint", "System‣Repaint screen");
|
||||||
inverse_key itogglepause("toggle-pause-on-end", "Movie‣Toggle pause-on-end");
|
inverse_key itogglepause("toggle-pause-on-end", "Movie‣Toggle pause-on-end");
|
||||||
inverse_key irewind_movie("rewind-movie", "Movie‣Rewind movie");
|
inverse_key irewind_movie("rewind-movie", "Movie‣Rewind movie");
|
||||||
|
|
|
@ -220,11 +220,32 @@ bool movie::get_DRDY(unsigned pid, unsigned ctrl) throw(std::logic_error)
|
||||||
return pollcounters.get_DRDY(pid, ctrl);
|
return pollcounters.get_DRDY(pid, ctrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
controller_frame movie::current_subframe() throw(std::bad_alloc)
|
||||||
|
{
|
||||||
|
//Reload mode works like readwrite once movie end is reached.
|
||||||
|
if(readonly && (!reload_mode || current_frame_first_subframe < movie_data.size())) {
|
||||||
|
//In readonly mode...
|
||||||
|
//If at the end of the movie, return released / neutral...
|
||||||
|
//Before the beginning? Somebody screwed up (but return released / neutral anyway)...
|
||||||
|
if(current_frame_first_subframe >= movie_data.size() || current_frame == 0)
|
||||||
|
return movie_data.blank_frame(false);
|
||||||
|
//Otherwise find the last valid frame of input.
|
||||||
|
uint32_t changes = count_changes(current_frame_first_subframe);
|
||||||
|
uint32_t polls = pollcounters.max_polls();
|
||||||
|
uint32_t index = (changes >= polls) ? polls : changes - 1;
|
||||||
|
return movie_data[current_frame_first_subframe + index].copy(index == 0);
|
||||||
|
} else {
|
||||||
|
//Readwrite mode. The frame is always empty.
|
||||||
|
return movie_data.blank_frame(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
short movie::next_input(unsigned pid, unsigned ctrl) throw(std::bad_alloc, std::logic_error)
|
short movie::next_input(unsigned pid, unsigned ctrl) throw(std::bad_alloc, std::logic_error)
|
||||||
{
|
{
|
||||||
pollcounters.clear_DRDY(pid, ctrl);
|
pollcounters.clear_DRDY(pid, ctrl);
|
||||||
|
|
||||||
if(readonly) {
|
//Reload mode works like readwrite once movie end is reached.
|
||||||
|
if(readonly && (!reload_mode || current_frame_first_subframe < movie_data.size())) {
|
||||||
//In readonly mode...
|
//In readonly mode...
|
||||||
//If at the end of the movie, return released / neutral (but also record the poll)...
|
//If at the end of the movie, return released / neutral (but also record the poll)...
|
||||||
if(current_frame_first_subframe >= movie_data.size()) {
|
if(current_frame_first_subframe >= movie_data.size()) {
|
||||||
|
@ -237,8 +258,11 @@ short movie::next_input(unsigned pid, unsigned ctrl) throw(std::bad_alloc, std::
|
||||||
//Otherwise find the last valid frame of input.
|
//Otherwise find the last valid frame of input.
|
||||||
uint32_t changes = count_changes(current_frame_first_subframe);
|
uint32_t changes = count_changes(current_frame_first_subframe);
|
||||||
uint32_t polls = pollcounters.increment_polls(pid, ctrl);
|
uint32_t polls = pollcounters.increment_polls(pid, ctrl);
|
||||||
uint32_t index = (changes > polls) ? polls : changes - 1;
|
uint32_t index = (changes >= polls) ? polls : changes - 1;
|
||||||
//debuglog << "Frame=" << current_frame << " Subframe=" << polls << " control=" << controlindex << " value=" << movie_data[current_frame_first_subframe + index](controlindex) << " fetchrow=" << current_frame_first_subframe + index << std::endl << std::flush;
|
//debuglog << "Frame=" << current_frame << " Subframe=" << polls << " control=" << controlindex << " value=" << movie_data[current_frame_first_subframe + index](controlindex) << " fetchrow=" << current_frame_first_subframe + index << std::endl << std::flush;
|
||||||
|
//Reload mode reloads the frames.
|
||||||
|
if(reload_mode && changes < polls)
|
||||||
|
movie_data[current_frame_first_subframe + index] = current_controls.copy(index == 0);
|
||||||
return movie_data[current_frame_first_subframe + index].axis(pid, ctrl);
|
return movie_data[current_frame_first_subframe + index].axis(pid, ctrl);
|
||||||
} else {
|
} else {
|
||||||
//Readwrite mode.
|
//Readwrite mode.
|
||||||
|
@ -283,6 +307,7 @@ movie::movie() throw(std::bad_alloc)
|
||||||
{
|
{
|
||||||
seqno = 0;
|
seqno = 0;
|
||||||
readonly = false;
|
readonly = false;
|
||||||
|
reload_mode = false;
|
||||||
rerecords = "0";
|
rerecords = "0";
|
||||||
_project_id = "";
|
_project_id = "";
|
||||||
current_frame = 0;
|
current_frame = 0;
|
||||||
|
@ -548,6 +573,7 @@ movie& movie::operator=(const movie& m)
|
||||||
{
|
{
|
||||||
seqno++;
|
seqno++;
|
||||||
readonly = m.readonly;
|
readonly = m.readonly;
|
||||||
|
reload_mode = m.reload_mode;
|
||||||
rerecords = m.rerecords;
|
rerecords = m.rerecords;
|
||||||
_project_id = m._project_id;
|
_project_id = m._project_id;
|
||||||
movie_data = m.movie_data;
|
movie_data = m.movie_data;
|
||||||
|
|
|
@ -338,6 +338,7 @@ void do_load_beginning(bool reload) throw(std::bad_alloc, std::runtime_error)
|
||||||
void do_load_state(struct moviefile& _movie, int lmode)
|
void do_load_state(struct moviefile& _movie, int lmode)
|
||||||
{
|
{
|
||||||
bool current_mode = movb.get_movie().readonly_mode();
|
bool current_mode = movb.get_movie().readonly_mode();
|
||||||
|
bool in_reload = movb.get_movie().get_reload_mode();
|
||||||
if(_movie.force_corrupt)
|
if(_movie.force_corrupt)
|
||||||
throw std::runtime_error("Movie file invalid");
|
throw std::runtime_error("Movie file invalid");
|
||||||
bool will_load_state = _movie.is_savestate && lmode != LOAD_STATE_MOVIE;
|
bool will_load_state = _movie.is_savestate && lmode != LOAD_STATE_MOVIE;
|
||||||
|
@ -457,6 +458,9 @@ void do_load_state(struct moviefile& _movie, int lmode)
|
||||||
if(lmode == LOAD_STATE_CURRENT && !current_mode)
|
if(lmode == LOAD_STATE_CURRENT && !current_mode)
|
||||||
movb.get_movie().readonly_mode(false);
|
movb.get_movie().readonly_mode(false);
|
||||||
information_dispatch::do_mode_change(movb.get_movie().readonly_mode());
|
information_dispatch::do_mode_change(movb.get_movie().readonly_mode());
|
||||||
|
//Anything except load_state_preserve disenages reload mode.
|
||||||
|
if(lmode != LOAD_STATE_PRESERVE)
|
||||||
|
movb.get_movie().set_reload_mode(false);
|
||||||
if(our_rom->rtype)
|
if(our_rom->rtype)
|
||||||
messages << "ROM Type " << our_rom->rtype->get_hname() << " region " << our_rom->region->get_hname()
|
messages << "ROM Type " << our_rom->rtype->get_hname() << " region " << our_rom->region->get_hname()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
|
@ -35,9 +35,39 @@ namespace
|
||||||
function_ptr_luafun mrw("movie.readwrite", [](lua_State* LS, const std::string& fname) -> int {
|
function_ptr_luafun mrw("movie.readwrite", [](lua_State* LS, const std::string& fname) -> int {
|
||||||
auto& m = get_movie();
|
auto& m = get_movie();
|
||||||
m.readonly_mode(false);
|
m.readonly_mode(false);
|
||||||
|
m.set_reload_mode(false);
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function_ptr_luafun mgm("movie.getmode", [](lua_State* LS, const std::string& fname) -> int {
|
||||||
|
auto& m = get_movie();
|
||||||
|
if(m.readonly_mode())
|
||||||
|
if(m.get_reload_mode())
|
||||||
|
lua_pushstring(LS, "reload");
|
||||||
|
else
|
||||||
|
lua_pushstring(LS, "readonly");
|
||||||
|
else
|
||||||
|
lua_pushstring(LS, "readwrite");
|
||||||
|
return 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
function_ptr_luafun msm("movie.setmode", [](lua_State* LS, const std::string& fname) -> int {
|
||||||
|
auto& m = get_movie();
|
||||||
|
std::string mod = get_string_argument(LS, 1, fname.c_str());
|
||||||
|
if(mod == "reload") {
|
||||||
|
m.readonly_mode(true);
|
||||||
|
m.set_reload_mode(true);
|
||||||
|
} else if(mod == "readonly") {
|
||||||
|
m.readonly_mode(true);
|
||||||
|
m.set_reload_mode(false);
|
||||||
|
} else if(mod == "readwrite") {
|
||||||
|
m.readonly_mode(false);
|
||||||
|
m.set_reload_mode(false);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
function_ptr_luafun mfs("movie.frame_subframes", [](lua_State* LS, const std::string& fname) -> int {
|
function_ptr_luafun mfs("movie.frame_subframes", [](lua_State* LS, const std::string& fname) -> int {
|
||||||
uint64_t frame = get_numeric_argument<uint64_t>(LS, 1, "movie.frame_subframes");
|
uint64_t frame = get_numeric_argument<uint64_t>(LS, 1, "movie.frame_subframes");
|
||||||
auto& m = get_movie();
|
auto& m = get_movie();
|
||||||
|
|
Loading…
Add table
Reference in a new issue