From 97aaf42446fd2fd6b2d72ebc0b6509858e200e76 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Thu, 6 Jun 2019 17:35:44 +0100 Subject: [PATCH 1/2] Overhaul content 'Information' menu display --- intl/msg_hash_lbl.h | 16 ++ intl/msg_hash_us.h | 28 +++ menu/cbs/menu_cbs_deferred_push.c | 9 + menu/cbs/menu_cbs_label.c | 6 +- menu/cbs/menu_cbs_left.c | 2 +- menu/cbs/menu_cbs_ok.c | 1 + menu/cbs/menu_cbs_right.c | 2 +- menu/cbs/menu_cbs_sublabel.c | 4 + menu/cbs/menu_cbs_title.c | 7 + menu/drivers/xmb.c | 1 - menu/menu_displaylist.c | 350 ++++++++++++++++++++++++++---- menu/menu_displaylist.h | 1 + msg_hash.h | 13 ++ 13 files changed, 387 insertions(+), 53 deletions(-) diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 8cc91688c5..3d6f66debb 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -405,6 +405,8 @@ MSG_HASH(MENU_ENUM_LABEL_DEFERRED_CRT_SWITCHRES_SETTINGS_LIST, "deferred_crt_switchres_settings_list") MSG_HASH(MENU_ENUM_LABEL_DEFERRED_WIFI_SETTINGS_LIST, "deferred_wifi_settings_list") +MSG_HASH(MENU_ENUM_LABEL_DEFERRED_INFORMATION, + "deferred_information") MSG_HASH(MENU_ENUM_LABEL_DELETE_ENTRY, "delete_entry") MSG_HASH(MENU_ENUM_LABEL_FAVORITES, @@ -871,6 +873,8 @@ MSG_HASH(MENU_ENUM_LABEL_QUIT_RETROARCH, "quit_retroarch") MSG_HASH(MENU_ENUM_LABEL_RDB_ENTRY, "rdb_entry") +MSG_HASH(MENU_ENUM_LABEL_RDB_ENTRY_DETAIL, + "rdb_entry_detail") MSG_HASH(MENU_ENUM_LABEL_RDB_ENTRY_ANALOG, "rdb_entry_analog") MSG_HASH(MENU_ENUM_LABEL_RDB_ENTRY_BBFC_RATING, @@ -955,6 +959,18 @@ MSG_HASH(MENU_ENUM_LABEL_RDB_ENTRY_START_CONTENT, "rdb_entry_start_content") MSG_HASH(MENU_ENUM_LABEL_RDB_ENTRY_TGDB_RATING, "rdb_entry_tgdb_rating") +MSG_HASH(MENU_ENUM_LABEL_CONTENT_INFO_LABEL, + "content_info_label") +MSG_HASH(MENU_ENUM_LABEL_CONTENT_INFO_PATH, + "content_info_path") +MSG_HASH(MENU_ENUM_LABEL_CONTENT_INFO_CORE_NAME, + "content_info_core_name") +MSG_HASH(MENU_ENUM_LABEL_CONTENT_INFO_DATABASE, + "content_info_database") +MSG_HASH(MENU_ENUM_LABEL_CONTENT_INFO_RUNTIME, + "content_info_runtime") +MSG_HASH(MENU_ENUM_LABEL_CONTENT_INFO_LAST_PLAYED, + "content_info_last_played") MSG_HASH(MENU_ENUM_LABEL_REBOOT, "reboot") MSG_HASH(MENU_ENUM_LABEL_RECORDING_CONFIG_DIRECTORY, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index f6cfdc807d..0e0f7a10a7 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -2183,6 +2183,10 @@ MSG_HASH( "Restart RetroArch" ) #endif +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DETAIL, + "Database Entry") +MSG_HASH(MENU_ENUM_SUBLABEL_RDB_ENTRY_DETAIL, + "Show database information for current content") MSG_HASH( MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ANALOG, "Analog supported" @@ -2295,6 +2299,30 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_RDB_ENTRY_TGDB_RATING, "TGDB Rating" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_INFO_LABEL, + "Name" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_INFO_PATH, + "File Path" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_INFO_CORE_NAME, + "Core" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_INFO_DATABASE, + "Database" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_INFO_RUNTIME, + "Play Time" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_INFO_LAST_PLAYED, + "Last Played" + ) #ifdef HAVE_LAKKA_SWITCH MSG_HASH( MENU_ENUM_LABEL_VALUE_REBOOT, diff --git a/menu/cbs/menu_cbs_deferred_push.c b/menu/cbs/menu_cbs_deferred_push.c index 52de59e374..3982135d07 100644 --- a/menu/cbs/menu_cbs_deferred_push.c +++ b/menu/cbs/menu_cbs_deferred_push.c @@ -96,6 +96,7 @@ generic_deferred_push(deferred_push_configurations_list, DISPLAYLIST_ generic_deferred_push(deferred_push_load_content_special, DISPLAYLIST_LOAD_CONTENT_LIST) generic_deferred_push(deferred_push_load_content_list, DISPLAYLIST_LOAD_CONTENT_LIST) generic_deferred_push(deferred_push_information_list, DISPLAYLIST_INFORMATION_LIST) +generic_deferred_push(deferred_push_information, DISPLAYLIST_INFORMATION) generic_deferred_push(deferred_archive_action_detect_core, DISPLAYLIST_ARCHIVE_ACTION_DETECT_CORE) generic_deferred_push(deferred_archive_action, DISPLAYLIST_ARCHIVE_ACTION) generic_deferred_push(deferred_push_management_options, DISPLAYLIST_OPTIONS_MANAGEMENT) @@ -1004,6 +1005,11 @@ static int menu_cbs_init_bind_deferred_push_compare_label( { BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_information_list); } + else if (strstr(label, + msg_hash_to_str(MENU_ENUM_LABEL_INFORMATION))) + { + BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_information); + } else if (strstr(label, msg_hash_to_str(MENU_ENUM_LABEL_SHADER_OPTIONS))) { @@ -1163,6 +1169,9 @@ static int menu_cbs_init_bind_deferred_push_compare_label( case MENU_ENUM_LABEL_INFORMATION_LIST: BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_information_list); break; + case MENU_ENUM_LABEL_INFORMATION: + BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_information); + break; case MENU_ENUM_LABEL_MANAGEMENT: BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_management_options); break; diff --git a/menu/cbs/menu_cbs_label.c b/menu/cbs/menu_cbs_label.c index f09e916f8a..266f970edd 100644 --- a/menu/cbs/menu_cbs_label.c +++ b/menu/cbs/menu_cbs_label.c @@ -43,7 +43,7 @@ static int (func)(file_list_t *list, unsigned type, unsigned i, const char *labe return 0; \ } -fill_label_macro(action_bind_label_information, MENU_ENUM_LABEL_VALUE_INFORMATION) +fill_label_macro(action_bind_label_rdb_entry_detail, MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DETAIL) fill_label_macro(action_bind_label_internal_memory, MSG_INTERNAL_STORAGE) fill_label_macro(action_bind_label_removable_storage, MSG_REMOVABLE_STORAGE) fill_label_macro(action_bind_label_external_application_dir, MSG_EXTERNAL_APPLICATION_DIR) @@ -108,8 +108,8 @@ int menu_cbs_init_bind_label(menu_file_list_cbs_t *cbs, case MSG_EXTERNAL_APPLICATION_DIR: BIND_ACTION_LABEL(cbs, action_bind_label_external_application_dir); break; - case MENU_ENUM_LABEL_INFORMATION: - BIND_ACTION_LABEL(cbs, action_bind_label_information); + case MENU_ENUM_LABEL_RDB_ENTRY_DETAIL: + BIND_ACTION_LABEL(cbs, action_bind_label_rdb_entry_detail); break; default: break; diff --git a/menu/cbs/menu_cbs_left.c b/menu/cbs/menu_cbs_left.c index 4d6f8c0705..17eb77fdd4 100644 --- a/menu/cbs/menu_cbs_left.c +++ b/menu/cbs/menu_cbs_left.c @@ -494,7 +494,7 @@ static int menu_cbs_init_bind_left_compare_label(menu_file_list_cbs_t *cbs, return 0; } - if (strstr(label, "rdb_entry")) + if (strstr(label, "rdb_entry") || strstr(label, "content_info")) { BIND_ACTION_LEFT(cbs, action_left_scroll); } diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 3464603ba7..6cd4e6e19c 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -5796,6 +5796,7 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_CONFIGURATIONS_LIST: case MENU_ENUM_LABEL_HELP_LIST: case MENU_ENUM_LABEL_INFORMATION_LIST: + case MENU_ENUM_LABEL_INFORMATION: case MENU_ENUM_LABEL_CONTENT_SETTINGS: #ifdef HAVE_LAKKA_SWITCH case MENU_ENUM_LABEL_SWITCH_GPU_PROFILE: diff --git a/menu/cbs/menu_cbs_right.c b/menu/cbs/menu_cbs_right.c index 0f7f2f170a..5872678699 100644 --- a/menu/cbs/menu_cbs_right.c +++ b/menu/cbs/menu_cbs_right.c @@ -626,7 +626,7 @@ static int menu_cbs_init_bind_right_compare_label(menu_file_list_cbs_t *cbs, return 0; } - if (strstr(label, "rdb_entry")) + if (strstr(label, "rdb_entry") || strstr(label, "content_info")) { BIND_ACTION_RIGHT(cbs, action_right_scroll); } diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index da17b32fa0..0fde020b40 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -617,6 +617,7 @@ default_sublabel_macro(action_bind_sublabel_menu_rgui_extended_ascii, default_sublabel_macro(action_bind_sublabel_thumbnails_updater_list, MENU_ENUM_SUBLABEL_THUMBNAILS_UPDATER_LIST) default_sublabel_macro(action_bind_sublabel_pl_thumbnails_updater_list, MENU_ENUM_SUBLABEL_PL_THUMBNAILS_UPDATER_LIST) default_sublabel_macro(action_bind_sublabel_help_send_debug_info, MENU_ENUM_SUBLABEL_HELP_SEND_DEBUG_INFO) +default_sublabel_macro(action_bind_sublabel_rdb_entry_detail, MENU_ENUM_SUBLABEL_RDB_ENTRY_DETAIL) static int action_bind_sublabel_systeminfo_controller_entry( file_list_t *list, @@ -2623,6 +2624,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_HELP_SEND_DEBUG_INFO: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_help_send_debug_info); break; + case MENU_ENUM_LABEL_RDB_ENTRY_DETAIL: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_rdb_entry_detail); + break; default: case MSG_UNKNOWN: return -1; diff --git a/menu/cbs/menu_cbs_title.c b/menu/cbs/menu_cbs_title.c index 12c76664aa..1a140e1a64 100644 --- a/menu/cbs/menu_cbs_title.c +++ b/menu/cbs/menu_cbs_title.c @@ -167,6 +167,7 @@ default_title_macro(action_get_system_information_list, MENU_ENUM_LABEL_ default_title_macro(action_get_network_information_list, MENU_ENUM_LABEL_VALUE_NETWORK_INFORMATION) default_title_macro(action_get_settings_list, MENU_ENUM_LABEL_VALUE_SETTINGS) default_title_macro(action_get_title_information_list, MENU_ENUM_LABEL_VALUE_INFORMATION_LIST) +default_title_macro(action_get_title_information, MENU_ENUM_LABEL_VALUE_INFORMATION) default_title_macro(action_get_title_goto_favorites, MENU_ENUM_LABEL_VALUE_GOTO_FAVORITES) default_title_macro(action_get_title_goto_image, MENU_ENUM_LABEL_VALUE_GOTO_IMAGES) default_title_macro(action_get_title_goto_music, MENU_ENUM_LABEL_VALUE_GOTO_MUSIC) @@ -736,6 +737,9 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_INFORMATION_LIST: BIND_ACTION_GET_TITLE(cbs, action_get_title_information_list); break; + case MENU_ENUM_LABEL_INFORMATION: + BIND_ACTION_GET_TITLE(cbs, action_get_title_information); + break; case MENU_ENUM_LABEL_SETTINGS: BIND_ACTION_GET_TITLE(cbs, action_get_settings_list); break; @@ -1084,6 +1088,9 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs, case MENU_LABEL_INFORMATION_LIST: BIND_ACTION_GET_TITLE(cbs, action_get_title_information_list); break; + case MENU_LABEL_INFORMATION: + BIND_ACTION_GET_TITLE(cbs, action_get_title_information); + break; case MENU_LABEL_SETTINGS: BIND_ACTION_GET_TITLE(cbs, action_get_settings_list); break; diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 0afd29078e..4cd0f08d17 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -3140,7 +3140,6 @@ static void xmb_draw_items( menu_entry_t entry; menu_entry_init(&entry); entry.label_enabled = false; - entry.rich_label_enabled = false; entry.sublabel_enabled = (i == current); menu_entry_get(&entry, 0, i, list, true); ret = xmb_draw_item(video_info, diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 9188faf6bc..eb41119fba 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -93,6 +93,7 @@ #include "../wifi/wifi_driver.h" #include "../tasks/tasks_internal.h" #include "../dynamic.h" +#include "../runtime_file.h" static char new_path_entry[4096] = {0}; static char new_lbl_entry[4096] = {0}; @@ -1003,51 +1004,40 @@ static int create_string_list_rdb_entry_int( int actual_int, const char *path, file_list_t *list) { union string_list_elem_attr attr; - size_t path_size = PATH_MAX_LENGTH * sizeof(char); - char *tmp = NULL; - char *str = NULL; - char *output_label = NULL; int str_len = 0; struct string_list *str_list = string_list_new(); + char tmp[PATH_MAX_LENGTH]; + char str[PATH_MAX_LENGTH]; + char output_label[PATH_MAX_LENGTH]; + + tmp[0] = '\0'; + str[0] = '\0'; + output_label[0] = '\0'; if (!str_list) return -1; attr.i = 0; - tmp = (char*)malloc(path_size); - str = (char*)malloc(path_size); - tmp[0] = str[0] = '\0'; str_len += strlen(label) + 1; string_list_append(str_list, label, attr); - snprintf(str, path_size, "%d", actual_int); + snprintf(str, sizeof(str), "%d", actual_int); str_len += strlen(str) + 1; string_list_append(str_list, str, attr); - free(str); str_len += strlen(path) + 1; string_list_append(str_list, path, attr); - output_label = (char*)calloc(str_len, sizeof(char)); - - if (!output_label) - { - string_list_free(str_list); - free(tmp); - return -1; - } - string_list_join_concat(output_label, str_len, str_list, "|"); string_list_free(str_list); + str_list = NULL; - snprintf(tmp, path_size, "%s : %d", desc, actual_int); + snprintf(tmp, sizeof(tmp), "%s : %d", desc, actual_int); menu_entries_append_enum(list, tmp, output_label, enum_idx, 0, 0, 0); - free(output_label); - return 0; } @@ -1977,6 +1967,15 @@ static int menu_displaylist_parse_load_content_settings( MENU_SETTING_ACTION, 0, 0); } #endif + + if (settings->bools.quick_menu_show_information) + { + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_INFORMATION), + msg_hash_to_str(MENU_ENUM_LABEL_INFORMATION), + MENU_ENUM_LABEL_INFORMATION, + MENU_SETTING_ACTION, 0, 0); + } } else menu_entries_append_enum(info->list, @@ -2061,6 +2060,25 @@ static int menu_displaylist_parse_horizontal_content_actions( string_is_equal(system, "images_history") || string_is_equal(system, "music_history") || string_is_equal(system, "video_history"); + + /* An annoyance: if the user navigates to the information menu, + * then to the database entry, the thumbnail system will be changed. + * This breaks the above 'remove_entry_enabled' check for the + * history and favorites playlists. We therefore have to check + * the playlist file name as well... */ + if (!remove_entry_enabled && settings->bools.quick_menu_show_information) + { + const char *playlist_path = playlist_get_conf_path(playlist); + + if (!string_is_empty(playlist_path)) + { + const char *playlist_file = path_basename(playlist_path); + + if (!string_is_empty(playlist_file)) + remove_entry_enabled = string_is_equal(playlist_file, file_path_str(FILE_PATH_CONTENT_HISTORY)) || + string_is_equal(playlist_file, file_path_str(FILE_PATH_CONTENT_FAVORITES)); + } + } } if (remove_entry_enabled) @@ -2086,33 +2104,14 @@ static int menu_displaylist_parse_horizontal_content_actions( msg_hash_to_str(MENU_ENUM_LABEL_RESET_CORE_ASSOCIATION), MENU_ENUM_LABEL_RESET_CORE_ASSOCIATION, FILE_TYPE_PLAYLIST_ENTRY, 0, 0); } - } - if ((entry && !string_is_empty(entry->db_name)) && (!content_loaded || - (content_loaded && settings->bools.quick_menu_show_information))) - { - char *db_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); - - db_path[0] = '\0'; - - fill_pathname_join_noext(db_path, - settings->paths.path_content_database, - entry->db_name, - PATH_MAX_LENGTH * sizeof(char)); - strlcat(db_path, - file_path_str(FILE_PATH_RDB_EXTENSION), - PATH_MAX_LENGTH * sizeof(char) - ); - - if (path_is_valid(db_path)) - menu_entries_append_enum( - info->list, - entry->label, - db_path, - MENU_ENUM_LABEL_INFORMATION, - FILE_TYPE_RDB_ENTRY, 0, idx); - - free(db_path); + if (settings->bools.quick_menu_show_information) + { + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_INFORMATION), + msg_hash_to_str(MENU_ENUM_LABEL_INFORMATION), + MENU_ENUM_LABEL_INFORMATION, MENU_SETTING_ACTION, 0, 0); + } } #ifdef HAVE_NETWORKING @@ -2690,6 +2689,249 @@ static unsigned menu_displaylist_parse_pl_thumbnail_download_list( } #endif +static unsigned menu_displaylist_parse_content_information( + menu_handle_t *menu, + menu_displaylist_info_t *info) +{ + settings_t *settings = config_get_ptr(); + playlist_t *playlist = playlist_get_cached(); + unsigned idx = menu->rpl_entry_selection_ptr; + const struct playlist_entry *entry = NULL; + const char *loaded_content_path = path_get(RARCH_PATH_CONTENT); + const char *loaded_core_path = path_get(RARCH_PATH_CORE); + const char *content_label = NULL; + const char *content_path = NULL; + const char *core_path = NULL; + const char *db_name = NULL; + bool content_loaded = false; + bool playlist_valid = false; + unsigned count = 0; + char core_name[PATH_MAX_LENGTH]; + char tmp[PATH_MAX_LENGTH]; + + core_name[0] = '\0'; + + if (!settings) + return count; + + content_loaded = !rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL) + && string_is_equal(menu->deferred_path, loaded_content_path); + + /* If content is currently running, have to make sure + * we have a valid playlist to work with + * (if content is not running, than playlist will always + * be valid provided that playlist_get_cached() does not + * return NULL) */ + if (content_loaded) + { + if (!string_is_empty(loaded_content_path) && !string_is_empty(loaded_core_path)) + playlist_valid = playlist_index_is_valid( + playlist, idx, loaded_content_path, loaded_core_path); + } + else if (playlist) + playlist_valid = true; + + if (playlist_valid) + { + /* If playlist is valid, all information is readily available */ + playlist_get_index(playlist, idx, &entry); + + if (entry) + { + content_label = entry->label; + content_path = entry->path; + core_path = entry->core_path; + db_name = entry->db_name; + + strlcpy(core_name, entry->core_name, sizeof(core_name)); + } + } + else + { + core_info_ctx_find_t core_info; + + /* No playlist - just extract what we can... */ + content_path = loaded_content_path; + core_path = loaded_core_path; + + core_info.inf = NULL; + core_info.path = core_path; + + if (core_info_find(&core_info, core_path)) + if (!string_is_empty(core_info.inf->display_name)) + strlcpy(core_name, core_info.inf->display_name, sizeof(core_name)); + } + + /* Content label */ + if (!string_is_empty(content_label)) + { + tmp[0] = '\0'; + + snprintf(tmp, sizeof(tmp), + "%s: %s", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_INFO_LABEL), content_label); + + if (menu_entries_append_enum(info->list, tmp, + msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_INFO_LABEL), + MENU_ENUM_LABEL_CONTENT_INFO_LABEL, + 0, 0, 0)) + count++; + } + + /* Content path */ + if (!string_is_empty(content_path)) + { + tmp[0] = '\0'; + + snprintf(tmp, sizeof(tmp), + "%s: %s", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_INFO_PATH), content_path); + + if (menu_entries_append_enum(info->list, tmp, + msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_INFO_PATH), + MENU_ENUM_LABEL_CONTENT_INFO_PATH, + 0, 0, 0)) + count++; + } + + /* Core name */ + if (!string_is_empty(core_name) && + !string_is_equal(core_name, file_path_str(FILE_PATH_DETECT))) + { + tmp[0] = '\0'; + + snprintf(tmp, sizeof(tmp), + "%s: %s", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_INFO_CORE_NAME), core_name); + + if (menu_entries_append_enum(info->list, tmp, + msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_INFO_CORE_NAME), + MENU_ENUM_LABEL_CONTENT_INFO_CORE_NAME, + 0, 0, 0)) + count++; + } + + /* Database */ + if (!string_is_empty(db_name)) + { + char *db_name_no_ext = NULL; + char db_name_no_ext_buff[PATH_MAX_LENGTH]; + + db_name_no_ext_buff[0] = '\0'; + + /* Remove .lpl extension + * > path_remove_extension() requires a char * (not const) + * so have to use a temporary buffer... */ + strlcpy(db_name_no_ext_buff, db_name, sizeof(db_name_no_ext_buff)); + db_name_no_ext = path_remove_extension(db_name_no_ext_buff); + + if (!string_is_empty(db_name_no_ext)) + { + tmp[0] = '\0'; + + snprintf(tmp, sizeof(tmp), + "%s: %s", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_INFO_DATABASE), db_name_no_ext); + + if (menu_entries_append_enum(info->list, tmp, + msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_INFO_DATABASE), + MENU_ENUM_LABEL_CONTENT_INFO_DATABASE, + 0, 0, 0)) + count++; + } + } + + /* Runtime */ + if (((settings->uints.playlist_sublabel_runtime_type == PLAYLIST_RUNTIME_PER_CORE) && + settings->bools.content_runtime_log) || + ((settings->uints.playlist_sublabel_runtime_type == PLAYLIST_RUNTIME_AGGREGATE) && + !settings->bools.content_runtime_log_aggregate)) + { + runtime_log_t *runtime_log = runtime_log_init( + content_path, core_path, + (settings->uints.playlist_sublabel_runtime_type == PLAYLIST_RUNTIME_PER_CORE)); + + if (runtime_log) + { + if (runtime_log_has_runtime(runtime_log)) + { + unsigned runtime_hours; + unsigned runtime_minutes; + unsigned runtime_seconds; + unsigned last_played_year; + unsigned last_played_month; + unsigned last_played_day; + unsigned last_played_hour; + unsigned last_played_minute; + unsigned last_played_second; + + /* Play time */ + runtime_log_get_runtime_hms(runtime_log, + &runtime_hours, &runtime_minutes, &runtime_seconds); + + tmp[0] = '\0'; + + snprintf(tmp, sizeof(tmp), + "%s: %02u:%02u:%02u", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_INFO_RUNTIME), + runtime_hours, runtime_minutes, runtime_seconds); + + if (menu_entries_append_enum(info->list, tmp, + msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_INFO_RUNTIME), + MENU_ENUM_LABEL_CONTENT_INFO_RUNTIME, + 0, 0, 0)) + count++; + + /* Last Played */ + runtime_log_get_last_played(runtime_log, + &last_played_year, &last_played_month, &last_played_day, + &last_played_hour, &last_played_minute, &last_played_second); + + tmp[0] = '\0'; + + snprintf(tmp, sizeof(tmp), + "%s: %04u/%02u/%02u - %02u:%02u:%02u", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_INFO_LAST_PLAYED), + last_played_year, last_played_month, last_played_day, + last_played_hour, last_played_minute, last_played_second); + + if (menu_entries_append_enum(info->list, tmp, + msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_INFO_LAST_PLAYED), + MENU_ENUM_LABEL_CONTENT_INFO_LAST_PLAYED, + 0, 0, 0)) + count++; + } + + free(runtime_log); + } + } + +#ifdef HAVE_LIBRETRODB + + /* Database entry */ + if (!string_is_empty(db_name)) + { + char db_path[PATH_MAX_LENGTH]; + + db_path[0] = '\0'; + + fill_pathname_join_noext(db_path, + settings->paths.path_content_database, + db_name, + sizeof(db_path)); + strlcat(db_path, + file_path_str(FILE_PATH_RDB_EXTENSION), + sizeof(db_path)); + + if (path_is_valid(db_path)) + if (menu_entries_append_enum(info->list, + entry->label, + db_path, + MENU_ENUM_LABEL_RDB_ENTRY_DETAIL, + FILE_TYPE_RDB_ENTRY, 0, 0)) + count++; + } + +#endif + + return count; +} + static bool menu_displaylist_push_internal( const char *label, menu_displaylist_ctx_entry_t *entry, @@ -4802,6 +5044,20 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, info->need_push = true; /* TODO/FIXME ? */ break; + case DISPLAYLIST_INFORMATION: + menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); + count = menu_displaylist_parse_content_information(menu, info); + + if (count == 0) + 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); + + info->need_push = true; + info->need_refresh = true; + break; case DISPLAYLIST_DATABASE_ENTRY: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); { diff --git a/menu/menu_displaylist.h b/menu/menu_displaylist.h index e0283a6460..7781d43b32 100644 --- a/menu/menu_displaylist.h +++ b/menu/menu_displaylist.h @@ -175,6 +175,7 @@ enum menu_displaylist_ctl_state DISPLAYLIST_LOAD_CONTENT_LIST, DISPLAYLIST_LOAD_CONTENT_SPECIAL, DISPLAYLIST_INFORMATION_LIST, + DISPLAYLIST_INFORMATION, DISPLAYLIST_CONTENT_SETTINGS, DISPLAYLIST_OPTIONS, DISPLAYLIST_OPTIONS_CHEATS, diff --git a/msg_hash.h b/msg_hash.h index 7291224d9e..6fd8a8db44 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1229,6 +1229,7 @@ enum msg_hash_enums MENU_ENUM_LABEL_DEFERRED_ACCOUNTS_TWITCH_LIST, MENU_ENUM_LABEL_DEFERRED_ACCOUNTS_YOUTUBE_LIST, MENU_ENUM_LABEL_DEFERRED_ACCOUNTS_LIST, + MENU_ENUM_LABEL_DEFERRED_INFORMATION, MENU_LABEL(FILE_DETECT_CORE_LIST_PUSH_DIR), MENU_LABEL(DOWNLOADED_FILE_DETECT_CORE_LIST), @@ -1596,6 +1597,15 @@ enum msg_hash_enums MENU_LABEL(RDB_ENTRY_SHA1), MENU_LABEL(RDB_ENTRY_MD5), MENU_LABEL(RDB_ENTRY_CRC32), + MENU_LABEL(RDB_ENTRY_DETAIL), + + /* Content information settings */ + MENU_LABEL(CONTENT_INFO_LABEL), + MENU_LABEL(CONTENT_INFO_PATH), + MENU_LABEL(CONTENT_INFO_CORE_NAME), + MENU_LABEL(CONTENT_INFO_DATABASE), + MENU_LABEL(CONTENT_INFO_RUNTIME), + MENU_LABEL(CONTENT_INFO_LAST_PLAYED), MENU_LABEL(NO_PLAYLIST_ENTRIES_AVAILABLE), @@ -2458,6 +2468,7 @@ enum msg_hash_enums #define MENU_LABEL_DEFERRED_INPUT_HOTKEY_BINDS_LIST 0x10b41d97U #define MENU_LABEL_DEFERRED_CONFIGURATIONS_LIST 0x679a1b0bU #define MENU_LABEL_DEFERRED_BROWSE_URL_START 0xcef58296U +#define MENU_LABEL_DEFERRED_INFORMATION 0x3FCC9F2BU /* Cheevos settings */ @@ -2478,6 +2489,8 @@ enum msg_hash_enums #define MENU_LABEL_INFORMATION_LIST 0x225e7606U +#define MENU_LABEL_INFORMATION 0x81E8DC6BU + #define MENU_LABEL_CONTENT_SETTINGS 0xe789f7f6U #define MENU_LABEL_SCREEN_RESOLUTION 0x5c9b3a58U From c03b20db55882acff717ae0ff019fcb6b127a67f Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Fri, 7 Jun 2019 11:23:06 +0100 Subject: [PATCH 2/2] - Hide content information 'Database Entry' item if content has no label - Correctly handle error conditions in menu_displaylist 'DISPLAYLIST_DATABASE_ENTRY' case (i.e. prevent segfaults/menu lockups when content has no label) --- menu/drivers/xmb.c | 3 +-- menu/menu_displaylist.c | 56 ++++++++++++++++++++++++++++++----------- 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 4cd0f08d17..a835f630c1 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -2947,8 +2947,7 @@ static int xmb_draw_item( ticker_limit = 70 * scale_mod[2]; } - if (!string_is_empty(entry->path)) - menu_entry_get_rich_label(entry, &ticker_str); + menu_entry_get_rich_label(entry, &ticker_str); ticker.s = tmp; ticker.len = ticker_limit; diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index eb41119fba..4c9c6b7dfa 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -2796,11 +2796,17 @@ static unsigned menu_displaylist_parse_content_information( if (!string_is_empty(core_name) && !string_is_equal(core_name, file_path_str(FILE_PATH_DETECT))) { + int n = 0; tmp[0] = '\0'; - snprintf(tmp, sizeof(tmp), + n = snprintf(tmp, sizeof(tmp), "%s: %s", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_INFO_CORE_NAME), core_name); + /* Silence gcc compiler warning + * (getting so sick of these...) */ + if ((n < 0) || (n >= PATH_MAX_LENGTH)) + n = 0; + if (menu_entries_append_enum(info->list, tmp, msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_INFO_CORE_NAME), MENU_ENUM_LABEL_CONTENT_INFO_CORE_NAME, @@ -2904,7 +2910,7 @@ static unsigned menu_displaylist_parse_content_information( #ifdef HAVE_LIBRETRODB /* Database entry */ - if (!string_is_empty(db_name)) + if (!string_is_empty(content_label) && !string_is_empty(db_name)) { char db_path[PATH_MAX_LENGTH]; @@ -2920,7 +2926,7 @@ static unsigned menu_displaylist_parse_content_information( if (path_is_valid(db_path)) if (menu_entries_append_enum(info->list, - entry->label, + content_label, db_path, MENU_ENUM_LABEL_RDB_ENTRY_DETAIL, FILE_TYPE_RDB_ENTRY, 0, 0)) @@ -5061,27 +5067,47 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, case DISPLAYLIST_DATABASE_ENTRY: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); { - struct string_list *str_list = string_split(info->label, "|"); + bool parse_database = false; + struct string_list *str_list = NULL; - if (!str_list) - return false; - - if (!string_is_empty(info->path_b)) - free(info->path_b); if (!string_is_empty(info->label)) + { + str_list = string_split(info->label, "|"); free(info->label); + info->label = NULL; + } + if (!string_is_empty(info->path_b)) + { + free(info->path_b); + info->path_b = NULL; + } - info->path_b = strdup(str_list->elems[1].data); - info->label = strdup(str_list->elems[0].data); + if (str_list) + { + if (str_list->size > 1) + { + if (!string_is_empty(str_list->elems[0].data) && + !string_is_empty(str_list->elems[1].data)) + { + info->path_b = strdup(str_list->elems[1].data); + info->label = strdup(str_list->elems[0].data); + parse_database = true; + } + } - string_list_free(str_list); - } + string_list_free(str_list); + } #ifdef HAVE_LIBRETRODB - ret = menu_displaylist_parse_database_entry(menu, info); + if (parse_database) + ret = menu_displaylist_parse_database_entry(menu, info); + else + info->need_push_no_playlist_entries = true; #else - ret = 0; + ret = 0; + info->need_push_no_playlist_entries = true; #endif + } info->need_push = true; break;