mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-08 17:28:49 -10:00
(menu_event) Fix D-pad repeat firing early after blocked input
Sixth instance of the class fixed byc09a057,8ab71e9,46288b2and9240338, but affecting a time delta rather than a button edge. 'last_time_us' drives the navigation auto-repeat clock: float delta_time = (float)(menu_st->current_time_us - last_time_us) / 1000; last_time_us = menu_st->current_time_us; ... delay_count += delta_time; if (delay_count >= delay_timer) /* fire repeat */ It is written at exactly one place, inside 'if (navigation_current)', which sits after both the MENU_ST_FLAG_BLOCK_ALL_INPUT and screensaver early returns. Taking either return leaves the clock frozen while current_time_us keeps advancing on wall-clock. 'hold_reset' normally protects against an oversized delta: on the first frame of a press it zeroes 'delay_count' and skips the accumulate, so an idle menu followed by a press is harmless. The early returns bypass that protection, because they leave 'hold_reset' and 'delay_count' holding their mid-hold values. When input is unblocked, the next 'delta_time' spans the entire blocked interval and is added to a 'delay_count' that is already partway to 'delay_timer', overshooting it in a single step. The result is a repeat firing on the frame after the press rather than after menu_scroll_delay, so one D-pad press moves the selection two or more entries. The screensaver path is the easier of the two to hit, since dismissing the screensaver with a direction press takes it. Advance 'last_time_us' on both early returns, alongside the 'ok_old' and 'switch_old' updates already there.
This commit is contained in:
1 parent
fc27e433a3
commit
656acd3a70
1 file changed
+8
@@ -5230,6 +5230,11 @@ unsigned menu_event(
|
||||
ok_old = ok_current;
|
||||
switch_old = BIT256_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_LEFT)
|
||||
| BIT256_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_RIGHT);
|
||||
/* The navigation auto-repeat clock must keep advancing too,
|
||||
* otherwise the next 'delta_time' spans the whole blocked
|
||||
* interval and overshoots 'delay_timer' in a single step,
|
||||
* firing a repeat immediately after the next press */
|
||||
last_time_us = menu_st->current_time_us;
|
||||
return MENU_ACTION_NOOP;
|
||||
}
|
||||
|
||||
@@ -5368,6 +5373,9 @@ unsigned menu_event(
|
||||
menu_input->cancel_inhibit = true;
|
||||
switch_old = BIT256_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_LEFT)
|
||||
| BIT256_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_RIGHT);
|
||||
/* Keep the navigation auto-repeat clock advancing, for the
|
||||
* same reason as the BLOCK_ALL_INPUT path above */
|
||||
last_time_us = menu_st->current_time_us;
|
||||
return MENU_ACTION_NOOP;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user