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.
This commit is contained in:
Joan Coll Cerdán 2020-05-12 20:08:37 +02:00
parent 1545285953
commit f1f248dd11
2 changed files with 187 additions and 88 deletions

View File

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

View File

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