diff --git a/dynamic.c b/dynamic.c index 03ad265027..344b4fd478 100644 --- a/dynamic.c +++ b/dynamic.c @@ -185,58 +185,6 @@ void libretro_free_system_info(struct retro_system_info *info) memset(info, 0, sizeof(*info)); } - -static bool find_first_libretro(char *path, size_t size, - const char *dir, const char *rom_path) -{ - size_t i; - bool ret = false; - const char *ext = path_get_extension(rom_path); - if (!ext || !*ext) - { - RARCH_ERR("Path has no extension. Cannot infer libretro implementation.\n"); - return false; - } - - RARCH_LOG("Searching for valid libretro implementation in: \"%s\".\n", dir); - - struct string_list *list = dir_list_new(dir, DYNAMIC_EXT, false); - if (!list) - { - RARCH_ERR("Couldn't open directory: \"%s\".\n", dir); - return false; - } - - for (i = 0; i < list->size && !ret; i++) - { - RARCH_LOG("Checking library: \"%s\".\n", list->elems[i].data); - - struct retro_system_info info = {0}; - dylib_t lib = libretro_get_system_info_lib(list->elems[i].data, &info, NULL); - if (!lib) - continue; - - if (!info.valid_extensions) - { - dylib_close(lib); - continue; - } - - struct string_list *supported_ext = string_split(info.valid_extensions, "|"); - - if (string_list_find_elem(supported_ext, ext)) - { - strlcpy(path, list->elems[i].data, size); - ret = true; - } - - string_list_free(supported_ext); - dylib_close(lib); - } - - dir_list_free(list); - return ret; -} #endif const struct retro_subsystem_info *libretro_find_subsystem_info(const struct retro_subsystem_info *info, unsigned num_info, @@ -307,19 +255,6 @@ static void load_symbols(bool is_dummy) else { #ifdef HAVE_DYNAMIC - if (path_is_directory(g_settings.libretro)) - { - char libretro_core_buffer[PATH_MAX]; - if (!find_first_libretro(libretro_core_buffer, sizeof(libretro_core_buffer), - g_settings.libretro, g_extern.fullpath)) - { - RARCH_ERR("libretro_path is a directory, but no valid libretro implementation was found.\n"); - rarch_fail(1, "load_dynamic()"); - } - - strlcpy(g_settings.libretro, libretro_core_buffer, sizeof(g_settings.libretro)); - } - // Need to use absolute path for this setting. It can be saved to ROM history, // and a relative path would break in that scenario. path_resolve_realpath(g_settings.libretro, sizeof(g_settings.libretro)); diff --git a/frontend/menu/backend/menu_common_backend.c b/frontend/menu/backend/menu_common_backend.c index 14e28ad554..feb15809c6 100644 --- a/frontend/menu/backend/menu_common_backend.c +++ b/frontend/menu/backend/menu_common_backend.c @@ -557,7 +557,7 @@ static int menu_settings_iterate(void *data, unsigned action) file_list_get_at_offset(rgui->selection_buf, rgui->selection_ptr, &label, &type); if (type == RGUI_SETTINGS_CORE) - label = rgui->libretro_dir; + label = g_settings.libretro_directory; else if (type == RGUI_SETTINGS_CONFIG) label = g_settings.rgui_config_directory; else if (type == RGUI_SETTINGS_DISK_APPEND) @@ -1469,7 +1469,7 @@ static int menu_common_iterate(void *data, unsigned action) } else if (menu_type == RGUI_LIBRETRO_DIR_PATH) { - strlcpy(rgui->libretro_dir, dir, sizeof(rgui->libretro_dir)); + strlcpy(g_settings.libretro_directory, dir, sizeof(g_settings.libretro_directory)); menu_init_core_info(rgui); menu_flush_stack_type(rgui, RGUI_SETTINGS_PATH_OPTIONS); } @@ -1536,7 +1536,7 @@ static int menu_common_iterate(void *data, unsigned action) } else // Present a selection. { - file_list_push(rgui->menu_stack, rgui->libretro_dir, RGUI_SETTINGS_DEFERRED_CORE, rgui->selection_ptr); + file_list_push(rgui->menu_stack, g_settings.libretro_directory, RGUI_SETTINGS_DEFERRED_CORE, rgui->selection_ptr); menu_clear_navigation(rgui); rgui->need_refresh = true; } @@ -2978,7 +2978,7 @@ static int menu_common_setting_set(void *data, unsigned setting, unsigned action case RGUI_LIBRETRO_DIR_PATH: if (action == RGUI_ACTION_START) { - *rgui->libretro_dir = '\0'; + *g_settings.libretro_directory = '\0'; menu_init_core_info(rgui); } break; @@ -3977,7 +3977,7 @@ static void menu_common_setting_set_label(char *type_str, size_t type_str_size, strlcpy(type_str, *g_extern.savestate_dir ? g_extern.savestate_dir : "", type_str_size); break; case RGUI_LIBRETRO_DIR_PATH: - strlcpy(type_str, *rgui->libretro_dir ? rgui->libretro_dir : "", type_str_size); + strlcpy(type_str, *g_settings.libretro_directory ? g_settings.libretro_directory : "", type_str_size); break; case RGUI_LIBRETRO_INFO_DIR_PATH: strlcpy(type_str, *g_settings.libretro_info_path ? g_settings.libretro_info_path : "", type_str_size); diff --git a/frontend/menu/disp/lakka.c b/frontend/menu/disp/lakka.c index 349b105535..e603c16e95 100644 --- a/frontend/menu/disp/lakka.c +++ b/frontend/menu/disp/lakka.c @@ -906,7 +906,7 @@ static void *lakka_init(void) menu_init_core_info(rgui); - rgui->core_info = core_info_list_new(*rgui->libretro_dir ? rgui->libretro_dir : "/usr/lib/libretro"); + rgui->core_info = core_info_list_new(*g_settings.libretro_directory ? g_settings.libretro_directory : "/usr/lib/libretro"); num_categories = rgui->core_info ? rgui->core_info->count + 1 : 1; diff --git a/frontend/menu/menu_common.c b/frontend/menu/menu_common.c index e62fc377fa..254f0be4ba 100644 --- a/frontend/menu/menu_common.c +++ b/frontend/menu/menu_common.c @@ -39,7 +39,7 @@ void menu_update_system_info(void *data, bool *load_no_rom) #ifdef HAVE_DYNAMIC libretro_free_system_info(&rgui->info); - if (!path_is_directory(g_settings.libretro)) + if (*g_settings.libretro) { libretro_get_system_info(g_settings.libretro, &rgui->info, load_no_rom); #endif @@ -204,17 +204,6 @@ static void menu_update_libretro_info(void *data) if (!rgui) return; - *rgui->libretro_dir = '\0'; - -#if defined(RARCH_CONSOLE) - strlcpy(rgui->libretro_dir, default_paths.core_dir, sizeof(rgui->libretro_dir)); -#else - if (path_is_directory(g_settings.libretro)) - strlcpy(rgui->libretro_dir, g_settings.libretro, sizeof(rgui->libretro_dir)); - else if (*g_settings.libretro) - fill_pathname_basedir(rgui->libretro_dir, g_settings.libretro, sizeof(rgui->libretro_dir)); -#endif - #ifndef HAVE_DYNAMIC retro_get_system_info(&rgui->info); #endif @@ -222,8 +211,8 @@ static void menu_update_libretro_info(void *data) memset(&rgui->core_info_current, 0, sizeof(rgui->core_info_current)); core_info_list_free(rgui->core_info); rgui->core_info = NULL; - if (*rgui->libretro_dir) - rgui->core_info = core_info_list_new(rgui->libretro_dir); + if (*g_settings.libretro_directory) + rgui->core_info = core_info_list_new(g_settings.libretro_directory); menu_update_system_info(rgui, NULL); } @@ -668,7 +657,7 @@ bool menu_save_new_config(void) bool found_path = false; char config_name[PATH_MAX]; char config_path[PATH_MAX]; - if (*g_settings.libretro && !path_is_directory(g_settings.libretro) && path_file_exists(g_settings.libretro)) // Infer file name based on libretro core. + if (*g_settings.libretro && path_file_exists(g_settings.libretro)) // Infer file name based on libretro core. { unsigned i; // In case of collision, find an alternative name. @@ -914,6 +903,6 @@ void menu_init_core_info(void *data) core_info_list_free(rgui->core_info); rgui->core_info = NULL; - if (*rgui->libretro_dir) - rgui->core_info = core_info_list_new(rgui->libretro_dir); + if (*g_settings.libretro_directory) + rgui->core_info = core_info_list_new(g_settings.libretro_directory); } diff --git a/frontend/menu/menu_common.h b/frontend/menu/menu_common.h index 9074734b30..f7137f8f92 100644 --- a/frontend/menu/menu_common.h +++ b/frontend/menu/menu_common.h @@ -159,7 +159,6 @@ typedef struct const uint8_t *font; bool alloc_font; - char libretro_dir[PATH_MAX]; struct retro_system_info info; bool load_no_rom; diff --git a/general.h b/general.h index 520a69f740..3b5f7b781e 100644 --- a/general.h +++ b/general.h @@ -290,6 +290,7 @@ struct settings unsigned game_history_size; char libretro[PATH_MAX]; + char libretro_directory[PATH_MAX]; unsigned libretro_log_level; char libretro_info_path[PATH_MAX]; char cheat_database[PATH_MAX]; @@ -375,6 +376,7 @@ struct global bool has_set_state_path; bool has_set_libretro_device[MAX_PLAYERS]; bool has_set_libretro; + bool has_set_libretro_directory; #ifdef HAVE_RMENU char menu_texture_path[PATH_MAX]; diff --git a/retroarch.c b/retroarch.c index d793073917..7256ead358 100644 --- a/retroarch.c +++ b/retroarch.c @@ -892,6 +892,7 @@ static void parse_input(int argc, char *argv[]) g_extern.has_set_save_path = false; g_extern.has_set_state_path = false; g_extern.has_set_libretro = false; + g_extern.has_set_libretro_directory = false; *g_extern.subsystem = '\0'; if (argc < 2) @@ -1069,8 +1070,18 @@ static void parse_input(int argc, char *argv[]) #ifdef HAVE_DYNAMIC case 'L': - strlcpy(g_settings.libretro, optarg, sizeof(g_settings.libretro)); - g_extern.has_set_libretro = true; + if (path_is_directory(optarg)) + { + *g_settings.libretro = '\0'; + strlcpy(g_settings.libretro_directory, optarg, sizeof(g_settings.libretro_directory)); + g_extern.has_set_libretro = true; + g_extern.has_set_libretro_directory = true; + } + else + { + strlcpy(g_settings.libretro, optarg, sizeof(g_settings.libretro)); + g_extern.has_set_libretro = true; + } break; #endif diff --git a/retroarch.cfg b/retroarch.cfg index dafdfc6292..14e093066d 100644 --- a/retroarch.cfg +++ b/retroarch.cfg @@ -21,11 +21,12 @@ # Load libretro from a dynamic location for dynamically built RetroArch. # This option is mandatory. -# If a directory, RetroArch will look through the directory until it finds an implementation -# that appears to support the extension of the ROM loaded. -# This could fail if ROM extensions overlap. +# Path to a libretro implementation. # libretro_path = "/path/to/libretro.so" +# A directory for where to search for libretro implmentations. +# libretro_directory = + # Sets log level for libretro cores (GET_LOG_INTERFACE). # If a log level issued by a libretro core is below libretro_log_level, it is ignored. # DEBUG logs are always ignored unless verbose mode is activated (--verbose). diff --git a/settings.c b/settings.c index 7a35ea17fa..d8d8e530be 100644 --- a/settings.c +++ b/settings.c @@ -381,6 +381,7 @@ void config_set_defaults(void) if (!g_extern.has_set_state_path) *g_extern.savestate_dir = '\0'; *g_settings.libretro_info_path = '\0'; + *g_settings.libretro_directory = '\0'; *g_settings.core_options_path = '\0'; *g_settings.game_history_path = '\0'; *g_settings.cheat_database = '\0'; @@ -452,8 +453,8 @@ void config_set_defaults(void) if (default_dsp_filter_dir) fill_pathname_expand_special(g_settings.audio.filter_dir, default_dsp_filter_dir, sizeof(g_settings.audio.filter_dir)); - if (default_libretro_path && !g_extern.has_set_libretro) - fill_pathname_expand_special(g_settings.libretro, default_libretro_path, sizeof(g_settings.libretro)); + if (default_libretro_path && !g_extern.has_set_libretro_directory) + fill_pathname_expand_special(g_settings.libretro_directory, default_libretro_path, sizeof(g_settings.libretro_directory)); if (default_libretro_info_path) fill_pathname_expand_special(g_settings.libretro_info_path, default_libretro_info_path, sizeof(g_settings.libretro_info_path)); @@ -955,6 +956,16 @@ bool config_load_file(const char *path, bool set_defaults) if (!g_extern.has_set_libretro) CONFIG_GET_PATH(libretro, "libretro_path"); + if (!g_extern.has_set_libretro_directory) + CONFIG_GET_PATH(libretro_directory, "libretro_directory"); + + // Safe-guard against older behavior. + if (path_is_directory(g_settings.libretro)) + { + RARCH_WARN("\"libretro_path\" is a directory, using this for \"libretro_directory\" instead.\n"); + strlcpy(g_settings.libretro_directory, g_settings.libretro, sizeof(g_settings.libretro_directory)); + *g_settings.libretro = '\0'; + } CONFIG_GET_BOOL(fps_show, "fps_show"); CONFIG_GET_BOOL(load_dummy_on_core_shutdown, "load_dummy_on_core_shutdown"); @@ -1286,6 +1297,7 @@ bool config_save_file(const char *path) config_set_bool(conf, "load_dummy_on_core_shutdown", g_settings.load_dummy_on_core_shutdown); config_set_bool(conf, "fps_show", g_settings.fps_show); config_set_path(conf, "libretro_path", g_settings.libretro); + config_set_path(conf, "libretro_directory", g_settings.libretro_directory); config_set_path(conf, "libretro_info_path", g_settings.libretro_info_path); config_set_path(conf, "cheat_database_path", g_settings.cheat_database); config_set_bool(conf, "rewind_enable", g_settings.rewind_enable);