From 60407a84e65efaea7aa48c2e02d0b0dc48a17645 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Thu, 23 Jul 2020 17:19:41 +0100 Subject: [PATCH] Add input remap drop-down lists --- intl/msg_hash_lbl.h | 8 + menu/cbs/menu_cbs_deferred_push.c | 4 + menu/cbs/menu_cbs_left.c | 4 + menu/cbs/menu_cbs_ok.c | 109 +++++++++++++ menu/cbs/menu_cbs_right.c | 8 +- menu/cbs/menu_cbs_select.c | 39 +---- menu/cbs/menu_cbs_start.c | 30 ++++ menu/cbs/menu_cbs_title.c | 57 +++++++ menu/drivers/materialui.c | 6 +- menu/menu_cbs.h | 8 +- menu/menu_displaylist.c | 244 +++++++++++++++++++++++++++++- menu/menu_displaylist.h | 2 + menu/menu_driver.h | 2 + msg_hash.h | 5 + retroarch.c | 7 + 15 files changed, 486 insertions(+), 47 deletions(-) diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index a79f925857..b965644419 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -656,6 +656,14 @@ MSG_HASH( MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_DISK_INDEX, "deferred_dropdown_box_list_disk_index" ) +MSG_HASH( + MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION, + "deferred_dropdown_box_list_input_description" + ) +MSG_HASH( + MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION_KBD, + "deferred_dropdown_box_list_input_description_kbd" + ) MSG_HASH( MENU_ENUM_LABEL_DEFERRED_CONFIGURATIONS_LIST, "deferred_configurations_list" diff --git a/menu/cbs/menu_cbs_deferred_push.c b/menu/cbs/menu_cbs_deferred_push.c index c23feb93f2..48b3a934ac 100644 --- a/menu/cbs/menu_cbs_deferred_push.c +++ b/menu/cbs/menu_cbs_deferred_push.c @@ -683,6 +683,8 @@ GENERIC_DEFERRED_PUSH_CLEAR_GENERAL(deferred_push_dropdown_box_list_playlist_sor GENERIC_DEFERRED_PUSH_CLEAR_GENERAL(deferred_push_dropdown_box_list_manual_content_scan_system_name, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME) GENERIC_DEFERRED_PUSH_CLEAR_GENERAL(deferred_push_dropdown_box_list_manual_content_scan_core_name, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_CORE_NAME) GENERIC_DEFERRED_PUSH_CLEAR_GENERAL(deferred_push_dropdown_box_list_disk_index, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_DISK_INDEX) +GENERIC_DEFERRED_PUSH_CLEAR_GENERAL(deferred_push_dropdown_box_list_input_description, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_INPUT_DESCRIPTION) +GENERIC_DEFERRED_PUSH_CLEAR_GENERAL(deferred_push_dropdown_box_list_input_description_kbd, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_INPUT_DESCRIPTION_KBD) static int menu_cbs_init_bind_deferred_push_compare_label( menu_file_list_cbs_t *cbs, @@ -711,6 +713,8 @@ static int menu_cbs_init_bind_deferred_push_compare_label( {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE, deferred_push_dropdown_box_list_playlist_left_thumbnail_mode}, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_SORT_MODE, deferred_push_dropdown_box_list_playlist_sort_mode}, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_DISK_INDEX, deferred_push_dropdown_box_list_disk_index}, + {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION, deferred_push_dropdown_box_list_input_description}, + {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION_KBD, deferred_push_dropdown_box_list_input_description_kbd}, {MENU_ENUM_LABEL_DEFERRED_BROWSE_URL_LIST, deferred_push_browse_url_list}, {MENU_ENUM_LABEL_DEFERRED_BROWSE_URL_START, deferred_push_browse_url_start}, {MENU_ENUM_LABEL_DEFERRED_CORE_SETTINGS_LIST, deferred_push_core_settings_list}, diff --git a/menu/cbs/menu_cbs_left.c b/menu/cbs/menu_cbs_left.c index b57ce807d4..72d5020bc7 100644 --- a/menu/cbs/menu_cbs_left.c +++ b/menu/cbs/menu_cbs_left.c @@ -1079,6 +1079,10 @@ static int menu_cbs_init_bind_left_compare_type(menu_file_list_cbs_t *cbs, case MENU_SETTING_ACTION_CORE_LOCK: BIND_ACTION_LEFT(cbs, action_left_core_lock); break; + case MENU_SETTING_DROPDOWN_ITEM_INPUT_DESCRIPTION: + case MENU_SETTING_DROPDOWN_ITEM_INPUT_DESCRIPTION_KBD: + BIND_ACTION_LEFT(cbs, action_left_scroll); + break; default: return -1; } diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index e93ebd0467..8be727634f 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -279,6 +279,10 @@ static enum msg_hash_enums action_ok_dl_to_enum(unsigned lbl) return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME; case ACTION_OK_DL_DROPDOWN_BOX_LIST_DISK_INDEX: return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_DISK_INDEX; + case ACTION_OK_DL_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION: + return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION; + case ACTION_OK_DL_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION_KBD: + return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION_KBD; case ACTION_OK_DL_MIXER_STREAM_SETTINGS_LIST: return MENU_ENUM_LABEL_DEFERRED_MIXER_STREAM_SETTINGS_LIST; case ACTION_OK_DL_ACCOUNTS_LIST: @@ -658,6 +662,24 @@ int generic_action_ok_displaylist_push(const char *path, info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_DISK_INDEX; dl_type = DISPLAYLIST_GENERIC; break; + case ACTION_OK_DL_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION: + info.type = type; + info.directory_ptr = idx; + info_path = path; + info_label = msg_hash_to_str( + MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION); + info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION; + dl_type = DISPLAYLIST_GENERIC; + break; + case ACTION_OK_DL_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION_KBD: + info.type = type; + info.directory_ptr = idx; + info_path = path; + info_label = msg_hash_to_str( + MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION_KBD); + info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION_KBD; + dl_type = DISPLAYLIST_GENERIC; + break; case ACTION_OK_DL_USER_BINDS_LIST: info.type = type; info.directory_ptr = idx; @@ -5820,6 +5842,61 @@ static int action_ok_push_dropdown_item_disk_index(const char *path, return 0; } +static int action_ok_push_dropdown_item_input_description(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + unsigned remap_idx = (unsigned)entry_idx; + unsigned entry_type = string_to_unsigned(label); + settings_t *settings = config_get_ptr(); + unsigned user_idx; + unsigned btn_idx; + + if (!settings || + (entry_type < MENU_SETTINGS_INPUT_DESC_BEGIN) || + ((remap_idx >= RARCH_CUSTOM_BIND_LIST_END) && + (remap_idx != RARCH_UNMAPPED))) + return menu_cbs_exit(); + + /* Determine user/button indices */ + user_idx = (entry_type - MENU_SETTINGS_INPUT_DESC_BEGIN) / (RARCH_FIRST_CUSTOM_BIND + 8); + btn_idx = (entry_type - MENU_SETTINGS_INPUT_DESC_BEGIN) - (RARCH_FIRST_CUSTOM_BIND + 8) * user_idx; + + if ((user_idx >= MAX_USERS) || (btn_idx >= RARCH_CUSTOM_BIND_LIST_END)) + return menu_cbs_exit(); + + /* Assign new mapping */ + settings->uints.input_remap_ids[user_idx][btn_idx] = remap_idx; + + return action_cancel_pop_default(NULL, NULL, 0, 0); +} + +static int action_ok_push_dropdown_item_input_description_kbd(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + unsigned key_id = (unsigned)entry_idx; + unsigned entry_type = string_to_unsigned(label); + settings_t *settings = config_get_ptr(); + unsigned user_idx; + unsigned btn_idx; + + if (!settings || + (entry_type < MENU_SETTINGS_INPUT_DESC_KBD_BEGIN) || + (key_id >= (RARCH_MAX_KEYS + MENU_SETTINGS_INPUT_DESC_KBD_BEGIN))) + return menu_cbs_exit(); + + /* Determine user/button indices */ + user_idx = (entry_type - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN) / RARCH_FIRST_CUSTOM_BIND; + btn_idx = (entry_type - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN) - RARCH_FIRST_CUSTOM_BIND * user_idx; + + if ((user_idx >= MAX_USERS) || (btn_idx >= RARCH_CUSTOM_BIND_LIST_END)) + return menu_cbs_exit(); + + /* Assign new mapping */ + settings->uints.input_keymapper_ids[user_idx][btn_idx] = key_id; + + return action_cancel_pop_default(NULL, NULL, 0, 0); +} + static int action_ok_push_default(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { @@ -6086,6 +6163,22 @@ static int action_ok_disk_index_dropdown_box_list(const char *path, ACTION_OK_DL_DROPDOWN_BOX_LIST_DISK_INDEX); } +static int action_ok_input_description_dropdown_box_list(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + return generic_action_ok_displaylist_push( + path, NULL, label, type, idx, entry_idx, + ACTION_OK_DL_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION); +} + +static int action_ok_input_description_kbd_dropdown_box_list(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + return generic_action_ok_displaylist_push( + path, NULL, label, type, idx, entry_idx, + ACTION_OK_DL_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION_KBD); +} + static int action_ok_disk_cycle_tray_status(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { @@ -7127,6 +7220,16 @@ static int menu_cbs_init_bind_ok_compare_type(menu_file_list_cbs_t *cbs, { BIND_ACTION_OK(cbs, action_ok_core_option_dropdown_list); } + else if ((type >= MENU_SETTINGS_INPUT_DESC_BEGIN) && + (type <= MENU_SETTINGS_INPUT_DESC_END)) + { + BIND_ACTION_OK(cbs, action_ok_input_description_dropdown_box_list); + } + else if ((type >= MENU_SETTINGS_INPUT_DESC_KBD_BEGIN) && + (type <= MENU_SETTINGS_INPUT_DESC_KBD_END)) + { + BIND_ACTION_OK(cbs, action_ok_input_description_kbd_dropdown_box_list); + } else { switch (type) @@ -7188,6 +7291,12 @@ static int menu_cbs_init_bind_ok_compare_type(menu_file_list_cbs_t *cbs, case MENU_SETTING_DROPDOWN_ITEM_DISK_INDEX: BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_disk_index); break; + case MENU_SETTING_DROPDOWN_ITEM_INPUT_DESCRIPTION: + BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_input_description); + break; + case MENU_SETTING_DROPDOWN_ITEM_INPUT_DESCRIPTION_KBD: + BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_input_description_kbd); + break; case MENU_SETTING_ACTION_CORE_DISK_OPTIONS: BIND_ACTION_OK(cbs, action_ok_push_default); break; diff --git a/menu/cbs/menu_cbs_right.c b/menu/cbs/menu_cbs_right.c index 83716afbfd..645903f933 100644 --- a/menu/cbs/menu_cbs_right.c +++ b/menu/cbs/menu_cbs_right.c @@ -138,7 +138,7 @@ static int action_right_cheat_num_passes(unsigned type, const char *label, #endif -int action_right_input_desc_kbd(unsigned type, const char *label, +static int action_right_input_desc_kbd(unsigned type, const char *label, bool wraparound) { unsigned key_id, user_idx, btn_idx; @@ -171,7 +171,7 @@ int action_right_input_desc_kbd(unsigned type, const char *label, } /* TODO/FIXME: incomplete, lacks error checking */ -int action_right_input_desc(unsigned type, const char *label, +static int action_right_input_desc(unsigned type, const char *label, bool wraparound) { rarch_system_info_t *system = runloop_get_system_info(); @@ -926,6 +926,10 @@ static int menu_cbs_init_bind_right_compare_type(menu_file_list_cbs_t *cbs, case MENU_SETTING_ACTION_CORE_LOCK: BIND_ACTION_RIGHT(cbs, action_right_core_lock); break; + case MENU_SETTING_DROPDOWN_ITEM_INPUT_DESCRIPTION: + case MENU_SETTING_DROPDOWN_ITEM_INPUT_DESCRIPTION_KBD: + BIND_ACTION_RIGHT(cbs, action_right_scroll); + break; default: return -1; } diff --git a/menu/cbs/menu_cbs_select.c b/menu/cbs/menu_cbs_select.c index 4b78117dab..8aa4fff208 100644 --- a/menu/cbs/menu_cbs_select.c +++ b/menu/cbs/menu_cbs_select.c @@ -124,43 +124,16 @@ static int action_select_core_setting(const char *path, const char *label, unsig return action_ok_core_option_dropdown_list(path, label, type, idx, 0); } -static int action_select_input_desc(const char *path, const char *label, unsigned type, - size_t idx, size_t entry_idx) -{ - return action_right_input_desc(type, label, true); -} - -static int action_select_input_desc_kbd(const char *path, - const char *label, unsigned type, - size_t idx, size_t entry_idx) -{ - return action_right_input_desc_kbd(type, label, true); -} - static int menu_cbs_init_bind_select_compare_type( menu_file_list_cbs_t *cbs, unsigned type) { - if (type >= MENU_SETTINGS_INPUT_DESC_BEGIN - && type <= MENU_SETTINGS_INPUT_DESC_END) + switch (type) { - BIND_ACTION_SELECT(cbs, action_select_input_desc); - } - else if (type >= MENU_SETTINGS_INPUT_DESC_KBD_BEGIN - && type <= MENU_SETTINGS_INPUT_DESC_KBD_END) - { - BIND_ACTION_SELECT(cbs, action_select_input_desc_kbd); - } - else - { - - switch (type) - { - case FILE_TYPE_USE_DIRECTORY: - BIND_ACTION_SELECT(cbs, action_select_path_use_directory); - break; - default: - return -1; - } + case FILE_TYPE_USE_DIRECTORY: + BIND_ACTION_SELECT(cbs, action_select_path_use_directory); + break; + default: + return -1; } return 0; diff --git a/menu/cbs/menu_cbs_start.c b/menu/cbs/menu_cbs_start.c index 4ffd19ce31..8371c6377e 100644 --- a/menu/cbs/menu_cbs_start.c +++ b/menu/cbs/menu_cbs_start.c @@ -180,6 +180,31 @@ static int action_start_input_desc( return 0; } +static int action_start_input_desc_kbd( + const char *path, const char *label, + unsigned type, size_t idx, size_t entry_idx) +{ + settings_t *settings = config_get_ptr(); + unsigned user_idx; + unsigned btn_idx; + + (void)label; + + if (!settings) + return 0; + + user_idx = (type - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN) / RARCH_FIRST_CUSTOM_BIND; + btn_idx = (type - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN) - RARCH_FIRST_CUSTOM_BIND * user_idx; + + if ((user_idx >= MAX_USERS) || (btn_idx >= RARCH_CUSTOM_BIND_LIST_END)) + return 0; + + /* By default, inputs are unmapped */ + settings->uints.input_keymapper_ids[user_idx][btn_idx] = RETROK_FIRST; + + return 0; +} + #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL) static int action_start_shader_action_parameter_generic( unsigned type, unsigned offset) @@ -675,6 +700,11 @@ static int menu_cbs_init_bind_start_compare_type(menu_file_list_cbs_t *cbs, { BIND_ACTION_START(cbs, action_start_input_desc); } + else if (type >= MENU_SETTINGS_INPUT_DESC_KBD_BEGIN + && type <= MENU_SETTINGS_INPUT_DESC_KBD_END) + { + BIND_ACTION_START(cbs, action_start_input_desc_kbd); + } else if (type >= MENU_SETTINGS_PERF_COUNTERS_BEGIN && type <= MENU_SETTINGS_PERF_COUNTERS_END) { diff --git a/menu/cbs/menu_cbs_title.c b/menu/cbs/menu_cbs_title.c index a1ab27740a..a52dbe2860 100644 --- a/menu/cbs/menu_cbs_title.c +++ b/menu/cbs/menu_cbs_title.c @@ -420,6 +420,61 @@ error: return 0; } +static int action_get_title_dropdown_input_description_common( + const char *input_name, unsigned port, char *s, size_t len) +{ + const char *input_label_ptr = input_name; + char input_label[256]; + + input_label[0] = '\0'; + + if (!string_is_empty(input_label_ptr)) + { + /* Strip off 'Auto:' prefix, if required */ + if (string_starts_with_size(input_label_ptr, "Auto:", + STRLEN_CONST("Auto:"))) + input_label_ptr += STRLEN_CONST("Auto:"); + + strlcpy(input_label, input_label_ptr, + sizeof(input_label)); + + string_trim_whitespace_left(input_label); + } + + /* Sanity check */ + if (string_is_empty(input_label)) + strlcpy(input_label, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE), + sizeof(input_label)); + + /* Build title string */ + snprintf(s, len, "%s #%u - %s", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PORT), + port + 1, + input_label); + + return 1; +} + +static int action_get_title_dropdown_input_description( + const char *path, const char *label, unsigned menu_type, char *s, size_t len) +{ + unsigned port = (menu_type - MENU_SETTINGS_INPUT_DESC_BEGIN) / + (RARCH_FIRST_CUSTOM_BIND + 8); + + return action_get_title_dropdown_input_description_common( + path, port, s, len); +} + +static int action_get_title_dropdown_input_description_kbd( + const char *path, const char *label, unsigned menu_type, char *s, size_t len) +{ + unsigned port = (menu_type - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN) / + RARCH_FIRST_CUSTOM_BIND; + + return action_get_title_dropdown_input_description_common( + path, port, 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) @@ -1486,6 +1541,8 @@ int menu_cbs_init_bind_title(menu_file_list_cbs_t *cbs, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME, action_get_title_dropdown_manual_content_scan_system_name_item}, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME, action_get_title_dropdown_manual_content_scan_core_name_item}, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_DISK_INDEX, action_get_title_dropdown_disk_index}, + {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION, action_get_title_dropdown_input_description}, + {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION_KBD, action_get_title_dropdown_input_description_kbd}, {MENU_ENUM_LABEL_DEFERRED_RPL_ENTRY_ACTIONS, action_get_quick_menu_views_settings_list}, {MENU_ENUM_LABEL_DEFERRED_PLAYLIST_LIST, action_get_title_deferred_playlist_list}, {MENU_ENUM_LABEL_DEFERRED_PLAYLIST_MANAGER_SETTINGS, action_get_title_deferred_playlist_list}, diff --git a/menu/drivers/materialui.c b/menu/drivers/materialui.c index b594de8a62..2ded50bc46 100644 --- a/menu/drivers/materialui.c +++ b/menu/drivers/materialui.c @@ -7653,7 +7653,9 @@ static void materialui_populate_entries( string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_SORT_MODE)) || string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME)) || string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME)) || - string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_DISK_INDEX)); + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_DISK_INDEX)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION_KBD)); } /* If this is a playlist, then cache it */ @@ -9231,6 +9233,8 @@ static void materialui_list_insert( case MENU_SETTING_DROPDOWN_ITEM_MANUAL_CONTENT_SCAN_SYSTEM_NAME: case MENU_SETTING_DROPDOWN_ITEM_MANUAL_CONTENT_SCAN_CORE_NAME: case MENU_SETTING_DROPDOWN_ITEM_DISK_INDEX: + case MENU_SETTING_DROPDOWN_ITEM_INPUT_DESCRIPTION: + case MENU_SETTING_DROPDOWN_ITEM_INPUT_DESCRIPTION_KBD: case MENU_SETTING_DROPDOWN_SETTING_CORE_OPTIONS_ITEM: case MENU_SETTING_DROPDOWN_SETTING_STRING_OPTIONS_ITEM: case MENU_SETTING_DROPDOWN_SETTING_FLOAT_ITEM: diff --git a/menu/menu_cbs.h b/menu/menu_cbs.h index b8d87991d8..d8ef1b022a 100644 --- a/menu/menu_cbs.h +++ b/menu/menu_cbs.h @@ -59,6 +59,8 @@ enum ACTION_OK_DL_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME, ACTION_OK_DL_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME, ACTION_OK_DL_DROPDOWN_BOX_LIST_DISK_INDEX, + ACTION_OK_DL_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION, + ACTION_OK_DL_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION_KBD, ACTION_OK_DL_OPEN_ARCHIVE, ACTION_OK_DL_OPEN_ARCHIVE_DETECT_CORE, ACTION_OK_DL_MUSIC, @@ -233,12 +235,6 @@ int action_ok_directory_push(const char *path, int core_setting_right(unsigned type, const char *label, bool wraparound); -int action_right_input_desc(unsigned type, const char *label, - bool wraparound); - -int action_right_input_desc_kbd(unsigned type, const char *label, - bool wraparound); - int action_right_cheat(unsigned type, const char *label, bool wraparound); diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index d4b27351ab..12128c9bac 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -137,6 +137,8 @@ static struct menu_displaylist_state menu_displist_st; /* TODO/FIXME - static public global variables */ static enum filebrowser_enums filebrowser_types = FILEBROWSER_NONE; +extern struct key_desc key_descriptors[RARCH_MAX_KEYS]; + enum filebrowser_enums filebrowser_get_type(void) { return filebrowser_types; @@ -4002,6 +4004,224 @@ static unsigned menu_displaylist_parse_disk_options( return count; } +static int menu_displaylist_parse_input_description_list(menu_displaylist_info_t *info) +{ + unsigned count = 0; + rarch_system_info_t *system = runloop_get_system_info(); + settings_t *settings = config_get_ptr(); + size_t menu_index = 0; + bool current_input_mapped = false; + unsigned user_idx; + unsigned btn_idx; + unsigned current_remap_idx; + size_t i; + char entry_label[21]; + + entry_label[0] = '\0'; + + if (!system || !settings) + goto end; + + /* Determine user/button indices */ + user_idx = (info->type - MENU_SETTINGS_INPUT_DESC_BEGIN) / (RARCH_FIRST_CUSTOM_BIND + 8); + btn_idx = (info->type - MENU_SETTINGS_INPUT_DESC_BEGIN) - (RARCH_FIRST_CUSTOM_BIND + 8) * user_idx; + + if ((user_idx >= MAX_USERS) || (btn_idx >= RARCH_CUSTOM_BIND_LIST_END)) + goto end; + + /* Get current mapping for selected button */ + current_remap_idx = settings->uints.input_remap_ids[user_idx][btn_idx]; + + if (current_remap_idx >= RARCH_CUSTOM_BIND_LIST_END) + current_remap_idx = RARCH_UNMAPPED; + + /* An annoyance: Menu entries do not have + * enough parameters to pass on all the information + * required to interpret a remap selection without + * adding workarounds... + * We need to record the current user/button indices, + * and so have to convert 'info->type' to a string + * and pass it as the entry label... */ + snprintf(entry_label, sizeof(entry_label), + "%u", info->type); + + /* Loop over core input definitions */ + for (i = 0; i < RARCH_CUSTOM_BIND_LIST_END; i++) + { + const char *input_desc_btn = system->input_desc_btn[user_idx][i]; + + /* Check whether an input is defined for + * this button */ + if (!string_is_empty(input_desc_btn)) + { + char input_description[256]; + + input_description[0] = '\0'; + + /* > Up to RARCH_FIRST_CUSTOM_BIND, inputs + * are buttons - description can be used + * directly + * > Above RARCH_FIRST_CUSTOM_BIND, inputs + * are analog axes - have to add +/- + * indicators */ + if (i < RARCH_FIRST_CUSTOM_BIND) + strlcpy(input_description, input_desc_btn, + sizeof(input_description)); + else + snprintf(input_description, sizeof(input_description), + "%s %c", input_desc_btn, + ((i % 2) == 0) ? '+' : '-'); + + if (string_is_empty(input_description)) + continue; + + /* Add menu entry */ + if (menu_entries_append_enum(info->list, + input_description, + entry_label, + MENU_ENUM_LABEL_INPUT_DESCRIPTION, + MENU_SETTING_DROPDOWN_ITEM_INPUT_DESCRIPTION, + 0, i)) + { + /* Add checkmark if input is currently + * mapped to this entry */ + if (current_remap_idx == i) + { + menu_entries_set_checked(info->list, menu_index, true); + menu_navigation_set_selection(menu_index); + current_input_mapped = true; + } + + count++; + menu_index++; + } + } + } + + /* Add 'unmapped' entry at end of list */ + if (menu_entries_append_enum(info->list, + "---", + entry_label, + MENU_ENUM_LABEL_INPUT_DESCRIPTION, + MENU_SETTING_DROPDOWN_ITEM_INPUT_DESCRIPTION, + 0, RARCH_UNMAPPED)) + { + /* Add checkmark if input is currently unmapped */ + if (!current_input_mapped) + { + menu_entries_set_checked(info->list, menu_index, true); + menu_navigation_set_selection(menu_index); + } + + count++; + menu_index++; + } + +end: + /* Fallback */ + if (count == 0) + if (menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_ENTRIES_TO_DISPLAY), + msg_hash_to_str(MENU_ENUM_LABEL_NO_ENTRIES_TO_DISPLAY), + MENU_ENUM_LABEL_NO_ENTRIES_TO_DISPLAY, + FILE_TYPE_NONE, 0, 0)) + count++; + + return count; +} + +static int menu_displaylist_parse_input_description_kbd_list(menu_displaylist_info_t *info) +{ + unsigned count = 0; + settings_t *settings = config_get_ptr(); + size_t menu_index = 0; + unsigned user_idx; + unsigned btn_idx; + unsigned current_key_id; + size_t i; + char entry_label[21]; + + entry_label[0] = '\0'; + + if (!settings) + goto end; + + /* Determine user/button indices */ + user_idx = (info->type - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN) / RARCH_FIRST_CUSTOM_BIND; + btn_idx = (info->type - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN) - RARCH_FIRST_CUSTOM_BIND * user_idx; + + if ((user_idx >= MAX_USERS) || (btn_idx >= RARCH_CUSTOM_BIND_LIST_END)) + goto end; + + /* Get current mapping for selected button */ + current_key_id = settings->uints.input_keymapper_ids[user_idx][btn_idx]; + + if (current_key_id >= (RARCH_MAX_KEYS + MENU_SETTINGS_INPUT_DESC_KBD_BEGIN)) + current_key_id = RETROK_FIRST; + + /* An annoyance: Menu entries do not have + * enough parameters to pass on all the information + * required to interpret a remap selection without + * adding workarounds... + * We need to record the current user/button indices, + * and so have to convert 'info->type' to a string + * and pass it as the entry label... */ + snprintf(entry_label, sizeof(entry_label), + "%u", info->type); + + /* Loop over keyboard keys */ + for (i = 0; i < RARCH_MAX_KEYS; i++) + { + unsigned key_id = key_descriptors[i].key; + const char *key_label = key_descriptors[i].desc; + char input_description[256]; + + input_description[0] = '\0'; + + if (string_is_empty(key_label)) + continue; + + /* TODO/FIXME: Localise 'Keyboard' */ + if (key_id == RETROK_FIRST) + strlcpy(input_description, "---", sizeof(input_description)); + else + snprintf(input_description, sizeof(input_description), + "Keyboard %s", key_label); + + /* Add menu entry */ + if (menu_entries_append_enum(info->list, + input_description, + entry_label, + MENU_ENUM_LABEL_INPUT_DESCRIPTION_KBD, + MENU_SETTING_DROPDOWN_ITEM_INPUT_DESCRIPTION_KBD, + 0, key_id)) + { + /* Add checkmark if input is currently + * mapped to this entry */ + if (current_key_id == key_id) + { + menu_entries_set_checked(info->list, menu_index, true); + menu_navigation_set_selection(menu_index); + } + + count++; + menu_index++; + } + } + +end: + /* Fallback */ + if (count == 0) + if (menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_ENTRIES_TO_DISPLAY), + msg_hash_to_str(MENU_ENUM_LABEL_NO_ENTRIES_TO_DISPLAY), + MENU_ENUM_LABEL_NO_ENTRIES_TO_DISPLAY, + FILE_TYPE_NONE, 0, 0)) + count++; + + return count; +} + static bool menu_displaylist_push_internal( const char *label, menu_displaylist_ctx_entry_t *entry, @@ -8701,8 +8921,6 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, info->need_refresh = true; break; case DISPLAYLIST_OPTIONS_REMAPPINGS_PORT: - menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - { settings_t *settings = config_get_ptr(); unsigned max_users = *(input_driver_get_uint(INPUT_ACTION_MAX_USERS)); @@ -8710,6 +8928,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, bool is_rgui = string_is_equal(menu_driver, "rgui"); file_list_t *list = info->list; unsigned p = atoi(info->path); + size_t selection = menu_navigation_get_selection(); + + menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); { char key_type[PATH_MAX_LENGTH]; @@ -8824,9 +9045,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, } } - info->need_push = true; - info->need_refresh = true; - info->need_clear = true; + info->need_push = true; + info->need_refresh = true; + if (selection >= count) + info->need_clear = true; } break; #ifdef HAVE_CDROM @@ -10473,6 +10695,18 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, info->need_refresh = true; info->need_push = true; break; + case DISPLAYLIST_DROPDOWN_LIST_INPUT_DESCRIPTION: + menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); + count = menu_displaylist_parse_input_description_list(info); + info->need_refresh = true; + info->need_push = true; + break; + case DISPLAYLIST_DROPDOWN_LIST_INPUT_DESCRIPTION_KBD: + menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); + count = menu_displaylist_parse_input_description_kbd_list(info); + info->need_refresh = true; + info->need_push = true; + break; case DISPLAYLIST_SAVING_SETTINGS_LIST: case DISPLAYLIST_DRIVER_SETTINGS_LIST: case DISPLAYLIST_LOGGING_SETTINGS_LIST: diff --git a/menu/menu_displaylist.h b/menu/menu_displaylist.h index 92ff7f1d37..fcd5b44c87 100644 --- a/menu/menu_displaylist.h +++ b/menu/menu_displaylist.h @@ -67,6 +67,8 @@ enum menu_displaylist_ctl_state DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME, DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_CORE_NAME, DISPLAYLIST_DROPDOWN_LIST_DISK_INDEX, + DISPLAYLIST_DROPDOWN_LIST_INPUT_DESCRIPTION, + DISPLAYLIST_DROPDOWN_LIST_INPUT_DESCRIPTION_KBD, DISPLAYLIST_CDROM_DETAIL_INFO, DISPLAYLIST_INFO, DISPLAYLIST_HELP, diff --git a/menu/menu_driver.h b/menu/menu_driver.h index aad10cb099..3cd6612583 100644 --- a/menu/menu_driver.h +++ b/menu/menu_driver.h @@ -81,6 +81,8 @@ enum menu_settings_type MENU_SETTING_DROPDOWN_ITEM_MANUAL_CONTENT_SCAN_SYSTEM_NAME, MENU_SETTING_DROPDOWN_ITEM_MANUAL_CONTENT_SCAN_CORE_NAME, MENU_SETTING_DROPDOWN_ITEM_DISK_INDEX, + MENU_SETTING_DROPDOWN_ITEM_INPUT_DESCRIPTION, + MENU_SETTING_DROPDOWN_ITEM_INPUT_DESCRIPTION_KBD, MENU_SETTING_DROPDOWN_SETTING_CORE_OPTIONS_ITEM, MENU_SETTING_DROPDOWN_SETTING_STRING_OPTIONS_ITEM, MENU_SETTING_DROPDOWN_SETTING_FLOAT_ITEM, diff --git a/msg_hash.h b/msg_hash.h index 9263eb4e76..13024c43e7 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -901,6 +901,9 @@ enum msg_hash_enums MENU_ENUM_SUBLABEL_INPUT_META_AI_SERVICE, MENU_ENUM_SUBLABEL_INPUT_META_MENU_TOGGLE, + MENU_ENUM_LABEL_INPUT_DESCRIPTION, + MENU_ENUM_LABEL_INPUT_DESCRIPTION_KBD, + MENU_LABEL(INPUT_MAX_USERS), MENU_LABEL(INPUT_USER_BINDS), MENU_LABEL(INPUT_DUTY_CYCLE), @@ -1346,6 +1349,8 @@ enum msg_hash_enums MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME, MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME, MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_DISK_INDEX, + MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION, + MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION_KBD, MENU_ENUM_LABEL_DEFERRED_MIXER_STREAM_SETTINGS_LIST, MENU_ENUM_LABEL_DEFERRED_CONFIGURATIONS_LIST, MENU_ENUM_LABEL_DEFERRED_FAVORITES_LIST, diff --git a/retroarch.c b/retroarch.c index aa53a8b92b..d590916d81 100644 --- a/retroarch.c +++ b/retroarch.c @@ -4587,7 +4587,14 @@ static int generic_menu_iterate( if (enum_idx != MSG_UNKNOWN) ret = msg_hash_get_help_enum(enum_idx, menu->menu_state_msg, sizeof(menu->menu_state_msg)); + else + { + strlcpy(menu->menu_state_msg, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE), + sizeof(menu->menu_state_msg)); + ret = 0; + } } } BIT64_SET(menu->state, MENU_STATE_RENDER_MESSAGEBOX);