Add basic turbo support.

This commit is contained in:
Themaister 2012-10-01 22:15:48 +02:00
parent 10da277059
commit 9c462e19b7
7 changed files with 86 additions and 12 deletions

View File

@ -324,8 +324,9 @@ static const bool stdin_cmd_enable = false;
// How far an axis must be tilted to result in a button press
static const float axis_threshold = 0.5;
// To figure out which joypad buttons to use, check jstest or similar.
// SDL sometimes reverses the axes for some odd reason, but hey. :D
// Describes speed of which turbo-enabled buttons toggle.
static const unsigned turbo_period = 6;
static const unsigned turbo_duty_cycle = 3;
// Player 1
static const struct retro_keybind retro_keybinds_1[] = {
@ -347,6 +348,7 @@ static const struct retro_keybind retro_keybinds_1[] = {
{ true, RETRO_DEVICE_ID_JOYPAD_L3, RETROK_UNKNOWN, NO_BTN, AXIS_NONE },
{ true, RETRO_DEVICE_ID_JOYPAD_R3, RETROK_UNKNOWN, NO_BTN, AXIS_NONE },
{ true, RARCH_TURBO_ENABLE, RETROK_UNKNOWN, NO_BTN, AXIS_NONE },
{ true, RARCH_ANALOG_LEFT_X_PLUS, RETROK_UNKNOWN, NO_BTN, AXIS_NONE },
{ true, RARCH_ANALOG_LEFT_X_MINUS, RETROK_UNKNOWN, NO_BTN, AXIS_NONE },
{ true, RARCH_ANALOG_LEFT_Y_PLUS, RETROK_UNKNOWN, NO_BTN, AXIS_NONE },
@ -402,6 +404,7 @@ static const struct retro_keybind retro_keybinds_rest[] = {
{ true, RETRO_DEVICE_ID_JOYPAD_L3, RETROK_UNKNOWN, NO_BTN, AXIS_NONE },
{ true, RETRO_DEVICE_ID_JOYPAD_R3, RETROK_UNKNOWN, NO_BTN, AXIS_NONE },
{ true, RARCH_TURBO_ENABLE, RETROK_UNKNOWN, NO_BTN, AXIS_NONE },
{ true, RARCH_ANALOG_LEFT_X_PLUS, RETROK_UNKNOWN, NO_BTN, AXIS_NONE },
{ true, RARCH_ANALOG_LEFT_X_MINUS, RETROK_UNKNOWN, NO_BTN, AXIS_NONE },
{ true, RARCH_ANALOG_LEFT_Y_PLUS, RETROK_UNKNOWN, NO_BTN, AXIS_NONE },

View File

@ -40,12 +40,16 @@
// Analog binds use RETRO_DEVICE_ANALOG, but we follow the same scheme internally
// in RetroArch for simplicity,
// so they are mapped into [16, 23].
#define RARCH_FIRST_ANALOG_BIND 16
#define RARCH_FIRST_META_KEY RARCH_ANALOG_BIND_LIST_END
#define RARCH_FIRST_CUSTOM_BIND 16
#define RARCH_FIRST_META_KEY RARCH_CUSTOM_BIND_LIST_END
enum // RetroArch specific bind IDs.
{
// Custom binds that extend the scope of RETRO_DEVICE_JOYPAD for RetroArch specifically.
// Turbo
RARCH_TURBO_ENABLE = RARCH_FIRST_CUSTOM_BIND,
// Analogs (RETRO_DEVICE_ANALOG)
RARCH_ANALOG_LEFT_X_PLUS = RARCH_FIRST_ANALOG_BIND,
RARCH_ANALOG_LEFT_X_PLUS,
RARCH_ANALOG_LEFT_X_MINUS,
RARCH_ANALOG_LEFT_Y_PLUS,
RARCH_ANALOG_LEFT_Y_MINUS,
@ -54,10 +58,10 @@ enum // RetroArch specific bind IDs.
RARCH_ANALOG_RIGHT_Y_PLUS,
RARCH_ANALOG_RIGHT_Y_MINUS,
RARCH_ANALOG_BIND_LIST_END,
RARCH_CUSTOM_BIND_LIST_END,
// Command binds.
RARCH_FAST_FORWARD_KEY = RARCH_ANALOG_BIND_LIST_END,
// Command binds. Not related to game input, only usable for port 0.
RARCH_FAST_FORWARD_KEY = RARCH_FIRST_META_KEY,
RARCH_FAST_FORWARD_HOLD_KEY,
RARCH_LOAD_STATE_KEY,
RARCH_SAVE_STATE_KEY,

View File

@ -365,7 +365,7 @@ static bool environment_cb(unsigned cmd, void *data)
if (desc->device != RETRO_DEVICE_JOYPAD) // Ignore all others for now.
continue;
if (desc->id >= RARCH_FIRST_ANALOG_BIND)
if (desc->id >= RARCH_FIRST_CUSTOM_BIND)
continue;
g_extern.system.input_desc_btn[desc->port][desc->id] = desc->description;
@ -381,7 +381,7 @@ static bool environment_cb(unsigned cmd, void *data)
RARCH_LOG("Environ SET_INPUT_DESCRIPTORS:\n");
for (unsigned p = 0; p < MAX_PLAYERS; p++)
{
for (unsigned id = 0; id < RARCH_FIRST_ANALOG_BIND; id++)
for (unsigned id = 0; id < RARCH_FIRST_CUSTOM_BIND; id++)
{
const char *desc = g_extern.system.input_desc_btn[p][id];
if (desc)

View File

@ -156,6 +156,9 @@ struct settings
unsigned device[MAX_PLAYERS];
#endif
bool netplay_client_swap_input;
unsigned turbo_period;
unsigned turbo_duty_cycle;
} input;
char libretro[PATH_MAX];
@ -338,7 +341,7 @@ struct global
bool force_nonblock;
const char *input_desc_btn[MAX_PLAYERS][RARCH_FIRST_ANALOG_BIND];
const char *input_desc_btn[MAX_PLAYERS][RARCH_FIRST_CUSTOM_BIND];
} system;
struct
@ -422,6 +425,11 @@ struct global
bool is_oneshot;
bool is_slowmotion;
// Turbo support
bool turbo_frame_enable[MAX_PLAYERS];
uint16_t turbo_enable[MAX_PLAYERS];
unsigned turbo_count;
// Autosave support.
autosave_t *autosave[2];

View File

@ -474,6 +474,22 @@ static void input_poll(void)
input_poll_func();
}
// Turbo scheme: If turbo button is held, all buttons pressed except for D-pad will go into
// a turbo mode. Until the button is released again, the input state will be modulated by a periodic pulse defined
// by the configured duty cycle.
static bool input_apply_turbo(unsigned port, unsigned id, bool res)
{
if (res && g_extern.turbo_frame_enable[port])
g_extern.turbo_enable[port] |= (1 << id);
else if (!res)
g_extern.turbo_enable[port] &= ~(1 << id);
if (g_extern.turbo_enable[port] & (1 << id))
return res & ((g_extern.turbo_count % g_settings.input.turbo_period) < g_settings.input.turbo_duty_cycle);
else
return res;
}
static int16_t input_state(unsigned port, unsigned device, unsigned index, unsigned id)
{
device &= RETRO_DEVICE_MASK;
@ -504,6 +520,10 @@ static int16_t input_state(unsigned port, unsigned device, unsigned index, unsig
if (id < RARCH_FIRST_META_KEY || device == RETRO_DEVICE_KEYBOARD)
res = input_input_state_func(binds, port, device, index, id);
// Don't allow turbo for D-pad.
if (device == RETRO_DEVICE_JOYPAD && (id < RETRO_DEVICE_ID_JOYPAD_UP || id > RETRO_DEVICE_ID_JOYPAD_RIGHT))
res = input_apply_turbo(port, id, res);
#ifdef HAVE_BSV_MOVIE
if (g_extern.bsv.movie && !g_extern.bsv.movie_playback)
bsv_movie_set_input(g_extern.bsv.movie, res);
@ -2261,6 +2281,26 @@ static void check_reset(void)
old_state = new_state;
}
static void check_turbo(void)
{
g_extern.turbo_count++;
static const struct retro_keybind *binds[MAX_PLAYERS] = {
g_settings.input.binds[0],
g_settings.input.binds[1],
g_settings.input.binds[2],
g_settings.input.binds[3],
g_settings.input.binds[4],
g_settings.input.binds[5],
g_settings.input.binds[6],
g_settings.input.binds[7],
};
for (unsigned i = 0; i < MAX_PLAYERS; i++)
g_extern.turbo_frame_enable[i] =
input_input_state_func(binds, i, RETRO_DEVICE_JOYPAD, 0, RARCH_TURBO_ENABLE);
}
#ifdef HAVE_XML
static void check_shader_dir(void)
{
@ -2416,6 +2456,8 @@ static void do_state_checks(void)
check_mute();
#endif
check_turbo();
#ifdef HAVE_NETPLAY
if (!g_extern.netplay)
{

View File

@ -248,7 +248,7 @@
# input_player1_l3_btn =
# input_player1_r3_btn =
# Axis for SNES DPAD.
# Axis for RetroArch D-Pad.
# Needs to be either '+' or '-' in the first character signaling either positive or negative direction of the axis, then the axis number.
# Do note that every other input option has the corresponding _btn and _axis binds as well; they are omitted here for clarity.
# input_player1_left_axis =
@ -256,7 +256,18 @@
# input_player1_up_axis =
# input_player1_down_axis =
# Holding the turbo while pressing another button will let the button enter a turbo mode
# where the button state is modulated with a periodic signal.
# The modulation stops when the button itself (not turbo button) is released.
# input_player1_turbo =
# Describes the period and how long of that period a turbo-enabled button should behave.
# Numbers are described in frames.
# input_turbo_period = 6
# input_turbo_duty_cycle = 3
# This goes all the way to player 8 (*_player2_*, *_player3_*, etc), but omitted for clarity.
# All input binds have corresponding binds for keyboard (none), joykeys (_btn) and joyaxes (_axis) as well.
# Toggles fullscreen.
# input_toggle_fullscreen = f

View File

@ -221,6 +221,8 @@ void config_set_defaults(void)
g_settings.input.axis_threshold = axis_threshold;
g_settings.input.netplay_client_swap_input = netplay_client_swap_input;
g_settings.input.turbo_period = turbo_period;
g_settings.input.turbo_duty_cycle = turbo_duty_cycle;
for (int i = 0; i < MAX_PLAYERS; i++)
g_settings.input.joypad_map[i] = i;
@ -494,6 +496,9 @@ bool config_load_file(const char *path)
CONFIG_GET_INT(network_cmd_port, "network_cmd_port");
CONFIG_GET_BOOL(stdin_cmd_enable, "stdin_cmd_enable");
CONFIG_GET_INT(input.turbo_period, "input_turbo_period");
CONFIG_GET_INT(input.turbo_duty_cycle, "input_duty_cycle");
if (config_get_string(conf, "environment_variables",
&g_extern.system.environment))
{
@ -567,6 +572,7 @@ struct bind_map
DECLARE_BIND(player##P##_r2, RETRO_DEVICE_ID_JOYPAD_R2), \
DECLARE_BIND(player##P##_l3, RETRO_DEVICE_ID_JOYPAD_L3), \
DECLARE_BIND(player##P##_r3, RETRO_DEVICE_ID_JOYPAD_R3), \
DECLARE_BIND(player##P##_turbo, RARCH_TURBO_ENABLE), \
DECLARE_BIND(player##P##_l_x_plus, RARCH_ANALOG_LEFT_X_PLUS), \
DECLARE_BIND(player##P##_l_x_minus, RARCH_ANALOG_LEFT_X_MINUS), \
DECLARE_BIND(player##P##_l_y_plus, RARCH_ANALOG_LEFT_Y_PLUS), \