diff --git a/libretro-common/include/string/stdstring.h b/libretro-common/include/string/stdstring.h index 0eb37c7d43..1e5e0a3bd3 100644 --- a/libretro-common/include/string/stdstring.h +++ b/libretro-common/include/string/stdstring.h @@ -135,7 +135,7 @@ void string_remove_all_chars(char *str, char c); /* Converts string to unsigned integer. * Returns 0 if string is invalid */ -unsigned string_to_unsigned(char *str); +unsigned string_to_unsigned(const char *str); RETRO_END_DECLS diff --git a/libretro-common/string/stdstring.c b/libretro-common/string/stdstring.c index 1e8c93452e..51258ea424 100644 --- a/libretro-common/string/stdstring.c +++ b/libretro-common/string/stdstring.c @@ -321,9 +321,9 @@ void string_remove_all_chars(char *str, char c) /* Converts string to unsigned integer. * Returns 0 if string is invalid */ -unsigned string_to_unsigned(char *str) +unsigned string_to_unsigned(const char *str) { - char *ptr = NULL; + const char *ptr = NULL; if (string_is_empty(str)) return 0; diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index ac9d5408f3..0aa0d22ef2 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -3223,7 +3223,7 @@ int action_ok_core_option_dropdown_list(const char *path, generic_action_ok_displaylist_push( core_option_lbl, NULL, - core_option_idx, 0, 0, 0, + core_option_idx, 0, idx, 0, ACTION_OK_DL_DROPDOWN_BOX_LIST); return 0; } @@ -4198,7 +4198,7 @@ static int action_ok_set_core_association(const char *path, return menu_cbs_exit(); return generic_action_ok_displaylist_push(path, NULL, - NULL, 0, menu->rpl_entry_selection_ptr, entry_idx, + NULL, 0, idx, entry_idx, ACTION_OK_DL_DEFERRED_CORE_LIST_SET); } @@ -5701,7 +5701,7 @@ static int action_ok_video_resolution(const char *path, #else generic_action_ok_displaylist_push( NULL, - NULL, NULL, 0, 0, 0, + NULL, NULL, 0, idx, 0, ACTION_OK_DL_DROPDOWN_BOX_LIST_RESOLUTION); #endif @@ -5713,7 +5713,7 @@ static int action_ok_playlist_default_core(const char *path, { generic_action_ok_displaylist_push( NULL, - NULL, NULL, 0, 0, 0, + NULL, NULL, 0, idx, 0, ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_DEFAULT_CORE); return 0; } @@ -5723,7 +5723,7 @@ static int action_ok_playlist_label_display_mode(const char *path, { generic_action_ok_displaylist_push( NULL, - NULL, NULL, 0, 0, 0, + NULL, NULL, 0, idx, 0, ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_LABEL_DISPLAY_MODE); return 0; } @@ -5733,7 +5733,7 @@ static int action_ok_playlist_right_thumbnail_mode(const char *path, { generic_action_ok_displaylist_push( NULL, - NULL, NULL, 0, 0, 0, + NULL, NULL, 0, idx, 0, ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE); return 0; } @@ -5743,7 +5743,7 @@ static int action_ok_playlist_left_thumbnail_mode(const char *path, { generic_action_ok_displaylist_push( NULL, - NULL, NULL, 0, 0, 0, + NULL, NULL, 0, idx, 0, ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE); return 0; } diff --git a/menu/cbs/menu_cbs_title.c b/menu/cbs/menu_cbs_title.c index e93b2193da..f17532d933 100644 --- a/menu/cbs/menu_cbs_title.c +++ b/menu/cbs/menu_cbs_title.c @@ -23,6 +23,8 @@ #include "../menu_cbs.h" #include "../../retroarch.h" +#include "../../configuration.h" +#include "../managers/core_option_manager.h" #ifndef BIND_ACTION_GET_TITLE #define BIND_ACTION_GET_TITLE(cbs, name) \ @@ -73,8 +75,165 @@ static int action_get_title_action_generic(const char *path, const char *label, return 1; \ } +static int action_get_title_thumbnails( + const char *path, const char *label, unsigned menu_type, char *s, size_t len) +{ + settings_t *settings = config_get_ptr(); + const char *title = NULL; + enum msg_hash_enums label_value; + + /* Get label value */ + if (string_is_equal(settings->arrays.menu_driver, "rgui")) + label_value = MENU_ENUM_LABEL_VALUE_THUMBNAILS_RGUI; + else + label_value = MENU_ENUM_LABEL_VALUE_THUMBNAILS; + + title = msg_hash_to_str(label_value); + + if (s && !string_is_empty(title)) + { + sanitize_to_string(s, title, len); + return 1; + } + + return 0; +} + +static int action_get_title_left_thumbnails( + const char *path, const char *label, unsigned menu_type, char *s, size_t len) +{ + settings_t *settings = config_get_ptr(); + const char *title = NULL; + enum msg_hash_enums label_value; + + /* Get label value */ + if (string_is_equal(settings->arrays.menu_driver, "rgui")) + label_value = MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS_RGUI; + else if (string_is_equal(settings->arrays.menu_driver, "ozone")) + label_value = MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS_OZONE; + else + label_value = MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS; + + title = msg_hash_to_str(label_value); + + if (s && !string_is_empty(title)) + { + sanitize_to_string(s, title, len); + return 1; + } + + return 0; +} + static int action_get_title_dropdown_item(const char *path, const char *label, unsigned menu_type, char *s, size_t len) { + /* Sanity check */ + if (string_is_empty(path)) + return 0; + + if (strstr(path, "core_option_")) + { + /* This is a core options item */ + struct string_list *tmp_str_list = string_split(path, "_"); + int ret = 0; + + if (tmp_str_list && tmp_str_list->size > 0) + { + core_option_manager_t *coreopts = NULL; + + rarch_ctl(RARCH_CTL_CORE_OPTIONS_LIST_GET, &coreopts); + + if (coreopts) + { + settings_t *settings = config_get_ptr(); + unsigned menu_index = string_to_unsigned(tmp_str_list->elems[(unsigned)tmp_str_list->size - 1].data); + unsigned visible_index = 0; + unsigned option_index = 0; + bool option_found = false; + struct core_option *option = NULL; + unsigned i; + + /* Convert menu index to option index */ + if (settings->bools.game_specific_options) + menu_index--; + + for (i = 0; i < coreopts->size; i++) + { + if (core_option_manager_get_visible(coreopts, i)) + { + if (visible_index == menu_index) + { + option_found = true; + option_index = i; + break; + } + visible_index++; + } + } + + /* If option was found, title == option description */ + if (option_found) + { + const char *title = core_option_manager_get_desc(coreopts, option_index); + + if (s && !string_is_empty(title)) + { + sanitize_to_string(s, title, len); + ret = 1; + } + } + } + } + + /* Clean up */ + if (tmp_str_list) + string_list_free(tmp_str_list); + + return ret; + } + else + { + /* This is a 'normal' drop down list */ + + /* In msg_hash.h, msg_hash_enums are generated via + * the following macro: + * #define MENU_LABEL(STR) \ + * MENU_ENUM_LABEL_##STR, \ + * MENU_ENUM_SUBLABEL_##STR, \ + * MENU_ENUM_LABEL_VALUE_##STR + * to get 'MENU_ENUM_LABEL_VALUE_' from a + * 'MENU_ENUM_LABEL_', we therefore add 2... */ + enum msg_hash_enums enum_idx = (enum msg_hash_enums)(string_to_unsigned(path) + 2); + + /* Check if enum index is valid + * Note: This is a very crude check, but better than nothing */ + if ((enum_idx > MSG_UNKNOWN) && (enum_idx < MSG_LAST)) + { + /* An annoyance: MENU_ENUM_LABEL_THUMBNAILS and + * MENU_ENUM_LABEL_LEFT_THUMBNAILS require special + * treatment, since their titles depend upon the + * current menu driver... */ + if (enum_idx == MENU_ENUM_LABEL_VALUE_THUMBNAILS) + { + return action_get_title_thumbnails(path, label, menu_type, s, len); + } + else if (enum_idx == MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS) + { + return action_get_title_left_thumbnails(path, label, menu_type, s, len); + } + else + { + const char *title = msg_hash_to_str(enum_idx); + + if (s && !string_is_empty(title)) + { + sanitize_to_string(s, title, len); + return 1; + } + } + } + } + return 0; } @@ -130,6 +289,18 @@ static int action_get_title_deferred_playlist_list(const char *path, const char return 0; } +static int action_get_title_dropdown_playlist_right_thumbnail_mode_item( + const char *path, const char *label, unsigned menu_type, char *s, size_t len) +{ + return action_get_title_thumbnails(path, label, menu_type, s, len); +} + +static int action_get_title_dropdown_playlist_left_thumbnail_mode_item( + const char *path, const char *label, unsigned menu_type, char *s, size_t len) +{ + return action_get_title_left_thumbnails(path, label, menu_type, s, len); +} + default_title_macro(action_get_quick_menu_override_options, MENU_ENUM_LABEL_VALUE_QUICK_MENU_OVERRIDE_OPTIONS) default_title_macro(action_get_user_accounts_cheevos_list, MENU_ENUM_LABEL_VALUE_ACCOUNTS_RETRO_ACHIEVEMENTS) default_title_macro(action_get_user_accounts_youtube_list, MENU_ENUM_LABEL_VALUE_ACCOUNTS_YOUTUBE) @@ -221,6 +392,10 @@ default_title_macro(action_get_title_goto_video, MENU_ENUM_LABEL_ default_title_macro(action_get_title_collection, MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB) default_title_macro(action_get_title_deferred_core_list, MENU_ENUM_LABEL_VALUE_SUPPORTED_CORES) +default_title_macro(action_get_title_dropdown_resolution_item, MENU_ENUM_LABEL_VALUE_SCREEN_RESOLUTION) +default_title_macro(action_get_title_dropdown_playlist_default_core_item, MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_DEFAULT_CORE) +default_title_macro(action_get_title_dropdown_playlist_label_display_mode_item, MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_LABEL_DISPLAY_MODE) + default_fill_title_macro(action_get_title_disk_image_append, MENU_ENUM_LABEL_VALUE_DISK_IMAGE_APPEND) default_fill_title_macro(action_get_title_cheat_file_load, MENU_ENUM_LABEL_VALUE_CHEAT_FILE) default_fill_title_macro(action_get_title_cheat_file_load_append, MENU_ENUM_LABEL_VALUE_CHEAT_FILE_APPEND) @@ -1426,44 +1601,44 @@ int menu_cbs_init_bind_title(menu_file_list_cbs_t *cbs, if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST))) { - BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_item); - return 0; + BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_item); + return 0; } if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_SPECIAL))) { - BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_item); - return 0; + BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_item); + return 0; } if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_RESOLUTION))) { - BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_item); - return 0; + BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_resolution_item); + return 0; } if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_DEFAULT_CORE))) { - BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_item); - return 0; + BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_playlist_default_core_item); + return 0; } if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LABEL_DISPLAY_MODE))) { - BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_item); - return 0; + BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_playlist_label_display_mode_item); + return 0; } if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE))) { - BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_item); - return 0; + BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_playlist_right_thumbnail_mode_item); + return 0; } if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE))) { - BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_item); - return 0; + BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_playlist_left_thumbnail_mode_item); + return 0; } if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_RPL_ENTRY_ACTIONS))) { diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index f191443ec9..c0b0d80c0d 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -6922,11 +6922,15 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, * toggles the Quick Menu off and on again (returning * to the Core Options menu) the menu must be refreshed * (or undefined behaviour occurs). - * The only way to check whether the number of visible - * options has changed is to cache the last set menu size, + * We therefore have to cache the last set menu size, * and compare this with the new size after processing - * the current core_option_manager_t struct */ - size_t prev_count = info->list->size; + * the current core_option_manager_t struct. + * Note: It would be 'nicer' to only refresh the menu + * if the selection marker is at an index higher than + * the new size, but we don't really have access that + * information at this stage (i.e. the selection can + * change after this function is called) */ + static size_t prev_count = 0; menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); @@ -6992,6 +6996,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, { info->need_refresh = true; info->need_navigation_clear = true; + prev_count = count; } info->need_push = true; }