diff --git a/input.c b/input.c index 44455d2..9aef248 100644 --- a/input.c +++ b/input.c @@ -24,6 +24,11 @@ bool libretro_supports_ff_override = false; bool libretro_ff_enabled = false; bool libretro_ff_enabled_prev = false; +unsigned turbo_period = TURBO_PERIOD_MIN; +unsigned turbo_pulse_width = TURBO_PULSE_WIDTH_MIN; +unsigned turbo_a_counter = 0; +unsigned turbo_b_counter = 0; + static u32 old_key = 0; static retro_input_state_t input_state_cb; @@ -56,6 +61,8 @@ u32 update_input(void) { unsigned i; uint32_t new_key = 0; + bool turbo_a = false; + bool turbo_b = false; if (!input_state_cb) return 0; @@ -69,6 +76,9 @@ u32 update_input(void) libretro_ff_enabled = libretro_supports_ff_override && (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 { @@ -77,8 +87,36 @@ u32 update_input(void) libretro_ff_enabled = libretro_supports_ff_override && 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); } + /* Handle turbo buttons */ + if (turbo_a) + { + new_key |= (turbo_a_counter < turbo_pulse_width) ? + BUTTON_A : 0; + + turbo_a_counter++; + if (turbo_a_counter >= turbo_period) + turbo_a_counter = 0; + } + else + turbo_a_counter = 0; + + if (turbo_b) + { + new_key |= (turbo_b_counter < turbo_pulse_width) ? + BUTTON_B : 0; + + turbo_b_counter++; + if (turbo_b_counter >= turbo_period) + turbo_b_counter = 0; + } + else + turbo_b_counter = 0; + if ((new_key | old_key) != old_key) trigger_key(new_key); diff --git a/input.h b/input.h index 90fc930..72c7e1e 100644 --- a/input.h +++ b/input.h @@ -61,6 +61,18 @@ extern bool libretro_supports_ff_override; extern bool libretro_ff_enabled; extern bool libretro_ff_enabled_prev; +/* 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 + +extern unsigned turbo_period; +extern unsigned turbo_pulse_width; +extern unsigned turbo_a_counter; +extern unsigned turbo_b_counter; + void init_input(void); u32 update_input(void); void input_write_savestate(void); diff --git a/libretro.c b/libretro.c index 28db9dd..5dfe0df 100644 --- a/libretro.c +++ b/libretro.c @@ -841,6 +841,28 @@ static void check_variables(int started_from_load) use_libretro_save_method = 0; } } + + var.key = "gpsp_turbo_period"; + var.value = NULL; + turbo_period = TURBO_PERIOD_MIN; + turbo_pulse_width = TURBO_PULSE_WIDTH_MIN; + 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; + } } static void set_input_descriptors() @@ -852,6 +874,8 @@ static void set_input_descriptors() { 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_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_START, "Start" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" }, @@ -866,6 +890,8 @@ static void set_input_descriptors() { 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_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_START, "Start" }, { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" }, @@ -980,6 +1006,11 @@ void retro_unload_game(void) libretro_supports_ff_override = false; libretro_ff_enabled = false; libretro_ff_enabled_prev = false; + + turbo_period = TURBO_PERIOD_MIN; + turbo_pulse_width = TURBO_PULSE_WIDTH_MIN; + turbo_a_counter = 0; + turbo_b_counter = 0; } unsigned retro_get_region(void) @@ -1052,9 +1083,8 @@ void retro_run(void) { bool updated = false; - update_input(); - input_poll_cb(); + update_input(); /* Check whether current frame should * be skipped */ diff --git a/libretro_core_options.h b/libretro_core_options.h index d2b95fa..c23a2c3 100644 --- a/libretro_core_options.h +++ b/libretro_core_options.h @@ -180,6 +180,132 @@ struct retro_core_option_definition option_defs_us[] = { "enabled" }, #endif + { + "gpsp_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" + }, { NULL, NULL, NULL, {{0}}, NULL }, };