Menu support for loading directories as content if a core indicates supports for that (#17142)

A core needs to have "/" in its list of supported extensions to indicate support for loading directories.
If a core additionally supports the disk control interface, also support loading of directories as disk images.
This commit is contained in:
Bernhard Schelling 2024-10-31 09:56:30 +09:00 committed by GitHub
parent 5cc9721ea3
commit cab85c6f8d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 54 additions and 2 deletions

View File

@ -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

View File

@ -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

View File

@ -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;
}