Reload mode for movies
This commit is contained in:
parent
c1c9c1d2b2
commit
3a80e18300
5 changed files with 101 additions and 3 deletions
|
@ -268,6 +268,18 @@ public:
|
|||
* Adjust frame count.
|
||||
*/
|
||||
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:
|
||||
//TRUE if readonly mode is active.
|
||||
bool readonly;
|
||||
|
@ -296,6 +308,8 @@ private:
|
|||
uint32_t count_changes(uint64_t first_subframe) throw();
|
||||
//Sequence number.
|
||||
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);
|
||||
else if(!subframe)
|
||||
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);
|
||||
return tmp;
|
||||
}
|
||||
|
@ -270,6 +277,8 @@ void update_movie_state()
|
|||
x << "C";
|
||||
else if(!mo.readonly_mode())
|
||||
x << "R";
|
||||
else if(mo.get_reload_mode())
|
||||
x << "L";
|
||||
else if(mo.get_frame_count() >= mo.get_current_frame())
|
||||
x << "P";
|
||||
else
|
||||
|
@ -636,6 +645,20 @@ namespace
|
|||
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",
|
||||
"Syntax: repaint\nRedraws the screen\n",
|
||||
[]() 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 itoggle_romode("set-romode", "Movie‣Switch to 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 itogglepause("toggle-pause-on-end", "Movie‣Toggle pause-on-end");
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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...
|
||||
//If at the end of the movie, return released / neutral (but also record the poll)...
|
||||
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.
|
||||
uint32_t changes = count_changes(current_frame_first_subframe);
|
||||
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;
|
||||
//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);
|
||||
} else {
|
||||
//Readwrite mode.
|
||||
|
@ -283,6 +307,7 @@ movie::movie() throw(std::bad_alloc)
|
|||
{
|
||||
seqno = 0;
|
||||
readonly = false;
|
||||
reload_mode = false;
|
||||
rerecords = "0";
|
||||
_project_id = "";
|
||||
current_frame = 0;
|
||||
|
@ -548,6 +573,7 @@ movie& movie::operator=(const movie& m)
|
|||
{
|
||||
seqno++;
|
||||
readonly = m.readonly;
|
||||
reload_mode = m.reload_mode;
|
||||
rerecords = m.rerecords;
|
||||
_project_id = m._project_id;
|
||||
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)
|
||||
{
|
||||
bool current_mode = movb.get_movie().readonly_mode();
|
||||
bool in_reload = movb.get_movie().get_reload_mode();
|
||||
if(_movie.force_corrupt)
|
||||
throw std::runtime_error("Movie file invalid");
|
||||
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)
|
||||
movb.get_movie().readonly_mode(false);
|
||||
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)
|
||||
messages << "ROM Type " << our_rom->rtype->get_hname() << " region " << our_rom->region->get_hname()
|
||||
<< std::endl;
|
||||
|
|
|
@ -35,9 +35,39 @@ namespace
|
|||
function_ptr_luafun mrw("movie.readwrite", [](lua_State* LS, const std::string& fname) -> int {
|
||||
auto& m = get_movie();
|
||||
m.readonly_mode(false);
|
||||
m.set_reload_mode(false);
|
||||
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 {
|
||||
uint64_t frame = get_numeric_argument<uint64_t>(LS, 1, "movie.frame_subframes");
|
||||
auto& m = get_movie();
|
||||
|
|
Loading…
Add table
Reference in a new issue