diff --git a/core_info.c b/core_info.c index bb0e4583a2..5726df4135 100644 --- a/core_info.c +++ b/core_info.c @@ -2207,13 +2207,23 @@ static bool core_info_does_support_any_file(const core_info_t *core, static bool core_info_does_support_file( const core_info_t *core, const char *path) { + const char *basename, *ext; + if (!core || !core->supported_extensions_list) return false; if (string_is_empty(path)) return false; + basename = path_basename(path); + + /* if a core has / in its list of supported extensions, the core + supports loading of directories on the host file system */ + if (string_is_empty(basename)) + return string_list_find_elem(core->supported_extensions_list, "/"); + + ext = strrchr(basename, '.'); return string_list_find_elem_prefix( - core->supported_extensions_list, ".", path_get_extension(path)); + core->supported_extensions_list, ".", (ext ? ext + 1 : "")); } /* qsort_r() is not in standard C, sadly. */ @@ -2452,10 +2462,19 @@ void core_info_list_get_supported_cores(core_info_list_t *core_info_list, struct string_list *list = NULL; #endif core_info_state_t *p_coreinfo = &core_info_st; + char dir_path[PATH_MAX_LENGTH]; if (!core_info_list) return; + if (path_is_directory(path)) + { + /* Add a slash so core_info_does_support_file can know it is + a directory without having to check the file system again. */ + fill_pathname_join_special(dir_path, path, "", sizeof(dir_path)); + path = dir_path; + } + p_coreinfo->tmp_path = path; #ifdef HAVE_COMPRESSION diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 2eacff6bed..2e154a3e14 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -2014,6 +2014,17 @@ static int file_load_with_detect_core_wrapper( core_info_get_list(&list); + /* If loading a directory, use only path */ + if (path == NULL && !string_is_empty(menu_path_new)) + { + strlcpy(menu->deferred_path, menu_path_new, + sizeof(menu->deferred_path)); + strlcpy(menu->detect_content_path, menu_path_new, + sizeof(menu->detect_content_path)); + path = menu->detect_content_path; + menu_path_new[0] = '\0'; + } + def_info.data = list; def_info.dir = menu_path_new; def_info.path = path; @@ -2101,6 +2112,10 @@ static int action_ok_file_load_with_detect_core_carchive( static int action_ok_file_load_with_detect_core(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { + bool is_dir = (entry_idx == FILE_TYPE_USE_DIRECTORY + && string_is_equal(label, + msg_hash_to_str(MENU_ENUM_LABEL_USE_THIS_DIRECTORY))); + if (is_dir) path = NULL; type = 0; label = NULL; @@ -7985,7 +8000,17 @@ static int action_ok_disk_image_append(const char *path, if (!string_is_empty(menu_path)) { - if (!string_is_empty(path)) + bool is_dir = (entry_idx == FILE_TYPE_USE_DIRECTORY + && string_is_equal(label, + msg_hash_to_str(MENU_ENUM_LABEL_USE_THIS_DIRECTORY))); + if (is_dir) + { + size_t past_slash; + strlcpy(image_path, menu_path, sizeof(image_path)); + past_slash = fill_pathname_slash(image_path, sizeof(image_path)); + if (past_slash > 1) image_path[past_slash - 1] = '\0'; + } + else if (!string_is_empty(path)) fill_pathname_join_special(image_path, menu_path, path, sizeof(image_path)); else diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 53de761247..d1ad8bf063 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -310,6 +310,14 @@ static int filebrowser_parse( FILE_TYPE_USE_DIRECTORY, 0 ,0); break; default: + /* if a core has / in its list of supported extensions, the core + supports loading of directories on the host file system */ + if (exts && strchr(exts, '/')) + menu_entries_prepend(info_list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_USE_THIS_DIRECTORY), + msg_hash_to_str(MENU_ENUM_LABEL_USE_THIS_DIRECTORY), + MSG_UNKNOWN, + FILE_TYPE_PLAIN, 0, FILE_TYPE_USE_DIRECTORY); break; }