(XMB/GLUI) Limit tab switch rate when input repeat is active

This commit is contained in:
jdgleaver 2020-05-14 11:23:41 +01:00
parent 89c7d1a835
commit eff8c31ffd
8 changed files with 138 additions and 51 deletions

View File

@ -220,12 +220,32 @@ static int action_left_scroll(unsigned type, const char *label,
return 0;
}
static int action_left_goto_tab(void)
{
menu_ctx_list_t list_info;
file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0);
file_list_t *menu_stack = menu_entries_get_menu_stack_ptr(0);
size_t selection = menu_navigation_get_selection();
menu_file_list_cbs_t *cbs = selection_buf ? (menu_file_list_cbs_t*)
selection_buf->list[selection].actiondata : NULL;
list_info.type = MENU_LIST_HORIZONTAL;
list_info.action = MENU_ACTION_LEFT;
menu_driver_list_cache(&list_info);
if (cbs && cbs->action_content_list_switch)
return cbs->action_content_list_switch(selection_buf, menu_stack,
"", "", 0);
return 0;
}
static int action_left_mainmenu(unsigned type, const char *label,
bool wraparound)
{
menu_ctx_list_t list_info;
unsigned push_list = 0;
settings_t *settings = config_get_ptr();
settings_t *settings = config_get_ptr();
bool menu_nav_wraparound_enable = settings->bools.menu_navigation_wraparound_enable;
const char *menu_ident = menu_driver_ident();
@ -235,48 +255,16 @@ static int action_left_mainmenu(unsigned type, const char *label,
menu_driver_list_get_size(&list_info);
/* List switching functionality does not
* apply to RGUI or MaterialUI */
/* Tab switching functionality only applies
* to XMB */
if ((list_info.size == 1) &&
!string_is_equal(menu_ident, "rgui") &&
!string_is_equal(menu_ident, "glui"))
string_is_equal(menu_ident, "xmb"))
{
if ((list_info.selection != 0)
|| menu_nav_wraparound_enable)
push_list = 1;
if ((list_info.selection != 0) || menu_nav_wraparound_enable)
return action_left_goto_tab();
}
else
push_list = 2;
switch (push_list)
{
case 1:
{
menu_ctx_list_t list_info;
file_list_t *menu_stack = menu_entries_get_menu_stack_ptr(0);
file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0);
size_t selection = menu_navigation_get_selection();
menu_file_list_cbs_t *cbs = selection_buf ?
(menu_file_list_cbs_t*)
selection_buf->list[selection].actiondata : NULL;
list_info.type = MENU_LIST_HORIZONTAL;
list_info.action = MENU_ACTION_LEFT;
menu_driver_list_cache(&list_info);
if (cbs && cbs->action_content_list_switch)
return cbs->action_content_list_switch(
selection_buf, menu_stack, "", "", 0);
}
break;
case 2:
action_left_scroll(0, "", false);
break;
case 0:
default:
break;
}
action_left_scroll(0, "", false);
return 0;
}

View File

