From f1f248dd119c27e5406501c2d127ffae4caf263e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Coll=20Cerd=C3=A1n?= Date: Tue, 12 May 2020 20:08:37 +0200 Subject: [PATCH 1/3] Add fallback directories to shader presets. Improves the management of shader presets by using the Menu Config directory and the directory of the configuration file as alternate fallback directories whenever the Video Shader directory is not writable. --- menu/menu_shader.c | 153 +++++++++++++++++++++++++++++++-------------- retroarch.c | 122 ++++++++++++++++++++++++------------ 2 files changed, 187 insertions(+), 88 deletions(-) diff --git a/menu/menu_shader.c b/menu/menu_shader.c index 5cf8cf70c2..b02839d8e0 100644 --- a/menu/menu_shader.c +++ b/menu/menu_shader.c @@ -278,8 +278,9 @@ static bool menu_shader_manager_save_preset_internal( } else { - const char *dirs[3] = {0}; + const char *dirs[3] = {0}; char config_directory[PATH_MAX_LENGTH]; + char basedir[PATH_MAX_LENGTH]; config_directory[0] = '\0'; @@ -301,6 +302,19 @@ static bool menu_shader_manager_save_preset_internal( fill_pathname_join(buffer, dirs[i], fullname, sizeof(buffer)); + strlcpy(basedir, buffer, sizeof(basedir)); + path_basedir(basedir); + + if (!path_is_directory(basedir)) { + ret = path_mkdir(basedir); + + if (!ret) + { + RARCH_WARN("Failed to create preset directory %s.\n", basedir); + continue; + } + } + preset_path = buffer; ret = video_shader_write_preset(preset_path, @@ -337,43 +351,25 @@ static bool menu_shader_manager_operate_auto_preset( char tmp[PATH_MAX_LENGTH]; char directory[PATH_MAX_LENGTH]; char file[PATH_MAX_LENGTH]; - bool success = false; struct retro_system_info *system = runloop_get_libretro_system_info(); const char *core_name = system ? system->library_name : NULL; tmp[0] = directory[0] = file[0] = '\0'; - if (type == SHADER_PRESET_GLOBAL) - fill_pathname_join( - directory, - dir_video_shader, - "presets", - sizeof(directory)); - else if (string_is_empty(core_name)) + if (type != SHADER_PRESET_GLOBAL && string_is_empty(core_name)) return false; - else - { - fill_pathname_join( - tmp, - dir_video_shader, - "presets", - sizeof(tmp)); - fill_pathname_join( - directory, - tmp, - core_name, - sizeof(directory)); - } switch (type) { case SHADER_PRESET_GLOBAL: - fill_pathname_join(file, directory, "global", sizeof(file)); + fill_pathname_join(file, "presets", "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)); 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)); @@ -384,6 +380,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)); break; } @@ -394,9 +391,6 @@ static bool menu_shader_manager_operate_auto_preset( switch (op) { case AUTO_SHADER_OP_SAVE: - if (!path_is_directory(directory)) - path_mkdir(directory); - return menu_shader_manager_save_preset_internal( shader, file, dir_video_shader, @@ -405,41 +399,106 @@ static bool menu_shader_manager_operate_auto_preset( case AUTO_SHADER_OP_REMOVE: { /* remove all supported auto-shaders of given type */ - char *end = file + strlen(file); - size_t i; - for (i = 0; i < ARRAY_SIZE(shader_types); i++) - { - const char *preset_ext; + char *end; + size_t i, j; + size_t n, m; - if (!video_shader_is_supported(shader_types[i])) + n = m = 0; + + 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_video_shader; + dirs[1] = dir_menu_config; + dirs[2] = config_directory; + + for (i = 0; i < ARRAY_SIZE(dirs); i++) + { + if (string_is_empty(dirs[i])) continue; - preset_ext = video_shader_get_preset_extension(shader_types[i]); - strlcpy(end, preset_ext, sizeof(file) - (end-file)); + fill_pathname_join(preset_path, dirs[i], file, sizeof(preset_path)); + end = preset_path + strlen(preset_path); - if (!filestream_delete(file)) - success = true; + for (j = 0; j < ARRAY_SIZE(shader_types); j++) + { + const char *preset_ext; + + if (!video_shader_is_supported(shader_types[j])) + continue; + + preset_ext = video_shader_get_preset_extension(shader_types[j]); + strlcpy(end, preset_ext, sizeof(preset_path) - (end - preset_path)); + + if (path_is_valid(preset_path)) + { + n++; + + if (!filestream_delete(preset_path)) + { + m++; + RARCH_LOG("Deleted shader preset from %s.\n", preset_path); + } + else + RARCH_WARN("Failed to remove shader preset at %s.\n", preset_path); + } + } } + + return n == m; } - return success; case AUTO_SHADER_OP_EXISTS: { /* test if any supported auto-shaders of given type exists */ - char *end = file + strlen(file); - size_t i; + char *end; + size_t i, j; - for (i = 0; i < ARRAY_SIZE(shader_types); i++) + 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_video_shader; + dirs[1] = dir_menu_config; + dirs[2] = config_directory; + + for (i = 0; i < ARRAY_SIZE(dirs); i++) { - const char *preset_ext; - - if (!video_shader_is_supported(shader_types[i])) + if (string_is_empty(dirs[i])) continue; - preset_ext = video_shader_get_preset_extension(shader_types[i]); - strlcpy(end, preset_ext, sizeof(file) - (end-file)); + fill_pathname_join(preset_path, dirs[i], file, sizeof(preset_path)); + end = preset_path + strlen(preset_path); - if (path_is_valid(file)) - return true; + for (j = 0; j < ARRAY_SIZE(shader_types); j++) + { + const char *preset_ext; + + if (!video_shader_is_supported(shader_types[j])) + continue; + + preset_ext = video_shader_get_preset_extension(shader_types[j]); + strlcpy(end, preset_ext, sizeof(preset_path) - (end - preset_path)); + + if (path_is_valid(preset_path)) + return true; + } } } break; diff --git a/retroarch.c b/retroarch.c index 2a54db3519..51e3b6c3b7 100644 --- a/retroarch.c +++ b/retroarch.c @@ -27318,6 +27318,13 @@ static bool retroarch_load_shader_preset_internal( * folder-specific: $SHADER_DIR/presets/$CORE_NAME/$FOLDER_NAME.$PRESET_EXT * game-specific: $SHADER_DIR/presets/$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): + * + * 1. The Video Shader directory + * 2. The Menu Config directory + * 3. The directory where the configuration file is stored + * * Note: Uses video_shader_is_supported() which only works after * context driver initialization. * @@ -27327,71 +27334,104 @@ static bool retroarch_load_shader_preset(void) { settings_t *settings = configuration_settings; const char *video_shader_directory = settings->paths.directory_video_shader; + const char *menu_config_directory = settings->paths.directory_menu_config; const char *core_name = runloop_system.info.library_name; const char *rarch_path_basename = path_get(RARCH_PATH_BASENAME); const char *game_name = path_basename(rarch_path_basename); + char *content_dir_name = NULL; + char *config_file_directory = NULL; char *shader_directory = NULL; bool auto_shaders_enable = settings->bools.auto_shaders_enable; + const char *dirs[3] = {0}; + size_t i = 0; + + bool ret = false; + if (!auto_shaders_enable) return false; - if (string_is_empty(video_shader_directory)) - return false; + + content_dir_name = (char*)malloc(PATH_MAX_LENGTH); + if (!content_dir_name) + goto end; + + config_file_directory = (char*)malloc(PATH_MAX_LENGTH); + if (!config_file_directory) + goto end; shader_directory = (char*)malloc(PATH_MAX_LENGTH); - if (!shader_directory) - return false; + goto end; - fill_pathname_join(shader_directory, - video_shader_directory, - "presets", PATH_MAX_LENGTH); + content_dir_name[0] = '\0'; - RARCH_LOG("[Shaders]: preset directory: %s\n", shader_directory); + if (!string_is_empty(rarch_path_basename)) + fill_pathname_parent_dir_name(content_dir_name, + rarch_path_basename, PATH_MAX_LENGTH); - if (retroarch_load_shader_preset_internal(shader_directory, core_name, - game_name)) + config_file_directory[0] = '\0'; + + if (!path_is_empty(RARCH_PATH_CONFIG)) + fill_pathname_basedir(config_file_directory, + path_get(RARCH_PATH_CONFIG), PATH_MAX_LENGTH); + + dirs[0] = video_shader_directory; + dirs[1] = menu_config_directory; + dirs[2] = config_file_directory; + + for (i = 0; i < ARRAY_SIZE(dirs); i++) { - RARCH_LOG("[Shaders]: game-specific shader preset found.\n"); - goto success; - } + if (string_is_empty(dirs[i])) + continue; - { - char content_dir_name[PATH_MAX_LENGTH]; - content_dir_name[0] = '\0'; - if (!string_is_empty(rarch_path_basename)) - fill_pathname_parent_dir_name(content_dir_name, - rarch_path_basename, sizeof(content_dir_name)); + fill_pathname_join(shader_directory, + dirs[i], "presets", PATH_MAX_LENGTH); - if (retroarch_load_shader_preset_internal(shader_directory, core_name, - content_dir_name)) + RARCH_LOG("[Shaders]: preset directory: %s\n", shader_directory); + + ret = retroarch_load_shader_preset_internal(shader_directory, core_name, + game_name); + + if (ret) + { + RARCH_LOG("[Shaders]: game-specific shader preset found.\n"); + break; + } + + ret = retroarch_load_shader_preset_internal(shader_directory, core_name, + content_dir_name); + + if (ret) { RARCH_LOG("[Shaders]: folder-specific shader preset found.\n"); - goto success; + break; + } + + ret = retroarch_load_shader_preset_internal(shader_directory, core_name, + core_name); + + if (ret) + { + RARCH_LOG("[Shaders]: core-specific shader preset found.\n"); + break; + } + + ret = retroarch_load_shader_preset_internal(shader_directory, NULL, + "global"); + + if (ret) + { + RARCH_LOG("[Shaders]: global shader preset found.\n"); + break; } } - if (retroarch_load_shader_preset_internal(shader_directory, core_name, - core_name)) - { - RARCH_LOG("[Shaders]: core-specific shader preset found.\n"); - goto success; - } - - if (retroarch_load_shader_preset_internal(shader_directory, NULL, - "global")) - { - RARCH_LOG("[Shaders]: global shader preset found.\n"); - goto success; - } - +end: + free(content_dir_name); + free(config_file_directory); free(shader_directory); - return false; - -success: - free(shader_directory); - return true; + return ret; } #endif From fe42f6bb73c8e1108903073079166d25ca97e576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Coll=20Cerd=C3=A1n?= Date: Wed, 13 May 2020 19:44:23 +0200 Subject: [PATCH 2/3] Changed the order of shader preset directories. The Menu Config directory now takes precedence over the Video Shader directory for the storage of shader preset overrides. With this, all user overrides are grouped by default under the same path. --- menu/menu_shader.c | 12 ++++++------ retroarch.c | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/menu/menu_shader.c b/menu/menu_shader.c index b02839d8e0..640b288ce3 100644 --- a/menu/menu_shader.c +++ b/menu/menu_shader.c @@ -290,8 +290,8 @@ static bool menu_shader_manager_save_preset_internal( path_get(RARCH_PATH_CONFIG), sizeof(config_directory)); - dirs[0] = dir_video_shader; - dirs[1] = dir_menu_config; + dirs[0] = dir_menu_config; + dirs[1] = dir_video_shader; dirs[2] = config_directory; for (i = 0; i < ARRAY_SIZE(dirs); i++) @@ -417,8 +417,8 @@ static bool menu_shader_manager_operate_auto_preset( path_get(RARCH_PATH_CONFIG), sizeof(config_directory)); - dirs[0] = dir_video_shader; - dirs[1] = dir_menu_config; + dirs[0] = dir_menu_config; + dirs[1] = dir_video_shader; dirs[2] = config_directory; for (i = 0; i < ARRAY_SIZE(dirs); i++) @@ -474,8 +474,8 @@ static bool menu_shader_manager_operate_auto_preset( path_get(RARCH_PATH_CONFIG), sizeof(config_directory)); - dirs[0] = dir_video_shader; - dirs[1] = dir_menu_config; + dirs[0] = dir_menu_config; + dirs[1] = dir_video_shader; dirs[2] = config_directory; for (i = 0; i < ARRAY_SIZE(dirs); i++) diff --git a/retroarch.c b/retroarch.c index 51e3b6c3b7..5543bd9ca5 100644 --- a/retroarch.c +++ b/retroarch.c @@ -27321,8 +27321,8 @@ static bool retroarch_load_shader_preset_internal( * $SHADER_DIR is composed by three different locations which will be searched * in the following order (search will stop on first match): * - * 1. The Video Shader directory - * 2. The Menu Config directory + * 1. The Menu Config directory + * 2. The Video Shader directory * 3. The directory where the configuration file is stored * * Note: Uses video_shader_is_supported() which only works after @@ -27376,8 +27376,8 @@ static bool retroarch_load_shader_preset(void) fill_pathname_basedir(config_file_directory, path_get(RARCH_PATH_CONFIG), PATH_MAX_LENGTH); - dirs[0] = video_shader_directory; - dirs[1] = menu_config_directory; + dirs[0] = menu_config_directory; + dirs[1] = video_shader_directory; dirs[2] = config_file_directory; for (i = 0; i < ARRAY_SIZE(dirs); i++) From 718e9eaf37da9b1a0c35dcad5994bb0b46620e8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Coll=20Cerd=C3=A1n?= <721143+johanbcn@users.noreply.github.com> Date: Thu, 14 May 2020 00:32:52 +0200 Subject: [PATCH 3/3] Comply with the C89 standard --- menu/menu_shader.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/menu/menu_shader.c b/menu/menu_shader.c index 640b288ce3..45eb76cfcd 100644 --- a/menu/menu_shader.c +++ b/menu/menu_shader.c @@ -400,15 +400,14 @@ static bool menu_shader_manager_operate_auto_preset( { /* remove all supported auto-shaders of given type */ char *end; - size_t i, j; - size_t n, m; - - n = m = 0; + size_t i, j, n, m; const char *dirs[3] = {0}; char config_directory[PATH_MAX_LENGTH]; char preset_path[PATH_MAX_LENGTH]; + n = m = 0; + config_directory[0] = '\0'; if (!path_is_empty(RARCH_PATH_CONFIG))