diff --git a/menu/cbs/menu_cbs_left.c b/menu/cbs/menu_cbs_left.c index db20c52547..812490bd8e 100644 --- a/menu/cbs/menu_cbs_left.c +++ b/menu/cbs/menu_cbs_left.c @@ -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; } diff --git a/menu/cbs/menu_cbs_right.c b/menu/cbs/menu_cbs_right.c index b8b3cf3561..cd0b77585a 100644 --- a/menu/cbs/menu_cbs_right.c +++ b/menu/cbs/menu_cbs_right.c @@ -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; diff --git a/menu/drivers/materialui.c b/menu/drivers/materialui.c index 7ba0c9a2a8..06d80434f2 100644 --- a/menu/drivers/materialui.c +++ b/menu/drivers/materialui.c @@ -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; } diff --git a/menu/drivers/ozone/ozone_display.c b/menu/drivers/ozone/ozone_display.c index 14c77487f9..2ce3263d30 100644 --- a/menu/drivers/ozone/ozone_display.c +++ b/menu/drivers/ozone/ozone_display.c @@ -25,7 +25,6 @@ #include #include #include -#include #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); diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index 43f6134000..391685113d 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -34,7 +34,6 @@ #include #include -#include #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); diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 38f198701c..c2979b1e2a 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -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 */ diff --git a/menu/menu_driver.c b/menu/menu_driver.c index 4240436654..f342977146 100644 --- a/menu/menu_driver.c +++ b/menu/menu_driver.c @@ -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) { diff --git a/menu/menu_driver.h b/menu/menu_driver.h index da4debff16..da972289de 100644 --- a/menu/menu_driver.h +++ b/menu/menu_driver.h @@ -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);