From b66819392385d1af71f25f9a00c93a083c2e40d6 Mon Sep 17 00:00:00 2001 From: Brian Koropoff Date: Wed, 8 Nov 2017 16:59:52 -0800 Subject: [PATCH 1/4] scanner: allow matching archives by member This allows more flexible detection of content packaged as multiple compressed files (e.g. MAME). --- core_info.c | 44 +++++++++++++++++++++++++++++++++++++++++++ core_info.h | 3 +++ tasks/task_database.c | 11 ++++++++++- 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/core_info.c b/core_info.c index 659a71fc6d..c2989d883b 100644 --- a/core_info.c +++ b/core_info.c @@ -389,6 +389,10 @@ static core_info_list_t *core_info_list_new(const char *path) &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; + core_info[i].config_data = conf; } else @@ -823,6 +827,46 @@ size_t core_info_list_num_info_files(core_info_list_t *core_info_list) return num; } +bool core_info_database_match_archive_member(const char *database_path) +{ + char *database = NULL; + const char *new_path = path_basename(database_path); + + if (string_is_empty(new_path)) + return false; + + database = strdup(new_path); + + if (string_is_empty(database)) + goto error; + + path_remove_extension(database); + + if (core_info_curr_list) + { + size_t i; + + for (i = 0; i < core_info_curr_list->count; i++) + { + const core_info_t *info = &core_info_curr_list->list[i]; + + if (!info->database_match_archive_member) + continue; + + if (!string_list_find_elem(info->databases_list, database)) + continue; + + free(database); + return true; + } + } + +error: + if (database) + free(database); + return false; +} + bool core_info_database_supports_content_path(const char *database_path, const char *path) { char *database = NULL; diff --git a/core_info.h b/core_info.h index 2800cd2edf..a151091673 100644 --- a/core_info.h +++ b/core_info.h @@ -38,6 +38,7 @@ typedef struct typedef struct { bool supports_no_game; + bool database_match_archive_member; size_t firmware_count; char *path; void *config_data; @@ -120,6 +121,8 @@ bool core_info_load(core_info_ctx_find_t *info); 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); RETRO_END_DECLS diff --git a/tasks/task_database.c b/tasks/task_database.c index 6e49a4125a..cef5171480 100644 --- a/tasks/task_database.c +++ b/tasks/task_database.c @@ -797,6 +797,7 @@ static int database_info_list_iterate_found_match( database_info_get_current_element_name(db); database_info_t *db_info_entry = &db_state->info->list[db_state->entry_index]; + char *hash; db_crc[0] = '\0'; db_playlist_path[0] = '\0'; @@ -827,6 +828,11 @@ static int database_info_list_iterate_found_match( entry_path_str, archive_name, '#', PATH_MAX_LENGTH * sizeof(char)); + if (core_info_database_match_archive_member( + db_state->list->elems[db_state->list_index].data) && + (hash = strchr(entry_path_str, '#'))) + *hash = '\0'; + #if 0 RARCH_LOG("Found match in database !\n"); @@ -900,7 +906,10 @@ static int task_database_iterate_crc_lookup( query[0] = '\0'; /* don't scan files that can't be in this database */ - if (!core_info_database_supports_content_path( + if (!(path_contains_compressed_file(name) && + core_info_database_match_archive_member( + db_state->list->elems[db_state->list_index].data)) && + !core_info_database_supports_content_path( db_state->list->elems[db_state->list_index].data, name)) return database_info_list_iterate_next(db_state); From bedf65e72ee87e950668d4ed542f05526f0735db Mon Sep 17 00:00:00 2001 From: Brian Koropoff Date: Wed, 8 Nov 2017 18:11:05 -0800 Subject: [PATCH 2/4] scanner: prioritize databases with recent matches This should improve performance when scanning many files in a row that all match against the same database, which is the expectation. --- tasks/task_database.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tasks/task_database.c b/tasks/task_database.c index cef5171480..3f3b158bc7 100644 --- a/tasks/task_database.c +++ b/tasks/task_database.c @@ -868,6 +868,17 @@ static int database_info_list_iterate_found_match( free(db_playlist_base_str); free(db_crc); + /* Move database to start since we are likely to match against it + again */ + if (db_state->list_index != 0) + { + struct string_list_elem entry = db_state->list->elems[db_state->list_index]; + memmove(&db_state->list->elems[1], + &db_state->list->elems[0], + sizeof(entry) * db_state->list_index); + db_state->list->elems[0] = entry; + } + return 0; } From 1db8ae9f6038553d93a9beef8ddcd7e7ffd77cb5 Mon Sep 17 00:00:00 2001 From: Brian Koropoff Date: Wed, 8 Nov 2017 18:22:26 -0800 Subject: [PATCH 3/4] Update changelog --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 6de0f51c9e..aa525a0463 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -45,6 +45,7 @@ - SCANNER: Support CHD files. - SCANNER: Support Gamecube ISO scanning. - SCANNER: Use primary data track of disc images for CRC lookups rather than cue files. This is slower but finds matches more reliably, and is necessary for CHD files to work at all. Update your databases! +- SCANNER: Fall back on looking inside archives when matching MAME/FBA content (most recent cores only). If you had difficulty with content being detected before, you may have better luck now. Update your databases and core info! # 1.6.7 - SCANNER: Fix directory scanning. From 711877b05653079d2163f02d0cb8b7de4389b7e7 Mon Sep 17 00:00:00 2001 From: Brian Koropoff Date: Wed, 8 Nov 2017 19:41:13 -0800 Subject: [PATCH 4/4] content: preserve info for history/favorites If the content came from a playlist, use the original label. Preserve the core path and name in the favorites list. --- command.c | 23 ++++++++++++++++++++--- menu/cbs/menu_cbs_ok.c | 12 +++++++----- retroarch.h | 1 + tasks/task_content.c | 12 +++++++++++- tasks/tasks_internal.h | 1 + 5 files changed, 40 insertions(+), 9 deletions(-) diff --git a/command.c b/command.c index e458b1d640..97b847c484 100644 --- a/command.c +++ b/command.c @@ -2237,18 +2237,35 @@ TODO: Add a setting for these tweaks */ ui_companion_driver_toggle(); break; case CMD_EVENT_ADD_TO_FAVORITES: + { + global_t *global = global_get_ptr(); + rarch_system_info_t *sys_info = runloop_get_system_info(); + const char *core_name = NULL; + const char *core_path = NULL; + const char *label = NULL; + + if (sys_info) + { + core_name = sys_info->info.library_name; + core_path = path_get(RARCH_PATH_CORE); + } + + if (!string_is_empty(global->name.label)) + label = global->name.label; + playlist_push( g_defaults.content_favorites, (const char*)data, - NULL, - file_path_str(FILE_PATH_DETECT), - file_path_str(FILE_PATH_DETECT), + label, + core_path, + core_name, NULL, NULL ); playlist_write_file(g_defaults.content_favorites); runloop_msg_queue_push(msg_hash_to_str(MSG_ADDED_TO_FAVORITES), 1, 180, true); break; + } case CMD_EVENT_RESTART_RETROARCH: if (!frontend_driver_set_fork(FRONTEND_FORK_RESTART)) return false; diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 00725f6909..c00e8410e5 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -1566,7 +1566,7 @@ static int action_ok_playlist_entry_collection(const char *path, if (!task_push_load_content_from_playlist_from_menu( - new_core_path, path, + new_core_path, path, entry_label, &content_info, NULL, NULL)) return -1; @@ -1582,6 +1582,7 @@ static int action_ok_playlist_entry(const char *path, size_t selection_ptr = 0; playlist_t *playlist = g_defaults.content_history; const char *entry_path = NULL; + const char *entry_label = NULL; const char *core_path = NULL; const char *core_name = NULL; playlist_t *tmp_playlist = NULL; @@ -1598,7 +1599,7 @@ static int action_ok_playlist_entry(const char *path, selection_ptr = entry_idx; playlist_get_index(playlist, selection_ptr, - &entry_path, NULL, &core_path, &core_name, NULL, NULL); + &entry_path, &entry_label, &core_path, &core_name, NULL, NULL); if ( string_is_equal(core_path, file_path_str(FILE_PATH_DETECT)) && string_is_equal(core_name, file_path_str(FILE_PATH_DETECT))) @@ -1662,7 +1663,7 @@ static int action_ok_playlist_entry(const char *path, NULL, NULL); if (!task_push_load_content_from_playlist_from_menu( - core_path, path, + core_path, path, entry_label, &content_info, NULL, NULL)) return -1; @@ -1679,6 +1680,7 @@ static int action_ok_playlist_entry_start_content(const char *path, bool playlist_initialized = false; playlist_t *playlist = NULL; const char *entry_path = NULL; + const char *entry_label = NULL; const char *core_path = NULL; const char *core_name = NULL; playlist_t *tmp_playlist = NULL; @@ -1708,7 +1710,7 @@ static int action_ok_playlist_entry_start_content(const char *path, selection_ptr = rdb_entry_start_game_selection_ptr; playlist_get_index(playlist, selection_ptr, - &entry_path, NULL, &core_path, &core_name, NULL, NULL); + &entry_path, &entry_label, &core_path, &core_name, NULL, NULL); if ( string_is_equal(core_path, file_path_str(FILE_PATH_DETECT)) && string_is_equal(core_name, file_path_str(FILE_PATH_DETECT))) @@ -1772,7 +1774,7 @@ static int action_ok_playlist_entry_start_content(const char *path, playlist_info.idx, &path, NULL, NULL, NULL, NULL, NULL); if (!task_push_load_content_from_playlist_from_menu( - core_path, path, + core_path, path, entry_label, &content_info, NULL, NULL)) return -1; diff --git a/retroarch.h b/retroarch.h index a8600f665b..a0e813c571 100644 --- a/retroarch.h +++ b/retroarch.h @@ -225,6 +225,7 @@ typedef struct global char ups[8192]; char bps[8192]; char ips[8192]; + char label[8192]; char *remapfile; } name; diff --git a/tasks/task_content.c b/tasks/task_content.c index 65a4ab6974..d82d912e34 100644 --- a/tasks/task_content.c +++ b/tasks/task_content.c @@ -920,7 +920,9 @@ static bool task_load_content(content_ctx_info_t *content_info, { const char *core_path = NULL; const char *core_name = NULL; + const char *label = NULL; playlist_t *playlist_tmp = g_defaults.content_history; + global_t *global = global_get_ptr(); switch (path_is_media_type(tmp)) { @@ -955,13 +957,16 @@ static bool task_load_content(content_ctx_info_t *content_info, content_ctx->history_list_enable = settings->bools.history_list_enable; } + if (global && !string_is_empty(global->name.label)) + label = global->name.label; + if ( content_ctx->history_list_enable && playlist_tmp && playlist_push( playlist_tmp, tmp, - NULL, + label, core_path, core_name, NULL, @@ -1150,6 +1155,7 @@ bool task_push_start_dummy_core(content_ctx_info_t *content_info) bool task_push_load_content_from_playlist_from_menu( const char *core_path, const char *fullpath, + const char *label, content_ctx_info_t *content_info, retro_task_callback_t cb, void *user_data) @@ -1191,6 +1197,10 @@ bool task_push_load_content_from_playlist_from_menu( content_ctx.name_bps = strdup(global->name.bps); if (!string_is_empty(global->name.ups)) content_ctx.name_ups = strdup(global->name.ups); + if (label) + strlcpy(global->name.label, label, sizeof(global->name.label)); + else + global->name.label[0] = '\0'; } if (!string_is_empty(settings->paths.directory_system)) diff --git a/tasks/tasks_internal.h b/tasks/tasks_internal.h index e9174eac43..bf32504ef0 100644 --- a/tasks/tasks_internal.h +++ b/tasks/tasks_internal.h @@ -198,6 +198,7 @@ bool task_push_load_content_with_new_core_from_menu( bool task_push_load_content_from_playlist_from_menu( const char *core_path, const char *fullpath, + const char *label, content_ctx_info_t *content_info, retro_task_callback_t cb, void *user_data);