Autofire support
This commit is contained in:
parent
6a823be7d1
commit
83b5a68abe
2 changed files with 66 additions and 4 deletions
59
mainloop.cpp
59
mainloop.cpp
|
@ -83,6 +83,8 @@ namespace
|
|||
//Current controls.
|
||||
controls_t curcontrols;
|
||||
controls_t autoheld_controls;
|
||||
std::vector<controls_t> autofire_pattern;
|
||||
size_t autofire_position;
|
||||
//Emulator status area.
|
||||
std::map<std::string, std::string>* status;
|
||||
//Pending reset cycles. -1 if no reset pending, otherwise, cycle count for reset.
|
||||
|
@ -176,6 +178,7 @@ controls_t movie_logic::update_controls(bool subframe) throw(std::bad_alloc, std
|
|||
location_special = SPECIAL_NONE;
|
||||
update_movie_state();
|
||||
} else {
|
||||
autofire_position = (autofire_position + 1) % autofire_pattern.size();
|
||||
if(amode == ADVANCE_SKIPLAG_PENDING)
|
||||
amode = ADVANCE_SKIPLAG;
|
||||
if(amode == ADVANCE_FRAME || amode == ADVANCE_SUBFRAME) {
|
||||
|
@ -195,6 +198,7 @@ controls_t movie_logic::update_controls(bool subframe) throw(std::bad_alloc, std
|
|||
}
|
||||
location_special = SPECIAL_FRAME_START;
|
||||
update_movie_state();
|
||||
|
||||
}
|
||||
window::notify_screen_update();
|
||||
window::poll_inputs();
|
||||
|
@ -207,7 +211,7 @@ controls_t movie_logic::update_controls(bool subframe) throw(std::bad_alloc, std
|
|||
curcontrols(CONTROL_SYSTEM_RESET_CYCLES_HI) = 0;
|
||||
curcontrols(CONTROL_SYSTEM_RESET_CYCLES_LO) = 0;
|
||||
}
|
||||
controls_t tmp = curcontrols ^ autoheld_controls;
|
||||
controls_t tmp = curcontrols ^ autoheld_controls ^ autofire_pattern[autofire_position];
|
||||
lua_callback_do_input(tmp, subframe);
|
||||
return tmp;
|
||||
}
|
||||
|
@ -236,7 +240,7 @@ namespace
|
|||
}
|
||||
|
||||
//Do button action.
|
||||
void do_button_action(unsigned ui_id, unsigned button, short newstate, bool do_xor = false)
|
||||
void do_button_action(unsigned ui_id, unsigned button, short newstate, bool do_xor, controls_t& c)
|
||||
{
|
||||
enum devicetype_t p = controller_type_by_logical(ui_id);
|
||||
int x = controller_index_by_logical(ui_id);
|
||||
|
@ -295,9 +299,18 @@ namespace
|
|||
break;
|
||||
};
|
||||
if(do_xor)
|
||||
autoheld_controls((x & 4) ? 1 : 0, x & 3, bid) ^= newstate;
|
||||
c((x & 4) ? 1 : 0, x & 3, bid) ^= newstate;
|
||||
else
|
||||
curcontrols((x & 4) ? 1 : 0, x & 3, bid) = newstate;
|
||||
c((x & 4) ? 1 : 0, x & 3, bid) = newstate;
|
||||
}
|
||||
|
||||
//Do button action.
|
||||
void do_button_action(unsigned ui_id, unsigned button, short newstate, bool do_xor = false)
|
||||
{
|
||||
if(do_xor)
|
||||
do_button_action(ui_id, button, newstate, do_xor, autoheld_controls);
|
||||
else
|
||||
do_button_action(ui_id, button, newstate, do_xor, curcontrols);
|
||||
}
|
||||
|
||||
|
||||
|
@ -640,6 +653,43 @@ namespace
|
|||
update_movie_state();
|
||||
});
|
||||
|
||||
function_ptr_command<tokensplitter&> autofire("autofire", "Set autofire pattern",
|
||||
"Syntax: autofire <buttons|->...\nSet autofire pattern\n",
|
||||
[](tokensplitter& t) throw(std::bad_alloc, std::runtime_error) {
|
||||
if(!t)
|
||||
throw std::runtime_error("Need at least one frame for autofire");
|
||||
std::vector<controls_t> new_autofire_pattern;
|
||||
init_buttonmap();
|
||||
while(t) {
|
||||
std::string fpattern = t;
|
||||
if(fpattern == "-")
|
||||
new_autofire_pattern.push_back(controls_t());
|
||||
else {
|
||||
controls_t c;
|
||||
while(fpattern != "") {
|
||||
size_t split = fpattern.find_first_of(",");
|
||||
std::string button = fpattern;
|
||||
std::string rest;
|
||||
if(split < fpattern.length()) {
|
||||
button = fpattern.substr(0, split);
|
||||
rest = fpattern.substr(split + 1);
|
||||
}
|
||||
if(!buttonmap.count(button)) {
|
||||
std::ostringstream x;
|
||||
x << "Invalid button '" << button << "'";
|
||||
throw std::runtime_error(x.str());
|
||||
}
|
||||
auto g = buttonmap[button];
|
||||
do_button_action(g.first, g.second, 1, false, c);
|
||||
fpattern = rest;
|
||||
}
|
||||
new_autofire_pattern.push_back(c);
|
||||
}
|
||||
}
|
||||
autofire_pattern = new_autofire_pattern;
|
||||
autofire_position = 0;
|
||||
});
|
||||
|
||||
function_ptr_command<> test1("test-1", "no description available", "No help available\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
framebuffer = screen_nosignal;
|
||||
|
@ -858,6 +908,7 @@ void main_loop(struct loaded_rom& rom, struct moviefile& initial) throw(std::bad
|
|||
auto old_inteface = SNES::system.interface;
|
||||
SNES::system.interface = &intrf;
|
||||
status = &window::get_emustatus();
|
||||
autofire_pattern.push_back(controls_t());
|
||||
|
||||
//Load our given movie.
|
||||
bool first_round = false;
|
||||
|
|
11
manual.lyx
11
manual.lyx
|
@ -903,6 +903,17 @@ Hold/unhold button <button> on controller <num> (1-8).
|
|||
See +controller for button names.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
autofire (<pattern>|-)...
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
Set autofire pattern.
|
||||
Each parameter is comma-separated list of button names (in form of 1start,
|
||||
1A, 2B, etc..) to hold on that frame.
|
||||
After reaching the end of pattern, the pattern restarts from the beginning.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
repaint
|
||||
\end_layout
|
||||
|
|
Loading…
Add table
Reference in a new issue