Skip to content

Commit 1ad5896

Browse files
authored
add "hold" button handling to overlays (#18526)
1 parent 81f05fb commit 1ad5896

9 files changed

Lines changed: 111 additions & 1 deletion

File tree

config.def.keybinds.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,13 @@ static const struct retro_keybind retro_keybinds_1[] = {
275275
RARCH_TURBO_ENABLE, NO_BTN, NO_BTN, 0,
276276
true
277277
},
278+
{
279+
NULL, NULL,
280+
AXIS_NONE, AXIS_NONE,
281+
MENU_ENUM_LABEL_VALUE_INPUT_HOLD, RETROK_UNKNOWN,
282+
RARCH_HOLD_ENABLE, NO_BTN, NO_BTN, 0,
283+
true
284+
},
278285
/* Hotkeys */
279286
{
280287
NULL, NULL,
@@ -935,6 +942,13 @@ static const struct retro_keybind retro_keybinds_1[] = {
935942
RARCH_TURBO_ENABLE, NO_BTN, NO_BTN, 0,
936943
true
937944
},
945+
{
946+
NULL, NULL,
947+
AXIS_NONE, AXIS_NONE,
948+
MENU_ENUM_LABEL_VALUE_INPUT_HOLD, RETROK_UNKNOWN,
949+
RARCH_HOLD_ENABLE, NO_BTN, NO_BTN, 0,
950+
true
951+
},
938952
/* Hotkeys */
939953
{
940954
NULL, NULL,
@@ -1595,6 +1609,13 @@ static const struct retro_keybind retro_keybinds_1[] = {
15951609
RARCH_TURBO_ENABLE, NO_BTN, NO_BTN, 0,
15961610
true
15971611
},
1612+
{
1613+
NULL, NULL,
1614+
AXIS_NONE, AXIS_NONE,
1615+
MENU_ENUM_LABEL_VALUE_INPUT_HOLD, RETROK_UNKNOWN,
1616+
RARCH_HOLD_ENABLE, NO_BTN, NO_BTN, 0,
1617+
true
1618+
},
15981619
/* Hotkeys */
15991620
{
16001621
NULL, NULL,
@@ -2269,6 +2290,13 @@ static const struct retro_keybind retro_keybinds_rest[] = {
22692290
RARCH_TURBO_ENABLE, NO_BTN, NO_BTN, 0,
22702291
true
22712292
},
2293+
{
2294+
NULL, NULL,
2295+
AXIS_NONE, AXIS_NONE,
2296+
MENU_ENUM_LABEL_VALUE_INPUT_HOLD, RETROK_UNKNOWN,
2297+
RARCH_HOLD_ENABLE, NO_BTN, NO_BTN, 0,
2298+
true
2299+
},
22722300
/* Hotkeys */
22732301
{
22742302
NULL, NULL,

configuration.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ const struct input_bind_map input_config_bind_map[RARCH_BIND_LIST_END_NULL] = {
334334
DECLARE_BIND(gun_dpad_right, RARCH_LIGHTGUN_DPAD_RIGHT, MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT),
335335

336336
DECLARE_BIND(turbo, RARCH_TURBO_ENABLE, MENU_ENUM_LABEL_VALUE_INPUT_TURBO),
337+
DECLARE_BIND(hold, RARCH_HOLD_ENABLE, MENU_ENUM_LABEL_VALUE_INPUT_HOLD),
337338

338339
DECLARE_META_BIND(2, enable_hotkey, RARCH_ENABLE_HOTKEY, MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY),
339340
#ifdef HAVE_MENU

input/input_defines.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ enum
118118

119119
/* Turbo */
120120
RARCH_TURBO_ENABLE = RARCH_FIRST_MISC_CUSTOM_BIND,
121+
/* Hold */
122+
RARCH_HOLD_ENABLE,
121123

122124
RARCH_CUSTOM_BIND_LIST_END,
123125

input/input_driver.c

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1515,11 +1515,40 @@ static int16_t input_state_device(
15151515

15161516
if (id <= RETRO_DEVICE_ID_JOYPAD_R3)
15171517
{
1518-
/* Apply turbo button if activated. */
15191518
uint8_t turbo_period = settings->uints.input_turbo_period;
15201519
uint8_t turbo_duty_cycle = settings->uints.input_turbo_duty_cycle;
15211520
uint8_t turbo_mode = settings->uints.input_turbo_mode;
15221521

1522+
/* Apply hold button logic.
1523+
* When hold modifier is pressed, tapping buttons toggles their held state.
1524+
* Held buttons report as pressed even when not physically touched.
1525+
* Physical presses pass through normally (no modification). */
1526+
1527+
/* Handle hold modifier state and toggle logic */
1528+
if (!input_st->hold_btns.frame_enable[port])
1529+
{
1530+
/* Hold modifier not pressed - clear edge detection state */
1531+
input_st->hold_btns.hold_pressed[port] = 0;
1532+
}
1533+
else
1534+
{
1535+
/* Hold modifier is pressed - handle toggle on rising edge */
1536+
if (!res)
1537+
input_st->hold_btns.hold_pressed[port] &= ~(1 << id);
1538+
else if (!(input_st->hold_btns.hold_pressed[port] & (1 << id)))
1539+
{
1540+
/* Rising edge - toggle hold for this button */
1541+
input_st->hold_btns.hold_pressed[port] |= (1 << id);
1542+
input_st->hold_btns.enable[port] ^= (1 << id);
1543+
}
1544+
}
1545+
1546+
/* Apply hold effect: if button is held and not physically pressed */
1547+
if (!res && (input_st->hold_btns.enable[port] & (1 << id)))
1548+
res = 1;
1549+
1550+
/* Apply turbo button if activated. */
1551+
15231552
/* Don't allow classic mode turbo for D-pad unless explicitly allowed. */
15241553
if ( turbo_mode <= INPUT_TURBO_MODE_CLASSIC_TOGGLE
15251554
&& !settings->bools.input_turbo_allow_dpad
@@ -6091,7 +6120,10 @@ void input_driver_poll(void)
60916120
if (input_st->flags & INP_FLAG_BLOCK_LIBRETRO_INPUT)
60926121
{
60936122
for (i = 0; i < max_users; i++)
6123+
{
60946124
input_st->turbo_btns.frame_enable[i] = 0;
6125+
input_st->hold_btns.frame_enable[i] = 0;
6126+
}
60956127
return;
60966128
}
60976129

@@ -6130,6 +6162,27 @@ void input_driver_poll(void)
61306162
#endif
61316163
}
61326164

6165+
/* Poll hold button modifier state */
6166+
for (i = 0; i < max_users; i++)
6167+
{
6168+
input_st->hold_btns.frame_enable[i] =
6169+
(*input_st->libretro_input_binds[i])[RARCH_HOLD_ENABLE].valid ?
6170+
input_state_wrap(input_st->current_driver, input_st->current_data,
6171+
joypad, sec_joypad, &joypad_info[i],
6172+
(*input_st->libretro_input_binds),
6173+
(input_st->flags & INP_FLAG_KB_MAPPING_BLOCKED) ? true : false,
6174+
(unsigned)i,
6175+
RETRO_DEVICE_JOYPAD, 0, RARCH_HOLD_ENABLE) : 0;
6176+
6177+
#ifdef HAVE_OVERLAY
6178+
if ( (i == 0)
6179+
&& input_st->overlay_ptr
6180+
&& (input_st->overlay_ptr->flags & INPUT_OVERLAY_ALIVE)
6181+
&& BIT256_GET(input_st->overlay_ptr->overlay_state.buttons, RARCH_HOLD_ENABLE))
6182+
input_st->hold_btns.frame_enable[i] = true;
6183+
#endif
6184+
}
6185+
61336186
#ifdef HAVE_MENU
61346187
if (!(menu_state_get_ptr()->flags & MENU_ST_FLAG_ALIVE))
61356188
#endif

input/input_driver.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,7 @@ typedef struct
624624
#endif
625625
int osk_ptr;
626626
turbo_buttons_t turbo_btns; /* int32_t alignment */
627+
hold_buttons_t hold_btns; /* int32_t alignment */
627628

628629
input_mapper_t mapper; /* uint32_t alignment */
629630
input_remap_cache_t remapping_cache;

input/input_types.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ struct turbo_buttons
6262
bool mode1_enable[MAX_USERS];
6363
};
6464

65+
/* Hold button support. */
66+
struct hold_buttons
67+
{
68+
int32_t hold_pressed[MAX_USERS]; /* Edge detection for toggle */
69+
uint16_t enable[MAX_USERS]; /* Bitmask of held buttons */
70+
bool frame_enable[MAX_USERS]; /* Hold modifier pressed this frame */
71+
};
72+
6573
struct retro_keybind
6674
{
6775
/* Human-readable label for the control. */
@@ -139,6 +147,7 @@ typedef struct rarch_joypad_info rarch_joypad_info_t;
139147
typedef struct input_driver input_driver_t;
140148
typedef struct input_keyboard_ctx_wait input_keyboard_ctx_wait_t;
141149
typedef struct turbo_buttons turbo_buttons_t;
150+
typedef struct hold_buttons hold_buttons_t;
142151
typedef struct joypad_connection joypad_connection_t;
143152

144153
#endif /* __INPUT_TYPES__H */

intl/msg_hash_us.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4597,6 +4597,10 @@ MSG_HASH(
45974597
MENU_ENUM_LABEL_VALUE_INPUT_TURBO,
45984598
"Turbo Fire"
45994599
)
4600+
MSG_HASH(
4601+
MENU_ENUM_LABEL_VALUE_INPUT_HOLD,
4602+
"Hold"
4603+
)
46004604

46014605
/* Settings > Latency */
46024606

msg_hash.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,6 +1129,7 @@ enum msg_hash_enums
11291129
MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_LEFT,
11301130
MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT,
11311131
MENU_ENUM_LABEL_VALUE_INPUT_TURBO,
1132+
MENU_ENUM_LABEL_VALUE_INPUT_HOLD,
11321133

11331134
MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY,
11341135
MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE,

retroarch.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1930,6 +1930,7 @@ static void retroarch_deinit_drivers(struct retro_callbacks *cbs)
19301930
| INP_FLAG_NONBLOCKING);
19311931

19321932
memset(&input_st->turbo_btns, 0, sizeof(turbo_buttons_t));
1933+
memset(&input_st->hold_btns, 0, sizeof(hold_buttons_t));
19331934
memset(&input_st->analog_requested, 0,
19341935
sizeof(input_st->analog_requested));
19351936
input_st->current_driver = NULL;
@@ -4262,6 +4263,16 @@ bool command_event(enum event_command cmd, void *data)
42624263
#endif
42634264
runloop_event_deinit_core();
42644265

4266+
/* Clear turbo and hold button state on core unload */
4267+
{
4268+
input_driver_state_t *input_st = input_state_get_ptr();
4269+
if (input_st)
4270+
{
4271+
memset(&input_st->turbo_btns, 0, sizeof(turbo_buttons_t));
4272+
memset(&input_st->hold_btns, 0, sizeof(hold_buttons_t));
4273+
}
4274+
}
4275+
42654276
#ifdef HAVE_RUNAHEAD
42664277
/* If 'runahead_available' is false, then
42674278
* runahead is enabled by the user but an

0 commit comments

Comments
 (0)