/* RetroArch - A frontend for libretro. * Copyright (C) 2011-2015 - Daniel De Matteis * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ #include #include "menu.h" #include "menu_entries_cbs.h" #include "menu_setting.h" #include "menu_entries.h" #include "../file_ext.h" #include "../retroarch.h" #include "../performance.h" #ifdef HAVE_NETWORKING #include "../net_http.h" #endif #ifdef HAVE_LIBRETRODB #include "../database_info.h" #endif #include "menu_database.h" #ifdef HAVE_LIBRETRODB static int create_string_list_rdb_entry_string(const char *desc, const char *label, const char *actual_string, const char *path, file_list_t *list) { char tmp[PATH_MAX_LENGTH]; union string_list_elem_attr attr; char *output_label = NULL; int str_len = 0; struct string_list *str_list = string_list_new(); if (!str_list) return -1; str_len += strlen(label) + 1; string_list_append(str_list, label, attr); str_len += strlen(actual_string) + 1; string_list_append(str_list, actual_string, attr); 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); return -1; } string_list_join_concat(output_label, str_len, str_list, "|"); snprintf(tmp, sizeof(tmp), "%s: %s", desc, actual_string); menu_list_push(list, tmp, output_label, 0, 0); if (output_label) free(output_label); string_list_free(str_list); str_list = NULL; return 0; } static int create_string_list_rdb_entry_int(const char *desc, const char *label, int actual_int, const char *path, file_list_t *list) { char tmp[PATH_MAX_LENGTH]; union string_list_elem_attr attr; char str[PATH_MAX_LENGTH]; char *output_label = NULL; int str_len = 0; struct string_list *str_list = string_list_new(); if (!str_list) return -1; str_len += strlen(label) + 1; string_list_append(str_list, label, attr); snprintf(str, sizeof(str), "%d", actual_int); str_len += strlen(str) + 1; string_list_append(str_list, str, attr); 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); return -1; } string_list_join_concat(output_label, str_len, str_list, "|"); snprintf(tmp, sizeof(tmp), "%s: %d", desc, actual_int); menu_list_push(list, tmp, output_label, 0, 0); if (output_label) free(output_label); string_list_free(str_list); str_list = NULL; return 0; } #endif static int deferred_push_core_information(void *data, void *userdata, const char *path, const char *label, unsigned type) { unsigned i; core_info_t *info = NULL; file_list_t *list = (file_list_t*)data; file_list_t *menu_list = (file_list_t*)userdata; if (!list || !menu_list) return -1; info = (core_info_t*)g_extern.core_info_current; menu_list_clear(list); if (info->data) { char tmp[PATH_MAX_LENGTH]; snprintf(tmp, sizeof(tmp), "Core name: %s", info->core_name ? info->core_name : ""); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); snprintf(tmp, sizeof(tmp), "Core label: %s", info->display_name ? info->display_name : ""); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); if (info->systemname) { snprintf(tmp, sizeof(tmp), "System name: %s", info->systemname); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); } if (info->system_manufacturer) { snprintf(tmp, sizeof(tmp), "System manufacturer: %s", info->system_manufacturer); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); } if (info->categories_list) { strlcpy(tmp, "Categories: ", sizeof(tmp)); string_list_join_concat(tmp, sizeof(tmp), info->categories_list, ", "); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); } if (info->authors_list) { strlcpy(tmp, "Authors: ", sizeof(tmp)); string_list_join_concat(tmp, sizeof(tmp), info->authors_list, ", "); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); } if (info->permissions_list) { strlcpy(tmp, "Permissions: ", sizeof(tmp)); string_list_join_concat(tmp, sizeof(tmp), info->permissions_list, ", "); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); } if (info->licenses_list) { strlcpy(tmp, "License(s): ", sizeof(tmp)); string_list_join_concat(tmp, sizeof(tmp), info->licenses_list, ", "); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); } if (info->supported_extensions_list) { strlcpy(tmp, "Supported extensions: ", sizeof(tmp)); string_list_join_concat(tmp, sizeof(tmp), info->supported_extensions_list, ", "); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); } if (info->firmware_count > 0) { core_info_list_update_missing_firmware( g_extern.core_info, info->path, g_settings.system_directory); menu_list_push(list, "Firmware: ", "", MENU_SETTINGS_CORE_INFO_NONE, 0); for (i = 0; i < info->firmware_count; i++) { if (info->firmware[i].desc) { snprintf(tmp, sizeof(tmp), " name: %s", info->firmware[i].desc ? info->firmware[i].desc : ""); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); snprintf(tmp, sizeof(tmp), " status: %s, %s", info->firmware[i].missing ? "missing" : "present", info->firmware[i].optional ? "optional" : "required"); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); } } } if (info->notes) { snprintf(tmp, sizeof(tmp), "Core notes: "); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); for (i = 0; i < info->note_list->size; i++) { snprintf(tmp, sizeof(tmp), " %s", info->note_list->elems[i].data); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); } } } else menu_list_push(list, "No information available.", "", MENU_SETTINGS_CORE_OPTION_NONE, 0); if (driver.menu_ctx && driver.menu_ctx->populate_entries) driver.menu_ctx->populate_entries(path, label, type); return 0; } static int deferred_push_rdb_entry_detail(void *data, void *userdata, const char *path, const char *label, unsigned type) { int ret = 0; #ifdef HAVE_LIBRETRODB content_playlist_t *playlist; char query[PATH_MAX_LENGTH]; char path_rdl[PATH_MAX_LENGTH], path_base[PATH_MAX_LENGTH]; unsigned i, j; database_info_list_t *db_info = NULL; file_list_t *list = NULL; file_list_t *menu_list = NULL; struct string_list *str_list = NULL; menu_handle_t *menu = menu_driver_resolve(); if (!menu) return -1; list = (file_list_t*)data; menu_list = (file_list_t*)userdata; str_list = string_split(label, "|"); if (!str_list) return -1; if (!list || !menu_list) { ret = -1; goto done; } strlcpy(query, "{'name':\"", sizeof(query)); strlcat(query, str_list->elems[1].data, sizeof(query)); strlcat(query, "\"}", sizeof(query)); menu_list_clear(list); if (!(db_info = database_info_list_new(path, query))) { ret = -1; goto done; } strlcpy(path_base, path_basename(path), sizeof(path_base)); path_remove_extension(path_base); strlcat(path_base, ".rdl", sizeof(path_base)); fill_pathname_join(path_rdl, g_settings.content_database, path_base, sizeof(path_rdl)); menu_database_realloc(path_rdl, false); playlist = menu->db_playlist; for (i = 0; i < db_info->count; i++) { char tmp[PATH_MAX_LENGTH]; database_info_t *db_info_entry = &db_info->list[i]; if (!db_info_entry) continue; if (db_info_entry->name) { snprintf(tmp, sizeof(tmp), "Name: %s", db_info_entry->name); menu_list_push(list, tmp, "rdb_entry_name", 0, 0); } if (db_info_entry->description) { snprintf(tmp, sizeof(tmp), "Description: %s", db_info_entry->description); menu_list_push(list, tmp, "rdb_entry_description", 0, 0); } if (db_info_entry->publisher) { if (create_string_list_rdb_entry_string("Publisher", "rdb_entry_publisher", db_info_entry->publisher, path, list) == -1) return -1; } if (db_info_entry->developer) { if (create_string_list_rdb_entry_string("Developer", "rdb_entry_developer", db_info_entry->developer, path, list) == -1) return -1; } if (db_info_entry->origin) { if (create_string_list_rdb_entry_string("Origin", "rdb_entry_origin", db_info_entry->origin, path, list) == -1) return -1; } if (db_info_entry->franchise) { if (create_string_list_rdb_entry_string("Franchise", "rdb_entry_franchise", db_info_entry->franchise, path, list) == -1) return -1; } if (db_info_entry->max_users) { if (create_string_list_rdb_entry_int("Max Users", "rdb_entry_max_users", db_info_entry->max_users, path, list) == -1) return -1; } if (db_info_entry->famitsu_magazine_rating) { if (create_string_list_rdb_entry_int("Famitsu Magazine Rating", "rdb_entry_famitsu_magazine_rating", db_info_entry->famitsu_magazine_rating, path, list) == -1) return -1; } if (db_info_entry->edge_magazine_review) { if (create_string_list_rdb_entry_string("Edge Magazine Review", "rdb_entry_edge_magazine_review", db_info_entry->edge_magazine_review, path, list) == -1) return -1; } if (db_info_entry->edge_magazine_rating) { if (create_string_list_rdb_entry_int("Edge Magazine Rating", "rdb_entry_edge_magazine_rating", db_info_entry->edge_magazine_rating, path, list) == -1) return -1; } if (db_info_entry->edge_magazine_issue) { if (create_string_list_rdb_entry_int("Edge Magazine Issue", "rdb_entry_edge_magazine_issue", db_info_entry->edge_magazine_issue, path, list) == -1) return -1; } if (db_info_entry->releasemonth) { if (create_string_list_rdb_entry_int("Releasedate Month", "rdb_entry_releasemonth", db_info_entry->releasemonth, path, list) == -1) return -1; } if (db_info_entry->releaseyear) { if (create_string_list_rdb_entry_int("Releasedate Year", "rdb_entry_releaseyear", db_info_entry->releaseyear, path, list) == -1) return -1; } if (db_info_entry->bbfc_rating) { if (create_string_list_rdb_entry_string("BBFC Rating", "rdb_entry_bbfc_rating", db_info_entry->bbfc_rating, path, list) == -1) return -1; } if (db_info_entry->esrb_rating) { if (create_string_list_rdb_entry_string("ESRB Rating", "rdb_entry_esrb_rating", db_info_entry->esrb_rating, path, list) == -1) return -1; } if (db_info_entry->elspa_rating) { if (create_string_list_rdb_entry_string("ELSPA Rating", "rdb_entry_elspa_rating", db_info_entry->elspa_rating, path, list) == -1) return -1; } if (db_info_entry->pegi_rating) { if (create_string_list_rdb_entry_string("PEGI Rating", "rdb_entry_pegi_rating", db_info_entry->pegi_rating, path, list) == -1) return -1; } if (db_info_entry->enhancement_hw) { if (create_string_list_rdb_entry_string("Enhancement Hardware", "rdb_entry_enhancement_hw", db_info_entry->enhancement_hw, path, list) == -1) return -1; } if (db_info_entry->cero_rating) { if (create_string_list_rdb_entry_string("CERO Rating", "rdb_entry_cero_rating", db_info_entry->cero_rating, path, list) == -1) return -1; } snprintf(tmp, sizeof(tmp), "Analog supported: %s", (db_info_entry->analog_supported == 1) ? "true" : (db_info_entry->analog_supported == -1) ? "N/A" : "false"); menu_list_push(list, tmp, "rdb_entry_analog", 0, 0); snprintf(tmp, sizeof(tmp), "Rumble supported: %s", (db_info_entry->rumble_supported == 1) ? "true" : (db_info_entry->rumble_supported == -1) ? "N/A" : "false"); menu_list_push(list, tmp, "rdb_entry_rumble", 0, 0); if (db_info_entry->crc32) { if (create_string_list_rdb_entry_string("CRC32 Checksum", "rdb_entry_crc32", db_info_entry->crc32, path, list) == -1) return -1; } if (db_info_entry->sha1) { if (create_string_list_rdb_entry_string("SHA1 Checksum", "rdb_entry_sha1", db_info_entry->sha1, path, list) == -1) return -1; } if (db_info_entry->md5) { if (create_string_list_rdb_entry_string("MD5 Checksum", "rdb_entry_md5", db_info_entry->md5, path, list) == -1) return -1; } if (playlist) { for (j = 0; j < playlist->size; j++) { char elem0[PATH_MAX_LENGTH], elem1[PATH_MAX_LENGTH]; bool match_found = false; struct string_list *tmp_str_list = string_split( playlist->entries[j].core_name, "|"); if (!tmp_str_list) continue; if (tmp_str_list->size > 0) strlcpy(elem0, tmp_str_list->elems[0].data, sizeof(elem0)); if (tmp_str_list->size > 1) strlcpy(elem1, tmp_str_list->elems[1].data, sizeof(elem1)); if (!strcmp(elem1, "crc")) { if (!strcmp(db_info_entry->crc32, elem0)) match_found = true; } else if (!strcmp(elem1, "sha1")) { if (!strcmp(db_info_entry->sha1, elem0)) match_found = true; } else if (!strcmp(elem1, "md5")) { if (!strcmp(db_info_entry->md5, elem0)) match_found = true; } string_list_free(tmp_str_list); if (!match_found) continue; rdb_entry_start_game_selection_ptr = j; menu_list_push(list, "Start Content", "rdb_entry_start_game", MENU_FILE_PLAYLIST_ENTRY, 0); } } } if (db_info->count < 1) menu_list_push(list, "No information available.", "", 0, 0); if (driver.menu_ctx && driver.menu_ctx->populate_entries) driver.menu_ctx->populate_entries(path, str_list->elems[0].data, type); ret = 0; done: string_list_free(str_list); #endif return ret; } static int deferred_push_core_list_deferred(void *data, void *userdata, const char *path, const char *label, unsigned type) { unsigned i; size_t list_size = 0; const core_info_t *info = NULL; file_list_t *list = NULL; file_list_t *menu_list = NULL; menu_handle_t *menu = menu_driver_resolve(); if (!menu) return -1; list = (file_list_t*)data; menu_list = (file_list_t*)userdata; if (!list || !menu_list) return -1; menu_list_clear(list); core_info_list_get_supported_cores(g_extern.core_info, menu->deferred_path, &info, &list_size); for (i = 0; i < list_size; i++) { menu_list_push(list, info[i].path, "", MENU_FILE_CORE, 0); menu_list_set_alt_at_offset(list, i, info[i].display_name); } menu_list_sort_on_alt(list); menu_list_populate_generic(list, path, label, type); return 0; } static int deferred_push_database_manager_list_deferred(void *data, void *userdata, const char *path, const char *label, unsigned type) { file_list_t *list = NULL; file_list_t *menu_list = NULL; menu_handle_t *menu = menu_driver_resolve(); if (!menu) return -1; list = (file_list_t*)data; menu_list = (file_list_t*)userdata; if (!list || !menu_list) return -1; menu_list_clear(list); menu_database_populate_query(list, path, NULL); menu_list_sort_on_alt(list); menu_list_populate_generic(list, path, label, type); return 0; } static int deferred_push_cursor_manager_list_deferred(void *data, void *userdata, const char *path, const char *label, unsigned type) { char *query = NULL, *rdb = NULL; char rdb_path[PATH_MAX_LENGTH]; config_file_t *conf = NULL; file_list_t *list = NULL; file_list_t *menu_list = NULL; menu_handle_t *menu = menu_driver_resolve(); if (!menu) return -1; list = (file_list_t*)data; menu_list = (file_list_t*)userdata; if (!list || !menu_list) return -1; menu_list_clear(list); conf = config_file_new(path); if (!conf) return -1; if (!config_get_string(conf, "query", &query)) return -1; if (!config_get_string(conf, "rdb", &rdb)) return -1; fill_pathname_join(rdb_path, g_settings.content_database, rdb, sizeof(rdb_path)); menu_database_populate_query(list, rdb_path, query); menu_list_sort_on_alt(list); menu_list_populate_generic(list, path, label, type); return 0; } static int deferred_push_cursor_manager_list_deferred_query_subsearch( void *data, void *userdata, const char *path, const char *label, unsigned type) { char query[PATH_MAX_LENGTH]; struct string_list *str_list = NULL; bool add_quotes = true; file_list_t *list = NULL; file_list_t *menu_list = NULL; menu_handle_t *menu = menu_driver_resolve(); if (!menu) return -1; str_list = string_split(path, "|"); list = (file_list_t*)data; menu_list = (file_list_t*)userdata; if (!list || !menu_list) { string_list_free(str_list); return -1; } strlcpy(query, "{'", sizeof(query)); if (!strcmp(label, "deferred_cursor_manager_list_rdb_entry_publisher")) strlcat(query, "publisher", sizeof(query)); else if (!strcmp(label, "deferred_cursor_manager_list_rdb_entry_developer")) strlcat(query, "developer", sizeof(query)); else if (!strcmp(label, "deferred_cursor_manager_list_rdb_entry_origin")) strlcat(query, "origin", sizeof(query)); else if (!strcmp(label, "deferred_cursor_manager_list_rdb_entry_franchise")) strlcat(query, "franchise", sizeof(query)); else if (!strcmp(label, "deferred_cursor_manager_list_rdb_entry_esrb_rating")) strlcat(query, "esrb_rating", sizeof(query)); else if (!strcmp(label, "deferred_cursor_manager_list_rdb_entry_bbfc_rating")) strlcat(query, "bbfc_rating", sizeof(query)); else if (!strcmp(label, "deferred_cursor_manager_list_rdb_entry_elspa_rating")) strlcat(query, "elspa_rating", sizeof(query)); else if (!strcmp(label, "deferred_cursor_manager_list_rdb_entry_pegi_rating")) strlcat(query, "pegi_rating", sizeof(query)); else if (!strcmp(label, "deferred_cursor_manager_list_rdb_entry_enhancement_hw")) strlcat(query, "enhancement_hw", sizeof(query)); else if (!strcmp(label, "deferred_cursor_manager_list_rdb_entry_cero_rating")) strlcat(query, "cero_rating", sizeof(query)); else if (!strcmp(label, "deferred_cursor_manager_list_rdb_entry_edge_magazine_rating")) { strlcat(query, "edge_rating", sizeof(query)); add_quotes = false; } else if (!strcmp(label, "deferred_cursor_manager_list_rdb_entry_edge_magazine_issue")) { strlcat(query, "edge_issue", sizeof(query)); add_quotes = false; } else if (!strcmp(label, "deferred_cursor_manager_list_rdb_entry_famitsu_magazine_rating")) { strlcat(query, "famitsu_rating", sizeof(query)); add_quotes = false; } else if (!strcmp(label, "deferred_cursor_manager_list_rdb_entry_releasemonth")) { strlcat(query, "releasemonth", sizeof(query)); add_quotes = false; } else if (!strcmp(label, "deferred_cursor_manager_list_rdb_entry_releaseyear")) { strlcat(query, "releaseyear", sizeof(query)); add_quotes = false; } else if (!strcmp(label, "deferred_cursor_manager_list_rdb_entry_max_users")) { strlcat(query, "users", sizeof(query)); add_quotes = false; } strlcat(query, "':", sizeof(query)); if (add_quotes) strlcat(query, "\"", sizeof(query)); strlcat(query, str_list->elems[0].data, sizeof(query)); if (add_quotes) strlcat(query, "\"", sizeof(query)); strlcat(query, "}", sizeof(query)); #if 0 RARCH_LOG("query: %s\n", query); #endif if (query[0] == '\0') { string_list_free(str_list); return -1; } menu_list_clear(list); menu_database_populate_query(list, str_list->elems[1].data, query); menu_list_sort_on_alt(list); menu_list_populate_generic(list, str_list->elems[0].data, label, type); string_list_free(str_list); return 0; } #if 0 static int deferred_push_core_information(void *data, void *userdata, const char *path, const char *label, unsigned type) { unsigned i; core_info_t *info = NULL; file_list_t *list = (file_list_t*)data; file_list_t *menu_list = (file_list_t*)userdata; if (!list || !menu_list) return -1; info = (core_info_t*)g_extern.core_info_current; menu_list_clear(list); if (info->data) { char tmp[PATH_MAX_LENGTH]; snprintf(tmp, sizeof(tmp), "Core name: %s", info->core_name ? info->core_name : ""); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); snprintf(tmp, sizeof(tmp), "Core label: %s", info->display_name ? info->display_name : ""); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); if (info->systemname) { snprintf(tmp, sizeof(tmp), "System name: %s", info->systemname); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); } if (info->system_manufacturer) { snprintf(tmp, sizeof(tmp), "System manufacturer: %s", info->system_manufacturer); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); } if (info->categories_list) { strlcpy(tmp, "Categories: ", sizeof(tmp)); string_list_join_concat(tmp, sizeof(tmp), info->categories_list, ", "); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); } if (info->authors_list) { strlcpy(tmp, "Authors: ", sizeof(tmp)); string_list_join_concat(tmp, sizeof(tmp), info->authors_list, ", "); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); } if (info->permissions_list) { strlcpy(tmp, "Permissions: ", sizeof(tmp)); string_list_join_concat(tmp, sizeof(tmp), info->permissions_list, ", "); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); } if (info->licenses_list) { strlcpy(tmp, "License(s): ", sizeof(tmp)); string_list_join_concat(tmp, sizeof(tmp), info->licenses_list, ", "); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); } if (info->supported_extensions_list) { strlcpy(tmp, "Supported extensions: ", sizeof(tmp)); string_list_join_concat(tmp, sizeof(tmp), info->supported_extensions_list, ", "); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); } if (info->firmware_count > 0) { core_info_list_update_missing_firmware( g_extern.core_info, info->path, g_settings.system_directory); menu_list_push(list, "Firmware: ", "", MENU_SETTINGS_CORE_INFO_NONE, 0); for (i = 0; i < info->firmware_count; i++) { if (info->firmware[i].desc) { snprintf(tmp, sizeof(tmp), " name: %s", info->firmware[i].desc ? info->firmware[i].desc : ""); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); snprintf(tmp, sizeof(tmp), " status: %s, %s", info->firmware[i].missing ? "missing" : "present", info->firmware[i].optional ? "optional" : "required"); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); } } } if (info->notes) { snprintf(tmp, sizeof(tmp), "Core notes: "); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); for (i = 0; i < info->note_list->size; i++) { snprintf(tmp, sizeof(tmp), " %s", info->note_list->elems[i].data); menu_list_push(list, tmp, "", MENU_SETTINGS_CORE_INFO_NONE, 0); } } } else menu_list_push(list, "No information available.", "", MENU_SETTINGS_CORE_OPTION_NONE, 0); if (driver.menu_ctx && driver.menu_ctx->populate_entries) driver.menu_ctx->populate_entries(path, label, type); return 0; } #endif static int deferred_push_performance_counters(void *data, void *userdata, const char *path, const char *label, unsigned type) { file_list_t *list = (file_list_t*)data; file_list_t *menu_list = (file_list_t*)userdata; if (!list || !menu_list) return -1; menu_list_clear(list); menu_list_push(list, "Frontend Counters", "frontend_counters", MENU_SETTING_ACTION, 0); menu_list_push(list, "Core Counters", "core_counters", MENU_SETTING_ACTION, 0); if (driver.menu_ctx && driver.menu_ctx->populate_entries) driver.menu_ctx->populate_entries(path, label, type); return 0; } static int deferred_push_video_shader_parameters_common(void *data, void *userdata, const char *path, const char *label, unsigned type, struct video_shader *shader, unsigned base_parameter) { unsigned i; file_list_t *list = (file_list_t*)data; file_list_t *menu_list = (file_list_t*)userdata; if (!list || !menu_list) return -1; menu_list_clear(list); for (i = 0; i < shader->num_parameters; i++) { menu_list_push(list, shader->parameters[i].desc, label, base_parameter + i, 0); } if (driver.menu_ctx && driver.menu_ctx->populate_entries) driver.menu_ctx->populate_entries(path, label, type); return 0; } static int deferred_push_video_shader_preset_parameters(void *data, void *userdata, const char *path, const char *label, unsigned type) { menu_handle_t *menu = menu_driver_resolve(); if (!menu) return -1; if (!menu->shader) return 0; return deferred_push_video_shader_parameters_common(data, userdata, path, label, type, menu->shader, MENU_SETTINGS_SHADER_PRESET_PARAMETER_0); } static int deferred_push_video_shader_parameters(void *data, void *userdata, const char *path, const char *label, unsigned type) { #ifdef HAVE_SHADER_MANAGER struct video_shader *shader = video_shader_driver_get_current_shader(); if (!shader) return 0; return deferred_push_video_shader_parameters_common(data, userdata, path, label, type, shader, MENU_SETTINGS_SHADER_PARAMETER_0); #else return 0; #endif } static int deferred_push_settings(void *data, void *userdata, const char *path, const char *label, unsigned type) { rarch_setting_t *setting = NULL; file_list_t *list = NULL; file_list_t *menu_list = NULL; menu_handle_t *menu = menu_driver_resolve(); if (!menu) return -1; list = (file_list_t*)data; menu_list = (file_list_t*)userdata; if (!list || !menu_list) return -1; settings_list_free(menu->list_settings); menu->list_settings = (rarch_setting_t *)setting_data_new(SL_FLAG_ALL_SETTINGS); setting = menu_setting_find("Driver Settings"); menu_list_clear(list); if (g_settings.menu.collapse_subgroups_enable) { for (; setting->type != ST_NONE; setting++) { if (setting->type == ST_GROUP) menu_list_push(list, setting->short_description, setting->name, menu_entries_setting_set_flags(setting), 0); } } else { for (; setting->type != ST_NONE; setting++) { char group_label[PATH_MAX_LENGTH]; char subgroup_label[PATH_MAX_LENGTH]; if (setting->type == ST_GROUP) strlcpy(group_label, setting->name, sizeof(group_label)); else if (setting->type == ST_SUB_GROUP) { char new_label[PATH_MAX_LENGTH], new_path[PATH_MAX_LENGTH]; strlcpy(subgroup_label, setting->name, sizeof(group_label)); strlcpy(new_label, group_label, sizeof(new_label)); strlcat(new_label, "|", sizeof(new_label)); strlcat(new_label, subgroup_label, sizeof(new_label)); strlcpy(new_path, group_label, sizeof(new_path)); strlcat(new_path, " - ", sizeof(new_path)); strlcat(new_path, setting->short_description, sizeof(new_path)); menu_list_push(list, new_path, new_label, MENU_SETTING_SUBGROUP, 0); } } } if (driver.menu_ctx && driver.menu_ctx->populate_entries) driver.menu_ctx->populate_entries(path, label, type); return 0; } static int deferred_push_settings_subgroup(void *data, void *userdata, const char *path, const char *label, unsigned type) { char elem0[PATH_MAX_LENGTH], elem1[PATH_MAX_LENGTH]; rarch_setting_t *setting = NULL; struct string_list *str_list = NULL; file_list_t *list = NULL; file_list_t *menu_list = NULL; menu_handle_t *menu = menu_driver_resolve(); if (!menu) return -1; list = (file_list_t*)data; menu_list = (file_list_t*)userdata; if (!list || !menu_list) return -1; if (label) { str_list = string_split(label, "|"); if (str_list && str_list->size > 0) strlcpy(elem0, str_list->elems[0].data, sizeof(elem0)); if (str_list && str_list->size > 1) strlcpy(elem1, str_list->elems[1].data, sizeof(elem1)); if (str_list) { string_list_free(str_list); str_list = NULL; } } settings_list_free(menu->list_settings); menu->list_settings = (rarch_setting_t *)setting_data_new(SL_FLAG_ALL_SETTINGS); setting = menu_setting_find(elem0); menu_list_clear(list); if (!setting) return -1; while (1) { if (!setting) return -1; if (setting->type == ST_SUB_GROUP) { if ((strlen(setting->name) != 0) && !strcmp(setting->name, elem1)) break; } setting++; } setting++; for (; setting->type != ST_END_SUB_GROUP; setting++) { char group_label[PATH_MAX_LENGTH]; strlcpy(group_label, setting->name, sizeof(group_label)); menu_list_push(list, setting->short_description, group_label, menu_entries_setting_set_flags(setting), 0); } if (driver.menu_ctx && driver.menu_ctx->populate_entries) driver.menu_ctx->populate_entries(path, label, type); return 0; } static int deferred_push_category(void *data, void *userdata, const char *path, const char *label, unsigned type) { menu_handle_t *menu = menu_driver_resolve(); if (!menu) return -1; return menu_entries_push_list(menu, (file_list_t*)data, path, label, type, SL_FLAG_ALL_SETTINGS); } static int deferred_push_video_options(void *data, void *userdata, const char *path, const char *label, unsigned type) { file_list_t *list = NULL; file_list_t *menu_list = NULL; menu_handle_t *menu = menu_driver_resolve(); if (!menu) return -1; list = (file_list_t*)data; menu_list = (file_list_t*)userdata; if (!list || !menu_list) return -1; menu_list_clear(list); #if defined(GEKKO) || defined(__CELLOS_LV2__) menu_list_push(list, "Screen Resolution", "", MENU_SETTINGS_VIDEO_RESOLUTION, 0); #endif menu_list_push(list, "Custom Ratio", "", MENU_SETTINGS_CUSTOM_VIEWPORT, 0); #ifndef HAVE_FILTERS_BUILTIN menu_list_push(list, "Video Filter", "video_filter", 0, 0); #endif if (driver.menu_ctx && driver.menu_ctx->populate_entries) driver.menu_ctx->populate_entries(path, label, type); return 0; } static int deferred_push_shader_options(void *data, void *userdata, const char *path, const char *label, unsigned type) { unsigned i; struct video_shader *shader = NULL; file_list_t *list = NULL; file_list_t *menu_list = NULL; menu_handle_t *menu = menu_driver_resolve(); if (!menu) return -1; list = (file_list_t*)data; menu_list = (file_list_t*)userdata; if (!list || !menu_list) return -1; shader = menu->shader; if (!shader) return -1; menu_list_clear(list); menu_list_push(list, "Apply Shader Changes", "shader_apply_changes", MENU_SETTING_ACTION, 0); menu_list_push(list, "Load Shader Preset", "video_shader_preset", MENU_SETTING_ACTION, 0); menu_list_push(list, "Shader Preset Save As", "video_shader_preset_save_as", MENU_SETTING_ACTION, 0); menu_list_push(list, "Parameters (Current)", "video_shader_parameters", MENU_SETTING_ACTION, 0); menu_list_push(list, "Parameters (Menu)", "video_shader_preset_parameters", MENU_SETTING_ACTION, 0); menu_list_push(list, "Shader Passes", "video_shader_num_passes", 0, 0); for (i = 0; i < shader->passes; i++) { char buf[64]; snprintf(buf, sizeof(buf), "Shader #%u", i); menu_list_push(list, buf, "video_shader_pass", MENU_SETTINGS_SHADER_PASS_0 + i, 0); snprintf(buf, sizeof(buf), "Shader #%u Filter", i); menu_list_push(list, buf, "video_shader_filter_pass", MENU_SETTINGS_SHADER_PASS_FILTER_0 + i, 0); snprintf(buf, sizeof(buf), "Shader #%u Scale", i); menu_list_push(list, buf, "video_shader_scale_pass", MENU_SETTINGS_SHADER_PASS_SCALE_0 + i, 0); } if (driver.menu_ctx && driver.menu_ctx->populate_entries) driver.menu_ctx->populate_entries(path, label, type); return 0; } static int deferred_push_options(void *data, void *userdata, const char *path, const char *label, unsigned type) { file_list_t *list = (file_list_t*)data; file_list_t *menu_list = (file_list_t*)userdata; if (!list || !menu_list) return -1; menu_list_clear(list); menu_list_push(list, "Core Options", "core_options", MENU_SETTING_ACTION, 0); if (g_extern.main_is_init) { if (g_extern.has_set_input_descriptors) menu_list_push(list, "Core Input Remapping Options", "core_input_remapping_options", MENU_SETTING_ACTION, 0); menu_list_push(list, "Core Cheat Options", "core_cheat_options", MENU_SETTING_ACTION, 0); if (!g_extern.libretro_dummy && g_extern.system.disk_control.get_num_images) menu_list_push(list, "Core Disk Options", "core_disk_options", MENU_SETTING_ACTION, 0); } menu_list_push(list, "Video Options", "video_options", MENU_SETTING_ACTION, 0); menu_list_push(list, "Shader Options", "shader_options", MENU_SETTING_ACTION, 0); if (driver.menu_ctx && driver.menu_ctx->populate_entries) driver.menu_ctx->populate_entries(path, label, type); return 0; } static int deferred_push_management_options(void *data, void *userdata, const char *path, const char *label, unsigned type) { file_list_t *list = (file_list_t*)data; file_list_t *menu_list = (file_list_t*)userdata; if (!list || !menu_list) return -1; menu_list_clear(list); #ifdef HAVE_LIBRETRODB menu_list_push(list, "Database Manager", "database_manager_list", MENU_SETTING_ACTION, 0); menu_list_push(list, "Cursor Manager", "cursor_manager_list", MENU_SETTING_ACTION, 0); #endif if (driver.menu_ctx && driver.menu_ctx->populate_entries) driver.menu_ctx->populate_entries(path, label, type); return 0; } static void push_perfcounter(menu_handle_t *menu, file_list_t *list, const struct retro_perf_counter **counters, unsigned num, unsigned id) { unsigned i; if (!counters || num == 0) return; for (i = 0; i < num; i++) if (counters[i] && counters[i]->ident) menu_list_push(list, counters[i]->ident, "", id + i, 0); } static int push_perfcounter_generic( void *data, void *userdata, const char *path, const char *label, const struct retro_perf_counter **counters, unsigned num, unsigned ident, unsigned type) { file_list_t *list = NULL; file_list_t *menu_list = NULL; menu_handle_t *menu = menu_driver_resolve(); if (!menu) return -1; list = (file_list_t*)data; menu_list = (file_list_t*)userdata; if (!list || !menu_list) return -1; menu_list_clear(list); push_perfcounter(menu, list, counters, num, ident); if (driver.menu_ctx && driver.menu_ctx->populate_entries) driver.menu_ctx->populate_entries(path, label, type); return 0; } static int deferred_push_core_counters(void *data, void *userdata, const char *path, const char *label, unsigned type) { return push_perfcounter_generic(data, userdata, path, label, perf_counters_libretro, perf_ptr_libretro, MENU_SETTINGS_LIBRETRO_PERF_COUNTERS_BEGIN, type); } static int deferred_push_frontend_counters(void *data, void *userdata, const char *path, const char *label, unsigned type) { return push_perfcounter_generic(data, userdata, path, label, perf_counters_rarch, perf_ptr_rarch, MENU_SETTINGS_PERF_COUNTERS_BEGIN, type); } static int deferred_push_core_cheat_options(void *data, void *userdata, const char *path, const char *label, unsigned type) { unsigned i; file_list_t *list = (file_list_t*)data; cheat_manager_t *cheat = g_extern.cheat; (void)userdata; (void)type; if (!list) return -1; if (!cheat) { g_extern.cheat = cheat_manager_new(0); if (!g_extern.cheat) return -1; cheat = g_extern.cheat; } menu_list_clear(list); menu_list_push(list, "Cheat File Load", "cheat_file_load", MENU_SETTING_ACTION, 0); menu_list_push(list, "Cheat File Save As", "cheat_file_save_as", MENU_SETTING_ACTION, 0); menu_list_push(list, "Cheat Passes", "cheat_num_passes", 0, 0); menu_list_push(list, "Apply Cheat Changes", "cheat_apply_changes", MENU_SETTING_ACTION, 0); for (i = 0; i < cheat->size; i++) { char cheat_label[64]; snprintf(cheat_label, sizeof(cheat_label), "Cheat #%d: ", i); if (cheat->cheats[i].desc) strlcat(cheat_label, cheat->cheats[i].desc, sizeof(cheat_label)); menu_list_push(list, cheat_label, "", MENU_SETTINGS_CHEAT_BEGIN + i, 0); } if (driver.menu_ctx && driver.menu_ctx->populate_entries) driver.menu_ctx->populate_entries(path, label, type); return 0; } static int deferred_push_core_input_remapping_options(void *data, void *userdata, const char *path, const char *label, unsigned type) { unsigned p, retro_id; file_list_t *list = (file_list_t*)data; (void)userdata; (void)type; if (!list) return -1; menu_list_clear(list); menu_list_push(list, "Remap File Load", "remap_file_load", MENU_SETTING_ACTION, 0); menu_list_push(list, "Remap File Save As", "remap_file_save_as", MENU_SETTING_ACTION, 0); for (p = 0; p < g_settings.input.max_users; p++) { for (retro_id = 0; retro_id < RARCH_FIRST_CUSTOM_BIND; retro_id++) { char desc_label[64]; unsigned user = p + 1; const char *description = g_extern.system.input_desc_btn[p][retro_id]; if (!description) continue; snprintf(desc_label, sizeof(desc_label), "User %u %s : ", user, description); menu_list_push(list, desc_label, "", MENU_SETTINGS_INPUT_DESC_BEGIN + (p * RARCH_FIRST_CUSTOM_BIND) + retro_id, 0); } } if (driver.menu_ctx && driver.menu_ctx->populate_entries) driver.menu_ctx->populate_entries(path, label, type); return 0; } static int deferred_push_core_options(void *data, void *userdata, const char *path, const char *label, unsigned type) { unsigned i; file_list_t *list = (file_list_t*)data; (void)userdata; if (!list) return -1; menu_list_clear(list); if (g_extern.system.core_options) { size_t opts = core_option_size(g_extern.system.core_options); for (i = 0; i < opts; i++) menu_list_push(list, core_option_get_desc(g_extern.system.core_options, i), "", MENU_SETTINGS_CORE_OPTION_START + i, 0); } else menu_list_push(list, "No options available.", "", MENU_SETTINGS_CORE_OPTION_NONE, 0); if (driver.menu_ctx && driver.menu_ctx->populate_entries) driver.menu_ctx->populate_entries(path, label, type); return 0; } static int deferred_push_disk_options(void *data, void *userdata, const char *path, const char *label, unsigned type) { file_list_t *list = (file_list_t*)data; (void)userdata; if (!list) return -1; menu_list_clear(list); menu_list_push(list, "Disk Index", "disk_idx", MENU_SETTINGS_CORE_DISK_OPTIONS_DISK_INDEX, 0); menu_list_push(list, "Disk Cycle Tray Status", "disk_cycle_tray_status", MENU_SETTINGS_CORE_DISK_OPTIONS_DISK_CYCLE_TRAY_STATUS, 0); menu_list_push(list, "Disk Image Append", "disk_image_append", MENU_SETTINGS_CORE_DISK_OPTIONS_DISK_IMAGE_APPEND, 0); if (driver.menu_ctx && driver.menu_ctx->populate_entries) driver.menu_ctx->populate_entries(path, label, type); return 0; } #ifdef HAVE_NETWORKING static void print_buf_lines(file_list_t *list, char *buf, int buf_size, unsigned type) { int i; char c, *line_start = buf; for (i = 0; i < buf_size; i++) { size_t ln; /* The end of the buffer, print the last bit */ if (*(buf + i) == '\0') break; if (*(buf + i) != '\n') continue; /* Found a line ending, print the line and compute new line_start */ /* Save the next char */ c = *(buf + i + 1); /* replace with \0 */ *(buf + i + 1) = '\0'; /* We need to strip the newline. */ ln = strlen(line_start) - 1; if (line_start[ln] == '\n') line_start[ln] = '\0'; menu_list_push(list, line_start, "", type, 0); /* Restore the saved char */ *(buf + i + 1) = c; line_start = buf + i + 1; } /* If the buffer was completely full, and didn't end with a newline, just * ignore the partial last line. */ } /* HACK - we have to find some way to pass state inbetween * function pointer callback functions that don't necessarily * call each other. */ static char core_updater_list_path[PATH_MAX_LENGTH]; static char core_updater_list_label[PATH_MAX_LENGTH]; static unsigned core_updater_list_type; int cb_core_updater_list(void *data_, size_t len) { char *data = (char*)data_; file_list_t *list = NULL; menu_handle_t *menu = menu_driver_resolve(); if (!menu) return -1; if (!data) return -1; list = (file_list_t*)menu->menu_list->selection_buf; if (!list) return -1; menu_list_clear(list); print_buf_lines(list, data, len, MENU_FILE_DOWNLOAD_CORE); menu_list_populate_generic(list, core_updater_list_path, core_updater_list_label, core_updater_list_type); return 0; } #endif static int deferred_push_core_updater_list(void *data, void *userdata, const char *path, const char *label, unsigned type) { #ifdef HAVE_NETWORKING char url_path[PATH_MAX_LENGTH]; strlcpy(core_updater_list_path, path, sizeof(core_updater_list_path)); strlcpy(core_updater_list_label, label, sizeof(core_updater_list_label)); core_updater_list_type = type; #endif if (g_settings.network.buildbot_url[0] == '\0') { file_list_t *list = (file_list_t*)data; menu_list_clear(list); #ifdef HAVE_NETWORKING menu_list_push(list, "Buildbot URL not configured.", "", 0, 0); #else menu_list_push(list, "Network not available.", "", 0, 0); #endif menu_list_populate_generic(list, path, label, type); return 0; } #ifdef HAVE_NETWORKING rarch_main_command(RARCH_CMD_NETWORK_INIT); fill_pathname_join(url_path, g_settings.network.buildbot_url, ".index", sizeof(url_path)); strlcat(url_path, "|cb_core_updater_list", sizeof(url_path)); msg_queue_clear(g_extern.http.msg_queue); msg_queue_push(g_extern.http.msg_queue, url_path, 0, 1); #endif return 0; } static int deferred_push_history_list(void *data, void *userdata, const char *path, const char *label, unsigned type) { unsigned i; size_t list_size = 0; file_list_t *list = (file_list_t*)data; if (!list) return -1; (void)userdata; menu_list_clear(list); list_size = content_playlist_size(g_defaults.history); for (i = 0; i < list_size; i++) { char fill_buf[PATH_MAX_LENGTH]; const char *core_name = NULL; content_playlist_get_index(g_defaults.history, i, &path, NULL, &core_name); strlcpy(fill_buf, core_name, sizeof(fill_buf)); if (path) { char path_short[PATH_MAX_LENGTH]; fill_short_pathname_representation(path_short,path,sizeof(path_short)); snprintf(fill_buf,sizeof(fill_buf),"%s (%s)", path_short,core_name); } menu_list_push(list, fill_buf, "", MENU_FILE_PLAYLIST_ENTRY, 0); } menu_list_populate_generic(list, path, label, type); return 0; } static int deferred_push_content_actions(void *data, void *userdata, const char *path, const char *label, unsigned type) { file_list_t *list = (file_list_t*)data; menu_handle_t *menu = menu_driver_resolve(); if (!menu) return -1; (void)userdata; if (!list) return -1; menu_list_clear(list); if (g_extern.main_is_init && !g_extern.libretro_dummy && !strcmp(menu->deferred_path, g_extern.fullpath)) { menu_list_push(list, "Resume", "file_load_or_resume", MENU_SETTING_ACTION_RUN, 0); menu_list_push(list, "Save State", "savestate", MENU_SETTING_ACTION_SAVESTATE, 0); menu_list_push(list, "Load State", "loadstate", MENU_SETTING_ACTION_LOADSTATE, 0); menu_list_push(list, "Core Information", "core_information", MENU_SETTING_ACTION_CORE_INFORMATION, 0); menu_list_push(list, "Core Options", "core_options", MENU_SETTING_ACTION_CORE_OPTIONS, 0); if (g_extern.has_set_input_descriptors) menu_list_push(list, "Core Input Remapping Options", "core_input_remapping_options", MENU_SETTING_ACTION_CORE_INPUT_REMAPPING_OPTIONS, 0); menu_list_push(list, "Core Cheat Options", "core_cheat_options", MENU_SETTING_ACTION_CORE_CHEAT_OPTIONS, 0); if ( !g_extern.libretro_dummy && g_extern.system.disk_control.get_num_images) menu_list_push(list, "Core Disk Options", "disk_options", MENU_SETTING_ACTION_CORE_DISK_OPTIONS, 0); menu_list_push(list, "Take Screenshot", "take_screenshot", MENU_SETTING_ACTION_SCREENSHOT, 0); menu_list_push(list, "Reset", "restart_content", MENU_SETTING_ACTION_RESET, 0); } else menu_list_push(list, "Run", "file_load_or_resume", MENU_SETTING_ACTION_RUN, 0); menu_list_populate_generic(list, path, label, type); return 0; } int deferred_push_content_list(void *data, void *userdata, const char *path, const char *label, unsigned type) { menu_handle_t *menu = menu_driver_resolve(); if (!menu) return -1; return menu_entries_deferred_push((file_list_t*)data, menu->menu_list->selection_buf); } static int deferred_push_database_manager_list(void *data, void *userdata, const char *path, const char *label, unsigned type) { return menu_entries_parse_list((file_list_t*)data, (file_list_t*)userdata, g_settings.content_database, label, type, MENU_FILE_RDB, "rdb", NULL); } static int deferred_push_cursor_manager_list(void *data, void *userdata, const char *path, const char *label, unsigned type) { return menu_entries_parse_list((file_list_t*)data, (file_list_t*)userdata, g_settings.cursor_directory, label, type, MENU_FILE_CURSOR, "dbc", NULL); } static int deferred_push_core_list(void *data, void *userdata, const char *path, const char *label, unsigned type) { return menu_entries_parse_list((file_list_t*)data, (file_list_t*)userdata, path, label, type, MENU_FILE_PLAIN, EXT_EXECUTABLES, NULL); } static int deferred_push_configurations(void *data, void *userdata, const char *path, const char *label, unsigned type) { return menu_entries_parse_list((file_list_t*)data, (file_list_t*)userdata, path, label, type, MENU_FILE_CONFIG, "cfg", NULL); } static int deferred_push_video_shader_preset(void *data, void *userdata, const char *path, const char *label, unsigned type) { return menu_entries_parse_list((file_list_t*)data, (file_list_t*)userdata, path, label, type, MENU_FILE_SHADER_PRESET, "cgp|glslp", NULL); } static int deferred_push_video_shader_pass(void *data, void *userdata, const char *path, const char *label, unsigned type) { return menu_entries_parse_list((file_list_t*)data, (file_list_t*)userdata, path, label, type, MENU_FILE_SHADER, "cg|glsl", NULL); } static int deferred_push_video_filter(void *data, void *userdata, const char *path, const char *label, unsigned type) { return menu_entries_parse_list((file_list_t*)data, (file_list_t*)userdata, path, label, type, MENU_FILE_VIDEOFILTER, "filt", NULL); } static int deferred_push_images(void *data, void *userdata, const char *path, const char *label, unsigned type) { return menu_entries_parse_list((file_list_t*)data, (file_list_t*)userdata, path, label, type, MENU_FILE_IMAGE, "png", NULL); } static int deferred_push_audio_dsp_plugin(void *data, void *userdata, const char *path, const char *label, unsigned type) { return menu_entries_parse_list((file_list_t*)data, (file_list_t*)userdata, path, label, type, MENU_FILE_AUDIOFILTER, "dsp", NULL); } static int deferred_push_cheat_file_load(void *data, void *userdata, const char *path, const char *label, unsigned type) { return menu_entries_parse_list((file_list_t*)data, (file_list_t*)userdata, path, label, type, MENU_FILE_CHEAT, "cht", NULL); } static int deferred_push_remap_file_load(void *data, void *userdata, const char *path, const char *label, unsigned type) { return menu_entries_parse_list((file_list_t*)data, (file_list_t*)userdata, path, label, type, MENU_FILE_REMAP, "rmp", NULL); } static int deferred_push_input_overlay(void *data, void *userdata, const char *path, const char *label, unsigned type) { return menu_entries_parse_list((file_list_t*)data, (file_list_t*)userdata, path, label, type, MENU_FILE_OVERLAY, "cfg", NULL); } static int deferred_push_input_osk_overlay(void *data, void *userdata, const char *path, const char *label, unsigned type) { return menu_entries_parse_list((file_list_t*)data, (file_list_t*)userdata, path, label, type, MENU_FILE_OVERLAY, "cfg", NULL); } static int deferred_push_video_font_path(void *data, void *userdata, const char *path, const char *label, unsigned type) { return menu_entries_parse_list((file_list_t*)data, (file_list_t*)userdata, path, label, type, MENU_FILE_FONT, "ttf", NULL); } static int deferred_push_content_history_path(void *data, void *userdata, const char *path, const char *label, unsigned type) { return menu_entries_parse_list((file_list_t*)data, (file_list_t*)userdata, path, label, type, MENU_FILE_PLAIN, "cfg", NULL); } static int deferred_push_detect_core_list(void *data, void *userdata, const char *path, const char *label, unsigned type) { return menu_entries_parse_list((file_list_t*)data, (file_list_t*)userdata, path, label, type, MENU_FILE_PLAIN, g_extern.core_info ? core_info_list_get_all_extensions( g_extern.core_info) : "", NULL); } static int deferred_push_default(void *data, void *userdata, const char *path, const char *label, unsigned type) { char ext_buf[PATH_MAX_LENGTH]; const char *exts = NULL; file_list_t *list = (file_list_t*)data; file_list_t *menu_list = (file_list_t*)userdata; rarch_setting_t *setting = (rarch_setting_t*) menu_setting_find(label); if (!list || !menu_list) return -1; if (setting && setting->browser_selection_type == ST_DIR) exts = ""; /* we ignore files anyway */ else if (g_extern.menu.info.valid_extensions) { exts = ext_buf; if (*g_extern.menu.info.valid_extensions) snprintf(ext_buf, sizeof(ext_buf), "%s", g_extern.menu.info.valid_extensions); else *ext_buf = '\0'; } else exts = g_extern.system.valid_extensions; menu_entries_parse_list(list, menu_list, path, label, type, MENU_FILE_PLAIN, exts, setting); return 0; } void menu_entries_cbs_init_bind_deferred_push(menu_file_list_cbs_t *cbs, const char *path, const char *label, unsigned type, size_t idx, const char *elem0, const char *elem1) { if (!cbs) return; cbs->action_deferred_push = deferred_push_default; if ((strlen(elem1) != 0) && !!strcmp(elem0, elem1)) { if (menu_entries_common_is_settings_entry(elem0)) { if (!g_settings.menu.collapse_subgroups_enable) { cbs->action_deferred_push = deferred_push_settings_subgroup; return; } } } if (strstr(label, "deferred_rdb_entry_detail")) cbs->action_deferred_push = deferred_push_rdb_entry_detail; else if (!strcmp(label, "core_updater_list")) cbs->action_deferred_push = deferred_push_core_updater_list; else if (!strcmp(label, "history_list")) cbs->action_deferred_push = deferred_push_history_list; else if (!strcmp(label, "database_manager_list")) cbs->action_deferred_push = deferred_push_database_manager_list; else if (!strcmp(label, "cursor_manager_list")) cbs->action_deferred_push = deferred_push_cursor_manager_list; else if (!strcmp(label, "cheat_file_load")) cbs->action_deferred_push = deferred_push_cheat_file_load; else if (!strcmp(label, "remap_file_load")) cbs->action_deferred_push = deferred_push_remap_file_load; else if (!strcmp(label, "content_actions")) cbs->action_deferred_push = deferred_push_content_actions; else if (!strcmp(label, "shader_options")) cbs->action_deferred_push = deferred_push_shader_options; else if (!strcmp(label, "video_options")) cbs->action_deferred_push = deferred_push_video_options; else if (!strcmp(label, "options")) cbs->action_deferred_push = deferred_push_options; else if (!strcmp(label, "management")) cbs->action_deferred_push = deferred_push_management_options; else if (type == MENU_SETTING_GROUP) cbs->action_deferred_push = deferred_push_category; else if (!strcmp(label, "deferred_core_list")) cbs->action_deferred_push = deferred_push_core_list_deferred; else if (!strcmp(label, "deferred_video_filter")) cbs->action_deferred_push = deferred_push_video_filter; else if (!strcmp(label, "deferred_database_manager_list")) cbs->action_deferred_push = deferred_push_database_manager_list_deferred; else if (!strcmp(label, "deferred_cursor_manager_list")) cbs->action_deferred_push = deferred_push_cursor_manager_list_deferred; else if ( !strcmp(label, "deferred_cursor_manager_list_rdb_entry_publisher") || !strcmp(label, "deferred_cursor_manager_list_rdb_entry_developer") || !strcmp(label, "deferred_cursor_manager_list_rdb_entry_origin") || !strcmp(label, "deferred_cursor_manager_list_rdb_entry_franchise") || !strcmp(label, "deferred_cursor_manager_list_rdb_entry_enhancement_hw") || !strcmp(label, "deferred_cursor_manager_list_rdb_entry_esrb_rating") || !strcmp(label, "deferred_cursor_manager_list_rdb_entry_bbfc_rating") || !strcmp(label, "deferred_cursor_manager_list_rdb_entry_elspa_rating") || !strcmp(label, "deferred_cursor_manager_list_rdb_entry_pegi_rating") || !strcmp(label, "deferred_cursor_manager_list_rdb_entry_cero_rating") || !strcmp(label, "deferred_cursor_manager_list_rdb_entry_edge_magazine_rating") || !strcmp(label, "deferred_cursor_manager_list_rdb_entry_edge_magazine_issue") || !strcmp(label, "deferred_cursor_manager_list_rdb_entry_famitsu_magazine_rating") || !strcmp(label, "deferred_cursor_manager_list_rdb_entry_max_users") || !strcmp(label, "deferred_cursor_manager_list_rdb_entry_releasemonth") || !strcmp(label, "deferred_cursor_manager_list_rdb_entry_releaseyear") ) cbs->action_deferred_push = deferred_push_cursor_manager_list_deferred_query_subsearch; else if (!strcmp(label, "core_information")) cbs->action_deferred_push = deferred_push_core_information; else if (!strcmp(label, "performance_counters")) cbs->action_deferred_push = deferred_push_performance_counters; else if (!strcmp(label, "core_counters")) cbs->action_deferred_push = deferred_push_core_counters; else if (!strcmp(label, "video_shader_preset_parameters")) cbs->action_deferred_push = deferred_push_video_shader_preset_parameters; else if (!strcmp(label, "video_shader_parameters")) cbs->action_deferred_push = deferred_push_video_shader_parameters; else if (!strcmp(label, "settings")) cbs->action_deferred_push = deferred_push_settings; else if (!strcmp(label, "frontend_counters")) cbs->action_deferred_push = deferred_push_frontend_counters; else if (!strcmp(label, "core_options")) cbs->action_deferred_push = deferred_push_core_options; else if (!strcmp(label, "core_cheat_options")) cbs->action_deferred_push = deferred_push_core_cheat_options; else if (!strcmp(label, "core_input_remapping_options")) cbs->action_deferred_push = deferred_push_core_input_remapping_options; else if (!strcmp(label, "disk_options")) cbs->action_deferred_push = deferred_push_disk_options; else if (!strcmp(label, "core_list")) cbs->action_deferred_push = deferred_push_core_list; else if (!strcmp(label, "configurations")) cbs->action_deferred_push = deferred_push_configurations; else if (!strcmp(label, "video_shader_preset")) cbs->action_deferred_push = deferred_push_video_shader_preset; else if (!strcmp(label, "video_shader_pass")) cbs->action_deferred_push = deferred_push_video_shader_pass; else if (!strcmp(label, "video_filter")) cbs->action_deferred_push = deferred_push_video_filter; else if (!strcmp(label, "menu_wallpaper")) cbs->action_deferred_push = deferred_push_images; else if (!strcmp(label, "audio_dsp_plugin")) cbs->action_deferred_push = deferred_push_audio_dsp_plugin; else if (!strcmp(label, "input_overlay")) cbs->action_deferred_push = deferred_push_input_overlay; else if (!strcmp(label, "input_osk_overlay")) cbs->action_deferred_push = deferred_push_input_osk_overlay; else if (!strcmp(label, "video_font_path")) cbs->action_deferred_push = deferred_push_video_font_path; else if (!strcmp(label, "game_history_path")) cbs->action_deferred_push = deferred_push_content_history_path; else if (!strcmp(label, "detect_core_list")) cbs->action_deferred_push = deferred_push_detect_core_list; }