@ -265,11 +265,10 @@ static int action_right_mainmenu(unsigned type, const char *label,
menu_driver_list_get_size(&list_info);
/* Tab switching functionality does not
* apply to RGUI or MaterialUI */
/* Tab switching functionality only applies
* to XMB */
if ((list_info.size == 1) &&
!string_is_equal(menu_ident, "rgui") &&
!string_is_equal(menu_ident, "glui"))
string_is_equal(menu_ident, "xmb"))
{
menu_ctx_list_t list_horiz_info;
menu_ctx_list_t list_tabs_info;

View File

@ -1073,6 +1073,23 @@ typedef struct
* Colour Themes END
* ============================== */
/* Specifies minimum period (in usec) between
* tab switch events when input repeat is
* active (i.e. when navigating between top level
* menu categories by *holding* left/right on
* RetroPad or keyboard)
* > Note: We want to set a value of 300 ms
* here, but doing so leads to bad pacing when
* running at 60 Hz (due to random frame time
* deviations - input repeat cycles always take
* slightly more or less than 300 ms, so tab
* switches occur every n or (n + 1) frames,
* which gives the appearance of stuttering).
* Reducing the delay by 1 ms accommodates
* any timing fluctuations, resulting in
* smooth motion */
#define MUI_TAB_SWITCH_REPEAT_DELAY 299000
/* Animation defines */
#define MUI_ANIM_DURATION_SCROLL 166.66667f
#define MUI_ANIM_DURATION_SCROLL_RESET 83.333333f
@ -1412,6 +1429,10 @@ typedef struct materialui_handle
bool last_auto_rotate_nav_bar;
bool menu_stack_flushed;
/* Keeps track of the last time tabs were switched
* via a MENU_ACTION_LEFT/MENU_ACTION_RIGHT event */
retro_time_t last_tab_switch_time;
enum materialui_landscape_layout_optimization_type
last_landscape_layout_optimization;
materialui_landscape_optimization_t
@ -7949,6 +7970,30 @@ static enum menu_action materialui_parse_menu_entry_action(
if ((mui->nav_bar.location != MUI_NAV_BAR_LOCATION_HIDDEN) &&
(materialui_list_get_size(mui, MENU_LIST_PLAIN) == 1))
{
retro_time_t current_time = menu_driver_get_current_time();
size_t scroll_accel = 0;
/* Determine whether input repeat is
* currently active
* > This is always true when scroll
* acceleration is greater than zero */
menu_driver_ctl(MENU_NAVIGATION_CTL_GET_SCROLL_ACCEL,
&scroll_accel);
if (scroll_accel > 0)
{
/* Ignore input action if tab switch period
* is less than defined limit */
if ((current_time - mui->last_tab_switch_time) <
MUI_TAB_SWITCH_REPEAT_DELAY)
{
new_action = MENU_ACTION_NOOP;
break;
}
}
mui->last_tab_switch_time = current_time;
/* Perform tab switch */
materialui_switch_tabs(mui, NULL, action);
new_action = MENU_ACTION_ACCESSIBILITY_SPEAK_TITLE_LABEL;
}

View File

@ -25,7 +25,6 @@
#include <file/file_path.h>
#include <encodings/utf.h>
#include <lists/string_list.h>
#include <features/features_cpu.h>
#include "../../../gfx/gfx_animation.h"
@ -355,7 +354,7 @@ void ozone_draw_osk(ozone_handle_t *ozone,
unsigned y_offset = 0;
bool draw_placeholder = string_is_empty(str);
retro_time_t current_time = cpu_features_get_time_usec();
retro_time_t current_time = menu_driver_get_current_time();
static retro_time_t last_time = 0;
if (current_time - last_time >= INTERVAL_OSK_CURSOR)
@ -467,9 +466,9 @@ void ozone_draw_osk(ozone_handle_t *ozone,
video_width,
video_height,
margin + padding*2 + cursor_x,
margin + padding + y_offset + ozone->dimensions.spacer_3px,
margin + padding + y_offset + ozone->fonts.entries_label.line_height - ozone->fonts.entries_label.line_ascender + ozone->dimensions.spacer_3px,
ozone->dimensions.spacer_1px,
25 * scale_factor,
ozone->fonts.entries_label.line_ascender,
video_width,
video_height,
ozone_pure_white);

View File

@ -34,7 +34,6 @@
#include <retro_inline.h>
#include <gfx/scaler/scaler.h>
#include <features/features_cpu.h>
#ifdef HAVE_CONFIG_H
#include "../../config.h"
@ -4768,7 +4767,7 @@ static void rgui_scan_selected_entry_thumbnail(rgui_t *rgui, bool force_load)
{
/* Schedule a delayed load */
rgui->thumbnail_load_pending = true;
rgui->thumbnail_load_trigger_time = cpu_features_get_time_usec();
rgui->thumbnail_load_trigger_time = menu_driver_get_current_time();
}
}
}
@ -5291,7 +5290,7 @@ static void rgui_frame(void *data, video_frame_info_t *video_info)
* Note: Delay is increased when viewing fullscreen thumbnails,
* since the flicker when switching between playlist view and
* fullscreen thumbnail view is incredibly jarring...) */
if ((cpu_features_get_time_usec() - rgui->thumbnail_load_trigger_time) >=
if ((menu_driver_get_current_time() - rgui->thumbnail_load_trigger_time) >=
(settings->uints.menu_rgui_thumbnail_delay * 1000 * (rgui->show_fs_thumbnail ? 1.5f : 1.0f)))
rgui_load_current_thumbnails(rgui,
settings->bools.network_on_demand_thumbnails);

View File

@ -67,6 +67,23 @@
#define XMB_DELAY 166.66667f
#endif
/* Specifies minimum period (in usec) between
* tab switch events when input repeat is
* active (i.e. when navigating between top level
* menu categories by *holding* left/right on
* RetroPad or keyboard)
* > Note: We want to set a value of 100 ms
* here, but doing so leads to bad pacing when
* running at 60 Hz (due to random frame time
* deviations - input repeat cycles always take
* slightly more or less than 100 ms, so tab
* switches occur every n or (n + 1) frames,
* which gives the appearance of stuttering).
* Reducing the delay by 1 ms accommodates
* any timing fluctuations, resulting in
* smooth motion */
#define XMB_TAB_SWITCH_REPEAT_DELAY 99000
#if 0
#define XMB_DEBUG
#endif
@ -346,6 +363,10 @@ typedef struct xmb_handle
size_t fullscreen_thumbnail_selection;
char fullscreen_thumbnail_label[255];
/* Keeps track of the last time tabs were switched
* via a MENU_ACTION_LEFT/MENU_ACTION_RIGHT event */
retro_time_t last_tab_switch_time;
} xmb_handle_t;
float scale_mod[8] = {
@ -6832,6 +6853,36 @@ static enum menu_action xmb_parse_menu_entry_action(
/* Scan user inputs */
switch (action)
{
case MENU_ACTION_LEFT:
case MENU_ACTION_RIGHT:
/* Check whether left/right action will
* trigger a tab switch event */
if (xmb->depth == 1)
{
retro_time_t current_time = menu_driver_get_current_time();
size_t scroll_accel = 0;
/* Determine whether input repeat is
* currently active
* > This is always true when scroll
* acceleration is greater than zero */
menu_driver_ctl(MENU_NAVIGATION_CTL_GET_SCROLL_ACCEL,
&scroll_accel);
if (scroll_accel > 0)
{
/* Ignore input action if tab switch period
* is less than defined limit */
if ((current_time - xmb->last_tab_switch_time) <
XMB_TAB_SWITCH_REPEAT_DELAY)
{
new_action = MENU_ACTION_NOOP;
break;
}
}
xmb->last_tab_switch_time = current_time;
}
break;
case MENU_ACTION_START:
/* If this is a menu with thumbnails, attempt
* to show fullscreen thumbnail view */

View File

@ -2662,6 +2662,10 @@ bool menu_driver_list_get_size(menu_ctx_list_t *list)
return true;
}
retro_time_t menu_driver_get_current_time(void)
{
return menu_driver_current_time_us;
}
bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data)
{

View File

@ -463,6 +463,8 @@ bool menu_driver_list_get_entry(menu_ctx_list_t *list);
bool menu_driver_list_get_size(menu_ctx_list_t *list);
retro_time_t menu_driver_get_current_time(void);
size_t menu_navigation_get_selection(void);
void menu_navigation_set_selection(size_t val);