diff --git a/core_info.c b/core_info.c index 3348d8956d..a2a6b1b5f3 100644 --- a/core_info.c +++ b/core_info.c @@ -50,6 +50,312 @@ enum compare_op COMPARE_OP_GREATER_EQUAL }; +static uint32_t core_info_hash_string(const char *str) +{ + unsigned char c; + uint32_t hash = (uint32_t)0x811c9dc5; + while ((c = (unsigned char)*(str++)) != '\0') + hash = ((hash * (uint32_t)0x01000193) ^ (uint32_t)c); + return (hash ? hash : 1); +} + +static bool core_info_get_file_id(const char *core_filename, + char *core_file_id, size_t len) +{ + char *last_underscore = NULL; + + if (string_is_empty(core_filename)) + return false; + + /* Core file 'id' is filename without extension + * or platform-specific suffix */ + + /* > Remove extension */ + strlcpy(core_file_id, core_filename, len); + path_remove_extension(core_file_id); + + /* > Remove suffix */ + last_underscore = (char*)strrchr(core_file_id, '_'); + + if (!string_is_empty(last_underscore) && + !string_is_equal(last_underscore, "_libretro")) + *last_underscore = '\0'; + + return !string_is_empty(core_file_id); +} + +static core_info_t *core_info_find_internal( + core_info_list_t *list, + const char *core_path) +{ + char core_file_id[256]; + uint32_t hash; + size_t i; + + core_file_id[0] = '\0'; + + if (!list || + string_is_empty(core_path) || + !core_info_get_file_id(path_basename_nocompression(core_path), + core_file_id, sizeof(core_file_id))) + return NULL; + + hash = core_info_hash_string(core_file_id); + + for (i = 0; i < list->count; i++) + { + core_info_t *info = &list->list[i]; + + if (info->core_file_id.hash == hash) + return info; + } + + return NULL; +} + +static void core_info_resolve_firmware( + core_info_t *info, config_file_t *conf) +{ + unsigned i; + unsigned firmware_count = 0; + core_info_firmware_t *firmware = NULL; + + if (!config_get_uint(conf, "firmware_count", &firmware_count)) + return; + + firmware = (core_info_firmware_t*)calloc(firmware_count, sizeof(*firmware)); + + if (!firmware) + return; + + for (i = 0; i < firmware_count; i++) + { + char path_key[64]; + char desc_key[64]; + char opt_key[64]; + struct config_entry_list *entry = NULL; + bool tmp_bool = false; + + path_key[0] = '\0'; + desc_key[0] = '\0'; + opt_key[0] = '\0'; + + snprintf(path_key, sizeof(path_key), "firmware%u_path", i); + snprintf(desc_key, sizeof(desc_key), "firmware%u_desc", i); + snprintf(opt_key, sizeof(opt_key), "firmware%u_opt", i); + + entry = config_get_entry(conf, path_key); + + if (entry && !string_is_empty(entry->value)) + { + firmware[i].path = entry->value; + entry->value = NULL; + } + + entry = config_get_entry(conf, desc_key); + + if (entry && !string_is_empty(entry->value)) + { + firmware[i].desc = entry->value; + entry->value = NULL; + } + + if (config_get_bool(conf, opt_key , &tmp_bool)) + firmware[i].optional = tmp_bool; + } + + info->firmware_count = firmware_count; + info->firmware = firmware; +} + +static config_file_t *core_info_get_config_file( + const char *core_file_id, + const char *info_dir) +{ + char info_path[PATH_MAX_LENGTH]; + + info_path[0] = '\0'; + + if (string_is_empty(info_dir)) + strlcpy(info_path, core_file_id, sizeof(info_path)); + else + fill_pathname_join(info_path, info_dir, core_file_id, + sizeof(info_path)); + + strlcat(info_path, ".info", sizeof(info_path)); + + return config_file_new_from_path_to_string(info_path); +} + +static void core_info_parse_config_file( + core_info_list_t *list, core_info_t *info, + config_file_t *conf) +{ + struct config_entry_list *entry = NULL; + bool tmp_bool = false; + + entry = config_get_entry(conf, "display_name"); + + if (entry && !string_is_empty(entry->value)) + { + info->display_name = entry->value; + entry->value = NULL; + } + + entry = config_get_entry(conf, "display_version"); + + if (entry && !string_is_empty(entry->value)) + { + info->display_version = entry->value; + entry->value = NULL; + } + + entry = config_get_entry(conf, "corename"); + + if (entry && !string_is_empty(entry->value)) + { + info->core_name = entry->value; + entry->value = NULL; + } + + entry = config_get_entry(conf, "systemname"); + + if (entry && !string_is_empty(entry->value)) + { + info->systemname = entry->value; + entry->value = NULL; + } + + entry = config_get_entry(conf, "systemid"); + + if (entry && !string_is_empty(entry->value)) + { + info->system_id = entry->value; + entry->value = NULL; + } + + entry = config_get_entry(conf, "manufacturer"); + + if (entry && !string_is_empty(entry->value)) + { + info->system_manufacturer = entry->value; + entry->value = NULL; + } + + entry = config_get_entry(conf, "supported_extensions"); + + if (entry && !string_is_empty(entry->value)) + { + info->supported_extensions = entry->value; + entry->value = NULL; + + info->supported_extensions_list = + string_split(info->supported_extensions, "|"); + } + + entry = config_get_entry(conf, "authors"); + + if (entry && !string_is_empty(entry->value)) + { + info->authors = entry->value; + entry->value = NULL; + + info->authors_list = + string_split(info->authors, "|"); + } + + entry = config_get_entry(conf, "permissions"); + + if (entry && !string_is_empty(entry->value)) + { + info->permissions = entry->value; + entry->value = NULL; + + info->permissions_list = + string_split(info->permissions, "|"); + } + + entry = config_get_entry(conf, "license"); + + if (entry && !string_is_empty(entry->value)) + { + info->licenses = entry->value; + entry->value = NULL; + + info->licenses_list = + string_split(info->licenses, "|"); + } + + entry = config_get_entry(conf, "categories"); + + if (entry && !string_is_empty(entry->value)) + { + info->categories = entry->value; + entry->value = NULL; + + info->categories_list = + string_split(info->categories, "|"); + } + + entry = config_get_entry(conf, "database"); + + if (entry && !string_is_empty(entry->value)) + { + info->databases = entry->value; + entry->value = NULL; + + info->databases_list = + string_split(info->databases, "|"); + } + + entry = config_get_entry(conf, "notes"); + + if (entry && !string_is_empty(entry->value)) + { + info->notes = entry->value; + entry->value = NULL; + + info->note_list = + string_split(info->notes, "|"); + } + + entry = config_get_entry(conf, "required_hw_api"); + + if (entry && !string_is_empty(entry->value)) + { + info->required_hw_api = entry->value; + entry->value = NULL; + + info->required_hw_api_list = + string_split(info->required_hw_api, "|"); + } + + entry = config_get_entry(conf, "description"); + + if (entry && !string_is_empty(entry->value)) + { + info->description = entry->value; + entry->value = NULL; + } + + if (config_get_bool(conf, "supports_no_game", + &tmp_bool)) + info->supports_no_game = tmp_bool; + + if (config_get_bool(conf, "database_match_archive_member", + &tmp_bool)) + info->database_match_archive_member = tmp_bool; + + if (config_get_bool(conf, "is_experimental", + &tmp_bool)) + info->is_experimental = tmp_bool; + + core_info_resolve_firmware(info, conf); + + info->has_info = true; + list->info_count++; +} + static void core_info_list_resolve_all_extensions( core_info_list_t *core_info_list) { @@ -90,59 +396,6 @@ static void core_info_list_resolve_all_extensions( #endif } -static void core_info_list_resolve_all_firmware( - core_info_list_t *core_info_list) -{ - size_t i; - unsigned c; - - for (i = 0; i < core_info_list->count; i++) - { - unsigned count = 0; - core_info_firmware_t *firmware = NULL; - core_info_t *info = (core_info_t*)&core_info_list->list[i]; - config_file_t *config = (config_file_t*)info->config_data; - - if (!config || !config_get_uint(config, "firmware_count", &count)) - continue; - - firmware = (core_info_firmware_t*)calloc(count, sizeof(*firmware)); - - if (!firmware) - continue; - - info->firmware = firmware; - - for (c = 0; c < count; c++) - { - char path_key[64]; - char desc_key[64]; - char opt_key[64]; - struct config_entry_list - *entry = NULL; - bool tmp_bool = false; - path_key[0] = desc_key[0] = opt_key[0] = '\0'; - - snprintf(path_key, sizeof(path_key), "firmware%u_path", c); - snprintf(desc_key, sizeof(desc_key), "firmware%u_desc", c); - snprintf(opt_key, sizeof(opt_key), "firmware%u_opt", c); - - entry = config_get_entry(config, path_key); - - if (entry && !string_is_empty(entry->value)) - info->firmware[c].path = strdup(entry->value); - - entry = config_get_entry(config, desc_key); - - if (entry && !string_is_empty(entry->value)) - info->firmware[c].desc = strdup(entry->value); - - if (config_get_bool(config, opt_key , &tmp_bool)) - info->firmware[c].optional = tmp_bool; - } - } -} - static void core_info_list_free(core_info_list_t *core_info_list) { size_t i, j; @@ -178,7 +431,6 @@ static void core_info_list_free(core_info_list_t *core_info_list) string_list_free(info->categories_list); string_list_free(info->databases_list); string_list_free(info->required_hw_api_list); - config_file_free((config_file_t*)info->config_data); for (j = 0; j < info->firmware_count; j++) { @@ -195,42 +447,6 @@ static void core_info_list_free(core_info_list_t *core_info_list) free(core_info_list); } -static config_file_t *core_info_list_iterate( - const char *current_path, - const char *path_basedir) -{ - char info_path[PATH_MAX_LENGTH]; - char info_path_base[PATH_MAX_LENGTH]; - - if (!current_path) - return NULL; - - info_path [0] = '\0'; - info_path_base[0] = '\0'; - - fill_pathname_base_noext(info_path_base, - current_path, - sizeof(info_path_base)); - -#if defined(RARCH_MOBILE) || (defined(RARCH_CONSOLE) && !defined(PSP) && !defined(_3DS) && !defined(VITA) && !defined(HW_WUP)) - { - char *substr = strrchr(info_path_base, '_'); - if (substr) - *substr = '\0'; - } -#endif - - strlcat(info_path_base, ".info", sizeof(info_path_base)); - - fill_pathname_join(info_path, - path_basedir, - info_path_base, sizeof(info_path_base)); - - if (path_is_valid(info_path)) - return config_file_new_from_path_to_string(info_path); - return NULL; -} - static core_info_list_t *core_info_list_new(const char *path, const char *libretro_info_dir, const char *exts, @@ -240,14 +456,13 @@ static core_info_list_t *core_info_list_new(const char *path, struct string_list contents = {0}; core_info_t *core_info = NULL; core_info_list_t *core_info_list = NULL; - const char *path_basedir = libretro_info_dir; - bool ok = false; + const char *info_dir = libretro_info_dir; + bool ok = false; string_list_initialize(&contents); - if (dir_list_append(&contents, path, exts, - false, dir_show_hidden_files, false, false)) - ok = true; + ok = dir_list_append(&contents, path, exts, + false, dir_show_hidden_files, false, false); #if defined(__WINRT__) || defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP { @@ -264,7 +479,7 @@ static core_info_list_t *core_info_list_new(const char *path, } } #else - /* Keep the old 'directory not found' behavior */ + /* Keep the old 'directory not found' behaviour */ if (!ok) goto error; #endif @@ -273,12 +488,12 @@ static core_info_list_t *core_info_list_new(const char *path, if (!core_info_list) goto error; - core_info_list->list = NULL; - core_info_list->count = 0; - core_info_list->all_ext = NULL; + core_info_list->list = NULL; + core_info_list->count = 0; + core_info_list->info_count = 0; + core_info_list->all_ext = NULL; - core_info = (core_info_t*) - calloc(contents.size, sizeof(*core_info)); + core_info = (core_info_t*)calloc(contents.size, sizeof(*core_info)); if (!core_info) { @@ -286,192 +501,50 @@ static core_info_list_t *core_info_list_new(const char *path, goto error; } - core_info_list->list = core_info; - core_info_list->count = contents.size; + core_info_list->list = core_info; + core_info_list->count = contents.size; for (i = 0; i < contents.size; i++) { - const char *base_path = contents.elems[i].data; - config_file_t *conf = core_info_list_iterate(base_path, - path_basedir); + core_info_t *info = &core_info[i]; + const char *base_path = contents.elems[i].data; + const char *core_filename = NULL; + config_file_t *conf = NULL; + char core_file_id[256]; + + core_file_id[0] = '\0'; + + if (string_is_empty(base_path) || + !(core_filename = path_basename_nocompression(base_path)) || + !core_info_get_file_id(core_filename, core_file_id, + sizeof(core_file_id))) + continue; + + /* Cache core path */ + info->path = strdup(base_path); + + /* Get core lock status */ + info->is_locked = core_info_get_core_lock(info->path, false); + + /* Cache core file 'id' */ + info->core_file_id.str = strdup(core_file_id); + info->core_file_id.hash = core_info_hash_string(core_file_id); + + /* Parse core info file */ + conf = core_info_get_config_file(core_file_id, info_dir); if (conf) { - bool tmp_bool = false; - unsigned tmp_uint = 0; - struct config_entry_list - *entry = config_get_entry(conf, "display_name"); - - if (entry && !string_is_empty(entry->value)) - core_info[i].display_name = strdup(entry->value); - - entry = config_get_entry(conf, "display_version"); - - if (entry && !string_is_empty(entry->value)) - core_info[i].display_version = strdup(entry->value); - - entry = config_get_entry(conf, "corename"); - - if (entry && !string_is_empty(entry->value)) - core_info[i].core_name = strdup(entry->value); - - entry = config_get_entry(conf, "systemname"); - - if (entry && !string_is_empty(entry->value)) - core_info[i].systemname = strdup(entry->value); - - entry = config_get_entry(conf, "systemid"); - - if (entry && !string_is_empty(entry->value)) - core_info[i].system_id = strdup(entry->value); - - entry = config_get_entry(conf, "manufacturer"); - - if (entry && !string_is_empty(entry->value)) - core_info[i].system_manufacturer = strdup(entry->value); - - config_get_uint(conf, "firmware_count", &tmp_uint); - core_info[i].firmware_count = tmp_uint; - - entry = config_get_entry(conf, "supported_extensions"); - - if (entry && !string_is_empty(entry->value)) - { - core_info[i].supported_extensions = strdup(entry->value); - core_info[i].supported_extensions_list = - string_split(core_info[i].supported_extensions, "|"); - } - - entry = config_get_entry(conf, "authors"); - - if (entry && !string_is_empty(entry->value)) - { - core_info[i].authors = strdup(entry->value); - core_info[i].authors_list = - string_split(core_info[i].authors, "|"); - } - - entry = config_get_entry(conf, "permissions"); - - if (entry && !string_is_empty(entry->value)) - { - core_info[i].permissions = strdup(entry->value); - core_info[i].permissions_list = - string_split(core_info[i].permissions, "|"); - } - - entry = config_get_entry(conf, "license"); - - if (entry && !string_is_empty(entry->value)) - { - core_info[i].licenses = strdup(entry->value); - core_info[i].licenses_list = - string_split(core_info[i].licenses, "|"); - } - - entry = config_get_entry(conf, "categories"); - - if (entry && !string_is_empty(entry->value)) - { - core_info[i].categories = strdup(entry->value); - core_info[i].categories_list = - string_split(core_info[i].categories, "|"); - } - - entry = config_get_entry(conf, "database"); - - if (entry && !string_is_empty(entry->value)) - { - core_info[i].databases = strdup(entry->value); - core_info[i].databases_list = - string_split(core_info[i].databases, "|"); - } - - entry = config_get_entry(conf, "notes"); - - if (entry && !string_is_empty(entry->value)) - { - core_info[i].notes = strdup(entry->value); - core_info[i].note_list = - string_split(core_info[i].notes, "|"); - } - - entry = config_get_entry(conf, "required_hw_api"); - - if (entry && !string_is_empty(entry->value)) - { - core_info[i].required_hw_api = strdup(entry->value); - core_info[i].required_hw_api_list = - string_split(core_info[i].required_hw_api, "|"); - } - - entry = config_get_entry(conf, "description"); - - if (entry && !string_is_empty(entry->value)) - core_info[i].description = strdup(entry->value); - - if (config_get_bool(conf, "supports_no_game", - &tmp_bool)) - core_info[i].supports_no_game = tmp_bool; - - if (config_get_bool(conf, "database_match_archive_member", - &tmp_bool)) - core_info[i].database_match_archive_member = tmp_bool; - - if (config_get_bool(conf, "is_experimental", - &tmp_bool)) - core_info[i].is_experimental = tmp_bool; - - core_info[i].config_data = conf; + core_info_parse_config_file(core_info_list, info, conf); + config_file_free(conf); } - if (!string_is_empty(base_path)) - { - const char *core_filename = path_basename(base_path); - - /* Cache core path */ - core_info[i].path = strdup(base_path); - - /* Cache core file 'id' - * > Filename without extension or platform-specific suffix */ - if (!string_is_empty(core_filename)) - { - char *core_file_id = strdup(core_filename); - path_remove_extension(core_file_id); - - if (!string_is_empty(core_file_id)) - { - /* TODO/FIXME - we should find a cleaner way to do this - * instead of this preprocessor hackery */ -#if defined(RARCH_MOBILE) || (defined(RARCH_CONSOLE) && !defined(PSP) && !defined(_3DS) && !defined(VITA) && !defined(HW_WUP)) - char *last_underscore = strrchr(core_file_id, '_'); - if (last_underscore) - *last_underscore = '\0'; -#endif - core_info[i].core_file_id.str = core_file_id; - core_info[i].core_file_id.len = strlen(core_file_id); - - core_file_id = NULL; - } - - if (core_file_id) - { - free(core_file_id); - core_file_id = NULL; - } - - /* Get fallback display name, if required */ - if (!core_info[i].display_name) - core_info[i].display_name = strdup(core_filename); - } - } - - /* Get core lock status */ - core_info[i].is_locked = core_info_get_core_lock(core_info[i].path, false); + /* Get fallback display name, if required */ + if (!info->display_name) + info->display_name = strdup(core_filename); } core_info_list_resolve_all_extensions(core_info_list); - core_info_list_resolve_all_firmware(core_info_list); string_list_deinitialize(&contents); return core_info_list; @@ -486,32 +559,20 @@ error: * Data in *info is invalidated when the * core_info_list is freed. */ bool core_info_list_get_info(core_info_list_t *core_info_list, - core_info_t *out_info, const char *path) + core_info_t *out_info, const char *core_path) { - size_t i; - const char *core_filename = NULL; + core_info_t *info = core_info_find_internal( + core_info_list, core_path); - if (!core_info_list || !out_info || string_is_empty(path)) - return false; - - core_filename = path_basename(path); - if (string_is_empty(core_filename)) + if (!out_info) return false; memset(out_info, 0, sizeof(*out_info)); - for (i = 0; i < core_info_list->count; i++) + if (info) { - const core_info_t *info = &core_info_list->list[i]; - - if (!info || (info->core_file_id.len == 0)) - continue; - - if (!strncmp(info->core_file_id.str, core_filename, info->core_file_id.len)) - { - *out_info = *info; - return true; - } + *out_info = *info; + return true; } return false; @@ -568,37 +629,9 @@ static int core_info_qsort_cmp(const void *a_, const void *b_) return strcasecmp(a->display_name, b->display_name); } -static core_info_t *core_info_find_internal( - core_info_list_t *list, - const char *core) -{ - size_t i; - const char *core_filename = NULL; - - if (!list || string_is_empty(core)) - return NULL; - - core_filename = path_basename_nocompression(core); - if (string_is_empty(core_filename)) - return NULL; - - for (i = 0; i < list->count; i++) - { - core_info_t *info = core_info_get(list, i); - - if (!info || (info->core_file_id.len == 0)) - continue; - - if (!strncmp(info->core_file_id.str, core_filename, info->core_file_id.len)) - return info; - } - - return NULL; -} - static bool core_info_list_update_missing_firmware_internal( core_info_list_t *core_info_list, - const char *core, + const char *core_path, const char *systemdir, bool *set_missing_bios) { @@ -606,10 +639,10 @@ static bool core_info_list_update_missing_firmware_internal( char path[PATH_MAX_LENGTH]; core_info_t *info = NULL; - if (!core_info_list || !core) + if (!core_info_list) return false; - info = core_info_find_internal(core_info_list, core); + info = core_info_find_internal(core_info_list, core_path); if (!info) return false; @@ -645,13 +678,13 @@ bool core_info_init_current_core(void) malloc(sizeof(*current)); if (!current) return false; + current->has_info = false; current->supports_no_game = false; current->database_match_archive_member = false; current->is_experimental = false; current->is_locked = false; current->firmware_count = 0; current->path = NULL; - current->config_data = NULL; current->display_name = NULL; current->display_version = NULL; current->core_name = NULL; @@ -677,8 +710,7 @@ bool core_info_init_current_core(void) current->required_hw_api_list = NULL; current->firmware = NULL; current->core_file_id.str = NULL; - current->core_file_id.len = 0; - current->userdata = NULL; + current->core_file_id.hash = 0; p_coreinfo->current = current; return true; @@ -743,15 +775,11 @@ bool core_info_list_update_missing_firmware(core_info_ctx_firmware_t *info, set_missing_bios); } -bool core_info_load( - core_info_ctx_find_t *info, +bool core_info_load(const char *core_path, core_info_state_t *p_coreinfo) { core_info_t *core_info = NULL; - if (!info) - return false; - if (!p_coreinfo->current) core_info_init_current_core(); @@ -761,24 +789,27 @@ bool core_info_load( return false; if (!core_info_list_get_info(p_coreinfo->curr_list, - core_info, info->path)) + core_info, core_path)) return false; return true; } -bool core_info_find(core_info_ctx_find_t *info) +bool core_info_find(const char *core_path, + core_info_t **core_info) { core_info_state_t *p_coreinfo = coreinfo_get_ptr(); + core_info_t *info = NULL; - if (!info || !p_coreinfo->curr_list) + if (!core_info || !p_coreinfo->curr_list) return false; - info->inf = core_info_find_internal(p_coreinfo->curr_list, info->path); + info = core_info_find_internal(p_coreinfo->curr_list, core_path); - if (!info->inf) + if (!info) return false; + *core_info = info; return true; } @@ -786,7 +817,7 @@ core_info_t *core_info_get(core_info_list_t *list, size_t i) { core_info_t *info = NULL; - if (!list) + if (!list || (i >= list->count)) return NULL; info = (core_info_t*)&list->list[i]; if (!info || !info->path) @@ -846,120 +877,31 @@ void core_info_list_get_supported_cores(core_info_list_t *core_info_list, } /* - * Matches core path A and B "base" filename (ignoring - * everything after _libretro) + * Matches core A and B file IDs * - * Ex: + * e.g.: * snes9x_libretro.dll and snes9x_libretro_android.so are matched * snes9x__2005_libretro.dll and snes9x_libretro_android.so are * NOT matched */ -bool core_info_core_file_id_is_equal(const char* core_path_a, - const char* core_path_b) +bool core_info_core_file_id_is_equal(const char *core_path_a, + const char *core_path_b) { - const char *core_path_basename_a = NULL; + char core_file_id_a[256]; + char core_file_id_b[256]; - if (!core_path_a || !core_path_b) + core_file_id_a[0] = '\0'; + core_file_id_b[0] = '\0'; + + if (string_is_empty(core_path_a) || + string_is_empty(core_path_b) || + !core_info_get_file_id(path_basename_nocompression(core_path_a), + core_file_id_a, sizeof(core_file_id_a)) || + !core_info_get_file_id(path_basename_nocompression(core_path_b), + core_file_id_b, sizeof(core_file_id_b))) return false; - core_path_basename_a = path_basename_nocompression(core_path_a); - - if (core_path_basename_a) - { - const char *extension_pos = strrchr(core_path_basename_a, '.'); - - if (extension_pos) - { - const char *underscore_pos = NULL; - - /* Remove extension */ - *((char*)extension_pos) = '\0'; - - underscore_pos = strrchr(core_path_basename_a, '_'); - - /* Restore extension */ - *((char*)extension_pos) = '.'; - - if (underscore_pos) - { - size_t core_base_file_id_length = - underscore_pos - core_path_basename_a; - const char* core_path_basename_b = - path_basename_nocompression( - core_path_b); - - if (string_starts_with_size( - core_path_basename_a, core_path_basename_b, - core_base_file_id_length)) - return true; - } - } - } - - return false; -} - -void core_info_get_name(const char *path, char *s, size_t len, - const char *path_info, const char *dir_cores, - const char *exts, bool dir_show_hidden_files, - bool get_display_name) -{ - size_t i; - struct string_list contents = {0}; - const char *path_basedir = !string_is_empty(path_info) ? - path_info : dir_cores; - const char *core_path_basename = path_basename(path); - - if (!dir_list_initialize(&contents, - dir_cores, exts, false, dir_show_hidden_files, false, false)) - return; - - for (i = 0; i < contents.size; i++) - { - struct config_entry_list - *entry = NULL; - config_file_t *conf = NULL; - const char *current_path = contents.elems[i].data; - - if (!string_is_equal(path_basename(current_path), core_path_basename)) - continue; - - conf = core_info_list_iterate(contents.elems[i].data, - path_basedir); - - if (!conf) - continue; - - if (get_display_name) - entry = config_get_entry(conf, "display_name"); - else - entry = config_get_entry(conf, "corename"); - - if (entry && !string_is_empty(entry->value)) - strlcpy(s, entry->value, len); - - config_file_free(conf); - break; - } - - dir_list_deinitialize(&contents); -} - -size_t core_info_list_num_info_files(core_info_list_t *core_info_list) -{ - size_t i, num = 0; - - if (!core_info_list) - return 0; - - for (i = 0; i < core_info_list->count; i++) - { - config_file_t *conf = (config_file_t*) - core_info_list->list[i].config_data; - num += !!conf; - } - - return num; + return string_is_equal(core_file_id_a, core_file_id_b); } bool core_info_database_match_archive_member(const char *database_path) @@ -1041,62 +983,28 @@ bool core_info_database_supports_content_path( } bool core_info_list_get_display_name(core_info_list_t *core_info_list, - const char *path, char *s, size_t len) + const char *core_path, char *s, size_t len) { - size_t i; - const char *core_filename = NULL; + core_info_t *info = core_info_find_internal( + core_info_list, core_path); - if (!core_info_list || string_is_empty(path)) - return false; - - core_filename = path_basename(path); - if (string_is_empty(core_filename)) - return false; - - for (i = 0; i < core_info_list->count; i++) + if (s && + info && + !string_is_empty(info->display_name)) { - const core_info_t *info = &core_info_list->list[i]; - - if (!info || (info->core_file_id.len == 0)) - continue; - - if (!strncmp(info->core_file_id.str, core_filename, info->core_file_id.len)) - { - if (string_is_empty(info->display_name)) - break; - - strlcpy(s, info->display_name, len); - return true; - } + strlcpy(s, info->display_name, len); + return true; } return false; } -bool core_info_get_display_name(const char *path, char *s, size_t len) -{ - struct config_entry_list - *entry = NULL; - config_file_t *conf = config_file_new_from_path_to_string(path); - - if (!conf) - return false; - - entry = config_get_entry(conf, "display_name"); - - if (entry && !string_is_empty(entry->value)) - strlcpy(s, entry->value, len); - - config_file_free(conf); - return true; -} - /* Returns core_info parameters required for * core updater tasks, read from specified file. * Returned core_updater_info_t object must be * freed using core_info_free_core_updater_info(). * Returns NULL if 'path' is invalid. */ -core_updater_info_t *core_info_get_core_updater_info(const char *path) +core_updater_info_t *core_info_get_core_updater_info(const char *info_path) { struct config_entry_list *entry = NULL; @@ -1104,11 +1012,11 @@ core_updater_info_t *core_info_get_core_updater_info(const char *path) core_updater_info_t *info = NULL; config_file_t *conf = NULL; - if (string_is_empty(path)) + if (string_is_empty(info_path)) return NULL; /* Read config file */ - conf = config_file_new_from_path_to_string(path); + conf = config_file_new_from_path_to_string(info_path); if (!conf) return NULL; @@ -1134,19 +1042,28 @@ core_updater_info_t *core_info_get_core_updater_info(const char *path) entry = config_get_entry(conf, "display_name"); if (entry && !string_is_empty(entry->value)) - info->display_name = strdup(entry->value); + { + info->display_name = entry->value; + entry->value = NULL; + } /* > description */ entry = config_get_entry(conf, "description"); if (entry && !string_is_empty(entry->value)) - info->description = strdup(entry->value); + { + info->description = entry->value; + entry->value = NULL; + } /* > licenses */ entry = config_get_entry(conf, "license"); if (entry && !string_is_empty(entry->value)) - info->licenses = strdup(entry->value); + { + info->licenses = entry->value; + entry->value = NULL; + } /* Clean up */ config_file_free(conf); @@ -1538,9 +1455,9 @@ bool core_info_hw_api_supported(core_info_t *info) * core info list this is *not* thread safe */ bool core_info_set_core_lock(const char *core_path, bool lock) { - core_info_ctx_find_t core_info; + core_info_t *core_info = NULL; + bool lock_file_exists = false; char lock_file_path[PATH_MAX_LENGTH]; - bool lock_file_exists = false; lock_file_path[0] = '\0'; @@ -1555,17 +1472,14 @@ bool core_info_set_core_lock(const char *core_path, bool lock) return false; /* Search for specified core */ - core_info.inf = NULL; - core_info.path = core_path; - - if (!core_info_find(&core_info)) + if (!core_info_find(core_path, &core_info)) return false; - if (string_is_empty(core_info.inf->path)) + if (string_is_empty(core_info->path)) return false; /* Get lock file path */ - strlcpy(lock_file_path, core_info.inf->path, + strlcpy(lock_file_path, core_info->path, sizeof(lock_file_path)); strlcat(lock_file_path, FILE_PATH_LOCK_EXTENSION, sizeof(lock_file_path)); @@ -1600,7 +1514,7 @@ bool core_info_set_core_lock(const char *core_path, bool lock) /* File operations were successful - update * core info entry */ - core_info.inf->is_locked = lock; + core_info->is_locked = lock; return true; } @@ -1616,10 +1530,10 @@ bool core_info_set_core_lock(const char *core_path, bool lock) * must be checked externally */ bool core_info_get_core_lock(const char *core_path, bool validate_path) { - char lock_file_path[PATH_MAX_LENGTH]; + core_info_t *core_info = NULL; const char *core_file_path = NULL; bool is_locked = false; - core_info_ctx_find_t core_info; + char lock_file_path[PATH_MAX_LENGTH]; lock_file_path[0] = '\0'; @@ -1633,16 +1547,11 @@ bool core_info_get_core_lock(const char *core_path, bool validate_path) if (string_is_empty(core_path)) return false; - core_info.inf = NULL; - core_info.path = NULL; - /* Check whether core path is to be validated */ if (validate_path) { - core_info.path = core_path; - - if (core_info_find(&core_info)) - core_file_path = core_info.inf->path; + if (core_info_find(core_path, &core_info)) + core_file_path = core_info->path; } else core_file_path = core_path; @@ -1665,8 +1574,8 @@ bool core_info_get_core_lock(const char *core_path, bool validate_path) * core info object is available), ensure * that core info 'is_locked' field is * up to date */ - if (validate_path && core_info.inf) - core_info.inf->is_locked = is_locked; + if (validate_path && core_info) + core_info->is_locked = is_locked; return is_locked; } diff --git a/core_info.h b/core_info.h index 4a38dd4892..96205ee4e2 100644 --- a/core_info.h +++ b/core_info.h @@ -45,25 +45,19 @@ typedef struct /* Simple container/convenience struct for * holding the 'id' of a core file - * > 'id' is the filename without extension or + * > 'str' is the filename without extension or * platform-specific suffix - * > 'id' is used for core info searches - enables - * matching regardless of core file base path, - * and is platform-independent (e.g. an Android - * core file will be correctly identified on Linux) - * > 'len' is used to cache the length of 'str', for - * improved performance when performing string - * comparisons */ + * > 'hash' is a hash key used for efficient core + * list searches */ typedef struct { char *str; - size_t len; + uint32_t hash; } core_file_id_t; typedef struct { char *path; - void *config_data; char *display_name; char *display_version; char *core_name; @@ -89,8 +83,8 @@ typedef struct struct string_list *required_hw_api_list; core_info_firmware_t *firmware; core_file_id_t core_file_id; /* ptr alignment */ - void *userdata; size_t firmware_count; + bool has_info; bool supports_no_game; bool database_match_archive_member; bool is_experimental; @@ -112,6 +106,7 @@ typedef struct core_info_t *list; char *all_ext; size_t count; + size_t info_count; } core_info_list_t; typedef struct core_info_ctx_firmware @@ -123,12 +118,6 @@ typedef struct core_info_ctx_firmware } directory; } core_info_ctx_firmware_t; -typedef struct core_info_ctx_find -{ - core_info_t *inf; - const char *path; -} core_info_ctx_find_t; - struct core_info_state { #ifdef HAVE_COMPRESSION @@ -141,30 +130,21 @@ struct core_info_state typedef struct core_info_state core_info_state_t; -size_t core_info_list_num_info_files(core_info_list_t *list); - /* Non-reentrant, does not allocate. Returns pointer to internal state. */ void core_info_list_get_supported_cores(core_info_list_t *list, const char *path, const core_info_t **infos, size_t *num_infos); bool core_info_list_get_display_name(core_info_list_t *list, - const char *path, char *s, size_t len); - -bool core_info_get_display_name(const char *path, char *s, size_t len); + const char *core_path, char *s, size_t len); /* Returns core_info parameters required for * core updater tasks, read from specified file. * Returned core_updater_info_t object must be * freed using core_info_free_core_updater_info(). * Returns NULL if 'path' is invalid. */ -core_updater_info_t *core_info_get_core_updater_info(const char *path); +core_updater_info_t *core_info_get_core_updater_info(const char *info_path); void core_info_free_core_updater_info(core_updater_info_t *info); -void core_info_get_name(const char *path, char *s, size_t len, - const char *path_info, const char *dir_cores, - const char *exts, bool show_hidden_files, - bool get_display_name); - core_info_t *core_info_get(core_info_list_t *list, size_t i); void core_info_free_current_core(core_info_state_t *p_coreinfo); @@ -186,22 +166,20 @@ size_t core_info_count(void); bool core_info_list_update_missing_firmware(core_info_ctx_firmware_t *info, bool *set_missing_bios); -bool core_info_find(core_info_ctx_find_t *info); +bool core_info_find(const char *core_path, + core_info_t **core_info); -bool core_info_load( - core_info_ctx_find_t *info, +bool core_info_load(const char *core_path, core_info_state_t *p_coreinfo); bool core_info_database_supports_content_path(const char *database_path, const char *path); bool core_info_database_match_archive_member(const char *database_path); -bool core_info_unsupported_content_path(const char *path); - void core_info_qsort(core_info_list_t *core_info_list, enum core_info_list_qsort_type qsort_type); bool core_info_list_get_info(core_info_list_t *core_info_list, - core_info_t *out_info, const char *path); + core_info_t *out_info, const char *core_path); bool core_info_hw_api_supported(core_info_t *info); @@ -223,7 +201,7 @@ bool core_info_get_core_lock(const char *core_path, bool validate_path); core_info_state_t *coreinfo_get_ptr(void); -bool core_info_core_file_id_is_equal(const char* core_path_a, const char* core_path_b); +bool core_info_core_file_id_is_equal(const char *core_path_a, const char *core_path_b); RETRO_END_DECLS diff --git a/gfx/widgets/gfx_widget_load_content_animation.c b/gfx/widgets/gfx_widget_load_content_animation.c index fd2652e2a6..284ebb6cf2 100644 --- a/gfx/widgets/gfx_widget_load_content_animation.c +++ b/gfx/widgets/gfx_widget_load_content_animation.c @@ -284,13 +284,13 @@ bool gfx_widget_start_load_content_animation(void) const char *content_path = path_get(RARCH_PATH_CONTENT); const char *core_path = path_get(RARCH_PATH_CORE); playlist_t *playlist = playlist_get_cached(); + core_info_t *core_info = NULL; bool playlist_entry_found = false; bool has_content = false; bool has_system = false; bool has_db_name = false; - core_info_ctx_find_t core_info_finder; char icon_path[PATH_MAX_LENGTH]; icon_path[0] = '\0'; @@ -314,13 +314,10 @@ bool gfx_widget_start_load_content_animation(void) return false; /* Check core validity */ - core_info_finder.inf = NULL; - core_info_finder.path = core_path; - - if (!core_info_find(&core_info_finder)) + if (!core_info_find(core_path, &core_info)) return false; - core_path = core_info_finder.inf->path; + core_path = core_info->path; /* Parse content path * > If we have a cached playlist, attempt to find @@ -357,10 +354,8 @@ bool gfx_widget_start_load_content_animation(void) /* Check whether core matches... */ if (string_is_empty(entry_core_file) || - !string_starts_with_size( - entry_core_file, - core_info_finder.inf->core_file_id.str, - core_info_finder.inf->core_file_id.len)) + !string_starts_with(entry_core_file, + core_info->core_file_id.str)) entry = NULL; } } @@ -430,8 +425,8 @@ bool gfx_widget_start_load_content_animation(void) if (!has_system) { /* Use core display name, if available */ - if (!string_is_empty(core_info_finder.inf->display_name)) - strlcpy(state->system_name, core_info_finder.inf->display_name, + if (!string_is_empty(core_info->display_name)) + strlcpy(state->system_name, core_info->display_name, sizeof(state->system_name)); /* Otherwise, just use 'RetroArch' as a fallback */ else @@ -466,7 +461,7 @@ bool gfx_widget_start_load_content_animation(void) { const char *core_db_name = NULL; struct string_list *databases_list = - core_info_finder.inf->databases_list; + core_info->databases_list; /* We can only use the core db_name if the * core is associated with exactly one database */ diff --git a/menu/cbs/menu_cbs_get_value.c b/menu/cbs/menu_cbs_get_value.c index c734f81efe..9aea7fe040 100644 --- a/menu/cbs/menu_cbs_get_value.c +++ b/menu/cbs/menu_cbs_get_value.c @@ -451,19 +451,16 @@ static void menu_action_setting_disp_set_label_core_updater_entry( core_updater_list_get_filename(core_list, path, &entry) && !string_is_empty(entry->local_core_path)) { - core_info_ctx_find_t core_info; + core_info_t *core_info = NULL; /* Check whether core is installed * > Note: We search core_info here instead * of calling path_is_valid() since we don't * want to perform disk access every frame */ - core_info.inf = NULL; - core_info.path = entry->local_core_path; - - if (core_info_find(&core_info)) + if (core_info_find(entry->local_core_path, &core_info)) { /* Highlight locked cores */ - if (core_info.inf->is_locked) + if (core_info->is_locked) { s[0] = '['; s[1] = '#'; @@ -493,12 +490,12 @@ static void menu_action_setting_disp_set_label_core_manager_entry( const char *path, char *s2, size_t len2) { - core_info_ctx_find_t core_info; - const char *alt = list->list[i].alt - ? list->list[i].alt - : list->list[i].path; - *s = '\0'; - *w = 0; + core_info_t *core_info = NULL; + const char *alt = list->list[i].alt + ? list->list[i].alt + : list->list[i].path; + *s = '\0'; + *w = 0; if (alt) strlcpy(s2, alt, len2); @@ -507,11 +504,8 @@ static void menu_action_setting_disp_set_label_core_manager_entry( * > Note: We search core_info here instead of * calling core_info_get_core_lock() since we * don't want to perform disk access every frame */ - core_info.inf = NULL; - core_info.path = path; - - if (core_info_find(&core_info) && - core_info.inf->is_locked) + if (core_info_find(path, &core_info) && + core_info->is_locked) { s[0] = '['; s[1] = '!'; @@ -529,12 +523,12 @@ static void menu_action_setting_disp_set_label_core_lock( const char *path, char *s2, size_t len2) { - core_info_ctx_find_t core_info; - const char *alt = list->list[i].alt - ? list->list[i].alt - : list->list[i].path; - *s = '\0'; - *w = 0; + core_info_t *core_info = NULL; + const char *alt = list->list[i].alt + ? list->list[i].alt + : list->list[i].path; + *s = '\0'; + *w = 0; if (alt) strlcpy(s2, alt, len2); @@ -543,11 +537,8 @@ static void menu_action_setting_disp_set_label_core_lock( * > Note: We search core_info here instead of * calling core_info_get_core_lock() since we * don't want to perform disk access every frame */ - core_info.inf = NULL; - core_info.path = path; - - if (core_info_find(&core_info) && - core_info.inf->is_locked) + if (core_info_find(path, &core_info) && + core_info->is_locked) strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ON), len); else strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF), len); diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index c631cab8aa..e963e6d693 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -3556,44 +3556,36 @@ static int action_ok_path_manual_scan_directory(const char *path, static int action_ok_core_deferred_set(const char *new_core_path, const char *content_label, unsigned type, size_t idx, size_t entry_idx) { - char ext_name[255]; - char core_display_name[PATH_MAX_LENGTH]; + size_t selection = menu_navigation_get_selection(); + struct playlist_entry entry = {0}; + menu_handle_t *menu = menu_driver_get_ptr(); + core_info_t *core_info = NULL; + const char *core_display_name = NULL; char resolved_core_path[PATH_MAX_LENGTH]; char msg[PATH_MAX_LENGTH]; - size_t selection = menu_navigation_get_selection(); - struct playlist_entry entry = {0}; - menu_handle_t *menu = menu_driver_get_ptr(); - settings_t *settings = config_get_ptr(); - const char *path_libretro_info = settings->paths.path_libretro_info; - const char *path_dir_libretro = settings->paths.directory_libretro; - bool show_hidden_files = settings->bools.show_hidden_files; - ext_name[0] = '\0'; - core_display_name[0] = '\0'; - resolved_core_path[0] = '\0'; - msg[0] = '\0'; + resolved_core_path[0] = '\0'; + msg[0] = '\0'; - if (!menu) + if (!menu || + string_is_empty(new_core_path)) return menu_cbs_exit(); - if (!frontend_driver_get_core_extension(ext_name, sizeof(ext_name))) - return menu_cbs_exit(); + /* Get core display name */ + if (core_info_find(new_core_path, &core_info)) + core_display_name = core_info->display_name; - core_info_get_name(new_core_path, - core_display_name, sizeof(core_display_name), - path_libretro_info, - path_dir_libretro, - ext_name, - show_hidden_files, - true); + if (string_is_empty(core_display_name)) + core_display_name = path_basename_nocompression(new_core_path); + /* Get 'real' core path */ strlcpy(resolved_core_path, new_core_path, sizeof(resolved_core_path)); playlist_resolve_path(PLAYLIST_SAVE, true, resolved_core_path, sizeof(resolved_core_path)); /* the update function reads our entry * as const, so these casts are safe */ entry.core_path = (char*)resolved_core_path; - entry.core_name = core_display_name; + entry.core_name = (char*)core_display_name; command_playlist_update_write( NULL, @@ -5200,19 +5192,16 @@ static int action_ok_add_to_favorites(const char *path, { if (!string_is_empty(path_get(RARCH_PATH_CORE))) { - core_info_ctx_find_t core_info; + core_info_t *core_info = NULL; /* >> core_path */ strlcpy(core_path, path_get(RARCH_PATH_CORE), sizeof(core_path)); /* >> core_name * (always use display name, if available) */ - core_info.inf = NULL; - core_info.path = core_path; - - if (core_info_find(&core_info)) - if (!string_is_empty(core_info.inf->display_name)) - strlcpy(core_name, core_info.inf->display_name, + if (core_info_find(core_path, &core_info)) + if (!string_is_empty(core_info->display_name)) + strlcpy(core_name, core_info->display_name, sizeof(core_name)); } @@ -5336,19 +5325,16 @@ static int action_ok_add_to_favorites_playlist(const char *path, /* > core_path + core_name */ if (!string_is_empty(entry->core_path) && !string_is_empty(entry->core_name)) { - core_info_ctx_find_t core_info; + core_info_t *core_info = NULL; /* >> core_path */ string_list_append(str_list, entry->core_path, attr); /* >> core_name * (always use display name, if available) */ - core_info.inf = NULL; - core_info.path = entry->core_path; - - if (core_info_find(&core_info)) - if (!string_is_empty(core_info.inf->display_name)) - strlcpy(core_display_name, core_info.inf->display_name, sizeof(core_display_name)); + if (core_info_find(entry->core_path, &core_info)) + if (!string_is_empty(core_info->display_name)) + strlcpy(core_display_name, core_info->display_name, sizeof(core_display_name)); if (!string_is_empty(core_display_name)) string_list_append(str_list, core_display_name, attr); @@ -7181,19 +7167,17 @@ int action_ok_core_lock(const char *path, if (!core_info_set_core_lock(core_path, lock)) { const char *core_name = NULL; - core_info_ctx_find_t core_info; + core_info_t *core_info = NULL; char msg[PATH_MAX_LENGTH]; msg[0] = '\0'; /* Need to fetch core name for error message */ - core_info.inf = NULL; - core_info.path = core_path; /* If core is found, use display name */ - if (core_info_find(&core_info) && - core_info.inf->display_name) - core_name = core_info.inf->display_name; + if (core_info_find(core_path, &core_info) && + core_info->display_name) + core_name = core_info->display_name; /* If not, use core file name */ else core_name = path_basename_nocompression(core_path); @@ -7240,20 +7224,18 @@ static int action_ok_core_delete(const char *path, /* Check whether core is locked */ if (core_info_get_core_lock(core_path, true)) { - const char *core_name = NULL; - core_info_ctx_find_t core_info; + const char *core_name = NULL; + core_info_t *core_info = NULL; char msg[PATH_MAX_LENGTH]; msg[0] = '\0'; /* Need to fetch core name for notification */ - core_info.inf = NULL; - core_info.path = core_path; /* If core is found, use display name */ - if (core_info_find(&core_info) && - core_info.inf->display_name) - core_name = core_info.inf->display_name; + if (core_info_find(core_path, &core_info) && + core_info->display_name) + core_name = core_info->display_name; /* If not, use core file name */ else core_name = path_basename_nocompression(core_path); diff --git a/menu/cbs/menu_cbs_start.c b/menu/cbs/menu_cbs_start.c index 567e4b3a20..10dd772b6d 100644 --- a/menu/cbs/menu_cbs_start.c +++ b/menu/cbs/menu_cbs_start.c @@ -571,20 +571,18 @@ static int action_start_core_lock( /* ...Otherwise, attempt to unlock it */ if (!core_info_set_core_lock(core_path, false)) { - const char *core_name = NULL; - core_info_ctx_find_t core_info; + const char *core_name = NULL; + core_info_t *core_info = NULL; char msg[PATH_MAX_LENGTH]; msg[0] = '\0'; /* Need to fetch core name for error message */ - core_info.inf = NULL; - core_info.path = core_path; /* If core is found, use display name */ - if (core_info_find(&core_info) && - core_info.inf->display_name) - core_name = core_info.inf->display_name; + if (core_info_find(core_path, &core_info) && + core_info->display_name) + core_name = core_info->display_name; /* If not, use core file name */ else core_name = path_basename(core_path); diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 6a6da555e9..0e1b0084b0 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -65,25 +65,23 @@ static int menu_action_sublabel_file_browser_core(file_list_t *list, unsigned type, unsigned i, const char *label, const char *path, char *s, size_t len) { - core_info_ctx_find_t core_info; + core_info_t *core_info = NULL; /* Set sublabel prefix */ strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_INFO_LICENSES), len); strlcat(s, ": ", len); /* Search for specified core */ - core_info.inf = NULL; - core_info.path = path; - if (core_info_find(&core_info) && - core_info.inf->licenses_list) + if (core_info_find(path, &core_info) && + core_info->licenses_list) { char tmp[MENU_SUBLABEL_MAX_LENGTH]; tmp[0] = '\0'; /* Add license text */ string_list_join_concat(tmp, sizeof(tmp), - core_info.inf->licenses_list, ", "); + core_info->licenses_list, ", "); strlcat(s, tmp, len); return 1; } diff --git a/menu/cbs/menu_cbs_title.c b/menu/cbs/menu_cbs_title.c index 06bdbcbcc5..359a7426f8 100644 --- a/menu/cbs/menu_cbs_title.c +++ b/menu/cbs/menu_cbs_title.c @@ -408,7 +408,7 @@ static int action_get_title_deferred_playlist_list(const char *path, const char static int action_get_title_deferred_core_backup_list( const char *core_path, const char *prefix, char *s, size_t len) { - core_info_ctx_find_t core_info; + core_info_t *core_info = NULL; if (string_is_empty(core_path) || string_is_empty(prefix)) return 0; @@ -417,17 +417,14 @@ static int action_get_title_deferred_core_backup_list( strlcpy(s, prefix, len); strlcat(s, ": ", len); - /* Search for specified core */ - core_info.inf = NULL; - core_info.path = core_path; - - /* If core is found, add display name */ - if (core_info_find(&core_info) && - core_info.inf->display_name) - strlcat(s, core_info.inf->display_name, len); + /* Search for specified core + * > If core is found, add display name */ + if (core_info_find(core_path, &core_info) && + core_info->display_name) + strlcat(s, core_info->display_name, len); else { - /* If not, use core file name */ + /* > If not, use core file name */ const char *core_filename = path_basename_nocompression(core_path); if (!string_is_empty(core_filename)) @@ -463,19 +460,15 @@ static int action_get_core_information_list( if ((menu_type == FILE_TYPE_DOWNLOAD_CORE) || (menu_type == MENU_SETTING_ACTION_CORE_MANAGER_OPTIONS)) { - const char *core_path = path; - core_info_ctx_find_t core_info_finder; + core_info_t *core_info_menu = NULL; - if (string_is_empty(core_path)) + if (string_is_empty(path)) goto error; /* Core updater/manager entry - search for * corresponding core info */ - core_info_finder.inf = NULL; - core_info_finder.path = core_path; - - if (core_info_find(&core_info_finder)) - core_info = core_info_finder.inf; + if (core_info_find(path, &core_info_menu)) + core_info = core_info_menu; } else core_info_get_current_core(&core_info); diff --git a/menu/drivers/materialui.c b/menu/drivers/materialui.c index 735ea932f8..9282df0fe9 100644 --- a/menu/drivers/materialui.c +++ b/menu/drivers/materialui.c @@ -9066,7 +9066,7 @@ static int materialui_list_push(void *data, void *userdata, MENU_SETTING_ACTION_FAVORITES_DIR, 0, 0); core_info_get_list(&list); - if (core_info_list_num_info_files(list)) + if (list->info_count > 0) { menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DOWNLOADED_FILE_DETECT_CORE_LIST), diff --git a/menu/drivers/ozone/ozone.c b/menu/drivers/ozone/ozone.c index d671faa137..f736b7398d 100644 --- a/menu/drivers/ozone/ozone.c +++ b/menu/drivers/ozone/ozone.c @@ -1456,7 +1456,7 @@ static int ozone_list_push(void *data, void *userdata, MENU_SETTING_ACTION_FAVORITES_DIR, 0, 0); core_info_get_list(&list); - if (core_info_list_num_info_files(list)) + if (list->info_count > 0) { menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DOWNLOADED_FILE_DETECT_CORE_LIST), diff --git a/menu/drivers/stripes.c b/menu/drivers/stripes.c index 155e448ba1..7c64a13d5d 100644 --- a/menu/drivers/stripes.c +++ b/menu/drivers/stripes.c @@ -4144,7 +4144,7 @@ static int stripes_list_push(void *data, void *userdata, MENU_SETTING_ACTION_FAVORITES_DIR, 0, 0); core_info_get_list(&list); - if (core_info_list_num_info_files(list)) + if (list->info_count > 0) { menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DOWNLOADED_FILE_DETECT_CORE_LIST), diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 0609ba0b33..c8725bbc39 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -6799,7 +6799,7 @@ static int xmb_list_push(void *data, void *userdata, MENU_SETTING_ACTION_FAVORITES_DIR, 0, 0); core_info_get_list(&list); - if (core_info_list_num_info_files(list)) + if (list->info_count > 0) menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DOWNLOADED_FILE_DETECT_CORE_LIST), msg_hash_to_str(MENU_ENUM_LABEL_DOWNLOADED_FILE_DETECT_CORE_LIST), diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 15bab6631c..7c1a90e13a 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -471,22 +471,19 @@ static int menu_displaylist_parse_core_info(menu_displaylist_info_t *info, if ((info->type == FILE_TYPE_DOWNLOAD_CORE) || (info->type == MENU_SETTING_ACTION_CORE_MANAGER_OPTIONS)) { - core_info_ctx_find_t core_info_finder; + core_info_t *core_info_menu = NULL; core_path = info->path; /* Core updater entry - search for corresponding * core info */ - core_info_finder.inf = NULL; - core_info_finder.path = core_path; - - if (core_info_find(&core_info_finder)) - core_info = core_info_finder.inf; + if (core_info_find(core_path, &core_info_menu)) + core_info = core_info_menu; } else if (core_info_get_current_core(&core_info) && core_info) core_path = core_info->path; - if (!core_info || !core_info->config_data) + if (!core_info || !core_info->has_info) { if (menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_CORE_INFORMATION_AVAILABLE), @@ -3074,7 +3071,7 @@ static unsigned menu_displaylist_parse_information_list(file_list_t *info_list) !string_is_equal(system->library_name, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_CORE)) ) - && core_info && core_info->config_data + && core_info && core_info->has_info ) if (menu_entries_append_enum(info_list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_INFORMATION), @@ -3843,18 +3840,15 @@ static unsigned menu_displaylist_parse_content_information( } else { - core_info_ctx_find_t core_info; + core_info_t *core_info = NULL; /* 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)) - if (!string_is_empty(core_info.inf->display_name)) - strlcpy(core_name, core_info.inf->display_name, sizeof(core_name)); + if (core_info_find(core_path, &core_info)) + if (!string_is_empty(core_info->display_name)) + strlcpy(core_name, core_info->display_name, sizeof(core_name)); } /* Content label */ @@ -6031,7 +6025,7 @@ unsigned menu_displaylist_build_list( { core_info_list_t *info_list = NULL; core_info_get_list(&info_list); - if (core_info_list_num_info_files(info_list)) + if (info_list->info_count > 0) { if (menu_entries_append_enum(list, msg_hash_to_str( diff --git a/playlist.c b/playlist.c index 198732f91e..95376ba965 100644 --- a/playlist.c +++ b/playlist.c @@ -2866,17 +2866,14 @@ bool playlist_entry_has_core(const struct playlist_entry *entry) * core association */ core_info_t *playlist_entry_get_core_info(const struct playlist_entry* entry) { - core_info_ctx_find_t core_info; + core_info_t *core_info = NULL; if (!playlist_entry_has_core(entry)) return NULL; /* Search for associated core */ - core_info.inf = NULL; - core_info.path = entry->core_path; - - if (core_info_find(&core_info)) - return core_info.inf; + if (core_info_find(entry->core_path, &core_info)) + return core_info; return NULL; } @@ -2888,7 +2885,7 @@ core_info_t *playlist_entry_get_core_info(const struct playlist_entry* entry) * default core association */ core_info_t *playlist_get_default_core_info(playlist_t* playlist) { - core_info_ctx_find_t core_info; + core_info_t *core_info = NULL; if (!playlist || string_is_empty(playlist->default_core_path) || @@ -2898,11 +2895,8 @@ core_info_t *playlist_get_default_core_info(playlist_t* playlist) return NULL; /* Search for associated core */ - core_info.inf = NULL; - core_info.path = playlist->default_core_path; - - if (core_info_find(&core_info)) - return core_info.inf; + if (core_info_find(playlist->default_core_path, &core_info)) + return core_info; return NULL; } diff --git a/retroarch.c b/retroarch.c index 3a13db7a34..08408ef136 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1986,17 +1986,15 @@ static int generic_menu_iterate( #endif case MENU_ENUM_LABEL_CORE_MANAGER_ENTRY: { - core_info_ctx_find_t core_info; - const char *path = selection_buf->list[selection].path; - /* Search for specified core */ - core_info.inf = NULL; - core_info.path = path; + core_info_t *core_info = NULL; + const char *path = selection_buf->list[selection].path; + /* Search for specified core */ if ( path - && core_info_find(&core_info) - && !string_is_empty(core_info.inf->description)) + && core_info_find(path, &core_info) + && !string_is_empty(core_info->description)) strlcpy(menu->menu_state_msg, - core_info.inf->description, + core_info->description, sizeof(menu->menu_state_msg)); else strlcpy(menu->menu_state_msg, @@ -13618,7 +13616,6 @@ bool command_event(enum event_command cmd, void *data) break; case CMD_EVENT_LOAD_CORE_PERSIST: { - core_info_ctx_find_t info_find; rarch_system_info_t *system_info = &p_rarch->runloop_system; struct retro_system_info *system = &system_info->info; const char *core_path = path_get(RARCH_PATH_CORE); @@ -13634,9 +13631,8 @@ bool command_event(enum event_command cmd, void *data) system, &system_info->load_no_content)) return false; - info_find.path = core_path; - if (!core_info_load(&info_find, &p_rarch->core_info_st)) + if (!core_info_load(core_path, &p_rarch->core_info_st)) { #ifdef HAVE_DYNAMIC return false; diff --git a/runtime_file.c b/runtime_file.c index 64d8dece3d..b90434f990 100644 --- a/runtime_file.c +++ b/runtime_file.c @@ -238,7 +238,7 @@ runtime_log_t *runtime_log_init( char log_file_dir[PATH_MAX_LENGTH]; char log_file_path[PATH_MAX_LENGTH]; char tmp_buf[PATH_MAX_LENGTH]; - core_info_ctx_find_t core_info; + core_info_t *core_info = NULL; runtime_log_t *runtime_log = NULL; content_name[0] = '\0'; @@ -266,12 +266,9 @@ runtime_log_t *runtime_log_init( * we are performing aggregate (not per core) logging, * since content name is sometimes dependent upon core * (e.g. see TyrQuake below) */ - core_info.inf = NULL; - core_info.path = core_path; - - if (core_info_find(&core_info) && - core_info.inf->core_name) - strlcpy(core_name, core_info.inf->core_name, sizeof(core_name)); + if (core_info_find(core_path, &core_info) && + core_info->core_name) + strlcpy(core_name, core_info->core_name, sizeof(core_name)); if (string_is_empty(core_name)) return NULL; diff --git a/tasks/task_core_backup.c b/tasks/task_core_backup.c index 09c7752f00..1af84a64da 100644 --- a/tasks/task_core_backup.c +++ b/tasks/task_core_backup.c @@ -556,15 +556,12 @@ void *task_push_core_backup( core_name = core_display_name; else { - core_info_ctx_find_t core_info; - - core_info.inf = NULL; - core_info.path = core_path; + core_info_t *core_info = NULL; /* If core is found, use display name */ - if (core_info_find(&core_info) && - core_info.inf->display_name) - core_name = core_info.inf->display_name; + if (core_info_find(core_path, &core_info) && + core_info->display_name) + core_name = core_info->display_name; else { /* If not, use core file name */ @@ -926,8 +923,8 @@ bool task_push_core_restore(const char *backup_path, const char *dir_libretro, bool *core_loaded) { task_finder_data_t find_data; - core_info_ctx_find_t core_info; enum core_backup_type backup_type; + core_info_t *core_info = NULL; const char *core_name = NULL; retro_task_t *task = NULL; core_backup_handle_t *backup_handle = NULL; @@ -974,17 +971,14 @@ bool task_push_core_restore(const char *backup_path, const char *dir_libretro, goto error; } - /* Get core name */ - core_info.inf = NULL; - core_info.path = core_path; - - /* If core is found, use display name */ - if (core_info_find(&core_info) && - core_info.inf->display_name) - core_name = core_info.inf->display_name; + /* Get core name + * > If core is found, use display name */ + if (core_info_find(core_path, &core_info) && + core_info->display_name) + core_name = core_info->display_name; else { - /* If not, use core file name */ + /* > If not, use core file name */ core_name = path_basename(core_path); if (string_is_empty(core_name)) diff --git a/tasks/task_playlist_manager.c b/tasks/task_playlist_manager.c index c929ec38e1..8163279002 100644 --- a/tasks/task_playlist_manager.c +++ b/tasks/task_playlist_manager.c @@ -474,17 +474,14 @@ static void pl_manager_validate_core_association( else { char core_display_name[PATH_MAX_LENGTH]; - core_info_ctx_find_t core_info; + core_info_t *core_info = NULL; core_display_name[0] = '\0'; /* Search core info */ - core_info.inf = NULL; - core_info.path = core_path; - - if (core_info_find(&core_info) && - !string_is_empty(core_info.inf->display_name)) - strlcpy(core_display_name, core_info.inf->display_name, + if (core_info_find(core_path, &core_info) && + !string_is_empty(core_info->display_name)) + strlcpy(core_display_name, core_info->display_name, sizeof(core_display_name)); /* If core_display_name string is empty, it means the diff --git a/ui/drivers/qt/qt_playlist.cpp b/ui/drivers/qt/qt_playlist.cpp index 5fb34742fc..41c09fc716 100644 --- a/ui/drivers/qt/qt_playlist.cpp +++ b/ui/drivers/qt/qt_playlist.cpp @@ -981,7 +981,7 @@ void MainWindow::onPlaylistWidgetContextMenuRequested(const QPoint&) if (!specialPlaylist && selectedAction->parent() == associateMenu.data()) { - core_info_ctx_find_t coreInfo; + core_info_t *coreInfo = NULL; playlist_t *cachedPlaylist = playlist_get_cached(); playlist_t *playlist = NULL; bool loadPlaylist = true; @@ -1010,14 +1010,11 @@ void MainWindow::onPlaylistWidgetContextMenuRequested(const QPoint&) if (playlist) { /* Get core info */ - coreInfo.inf = NULL; - coreInfo.path = corePath; - - if (core_info_find(&coreInfo)) + if (core_info_find(corePath, &coreInfo)) { /* Set new core association */ - playlist_set_default_core_path(playlist, coreInfo.inf->path); - playlist_set_default_core_name(playlist, coreInfo.inf->display_name); + playlist_set_default_core_path(playlist, coreInfo->path); + playlist_set_default_core_name(playlist, coreInfo->display_name); } else { diff --git a/ui/drivers/ui_qt.cpp b/ui/drivers/ui_qt.cpp index f605e6133d..d447a421c4 100644 --- a/ui/drivers/ui_qt.cpp +++ b/ui/drivers/ui_qt.cpp @@ -2308,22 +2308,17 @@ QVector > MainWindow::getCoreInfo() { unsigned i; QVector > infoList; - core_info_ctx_find_t core_info_finder; QHash currentCore = getSelectedCore(); - const core_info_t *core_info = NULL; + core_info_t *core_info = NULL; QByteArray currentCorePathArray = currentCore["core_path"].toUtf8(); const char *current_core_path_data = currentCorePathArray.constData(); /* Search for current core */ - core_info_finder.inf = NULL; - core_info_finder.path = current_core_path_data; - - if (core_info_find(&core_info_finder)) - core_info = core_info_finder.inf; + core_info_find(current_core_path_data, &core_info); if ( currentCore["core_path"].isEmpty() || !core_info - || !core_info->config_data) + || !core_info->has_info) { QHash hash; @@ -2780,7 +2775,7 @@ void MainWindow::loadContent(const QHash &contentHash) const char *contentCrc32 = NULL; QVariantMap coreMap = m_launchWithComboBox->currentData(Qt::UserRole).value(); core_selection coreSelection = static_cast(coreMap.value("core_selection").toInt()); - core_info_ctx_find_t core_info; + core_info_t *coreInfo = NULL; contentDbNameFull[0] = '\0'; @@ -2876,12 +2871,9 @@ void MainWindow::loadContent(const QHash &contentHash) /* Search for specified core - ensures path * is 'sanitised' */ - core_info.inf = NULL; - core_info.path = corePath; - - if (core_info_find(&core_info) && - !string_is_empty(core_info.inf->path)) - corePath = core_info.inf->path; + if (core_info_find(corePath, &coreInfo) && + !string_is_empty(coreInfo->path)) + corePath = coreInfo->path; /* Add lpl extension to db_name, if required */ if (!string_is_empty(contentDbName)) @@ -3056,7 +3048,6 @@ void MainWindow::setCoreActions() if (!defaultCorePath.isEmpty()) { QString currentPlaylistItemDataString; - core_info_ctx_find_t core_info_finder; bool allPlaylists = false; int row = 0; QByteArray defaultCorePathArray = defaultCorePath.toUtf8(); @@ -3071,6 +3062,8 @@ void MainWindow::setCoreActions() for (row = 0; row < m_listWidget->count(); row++) { + core_info_t *coreInfo = NULL; + if (allPlaylists) { QFileInfo info; @@ -3084,14 +3077,9 @@ void MainWindow::setCoreActions() } /* Search for default core */ - core_info_finder.inf = NULL; - core_info_finder.path = default_core_path_data; - - if (core_info_find(&core_info_finder)) + if (core_info_find(default_core_path_data, &coreInfo)) { - const core_info_t *info = core_info_finder.inf; - - if (m_launchWithComboBox->findText(info->core_name) == -1) + if (m_launchWithComboBox->findText(coreInfo->core_name) == -1) { int i = 0; bool found_existing = false; @@ -3106,9 +3094,9 @@ void MainWindow::setCoreActions() const char *core_path_data = CorePathArray.constData(); if (string_starts_with(path_basename(core_path_data), - info->core_file_id.str) || - map.value("core_name").toString() == info->core_name || - map.value("core_name").toString() == info->display_name) + coreInfo->core_file_id.str) || + map.value("core_name").toString() == coreInfo->core_name || + map.value("core_name").toString() == coreInfo->display_name) { found_existing = true; break; @@ -3118,10 +3106,10 @@ void MainWindow::setCoreActions() if (!found_existing) { QVariantMap comboBoxMap; - comboBoxMap["core_name"] = info->core_name; - comboBoxMap["core_path"] = info->path; + comboBoxMap["core_name"] = coreInfo->core_name; + comboBoxMap["core_path"] = coreInfo->path; comboBoxMap["core_selection"] = CORE_SELECTION_PLAYLIST_DEFAULT; - m_launchWithComboBox->addItem(info->core_name, QVariant::fromValue(comboBoxMap)); + m_launchWithComboBox->addItem(coreInfo->core_name, QVariant::fromValue(comboBoxMap)); } } }