Merge pull request #8933 from LazyBumHorse/master

make shader presets use relative paths
This commit is contained in:
Twinaphex 2019-06-08 03:52:20 +02:00 committed by GitHub
commit 81f1b3df7c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 122 additions and 43 deletions

View File

@ -945,16 +945,27 @@ static void shader_write_variable(config_file_t *conf,
/**
* video_shader_write_conf_cgp:
* @conf : Preset file to read from.
* @conf : Preset file to write to.
* @shader : Shader passes handle.
* @preset_path : Optional path to where the preset will be written.
*
* Saves preset and all associated state (passes,
* textures, imports, etc) to disk.
* If @preset_path is not NULL, shader paths are saved
* relative to it.
**/
void video_shader_write_conf_cgp(config_file_t *conf,
struct video_shader *shader)
struct video_shader *shader, const char *preset_path)
{
unsigned i;
char key[64];
size_t tmp_size = PATH_MAX_LENGTH;
char *tmp = (char*)malloc(tmp_size);
char *tmp_rel = (char*)malloc(tmp_size);
char *tmp_base = (char*)malloc(tmp_size);
if (!tmp || !tmp_rel || !tmp_base)
return;
config_set_int(conf, "shaders", shader->passes);
if (shader->feedback_pass >= 0)
@ -962,49 +973,52 @@ void video_shader_write_conf_cgp(config_file_t *conf,
for (i = 0; i < shader->passes; i++)
{
char key[64];
size_t tmp_size = PATH_MAX_LENGTH * sizeof(char);
char *tmp = (char*)malloc(tmp_size);
const struct video_shader_pass *pass = &shader->pass[i];
if (tmp)
snprintf(key, sizeof(key), "shader%u", i);
strlcpy(tmp, pass->source.path, tmp_size);
if (preset_path)
{
key[0] = '\0';
strlcpy(tmp_base, preset_path, tmp_size);
snprintf(key, sizeof(key), "shader%u", i);
strlcpy(tmp, pass->source.path, tmp_size);
path_basedir(tmp_base);
path_relative_to(tmp_rel, tmp, tmp_base, tmp_size);
if (!path_is_absolute(tmp))
path_resolve_realpath(tmp, tmp_size);
config_set_string(conf, key, tmp);
free(tmp);
if (pass->filter != RARCH_FILTER_UNSPEC)
{
snprintf(key, sizeof(key), "filter_linear%u", i);
config_set_bool(conf, key, pass->filter == RARCH_FILTER_LINEAR);
}
snprintf(key, sizeof(key), "wrap_mode%u", i);
config_set_string(conf, key, wrap_mode_to_str(pass->wrap));
if (pass->frame_count_mod)
{
snprintf(key, sizeof(key), "frame_count_mod%u", i);
config_set_int(conf, key, pass->frame_count_mod);
}
snprintf(key, sizeof(key), "mipmap_input%u", i);
config_set_bool(conf, key, pass->mipmap);
snprintf(key, sizeof(key), "alias%u", i);
config_set_string(conf, key, pass->alias);
shader_write_fbo(conf, &pass->fbo, i);
config_set_path(conf, key, tmp_rel);
}
else
config_set_path(conf, key, tmp);
if (pass->filter != RARCH_FILTER_UNSPEC)
{
snprintf(key, sizeof(key), "filter_linear%u", i);
config_set_bool(conf, key, pass->filter == RARCH_FILTER_LINEAR);
}
snprintf(key, sizeof(key), "wrap_mode%u", i);
config_set_string(conf, key, wrap_mode_to_str(pass->wrap));
if (pass->frame_count_mod)
{
snprintf(key, sizeof(key), "frame_count_mod%u", i);
config_set_int(conf, key, pass->frame_count_mod);
}
snprintf(key, sizeof(key), "mipmap_input%u", i);
config_set_bool(conf, key, pass->mipmap);
snprintf(key, sizeof(key), "alias%u", i);
config_set_string(conf, key, pass->alias);
shader_write_fbo(conf, &pass->fbo, i);
}
free(tmp);
free(tmp_rel);
free(tmp_base);
if (shader->num_parameters)
{
size_t param_size = 4096 * sizeof(char);

View File

@ -183,14 +183,17 @@ bool video_shader_read_conf_cgp(config_file_t *conf,
/**
* video_shader_write_conf_cgp:
* @conf : Preset file to read from.
* @conf : Preset file to write to.
* @shader : Shader passes handle.
* @preset_path : Optional path to where the preset will be written.
*
* Saves preset and all associated state (passes,
* textures, imports, etc) to disk.
* If @preset_path is not NULL, shader paths are saved
* relative to it.
**/
void video_shader_write_conf_cgp(config_file_t *conf,
struct video_shader *shader);
struct video_shader *shader, const char *preset_path);
/**
* video_shader_resolve_relative:

View File

@ -732,7 +732,8 @@ bool path_is_absolute(const char *path)
* @buf : buffer for path
* @size : size of buffer
*
* Turns relative paths into absolute path.
* Turns relative paths into absolute paths and
* resolves use of "." and ".." in absolute paths.
* If relative, rebases on current working dir.
**/
void path_resolve_realpath(char *buf, size_t size)
@ -759,6 +760,47 @@ void path_resolve_realpath(char *buf, size_t size)
#endif
}
/**
* path_relative_to:
* @out : buffer to write the relative path to
* @path : path to be expressed relatively
* @base : base directory to start out on
* @size : size of output buffer
*
* Turns @path into a path relative to @base and writes it to @out.
*
* @base is assumed to be a base directory, i.e. a path ending with '/' or '\'.
* Both @path and @base are assumed to be absolute paths without "." or "..".
*
* E.g. path /a/b/e/f.cg with base /a/b/c/d/ turns into ../../e/f.cg
**/
void path_relative_to(char *out, const char *path, const char *base, size_t size)
{
unsigned i;
const char *trimmed_path, *trimmed_base;
#ifdef _WIN32
/* For different drives, return absolute path */
if (strlen(path) > 2 && strlen(base) > 2)
if (path[1] == ':' && base[1] == ':')
if (path[0] != base[0])
return path;
#endif
/* Trim common beginning */
for (i = 0; path[i] && base[i] && path[i] == base[i]; )
i++;
trimmed_path = path+i;
trimmed_base = base+i;
/* Each segment of base turns into ".." */
out[0] = '\0';
for (i = 0; trimmed_base[i]; i++)
if (trimmed_base[i] == '/' || trimmed_base[i] == '\\')
strlcat(out, "../", size); /* Use '/' as universal separator */
strlcat(out, trimmed_path, size);
}
/**
* fill_pathname_resolve_relative:
* @out_path : output path
@ -782,6 +824,7 @@ void fill_pathname_resolve_relative(char *out_path,
fill_pathname_basedir(out_path, in_refpath, size);
strlcat(out_path, in_path, size);
path_resolve_realpath(out_path, size);
}
/**

View File

@ -150,11 +150,28 @@ void path_parent_dir(char *path);
* @buf : buffer for path
* @size : size of buffer
*
* Turns relative paths into absolute path.
* Turns relative paths into absolute paths and
* resolves use of "." and ".." in absolute paths.
* If relative, rebases on current working dir.
**/
void path_resolve_realpath(char *buf, size_t size);
/**
* path_relative_to:
* @out : buffer to write the relative path to
* @path : path to be expressed relatively
* @base : relative to this
* @size : size of output buffer
*
* Turns @path into a path relative to @base and writes it to @out.
*
* @base is assumed to be a base directory, i.e. a path ending with '/' or '\'.
* Both @path and @base are assumed to be absolute paths without "." or "..".
*
* E.g. path /a/b/e/f.cgp with base /a/b/c/d/ turns into ../../e/f.cgp
**/
void path_relative_to(char *out, const char *path, const char *base, size_t size);
/**
* path_is_absolute:
* @path : path

View File

@ -316,13 +316,13 @@ bool menu_shader_manager_save_preset(
if (!conf)
return false;
video_shader_write_conf_cgp(conf, shader);
if (fullpath)
{
if (!string_is_empty(basename))
strlcpy(preset_path, buffer, sizeof(preset_path));
video_shader_write_conf_cgp(conf, shader, preset_path);
if (config_file_write(conf, preset_path, false))
{
RARCH_LOG("Saved shader preset to %s.\n", preset_path);
@ -343,6 +343,8 @@ bool menu_shader_manager_save_preset(
fill_pathname_join(preset_path, dirs[d],
buffer, sizeof(preset_path));
video_shader_write_conf_cgp(conf, shader, preset_path);
if (config_file_write(conf, preset_path, false))
{
RARCH_LOG("Saved shader preset to %s.\n", preset_path);