Merge pull request #183 from jdgleaver/turbo-buttons

Add turbo A/B buttons
This commit is contained in:
Autechre 2021-05-17 13:22:39 +02:00 committed by GitHub
commit ca8f8e7e30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 274 additions and 58 deletions

View File

@ -48,7 +48,20 @@ static bool libretro_ff_enabled_prev = false;
static bool show_gb_link_settings = true; static bool show_gb_link_settings = true;
/* Minimum (and default) turbo pulse train
* is 2 frames ON, 2 frames OFF */
#define TURBO_PERIOD_MIN 4
#define TURBO_PERIOD_MAX 120
#define TURBO_PULSE_WIDTH_MIN 2
#define TURBO_PULSE_WIDTH_MAX 15
static unsigned libretro_input_state = 0;
static bool up_down_allowed = false; static bool up_down_allowed = false;
static unsigned turbo_period = TURBO_PERIOD_MIN;
static unsigned turbo_pulse_width = TURBO_PULSE_WIDTH_MIN;
static unsigned turbo_a_counter = 0;
static unsigned turbo_b_counter = 0;
static bool rom_loaded = false; static bool rom_loaded = false;
//Dual mode runs two GBCs side by side. //Dual mode runs two GBCs side by side.
@ -732,13 +745,13 @@ namespace input
}; };
} }
class SNESInput : public gambatte::InputGetter static void update_input_state(void)
{
public:
unsigned operator()()
{ {
unsigned i; unsigned i;
unsigned res = 0; unsigned res = 0;
bool turbo_a = false;
bool turbo_b = false;
if (libretro_supports_bitmasks) if (libretro_supports_bitmasks)
{ {
int16_t ret = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_MASK); int16_t ret = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_MASK);
@ -747,6 +760,9 @@ class SNESInput : public gambatte::InputGetter
libretro_ff_enabled = libretro_supports_ff_override && libretro_ff_enabled = libretro_supports_ff_override &&
(ret & (1 << RETRO_DEVICE_ID_JOYPAD_R2)); (ret & (1 << RETRO_DEVICE_ID_JOYPAD_R2));
turbo_a = (ret & (1 << RETRO_DEVICE_ID_JOYPAD_X));
turbo_b = (ret & (1 << RETRO_DEVICE_ID_JOYPAD_Y));
} }
else else
{ {
@ -755,6 +771,9 @@ class SNESInput : public gambatte::InputGetter
libretro_ff_enabled = libretro_supports_ff_override && libretro_ff_enabled = libretro_supports_ff_override &&
input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2); input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2);
turbo_a = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X);
turbo_b = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y);
} }
if (!up_down_allowed) if (!up_down_allowed)
@ -775,7 +794,44 @@ class SNESInput : public gambatte::InputGetter
libretro_ff_enabled_prev = libretro_ff_enabled; libretro_ff_enabled_prev = libretro_ff_enabled;
} }
return res; /* Handle turbo buttons */
if (turbo_a)
{
res |= (turbo_a_counter < turbo_pulse_width) ?
gambatte::InputGetter::A : 0;
turbo_a_counter++;
if (turbo_a_counter >= turbo_period)
turbo_a_counter = 0;
}
else
turbo_a_counter = 0;
if (turbo_b)
{
res |= (turbo_b_counter < turbo_pulse_width) ?
gambatte::InputGetter::B : 0;
turbo_b_counter++;
if (turbo_b_counter >= turbo_period)
turbo_b_counter = 0;
}
else
turbo_b_counter = 0;
libretro_input_state = res;
}
/* gb_input is called multiple times per frame.
* Determine input state once per frame using
* update_input_state(), and simply return
* cached value here */
class SNESInput : public gambatte::InputGetter
{
public:
unsigned operator()()
{
return libretro_input_state;
} }
} static gb_input; } static gb_input;
@ -926,6 +982,13 @@ void retro_deinit(void)
libretro_ff_enabled = false; libretro_ff_enabled = false;
libretro_ff_enabled_prev = false; libretro_ff_enabled_prev = false;
libretro_input_state = 0;
up_down_allowed = false;
turbo_period = TURBO_PERIOD_MIN;
turbo_pulse_width = TURBO_PULSE_WIDTH_MIN;
turbo_a_counter = 0;
turbo_b_counter = 0;
deactivate_rumble(); deactivate_rumble();
memset(&rumble, 0, sizeof(struct retro_rumble_interface)); memset(&rumble, 0, sizeof(struct retro_rumble_interface));
rumble_level = 0; rumble_level = 0;
@ -1221,6 +1284,28 @@ static void check_variables(void)
up_down_allowed = false; up_down_allowed = false;
} }
turbo_period = TURBO_PERIOD_MIN;
turbo_pulse_width = TURBO_PULSE_WIDTH_MIN;
var.key = "gambatte_turbo_period";
var.value = NULL;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{
turbo_period = atoi(var.value);
turbo_period = (turbo_period < TURBO_PERIOD_MIN) ?
TURBO_PERIOD_MIN : turbo_period;
turbo_period = (turbo_period > TURBO_PERIOD_MAX) ?
TURBO_PERIOD_MAX : turbo_period;
turbo_pulse_width = turbo_period >> 1;
turbo_pulse_width = (turbo_pulse_width < TURBO_PULSE_WIDTH_MIN) ?
TURBO_PULSE_WIDTH_MIN : turbo_pulse_width;
turbo_pulse_width = (turbo_pulse_width > TURBO_PULSE_WIDTH_MAX) ?
TURBO_PULSE_WIDTH_MAX : turbo_pulse_width;
turbo_a_counter = 0;
turbo_b_counter = 0;
}
rumble_level = 0; rumble_level = 0;
var.key = "gambatte_rumble_level"; var.key = "gambatte_rumble_level";
var.value = NULL; var.value = NULL;
@ -1538,6 +1623,8 @@ bool retro_load_game(const struct retro_game_info *info)
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Turbo B" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Turbo A" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
{ 0 }, { 0 },
@ -1550,6 +1637,8 @@ bool retro_load_game(const struct retro_game_info *info)
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Turbo B" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Turbo A" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "Fast Forward" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "Fast Forward" },
@ -1734,6 +1823,7 @@ void retro_run()
static uint64_t frames_count = 0; static uint64_t frames_count = 0;
input_poll_cb(); input_poll_cb();
update_input_state();
uint64_t expected_frames = samples_count / 35112; uint64_t expected_frames = samples_count / 35112;
if (frames_count < expected_frames) // Detect frame dupes. if (frames_count < expected_frames) // Detect frame dupes.

