From 2768655267fda1b6c2f7f696bef7eeedad2a3950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Coll=20Cerd=C3=A1n?= Date: Mon, 18 May 2020 23:40:32 +0200 Subject: [PATCH 1/3] Cleaner structure for auto shader presets. Additional changes: * Restore the previous storage path for user-presets until a better solution is agreed upon. * Stop using the Video Shaders directory as fallback directory to store autopresets. Will be used only when autoloading as last resort to ensure compatibility with old setups. --- menu/menu_shader.c | 142 ++++++++++++++++++++++----------------------- retroarch.c | 48 +++++++-------- 2 files changed, 95 insertions(+), 95 deletions(-) diff --git a/menu/menu_shader.c b/menu/menu_shader.c index 45eb76cfcd..1aafd41b93 100644 --- a/menu/menu_shader.c +++ b/menu/menu_shader.c @@ -220,8 +220,9 @@ clear: static bool menu_shader_manager_save_preset_internal( const struct video_shader *shader, const char *basename, const char *dir_video_shader, - const char *dir_menu_config, - bool apply, bool save_reference) + bool apply, bool save_reference, + const char **target_dirs, + size_t num_target_dirs) { bool ret = false; enum rarch_shader_type type = RARCH_SHADER_NONE; @@ -278,28 +279,14 @@ static bool menu_shader_manager_save_preset_internal( } else { - const char *dirs[3] = {0}; - char config_directory[PATH_MAX_LENGTH]; char basedir[PATH_MAX_LENGTH]; - config_directory[0] = '\0'; - - if (!path_is_empty(RARCH_PATH_CONFIG)) - fill_pathname_basedir( - config_directory, - path_get(RARCH_PATH_CONFIG), - sizeof(config_directory)); - - dirs[0] = dir_menu_config; - dirs[1] = dir_video_shader; - dirs[2] = config_directory; - - for (i = 0; i < ARRAY_SIZE(dirs); i++) + for (i = 0; i < num_target_dirs; i++) { - if (string_is_empty(dirs[i])) + if (string_is_empty(target_dirs[i])) continue; - fill_pathname_join(buffer, dirs[i], + fill_pathname_join(buffer, target_dirs[i], fullname, sizeof(buffer)); strlcpy(basedir, buffer, sizeof(basedir)); @@ -348,31 +335,50 @@ static bool menu_shader_manager_operate_auto_preset( const char *dir_menu_config, enum auto_shader_type type, bool apply) { + char old_presets_directory[PATH_MAX_LENGTH]; + char config_directory[PATH_MAX_LENGTH]; char tmp[PATH_MAX_LENGTH]; - char directory[PATH_MAX_LENGTH]; char file[PATH_MAX_LENGTH]; - struct retro_system_info *system = runloop_get_libretro_system_info(); - const char *core_name = system ? system->library_name : NULL; + struct retro_system_info *system = runloop_get_libretro_system_info(); + const char *core_name = system ? system->library_name : NULL; + const char *auto_preset_dirs[3] = {0}; - tmp[0] = directory[0] = file[0] = '\0'; + old_presets_directory[0] = config_directory[0] = tmp[0] = file[0] = '\0'; if (type != SHADER_PRESET_GLOBAL && string_is_empty(core_name)) return false; + if (!path_is_empty(RARCH_PATH_CONFIG)) + fill_pathname_basedir( + config_directory, + path_get(RARCH_PATH_CONFIG), + sizeof(config_directory)); + + /* We are only including this directory for compatibility purposes with + * versions 1.8.7 and older. */ + if (op != AUTO_SHADER_OP_SAVE && !string_is_empty(dir_video_shader)) + fill_pathname_join( + old_presets_directory, + dir_video_shader, + "presets", + sizeof(old_presets_directory)); + + auto_preset_dirs[0] = dir_menu_config; + auto_preset_dirs[1] = config_directory; + auto_preset_dirs[2] = old_presets_directory; + switch (type) { case SHADER_PRESET_GLOBAL: - fill_pathname_join(file, "presets", "global", sizeof(file)); + strlcpy(file, "global", sizeof(file)); break; case SHADER_PRESET_CORE: - fill_pathname_join(directory, "presets", core_name, sizeof(directory)); - fill_pathname_join(file, directory, core_name, sizeof(file)); + fill_pathname_join(file, core_name, core_name, sizeof(file)); break; case SHADER_PRESET_PARENT: - fill_pathname_join(directory, "presets", core_name, sizeof(directory)); fill_pathname_parent_dir_name(tmp, path_get(RARCH_PATH_BASENAME), sizeof(tmp)); - fill_pathname_join(file, directory, tmp, sizeof(file)); + fill_pathname_join(file, core_name, tmp, sizeof(file)); break; case SHADER_PRESET_GAME: { @@ -380,8 +386,7 @@ static bool menu_shader_manager_operate_auto_preset( path_basename(path_get(RARCH_PATH_BASENAME)); if (string_is_empty(game_name)) return false; - fill_pathname_join(directory, "presets", core_name, sizeof(directory)); - fill_pathname_join(file, directory, game_name, sizeof(file)); + fill_pathname_join(file, core_name, game_name, sizeof(file)); break; } default: @@ -394,38 +399,28 @@ static bool menu_shader_manager_operate_auto_preset( return menu_shader_manager_save_preset_internal( shader, file, dir_video_shader, - dir_menu_config, - apply, true); + apply, true, + auto_preset_dirs, + ARRAY_SIZE(auto_preset_dirs)); case AUTO_SHADER_OP_REMOVE: { /* remove all supported auto-shaders of given type */ char *end; size_t i, j, n, m; - const char *dirs[3] = {0}; - char config_directory[PATH_MAX_LENGTH]; char preset_path[PATH_MAX_LENGTH]; + /* n = amount of relevant shader presets found + * m = amount of successfully deleted shader presets */ n = m = 0; - config_directory[0] = '\0'; - - if (!path_is_empty(RARCH_PATH_CONFIG)) - fill_pathname_basedir( - config_directory, - path_get(RARCH_PATH_CONFIG), - sizeof(config_directory)); - - dirs[0] = dir_menu_config; - dirs[1] = dir_video_shader; - dirs[2] = config_directory; - - for (i = 0; i < ARRAY_SIZE(dirs); i++) + for (i = 0; i < ARRAY_SIZE(auto_preset_dirs); i++) { - if (string_is_empty(dirs[i])) + if (string_is_empty(auto_preset_dirs[i])) continue; - fill_pathname_join(preset_path, dirs[i], file, sizeof(preset_path)); + fill_pathname_join(preset_path, + auto_preset_dirs[i], file, sizeof(preset_path)); end = preset_path + strlen(preset_path); for (j = 0; j < ARRAY_SIZE(shader_types); j++) @@ -461,28 +456,15 @@ static bool menu_shader_manager_operate_auto_preset( char *end; size_t i, j; - const char *dirs[3] = {0}; - char config_directory[PATH_MAX_LENGTH]; char preset_path[PATH_MAX_LENGTH]; - config_directory[0] = '\0'; - - if (!path_is_empty(RARCH_PATH_CONFIG)) - fill_pathname_basedir( - config_directory, - path_get(RARCH_PATH_CONFIG), - sizeof(config_directory)); - - dirs[0] = dir_menu_config; - dirs[1] = dir_video_shader; - dirs[2] = config_directory; - - for (i = 0; i < ARRAY_SIZE(dirs); i++) + for (i = 0; i < ARRAY_SIZE(auto_preset_dirs); i++) { - if (string_is_empty(dirs[i])) + if (string_is_empty(auto_preset_dirs[i])) continue; - fill_pathname_join(preset_path, dirs[i], file, sizeof(preset_path)); + fill_pathname_join(preset_path, + auto_preset_dirs[i], file, sizeof(preset_path)); end = preset_path + strlen(preset_path); for (j = 0; j < ARRAY_SIZE(shader_types); j++) @@ -513,10 +495,10 @@ static bool menu_shader_manager_operate_auto_preset( * @apply : immediately set preset after saving * * Save a shader as an auto-shader to it's appropriate path: - * SHADER_PRESET_GLOBAL: /presets/global - * SHADER_PRESET_CORE: /presets// - * SHADER_PRESET_PARENT: /presets// - * SHADER_PRESET_GAME: /presets// + * SHADER_PRESET_GLOBAL: /global + * SHADER_PRESET_CORE: // + * SHADER_PRESET_PARENT: // + * SHADER_PRESET_GAME: // * Needs to be consistent with retroarch_load_shader_preset() * Auto-shaders will be saved as a reference if possible **/ @@ -549,11 +531,27 @@ bool menu_shader_manager_save_preset(const struct video_shader *shader, const char *dir_menu_config, bool apply) { + char config_directory[PATH_MAX_LENGTH]; + const char *preset_dirs[3] = {0}; + + config_directory[0] = '\0'; + + if (!path_is_empty(RARCH_PATH_CONFIG)) + fill_pathname_basedir( + config_directory, + path_get(RARCH_PATH_CONFIG), + sizeof(config_directory)); + + preset_dirs[0] = dir_video_shader; + preset_dirs[1] = dir_menu_config; + preset_dirs[2] = config_directory; + return menu_shader_manager_save_preset_internal( shader, basename, dir_video_shader, - dir_menu_config, - apply, false); + apply, false, + preset_dirs, + ARRAY_SIZE(preset_dirs)); } /** diff --git a/retroarch.c b/retroarch.c index 1f75f4aef4..26ade82b5a 100644 --- a/retroarch.c +++ b/retroarch.c @@ -27372,17 +27372,16 @@ static bool retroarch_load_shader_preset_internal( * Tries to load a supported core-, game-, folder-specific or global * shader preset from its respective location: * - * global: $SHADER_DIR/presets/global.$PRESET_EXT - * core-specific: $SHADER_DIR/presets/$CORE_NAME/$CORE_NAME.$PRESET_EXT - * folder-specific: $SHADER_DIR/presets/$CORE_NAME/$FOLDER_NAME.$PRESET_EXT - * game-specific: $SHADER_DIR/presets/$CORE_NAME/$GAME_NAME.$PRESET_EXT + * global: $CONFIG_DIR/global.$PRESET_EXT + * core-specific: $CONFIG_DIR/$CORE_NAME/$CORE_NAME.$PRESET_EXT + * folder-specific: $CONFIG_DIR/$CORE_NAME/$FOLDER_NAME.$PRESET_EXT + * game-specific: $CONFIG_DIR/$CORE_NAME/$GAME_NAME.$PRESET_EXT * - * $SHADER_DIR is composed by three different locations which will be searched - * in the following order (search will stop on first match): + * $CONFIG_DIR is expected to be Menu Config directory, or failing that, the + * directory where retroarch.cfg is stored. * - * 1. The Menu Config directory - * 2. The Video Shader directory - * 3. The directory where the configuration file is stored + * For compatibility purposes with versions 1.8.7 and older, the presets + * subdirectory on the Video Shader path is used as a fallback directory. * * Note: Uses video_shader_is_supported() which only works after * context driver initialization. @@ -27400,7 +27399,7 @@ static bool retroarch_load_shader_preset(void) const char *game_name = path_basename(rarch_path_basename); char *content_dir_name = NULL; char *config_file_directory = NULL; - char *shader_directory = NULL; + char *old_presets_directory = NULL; bool auto_shaders_enable = settings->bools.auto_shaders_enable; const char *dirs[3] = {0}; @@ -27419,8 +27418,8 @@ static bool retroarch_load_shader_preset(void) if (!config_file_directory) goto end; - shader_directory = (char*)malloc(PATH_MAX_LENGTH); - if (!shader_directory) + old_presets_directory = (char*)malloc(PATH_MAX_LENGTH); + if (!old_presets_directory) goto end; content_dir_name[0] = '\0'; @@ -27435,21 +27434,24 @@ static bool retroarch_load_shader_preset(void) fill_pathname_basedir(config_file_directory, path_get(RARCH_PATH_CONFIG), PATH_MAX_LENGTH); + old_presets_directory[0] = '\0'; + + if (!string_is_empty(video_shader_directory)) + fill_pathname_join(old_presets_directory, + video_shader_directory, "presets", PATH_MAX_LENGTH); + dirs[0] = menu_config_directory; - dirs[1] = video_shader_directory; - dirs[2] = config_file_directory; + dirs[1] = config_file_directory; + dirs[2] = old_presets_directory; for (i = 0; i < ARRAY_SIZE(dirs); i++) { if (string_is_empty(dirs[i])) continue; - fill_pathname_join(shader_directory, - dirs[i], "presets", PATH_MAX_LENGTH); + RARCH_LOG("[Shaders]: preset directory: %s\n", dirs[i]); - RARCH_LOG("[Shaders]: preset directory: %s\n", shader_directory); - - ret = retroarch_load_shader_preset_internal(shader_directory, core_name, + ret = retroarch_load_shader_preset_internal(dirs[i], core_name, game_name); if (ret) @@ -27458,7 +27460,7 @@ static bool retroarch_load_shader_preset(void) break; } - ret = retroarch_load_shader_preset_internal(shader_directory, core_name, + ret = retroarch_load_shader_preset_internal(dirs[i], core_name, content_dir_name); if (ret) @@ -27467,7 +27469,7 @@ static bool retroarch_load_shader_preset(void) break; } - ret = retroarch_load_shader_preset_internal(shader_directory, core_name, + ret = retroarch_load_shader_preset_internal(dirs[i], core_name, core_name); if (ret) @@ -27476,7 +27478,7 @@ static bool retroarch_load_shader_preset(void) break; } - ret = retroarch_load_shader_preset_internal(shader_directory, NULL, + ret = retroarch_load_shader_preset_internal(dirs[i], NULL, "global"); if (ret) @@ -27489,7 +27491,7 @@ static bool retroarch_load_shader_preset(void) end: free(content_dir_name); free(config_file_directory); - free(shader_directory); + free(old_presets_directory); return ret; } #endif From e43111d9cbbc18dbd332938a6b91e2f930fd280b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Coll=20Cerd=C3=A1n?= Date: Wed, 20 May 2020 17:35:04 +0200 Subject: [PATCH 2/3] Support fallback dirs to cycle user shader presets When a user shader preset was saved, if the Video Shader directory wasn't writable, it would fall back to the Menu Config directory, and failing that, it would fall back to the directory where retroarch.cfg is stored. This change allows the shader cycling feature to use those directories if no shader presets are found on the Video Shader directory. --- retroarch.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/retroarch.c b/retroarch.c index 26ade82b5a..419e45c8de 100644 --- a/retroarch.c +++ b/retroarch.c @@ -21465,6 +21465,8 @@ static bool video_driver_init_internal(bool *video_is_threaded) settings_t *settings = configuration_settings; struct retro_game_geometry *geom = &video_driver_av_info.geometry; const char *path_softfilter_plugin = settings->paths.path_softfilter_plugin; + char *config_file_directory = NULL; + bool dir_list_is_free = true; if (!string_is_empty(path_softfilter_plugin)) video_driver_init_filter(video_driver_pix_fmt); @@ -21667,9 +21669,30 @@ static bool video_driver_init_internal(bool *video_is_threaded) dir_free_shader(); if (!string_is_empty(settings->paths.directory_video_shader)) - dir_init_shader(settings->paths.directory_video_shader, + dir_list_is_free = !dir_init_shader( + settings->paths.directory_video_shader, settings->bools.show_hidden_files); + if (dir_list_is_free && !string_is_empty(settings->paths.directory_menu_config)) + dir_list_is_free = !dir_init_shader( + settings->paths.directory_menu_config, + settings->bools.show_hidden_files); + + if (dir_list_is_free && !path_is_empty(RARCH_PATH_CONFIG)) + { + config_file_directory = (char*)malloc(PATH_MAX_LENGTH); + + fill_pathname_basedir(config_file_directory, + path_get(RARCH_PATH_CONFIG), PATH_MAX_LENGTH); + + if (config_file_directory) + { + dir_list_is_free = !dir_init_shader( + config_file_directory, + settings->bools.show_hidden_files); + } + } + return true; error: From 04016ed4a6dff9d872c104300468e2a26b6767e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Coll=20Cerd=C3=A1n?= Date: Thu, 21 May 2020 13:28:17 +0200 Subject: [PATCH 3/3] Improve shader initialization code. Patch by @jdgleaver. --- retroarch.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/retroarch.c b/retroarch.c index 419e45c8de..2116301289 100644 --- a/retroarch.c +++ b/retroarch.c @@ -2452,8 +2452,10 @@ struct string_list *dir_list_new_special(const char *input_dir, string_list_free(str_list); exts = ext_shaders; } -#endif break; +#else + return NULL; +#endif case DIR_LIST_COLLECTIONS: exts = "lpl"; break; @@ -21668,6 +21670,7 @@ static bool video_driver_init_internal(bool *video_is_threaded) dir_free_shader(); +#if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL) if (!string_is_empty(settings->paths.directory_video_shader)) dir_list_is_free = !dir_init_shader( settings->paths.directory_video_shader, @@ -21680,18 +21683,18 @@ static bool video_driver_init_internal(bool *video_is_threaded) if (dir_list_is_free && !path_is_empty(RARCH_PATH_CONFIG)) { - config_file_directory = (char*)malloc(PATH_MAX_LENGTH); - - fill_pathname_basedir(config_file_directory, - path_get(RARCH_PATH_CONFIG), PATH_MAX_LENGTH); + config_file_directory = strdup(path_get(RARCH_PATH_CONFIG)); + path_basedir(config_file_directory); if (config_file_directory) { dir_list_is_free = !dir_init_shader( config_file_directory, settings->bools.show_hidden_files); + free(config_file_directory); } } +#endif return true;