View File

@ -49,17 +49,6 @@ extern "C" {
* frontend language definition */ * frontend language definition */
struct retro_core_option_definition option_defs_us[] = { struct retro_core_option_definition option_defs_us[] = {
{
"gambatte_up_down_allowed",
"Allow Opposing Directions",
"Enabling this will allow pressing / quickly alternating / holding both left and right (or up and down) directions at the same time. This may cause movement-based glitches.",
{
{ "disabled", NULL },
{ "enabled", NULL },
{ NULL, NULL },
},
"disabled"
},
{ {
"gambatte_gb_colorization", "gambatte_gb_colorization",
"GB Colorization", "GB Colorization",
@ -302,6 +291,143 @@ struct retro_core_option_definition option_defs_us[] = {
}, },
"disabled" "disabled"
}, },
{
"gambatte_up_down_allowed",
"Allow Opposing Directions",
"Enabling this will allow pressing / quickly alternating / holding both left and right (or up and down) directions at the same time. This may cause movement-based glitches.",
{
{ "disabled", NULL },
{ "enabled", NULL },
{ NULL, NULL },
},
"disabled"
},
{
"gambatte_turbo_period",
"Turbo Button Period",
"Specify the repeat interval (in frames) when holding down the Turbo A/B buttons.",
{
{ "4", NULL },
{ "5", NULL },
{ "6", NULL },
{ "7", NULL },
{ "8", NULL },
{ "9", NULL },
{ "10", NULL },
{ "11", NULL },
{ "12", NULL },
{ "13", NULL },
{ "14", NULL },
{ "15", NULL },
{ "16", NULL },
{ "17", NULL },
{ "18", NULL },
{ "19", NULL },
{ "20", NULL },
{ "21", NULL },
{ "22", NULL },
{ "23", NULL },
{ "24", NULL },
{ "25", NULL },
{ "26", NULL },
{ "27", NULL },
{ "28", NULL },
{ "29", NULL },
{ "30", NULL },
{ "31", NULL },
{ "32", NULL },
{ "33", NULL },
{ "34", NULL },
{ "35", NULL },
{ "36", NULL },
{ "37", NULL },
{ "38", NULL },
{ "39", NULL },
{ "40", NULL },
{ "41", NULL },
{ "42", NULL },
{ "43", NULL },
{ "44", NULL },
{ "45", NULL },
{ "46", NULL },
{ "47", NULL },
{ "48", NULL },
{ "49", NULL },
{ "50", NULL },
{ "51", NULL },
{ "52", NULL },
{ "53", NULL },
{ "54", NULL },
{ "55", NULL },
{ "56", NULL },
{ "57", NULL },
{ "58", NULL },
{ "59", NULL },
{ "60", NULL },
{ "61", NULL },
{ "62", NULL },
{ "63", NULL },
{ "64", NULL },
{ "65", NULL },
{ "66", NULL },
{ "67", NULL },
{ "68", NULL },
{ "69", NULL },
{ "70", NULL },
{ "71", NULL },
{ "72", NULL },
{ "73", NULL },
{ "74", NULL },
{ "75", NULL },
{ "76", NULL },
{ "77", NULL },
{ "78", NULL },
{ "79", NULL },
{ "80", NULL },
{ "81", NULL },
{ "82", NULL },
{ "83", NULL },
{ "84", NULL },
{ "85", NULL },
{ "86", NULL },
{ "87", NULL },
{ "88", NULL },
{ "89", NULL },
{ "90", NULL },
{ "91", NULL },
{ "92", NULL },
{ "93", NULL },
{ "94", NULL },
{ "95", NULL },
{ "96", NULL },
{ "97", NULL },
{ "98", NULL },
{ "99", NULL },
{ "100", NULL },
{ "101", NULL },
{ "102", NULL },
{ "103", NULL },
{ "104", NULL },
{ "105", NULL },
{ "106", NULL },
{ "107", NULL },
{ "108", NULL },
{ "109", NULL },
{ "110", NULL },
{ "111", NULL },
{ "112", NULL },
{ "113", NULL },
{ "114", NULL },
{ "115", NULL },
{ "116", NULL },
{ "117", NULL },
{ "118", NULL },
{ "119", NULL },
{ "120", NULL },
{ NULL, NULL },
},
"4"
},
{ {
"gambatte_rumble_level", "gambatte_rumble_level",
"Gamepad Rumble Strength", "Gamepad Rumble Strength",