Merge pull request #6184 from bparker06/shader_watch

Add quick menu option to watch shader files for changes and recompile automatically
This commit is contained in:
Twinaphex 2018-01-26 01:51:04 +01:00 committed by GitHub
commit 9182a2e519
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 465 additions and 77 deletions

View File

@ -10,6 +10,7 @@
- COMMON: Bugfix for issue related to 'Windows mouse pointer visible when running MESS or MAME cores'. - COMMON: Bugfix for issue related to 'Windows mouse pointer visible when running MESS or MAME cores'.
- COMMON: Fix bug 'Last item in a Playlist is ignored'. - COMMON: Fix bug 'Last item in a Playlist is ignored'.
- COMMON: New LED API. Driver implemented for Raspberry Pi, proof of concept implemented for core MAME 2003. - COMMON: New LED API. Driver implemented for Raspberry Pi, proof of concept implemented for core MAME 2003.
- COMMON: Add quick menu option to watch shader files for changes and recompile them automatically (Linux only for now).
- D3D8: Direct3D 8 can now work on systems that have Direct3D 8 installed. - D3D8: Direct3D 8 can now work on systems that have Direct3D 8 installed.
- D3D9: Add menu support for MaterialUI/XMB. - D3D9: Add menu support for MaterialUI/XMB.
- D3D10: Initial video driver implementation. - D3D10: Initial video driver implementation.

View File

@ -404,6 +404,9 @@ static const bool post_filter_record = false;
/* Screenshots post-shaded GPU output if available. */ /* Screenshots post-shaded GPU output if available. */
static const bool gpu_screenshot = true; static const bool gpu_screenshot = true;
/* Watch shader files for changes and auto-apply as necessary. */
static const bool video_shader_watch_files = false;
/* Screenshots named automatically. */ /* Screenshots named automatically. */
static const bool auto_screenshot_filename = true; static const bool auto_screenshot_filename = true;

View File

@ -1211,6 +1211,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings,
SETTING_BOOL("rewind_enable", &settings->bools.rewind_enable, true, rewind_enable, false); SETTING_BOOL("rewind_enable", &settings->bools.rewind_enable, true, rewind_enable, false);
SETTING_BOOL("audio_sync", &settings->bools.audio_sync, true, audio_sync, false); SETTING_BOOL("audio_sync", &settings->bools.audio_sync, true, audio_sync, false);
SETTING_BOOL("video_shader_enable", &settings->bools.video_shader_enable, true, shader_enable, false); SETTING_BOOL("video_shader_enable", &settings->bools.video_shader_enable, true, shader_enable, false);
SETTING_BOOL("video_shader_watch_files", &settings->bools.video_shader_watch_files, true, video_shader_watch_files, false);
/* Let implementation decide if automatic, or 1:1 PAR. */ /* Let implementation decide if automatic, or 1:1 PAR. */
SETTING_BOOL("video_aspect_ratio_auto", &settings->bools.video_aspect_ratio_auto, true, aspect_ratio_auto, false); SETTING_BOOL("video_aspect_ratio_auto", &settings->bools.video_aspect_ratio_auto, true, aspect_ratio_auto, false);

View File

@ -81,6 +81,7 @@ typedef struct settings
bool video_aspect_ratio_auto; bool video_aspect_ratio_auto;
bool video_scale_integer; bool video_scale_integer;
bool video_shader_enable; bool video_shader_enable;
bool video_shader_watch_files;
bool video_threaded; bool video_threaded;
bool video_font_enable; bool video_font_enable;
bool video_disable_composition; bool video_disable_composition;

View File

@ -558,5 +558,7 @@ frontend_ctx_driver_t frontend_ctx_ctr = {
NULL, /* destroy_signal_handler_state */ NULL, /* destroy_signal_handler_state */
NULL, /* attach_console */ NULL, /* attach_console */
NULL, /* detach_console */ NULL, /* detach_console */
NULL, /* watch_path_for_changes */
NULL, /* check_for_path_changes */
"ctr", "ctr",
}; };

View File

@ -68,5 +68,7 @@ frontend_ctx_driver_t frontend_ctx_dos = {
NULL, /* destroy_sighandler_state */ NULL, /* destroy_sighandler_state */
NULL, /* attach_console */ NULL, /* attach_console */
NULL, /* detach_console */ NULL, /* detach_console */
NULL, /* watch_path_for_changes */
NULL, /* check_for_path_changes */
"dos", "dos",
}; };

View File

@ -260,5 +260,7 @@ frontend_ctx_driver_t frontend_ctx_emscripten = {
NULL, /* destroy_signal_handler_state */ NULL, /* destroy_signal_handler_state */
NULL, /* attach_console */ NULL, /* attach_console */
NULL, /* detach_console */ NULL, /* detach_console */
NULL, /* watch_path_for_changes */
NULL, /* check_for_path_changes */
"emscripten" "emscripten"
}; };

View File

@ -559,5 +559,7 @@ frontend_ctx_driver_t frontend_ctx_gx = {
NULL, /* destroy_signal_handler_state */ NULL, /* destroy_signal_handler_state */
NULL, /* attach_console */ NULL, /* attach_console */
NULL, /* detach_console */ NULL, /* detach_console */
NULL, /* watch_path_for_changes */
NULL, /* check_for_path_changes */
"gx", "gx",
}; };

View File

@ -44,5 +44,7 @@ frontend_ctx_driver_t frontend_ctx_null = {
#ifdef HAVE_LAKKA #ifdef HAVE_LAKKA
NULL, /* get_lakka_version */ NULL, /* get_lakka_version */
#endif #endif
NULL, /* watch_path_for_changes */
NULL, /* check_for_path_changes */
"null", "null",
}; };

View File

@ -632,5 +632,7 @@ frontend_ctx_driver_t frontend_ctx_ps3 = {
NULL, /* destroy_sighandler_state */ NULL, /* destroy_sighandler_state */
NULL, /* attach_console */ NULL, /* attach_console */
NULL, /* detach_console */ NULL, /* detach_console */
NULL, /* watch_path_for_changes */
NULL, /* check_for_path_changes */
"ps3", "ps3",
}; };

View File

@ -518,6 +518,8 @@ frontend_ctx_driver_t frontend_ctx_psp = {
NULL, /* destroy_sighandler_state */ NULL, /* destroy_sighandler_state */
NULL, /* attach_console */ NULL, /* attach_console */
NULL, /* detach_console */ NULL, /* detach_console */
NULL, /* watch_path_for_changes */
NULL, /* check_for_path_changes */
#ifdef VITA #ifdef VITA
"vita", "vita",
#else #else

View File

@ -198,5 +198,7 @@ frontend_ctx_driver_t frontend_ctx_qnx = {
NULL, /* destroy_sighandler_state */ NULL, /* destroy_sighandler_state */
NULL, /* attach_console */ NULL, /* attach_console */
NULL, /* detach_console */ NULL, /* detach_console */
NULL, /* watch_path_for_changes */
NULL, /* check_for_path_changes */
"qnx", "qnx",
}; };

View File

@ -27,6 +27,24 @@
#include <sys/utsname.h> #include <sys/utsname.h>
#include <sys/resource.h> #include <sys/resource.h>
#ifdef __linux__
#include <linux/version.h>
/* inotify API was added in 2.6.13 */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
#define HAS_INOTIFY
#define INOTIFY_BUF_LEN (1024 * (sizeof(struct inotify_event) + 16))
#include <sys/inotify.h>
#include <net/net_socket.h>
#define VECTOR_LIST_TYPE int
#define VECTOR_LIST_NAME int
#include "../../libretro-common/lists/vector_list.c"
#undef VECTOR_LIST_TYPE
#undef VECTOR_LIST_NAME
#endif
#endif
#include <signal.h> #include <signal.h>
#include <pthread.h> #include <pthread.h>
@ -45,6 +63,7 @@
#include <retro_dirent.h> #include <retro_dirent.h>
#include <retro_inline.h> #include <retro_inline.h>
#include <compat/strl.h> #include <compat/strl.h>
#include <compat/fopen_utf8.h>
#include <rhash.h> #include <rhash.h>
#include <lists/file_list.h> #include <lists/file_list.h>
#include <file/file_path.h> #include <file/file_path.h>
@ -81,7 +100,6 @@ enum
struct android_app *g_android; struct android_app *g_android;
static pthread_key_t thread_key; static pthread_key_t thread_key;
static char screenshot_dir[PATH_MAX_LENGTH]; static char screenshot_dir[PATH_MAX_LENGTH];
@ -104,6 +122,17 @@ static volatile sig_atomic_t unix_sighandler_quit;
static enum frontend_fork unix_fork_mode = FRONTEND_FORK_NONE; static enum frontend_fork unix_fork_mode = FRONTEND_FORK_NONE;
#endif #endif
#ifdef HAS_INOTIFY
typedef struct inotify_data
{
int fd;
int flags;
struct int_vector_list *wd_list;
struct string_list *path_list;
} inotify_data_t;
#endif
int system_property_get(const char *command, int system_property_get(const char *command,
const char *args, char *value) const char *args, char *value)
{ {
@ -2223,6 +2252,187 @@ static void frontend_unix_destroy_signal_handler_state(void)
unix_sighandler_quit = 0; unix_sighandler_quit = 0;
} }
/* To free change_data, call the function again with a NULL string_list while providing change_data again */
static void frontend_unix_watch_path_for_changes(struct string_list *list, int flags, path_change_data_t **change_data)
{
#ifdef HAS_INOTIFY
int major = 0;
int minor = 0;
int inotify_mask = 0, fd = 0;
unsigned i, krel = 0;
struct utsname buffer;
inotify_data_t *inotify_data;
if (!list)
{
if (change_data && *change_data)
{
/* free the original data */
inotify_data = (inotify_data_t*)((*change_data)->data);
if (inotify_data->wd_list->count > 0)
{
for (i = 0; i < inotify_data->wd_list->count; i++)
{
inotify_rm_watch(inotify_data->fd, inotify_data->wd_list->data[i]);
}
}
int_vector_list_free(inotify_data->wd_list);
string_list_free(inotify_data->path_list);
close(inotify_data->fd);
free(inotify_data);
free(*change_data);
return;
}
}
else if (list->size == 0)
return;
else
if (!change_data)
return;
if (uname(&buffer) != 0)
{
RARCH_WARN("watch_path_for_changes: Failed to get current kernel version.\n");
return;
}
/* get_os doesn't provide all three */
sscanf(buffer.release, "%d.%d.%u", &major, &minor, &krel);
/* check if we are actually running on a high enough kernel version as well */
if (major < 2)
{
RARCH_WARN("watch_path_for_changes: inotify unsupported on this kernel version (%d.%d.%u).\n", major, minor, krel);
return;
}
else if (major == 2)
{
if (minor < 6)
{
RARCH_WARN("watch_path_for_changes: inotify unsupported on this kernel version (%d.%d.%u).\n", major, minor, krel);
return;
}
else if (minor == 6)
{
if (krel < 13)
{
RARCH_WARN("watch_path_for_changes: inotify unsupported on this kernel version (%d.%d.%u).\n", major, minor, krel);
return;
}
else
{
/* anything >= 2.6.13 is supported */
}
}
else
{
/* anything >= 2.7 is supported */
}
}
else
{
/* anything >= 3 is supported */
}
fd = inotify_init();
if (fd < 0)
{
RARCH_WARN("watch_path_for_changes: Could not initialize inotify.\n");
return;
}
socket_nonblock(fd);
inotify_data = (inotify_data_t*)calloc(1, sizeof(*inotify_data));
inotify_data->fd = fd;
inotify_data->wd_list = int_vector_list_new();
inotify_data->path_list = string_list_new();
/* handle other flags here as new ones are added */
if (flags & PATH_CHANGE_TYPE_MODIFIED)
inotify_mask |= IN_MODIFY;
if (flags & PATH_CHANGE_TYPE_WRITE_FILE_CLOSED)
inotify_mask |= IN_CLOSE_WRITE;
if (flags & PATH_CHANGE_TYPE_FILE_MOVED)
inotify_mask |= IN_MOVE_SELF;
if (flags & PATH_CHANGE_TYPE_FILE_DELETED)
inotify_mask |= IN_DELETE_SELF;
inotify_data->flags = inotify_mask;
for (i = 0; i < list->size; i++)
{
int wd = inotify_add_watch(fd, list->elems[i].data, inotify_mask);
union string_list_elem_attr attr = {0};
RARCH_LOG("Watching file for changes: %s\n", list->elems[i].data);
int_vector_list_append(inotify_data->wd_list, wd);
string_list_append(inotify_data->path_list, list->elems[i].data, attr);
}
*change_data = (path_change_data_t*)calloc(1, sizeof(path_change_data_t));
(*change_data)->data = inotify_data;
#endif
}
static bool frontend_unix_check_for_path_changes(path_change_data_t *change_data)
{
#ifdef HAS_INOTIFY
inotify_data_t *inotify_data = (inotify_data_t*)(change_data->data);
char buffer[INOTIFY_BUF_LEN] = {0};
int length, i = 0;
while ((length = read(inotify_data->fd, buffer, INOTIFY_BUF_LEN)) > 0)
{
i = 0;
while (i < length)
{
struct inotify_event *event = (struct inotify_event *)&buffer[i];
if (event->mask & inotify_data->flags)
{
unsigned j;
/* A successful close does not guarantee that the data has been successfully saved to disk, as the kernel defers writes. It is not common for a file system to flush the buffers when the stream is closed.
* So we manually fsync() here to flush the data to disk, to make sure that the new data is immediately available when the file is re-read.
*/
for (j = 0; j < inotify_data->wd_list->count; j++)
{
if (inotify_data->wd_list->data[j] == event->wd)
{
/* found the right file, now sync it */
const char *path = inotify_data->path_list->elems[j].data;
FILE *fp = fopen_utf8(path, "rb");
RARCH_LOG("file change detected: %s\n", path);
if (fp)
{
fsync(fileno(fp));
fclose(fp);
}
}
}
return true;
}
i += sizeof(struct inotify_event) + event->len;
}
}
return false;
#else
return false;
#endif
}
frontend_ctx_driver_t frontend_ctx_unix = { frontend_ctx_driver_t frontend_ctx_unix = {
frontend_unix_get_env, /* environment_get */ frontend_unix_get_env, /* environment_get */
frontend_unix_init, /* init */ frontend_unix_init, /* init */
@ -2264,6 +2474,8 @@ frontend_ctx_driver_t frontend_ctx_unix = {
#ifdef HAVE_LAKKA #ifdef HAVE_LAKKA
frontend_unix_get_lakka_version, /* get_lakka_version */ frontend_unix_get_lakka_version, /* get_lakka_version */
#endif #endif
frontend_unix_watch_path_for_changes,
frontend_unix_check_for_path_changes,
#ifdef ANDROID #ifdef ANDROID
"android" "android"
#else #else

View File

@ -305,6 +305,8 @@ frontend_ctx_driver_t frontend_ctx_wiiu =
NULL, /* destroy_signal_handler_state */ NULL, /* destroy_signal_handler_state */
NULL, /* attach_console */ NULL, /* attach_console */
NULL, /* detach_console */ NULL, /* detach_console */
NULL, /* watch_path_for_changes */
NULL, /* check_for_path_changes */
"wiiu", "wiiu",
NULL, /* get_video_driver */ NULL, /* get_video_driver */
}; };

View File

@ -584,5 +584,7 @@ frontend_ctx_driver_t frontend_ctx_win32 = {
NULL, /* destroy_sighandler_state */ NULL, /* destroy_sighandler_state */
frontend_win32_attach_console, /* attach_console */ frontend_win32_attach_console, /* attach_console */
frontend_win32_detach_console, /* detach_console */ frontend_win32_detach_console, /* detach_console */
NULL, /* watch_path_for_changes */
NULL, /* check_for_path_changes */
"win32" "win32"
}; };

View File

@ -1444,5 +1444,7 @@ frontend_ctx_driver_t frontend_ctx_xdk = {
NULL, /* destroy_sighandler_state */ NULL, /* destroy_sighandler_state */
NULL, /* attach_console */ NULL, /* attach_console */
NULL, /* detach_console */ NULL, /* detach_console */
NULL, /* watch_path_for_changes */
NULL, /* check_for_path_changes */
"xdk", "xdk",
}; };

View File

@ -91,5 +91,7 @@ frontend_ctx_driver_t frontend_ctx_qnx = {
NULL, /* destroy_sighandler_state */ NULL, /* destroy_sighandler_state */
NULL, /* attach_console */ NULL, /* attach_console */
NULL, /* detach_console */ NULL, /* detach_console */
NULL, /* watch_path_for_changes */
NULL, /* check_for_path_changes */
"xenon", "xenon",
}; };

View File

@ -384,4 +384,29 @@ void frontend_driver_destroy_signal_handler_state(void)
return; return;
frontend->destroy_signal_handler_state(); frontend->destroy_signal_handler_state();
} }
bool frontend_driver_can_watch_for_changes(void)
{
frontend_ctx_driver_t *frontend = frontend_get_ptr();
if (!frontend || !frontend->watch_path_for_changes)
return false;
return true;
}
void frontend_driver_watch_path_for_changes(struct string_list *list, int flags, path_change_data_t **change_data)
{
frontend_ctx_driver_t *frontend = frontend_get_ptr();
if (!frontend || !frontend->watch_path_for_changes)
return;
frontend->watch_path_for_changes(list, flags, change_data);
}
bool frontend_driver_check_for_path_changes(path_change_data_t *change_data)
{
frontend_ctx_driver_t *frontend = frontend_get_ptr();
if (!frontend || !frontend->check_for_path_changes)
return false;
return frontend->check_for_path_changes(change_data);
}
#endif #endif

View File

@ -22,6 +22,7 @@
#include <boolean.h> #include <boolean.h>
#include <retro_common_api.h> #include <retro_common_api.h>
#include <lists/string_list.h>
RETRO_BEGIN_DECLS RETRO_BEGIN_DECLS
@ -55,6 +56,20 @@ enum frontend_architecture
FRONTEND_ARCH_TILE FRONTEND_ARCH_TILE
}; };
/* different platforms may only support some of these types */
enum path_change_type
{
PATH_CHANGE_TYPE_MODIFIED = (1 << 0),
PATH_CHANGE_TYPE_WRITE_FILE_CLOSED = (1 << 1),
PATH_CHANGE_TYPE_FILE_MOVED = (1 << 2),
PATH_CHANGE_TYPE_FILE_DELETED = (1 << 3)
};
typedef struct path_change_data
{
void *data;
} path_change_data_t;
typedef void (*environment_get_t)(int *argc, char *argv[], void *args, typedef void (*environment_get_t)(int *argc, char *argv[], void *args,
void *params_data); void *params_data);
typedef void (*process_args_t)(int *argc, char *argv[]); typedef void (*process_args_t)(int *argc, char *argv[]);
@ -88,6 +103,8 @@ typedef struct frontend_ctx_driver
#ifdef HAVE_LAKKA #ifdef HAVE_LAKKA
void (*get_lakka_version)(char *, size_t); void (*get_lakka_version)(char *, size_t);
#endif #endif
void (*watch_path_for_changes)(struct string_list *list, int flags, path_change_data_t **change_data);
bool (*check_for_path_changes)(path_change_data_t *change_data);
const char *ident; const char *ident;
@ -180,6 +197,12 @@ void frontend_driver_attach_console(void);
void frontend_driver_detach_console(void); void frontend_driver_detach_console(void);
bool frontend_driver_can_watch_for_changes(void);
void frontend_driver_watch_path_for_changes(struct string_list *list, int flags, path_change_data_t **change_data);
bool frontend_driver_check_for_path_changes(path_change_data_t *change_data);
RETRO_END_DECLS RETRO_END_DECLS
#endif #endif

View File

@ -3332,7 +3332,6 @@ static struct video_shader *video_shader_driver_get_current_shader_null(void *da
return NULL; return NULL;
} }
static void video_shader_driver_set_params_null(void *data, void *shader_data, static void video_shader_driver_set_params_null(void *data, void *shader_data,
unsigned width, unsigned height, unsigned width, unsigned height,
unsigned tex_width, unsigned tex_height, unsigned tex_width, unsigned tex_height,

View File

@ -27,9 +27,12 @@
#include <string/stdstring.h> #include <string/stdstring.h>
#include <streams/interface_stream.h> #include <streams/interface_stream.h>
#include <streams/file_stream.h> #include <streams/file_stream.h>
#include <lists/string_list.h>
#include "../msg_hash.h" #include "../msg_hash.h"
#include "../verbosity.h" #include "../verbosity.h"
#include "../configuration.h"
#include "../frontend/frontend_driver.h"
#include "video_shader_parse.h" #include "video_shader_parse.h"
#ifdef HAVE_SLANG #ifdef HAVE_SLANG
@ -53,6 +56,8 @@
#define SEMANTIC_TRANSITION_COUNT 0x3ef2af78U #define SEMANTIC_TRANSITION_COUNT 0x3ef2af78U
#define SEMANTIC_PYTHON 0x15efc547U #define SEMANTIC_PYTHON 0x15efc547U
static path_change_data_t *file_change_data = NULL;
/** /**
* wrap_mode_to_str: * wrap_mode_to_str:
* @type : Wrap type. * @type : Wrap type.
@ -755,6 +760,11 @@ bool video_shader_read_conf_cgp(config_file_t *conf,
{ {
unsigned i; unsigned i;
unsigned shaders = 0; unsigned shaders = 0;
settings_t *settings = config_get_ptr();
struct string_list *file_list = NULL;
union string_list_elem_attr attr = {0};
(void)file_list;
memset(shader, 0, sizeof(*shader)); memset(shader, 0, sizeof(*shader));
shader->type = RARCH_SHADER_CG; shader->type = RARCH_SHADER_CG;
@ -776,10 +786,36 @@ bool video_shader_read_conf_cgp(config_file_t *conf,
shader->passes = MIN(shaders, GFX_MAX_SHADERS); shader->passes = MIN(shaders, GFX_MAX_SHADERS);
if (settings->bools.video_shader_watch_files)
{
if (file_change_data)
frontend_driver_watch_path_for_changes(NULL, 0, &file_change_data);
file_change_data = NULL;
file_list = string_list_new();
string_list_append(file_list, conf->path, attr);
}
for (i = 0; i < shader->passes; i++) for (i = 0; i < shader->passes; i++)
{ {
if (!video_shader_parse_pass(conf, &shader->pass[i], i)) if (!video_shader_parse_pass(conf, &shader->pass[i], i))
return false; return false;
if (settings->bools.video_shader_watch_files)
{
string_list_append(file_list, shader->pass[i].source.path, attr);
}
}
if (settings->bools.video_shader_watch_files)
{
int flags = PATH_CHANGE_TYPE_MODIFIED |
PATH_CHANGE_TYPE_WRITE_FILE_CLOSED |
PATH_CHANGE_TYPE_FILE_MOVED |
PATH_CHANGE_TYPE_FILE_DELETED;
frontend_driver_watch_path_for_changes(file_list, flags, &file_change_data);
string_list_free(file_list);
} }
if (!video_shader_parse_textures(conf, shader)) if (!video_shader_parse_textures(conf, shader))
@ -1198,3 +1234,10 @@ void video_shader_resolve_relative(struct video_shader *shader,
free(tmp_path); free(tmp_path);
} }
bool video_shader_check_for_changes(void)
{
if (!file_change_data)
return false;
return frontend_driver_check_for_path_changes(file_change_data);
}

View File

@ -231,6 +231,8 @@ bool video_shader_resolve_parameters(config_file_t *conf,
enum rarch_shader_type video_shader_parse_type(const char *path, enum rarch_shader_type video_shader_parse_type(const char *path,
enum rarch_shader_type fallback); enum rarch_shader_type fallback);
bool video_shader_check_for_changes(void);
RETRO_END_DECLS RETRO_END_DECLS
#endif #endif

View File

@ -3205,7 +3205,3 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY,
"Audio Resampler Quality") "Audio Resampler Quality")
MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY,
"Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.") "Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.")
MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PLACEHOLDER,
"Shader Placeholder")
MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_PLACEHOLDER,
"Shader Placeholder sublabel")

View File

@ -3199,7 +3199,3 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY,
"Audio Resampler Quality") "Audio Resampler Quality")
MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY,
"Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.") "Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.")
MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PLACEHOLDER,
"Shader Placeholder")
MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_PLACEHOLDER,
"Shader Placeholder sublabel")

View File

@ -3315,7 +3315,3 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY,
"Audio Resampler Quality") "Audio Resampler Quality")
MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY,
"Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.") "Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.")
MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PLACEHOLDER,
"Shader Placeholder")
MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_PLACEHOLDER,
"Shader Placeholder sublabel")

View File

@ -3072,7 +3072,3 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY,
"Audio Resampler Quality") "Audio Resampler Quality")
MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY,
"Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.") "Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.")
MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PLACEHOLDER,
"Shader Placeholder")
MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_PLACEHOLDER,
"Shader Placeholder sublabel")

View File

@ -5701,8 +5701,4 @@ MSG_HASH(
MSG_HASH( MSG_HASH(
MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY,
"Valores mas bajos favorecen el rendimiento y bajan la latencia a costa de la calidad, incrementar el valor aumentará la calidad a costa del rendimiento y latencia" "Valores mas bajos favorecen el rendimiento y bajan la latencia a costa de la calidad, incrementar el valor aumentará la calidad a costa del rendimiento y latencia"
) )
MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PLACEHOLDER,
"Shader Placeholder")
MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_PLACEHOLDER,
"Shader Placeholder sublabel")

View File

@ -3237,7 +3237,3 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY,
"Audio Resampler Quality") "Audio Resampler Quality")
MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY,
"Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.") "Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.")
MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PLACEHOLDER,
"Shader Placeholder")
MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_PLACEHOLDER,
"Shader Placeholder sublabel")

View File

@ -3295,7 +3295,3 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY,
"Qualità del Resampler Audio") "Qualità del Resampler Audio")
MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY,
"Abbassare questo valore per favorire prestazioni/bassa latenza rispetto alla qualità audio, aumentare se si desidera una migliore qualità audio a scapito delle prestazioni/minore latenza.") "Abbassare questo valore per favorire prestazioni/bassa latenza rispetto alla qualità audio, aumentare se si desidera una migliore qualità audio a scapito delle prestazioni/minore latenza.")
MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PLACEHOLDER,
"Shader Segnaposto")
MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_PLACEHOLDER,
"Shader Segnaposto sotto etichetta")

View File

@ -2990,7 +2990,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH,
MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR,
"If a joypad is plugged in, that joypad will be autoconfigured if a config file corresponding to it is present inside this directory.") "If a joypad is plugged in, that joypad will be autoconfigured if a config file corresponding to it is present inside this directory.")
MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY,
"すべてのコレクションをこのフォルダに保存する。") "すべてのプレイリストをこのフォルダに保存する。")
MSG_HASH( MSG_HASH(
MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, MENU_ENUM_SUBLABEL_CACHE_DIRECTORY,
"If set to a directory, content which is temporarily extracted (e.g. from archives) will be extracted to this directory." "If set to a directory, content which is temporarily extracted (e.g. from archives) will be extracted to this directory."
@ -3256,7 +3256,7 @@ MSG_HASH(MSG_GAME_REMAP_FILE_LOADED,
MSG_HASH(MSG_CORE_REMAP_FILE_LOADED, MSG_HASH(MSG_CORE_REMAP_FILE_LOADED,
"コアの優先ファイルをロードしました。") "コアの優先ファイルをロードしました。")
MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST,
"Automatically add content to playlist") "自動的にコンテンツをプレイリストに追加")
MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST,
"Automatically scans loaded content so they appear inside playlists.") "Automatically scans loaded content so they appear inside playlists.")
MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED,
@ -3267,7 +3267,5 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY,
"Audio Resampler Quality") "Audio Resampler Quality")
MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY,
"Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.") "Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.")
MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PLACEHOLDER, MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_WATCH_FOR_CHANGES,
"Shader Placeholder") "シェーダーファイルの変更を監視")
MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_PLACEHOLDER,
"Shader Placeholder sublabel")

View File

@ -3200,7 +3200,3 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY,
"Audio Resampler Quality") "Audio Resampler Quality")
MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY,
"Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.") "Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.")
MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PLACEHOLDER,
"Shader Placeholder")
MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_PLACEHOLDER,
"Shader Placeholder sublabel")

View File

@ -931,6 +931,8 @@ MSG_HASH(MENU_ENUM_LABEL_SETTINGS_TAB,
"settings_tab") "settings_tab")
MSG_HASH(MENU_ENUM_LABEL_SHADER_APPLY_CHANGES, MSG_HASH(MENU_ENUM_LABEL_SHADER_APPLY_CHANGES,
"shader_apply_changes") "shader_apply_changes")
MSG_HASH(MENU_ENUM_LABEL_SHADER_WATCH_FOR_CHANGES,
"video_shader_watch_files")
MSG_HASH(MENU_ENUM_LABEL_SHADER_OPTIONS, MSG_HASH(MENU_ENUM_LABEL_SHADER_OPTIONS,
"shader_options") "shader_options")
MSG_HASH(MENU_ENUM_LABEL_SHADER_PARAMETERS_ENTRY, MSG_HASH(MENU_ENUM_LABEL_SHADER_PARAMETERS_ENTRY,
@ -1391,5 +1393,3 @@ MSG_HASH(MENU_ENUM_LABEL_VIDEO_WINDOW_OPACITY,
"video_window_opacity") "video_window_opacity")
MSG_HASH(MENU_ENUM_LABEL_AUDIO_RESAMPLER_QUALITY, MSG_HASH(MENU_ENUM_LABEL_AUDIO_RESAMPLER_QUALITY,
"audio_resampler_quality") "audio_resampler_quality")
MSG_HASH(MENU_ENUM_LABEL_SHADER_PLACEHOLDER,
"shader_placeholder")

View File

@ -3074,7 +3074,3 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY,
"Audio Resampler Quality") "Audio Resampler Quality")
MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY,
"Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.") "Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.")
MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PLACEHOLDER,
"Shader Placeholder")
MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_PLACEHOLDER,
"Shader Placeholder sublabel")

View File

@ -3335,7 +3335,3 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY,
"Audio Resampler Quality") "Audio Resampler Quality")
MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY,
"Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.") "Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.")
MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PLACEHOLDER,
"Shader Placeholder")
MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_PLACEHOLDER,
"Shader Placeholder sublabel")

View File

@ -4179,7 +4179,3 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY,
"Audio Resampler Quality") "Audio Resampler Quality")
MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY,
"Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.") "Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.")
MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PLACEHOLDER,
"Shader Placeholder")
MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_PLACEHOLDER,
"Shader Placeholder sublabel")

View File

@ -3175,7 +3175,3 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY,
"Audio Resampler Quality") "Audio Resampler Quality")
MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY,
"Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.") "Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.")
MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PLACEHOLDER,
"Shader Placeholder")
MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_PLACEHOLDER,
"Shader Placeholder sublabel")

View File

@ -3258,7 +3258,3 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY,
"Audio Resampler Quality") "Audio Resampler Quality")
MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY,
"Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.") "Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.")
MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PLACEHOLDER,
"Shader Placeholder")
MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_PLACEHOLDER,
"Shader Placeholder sublabel")

View File

@ -1071,6 +1071,15 @@ int menu_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len)
"saved to Shader Directory." "saved to Shader Directory."
); );
break; break;
case MENU_ENUM_LABEL_SHADER_WATCH_FOR_CHANGES:
snprintf(s, len,
"Watch shader files for new changes. \n"
" \n"
"After saving changes to a shader on disk, \n"
"it will automatically be recompiled \n"
"and applied to the running content."
);
break;
case MENU_ENUM_LABEL_MENU_TOGGLE: case MENU_ENUM_LABEL_MENU_TOGGLE:
snprintf(s, len, snprintf(s, len,
"Toggles menu."); "Toggles menu.");

View File

@ -3405,7 +3405,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY,
"Audio Resampler Quality") "Audio Resampler Quality")
MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY,
"Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.") "Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.")
MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PLACEHOLDER, MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_WATCH_FOR_CHANGES,
"Shader Placeholder") "Watch shader files for changes")
MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_PLACEHOLDER, MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_WATCH_FOR_CHANGES,
"Shader Placeholder sublabel") "Auto-apply changes made to shader files on disk.")

View File

@ -3223,7 +3223,3 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_QUALITY,
"Audio Resampler Quality") "Audio Resampler Quality")
MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY, MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_QUALITY,
"Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.") "Lower this value to favor performance/lower latency over audio quality, increase if you want better audio quality at the expense of performance/lower latency.")
MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PLACEHOLDER,
"Shader Placeholder")
MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_PLACEHOLDER,
"Shader Placeholder sublabel")

View File

@ -309,6 +309,30 @@ static void menu_action_setting_disp_set_label_pipeline(
} }
static void menu_action_setting_disp_set_label_shader_watch_for_changes(
file_list_t* list,
unsigned *w, unsigned type, unsigned i,
const char *label,
char *s, size_t len,
const char *entry_label,
const char *path,
char *s2, size_t len2)
{
settings_t *settings = config_get_ptr();
*s = '\0';
*w = 19;
strlcpy(s2, path, len2);
if (settings)
{
if (settings->bools.video_shader_watch_files)
snprintf(s, len, "%s", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_TRUE));
else
snprintf(s, len, "%s", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_FALSE));
}
}
static void menu_action_setting_disp_set_label_shader_num_passes( static void menu_action_setting_disp_set_label_shader_num_passes(
file_list_t* list, file_list_t* list,
unsigned *w, unsigned type, unsigned i, unsigned *w, unsigned type, unsigned i,
@ -1873,6 +1897,10 @@ static int menu_cbs_init_bind_get_string_representation_compare_label(
BIND_ACTION_GET_VALUE(cbs, BIND_ACTION_GET_VALUE(cbs,
menu_action_setting_disp_set_label_shader_num_passes); menu_action_setting_disp_set_label_shader_num_passes);
break; break;
case MENU_ENUM_LABEL_SHADER_WATCH_FOR_CHANGES:
BIND_ACTION_GET_VALUE(cbs,
menu_action_setting_disp_set_label_shader_watch_for_changes);
break;
case MENU_ENUM_LABEL_XMB_RIBBON_ENABLE: case MENU_ENUM_LABEL_XMB_RIBBON_ENABLE:
BIND_ACTION_GET_VALUE(cbs, BIND_ACTION_GET_VALUE(cbs,
menu_action_setting_disp_set_label_pipeline); menu_action_setting_disp_set_label_pipeline);

View File

@ -324,6 +324,14 @@ static int action_left_shader_num_passes(unsigned type, const char *label,
return 0; return 0;
} }
static int action_left_shader_watch_for_changes(unsigned type, const char *label,
bool wraparound)
{
settings_t *settings = config_get_ptr();
settings->bools.video_shader_watch_files = !settings->bools.video_shader_watch_files;
return 0;
}
static int action_left_video_resolution(unsigned type, const char *label, static int action_left_video_resolution(unsigned type, const char *label,
bool wraparound) bool wraparound)
{ {
@ -482,6 +490,9 @@ static int menu_cbs_init_bind_left_compare_label(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_VIDEO_SHADER_DEFAULT_FILTER: case MENU_ENUM_LABEL_VIDEO_SHADER_DEFAULT_FILTER:
BIND_ACTION_LEFT(cbs, action_left_shader_filter_default); BIND_ACTION_LEFT(cbs, action_left_shader_filter_default);
break; break;
case MENU_ENUM_LABEL_SHADER_WATCH_FOR_CHANGES:
BIND_ACTION_LEFT(cbs, action_left_shader_watch_for_changes);
break;
case MENU_ENUM_LABEL_VIDEO_SHADER_NUM_PASSES: case MENU_ENUM_LABEL_VIDEO_SHADER_NUM_PASSES:
BIND_ACTION_LEFT(cbs, action_left_shader_num_passes); BIND_ACTION_LEFT(cbs, action_left_shader_num_passes);
break; break;

View File

@ -327,6 +327,14 @@ static int action_right_shader_num_passes(unsigned type, const char *label,
return 0; return 0;
} }
static int action_right_shader_watch_for_changes(unsigned type, const char *label,
bool wraparound)
{
settings_t *settings = config_get_ptr();
settings->bools.video_shader_watch_files = !settings->bools.video_shader_watch_files;
return 0;
}
static int action_right_video_resolution(unsigned type, const char *label, static int action_right_video_resolution(unsigned type, const char *label,
bool wraparound) bool wraparound)
{ {
@ -592,6 +600,9 @@ static int menu_cbs_init_bind_right_compare_label(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_VIDEO_SHADER_DEFAULT_FILTER: case MENU_ENUM_LABEL_VIDEO_SHADER_DEFAULT_FILTER:
BIND_ACTION_RIGHT(cbs, action_right_shader_filter_default); BIND_ACTION_RIGHT(cbs, action_right_shader_filter_default);
break; break;
case MENU_ENUM_LABEL_SHADER_WATCH_FOR_CHANGES:
BIND_ACTION_RIGHT(cbs, action_right_shader_watch_for_changes);
break;
case MENU_ENUM_LABEL_VIDEO_SHADER_NUM_PASSES: case MENU_ENUM_LABEL_VIDEO_SHADER_NUM_PASSES:
BIND_ACTION_RIGHT(cbs, action_right_shader_num_passes); BIND_ACTION_RIGHT(cbs, action_right_shader_num_passes);
break; break;

View File

@ -40,6 +40,8 @@
#include "../../input/input_driver.h" #include "../../input/input_driver.h"
#include "../../input/input_remapping.h" #include "../../input/input_remapping.h"
#include "../../config.def.h"
#ifndef BIND_ACTION_START #ifndef BIND_ACTION_START
#define BIND_ACTION_START(cbs, name) \ #define BIND_ACTION_START(cbs, name) \
cbs->action_start = name; \ cbs->action_start = name; \
@ -166,6 +168,13 @@ static int action_start_shader_filter_pass(unsigned type, const char *label)
return menu_shader_manager_clear_pass_filter(pass); return menu_shader_manager_clear_pass_filter(pass);
} }
static int action_start_shader_watch_for_changes(unsigned type, const char *label)
{
settings_t *settings = config_get_ptr();
settings->bools.video_shader_watch_files = video_shader_watch_files;
return 0;
}
static int action_start_shader_num_passes(unsigned type, const char *label) static int action_start_shader_num_passes(unsigned type, const char *label)
{ {
return menu_shader_manager_clear_num_passes(); return menu_shader_manager_clear_num_passes();
@ -279,6 +288,9 @@ static int menu_cbs_init_bind_start_compare_label(menu_file_list_cbs_t *cbs)
case MENU_ENUM_LABEL_VIDEO_SHADER_FILTER_PASS: case MENU_ENUM_LABEL_VIDEO_SHADER_FILTER_PASS:
BIND_ACTION_START(cbs, action_start_shader_filter_pass); BIND_ACTION_START(cbs, action_start_shader_filter_pass);
break; break;
case MENU_ENUM_LABEL_SHADER_WATCH_FOR_CHANGES:
BIND_ACTION_START(cbs, action_start_shader_watch_for_changes);
break;
case MENU_ENUM_LABEL_VIDEO_SHADER_NUM_PASSES: case MENU_ENUM_LABEL_VIDEO_SHADER_NUM_PASSES:
BIND_ACTION_START(cbs, action_start_shader_num_passes); BIND_ACTION_START(cbs, action_start_shader_num_passes);
break; break;

View File

@ -353,6 +353,7 @@ default_sublabel_macro(action_bind_sublabel_recording_output_directory,
default_sublabel_macro(action_bind_sublabel_recording_config_directory, MENU_ENUM_SUBLABEL_RECORDING_CONFIG_DIRECTORY) default_sublabel_macro(action_bind_sublabel_recording_config_directory, MENU_ENUM_SUBLABEL_RECORDING_CONFIG_DIRECTORY)
default_sublabel_macro(action_bind_sublabel_video_font_path, MENU_ENUM_SUBLABEL_VIDEO_FONT_PATH) default_sublabel_macro(action_bind_sublabel_video_font_path, MENU_ENUM_SUBLABEL_VIDEO_FONT_PATH)
default_sublabel_macro(action_bind_sublabel_shader_apply_changes, MENU_ENUM_SUBLABEL_SHADER_APPLY_CHANGES) default_sublabel_macro(action_bind_sublabel_shader_apply_changes, MENU_ENUM_SUBLABEL_SHADER_APPLY_CHANGES)
default_sublabel_macro(action_bind_sublabel_shader_watch_for_changes, MENU_ENUM_SUBLABEL_SHADER_WATCH_FOR_CHANGES)
default_sublabel_macro(action_bind_sublabel_shader_num_passes, MENU_ENUM_SUBLABEL_VIDEO_SHADER_NUM_PASSES) default_sublabel_macro(action_bind_sublabel_shader_num_passes, MENU_ENUM_SUBLABEL_VIDEO_SHADER_NUM_PASSES)
default_sublabel_macro(action_bind_sublabel_shader_preset, MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET) default_sublabel_macro(action_bind_sublabel_shader_preset, MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET)
default_sublabel_macro(action_bind_sublabel_shader_preset_save_as, MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_AS) default_sublabel_macro(action_bind_sublabel_shader_preset_save_as, MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_AS)
@ -518,6 +519,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_SHADER_APPLY_CHANGES: case MENU_ENUM_LABEL_SHADER_APPLY_CHANGES:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_shader_apply_changes); BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_shader_apply_changes);
break; break;
case MENU_ENUM_LABEL_SHADER_WATCH_FOR_CHANGES:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_shader_watch_for_changes);
break;
case MENU_ENUM_LABEL_VIDEO_FONT_PATH: case MENU_ENUM_LABEL_VIDEO_FONT_PATH:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_font_path); BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_font_path);
break; break;

View File

@ -1366,16 +1366,19 @@ static int menu_displaylist_parse_shader_options(menu_displaylist_info_t *info)
unsigned i; unsigned i;
unsigned pass_count = menu_shader_manager_get_amount_passes(); unsigned pass_count = menu_shader_manager_get_amount_passes();
menu_entries_append_enum(info->list,
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SHADER_PLACEHOLDER),
msg_hash_to_str(MENU_ENUM_LABEL_SHADER_PLACEHOLDER),
MENU_ENUM_LABEL_SHADER_PLACEHOLDER,
MENU_SETTING_ACTION, 0, 0);
menu_entries_append_enum(info->list, menu_entries_append_enum(info->list,
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SHADER_APPLY_CHANGES), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SHADER_APPLY_CHANGES),
msg_hash_to_str(MENU_ENUM_LABEL_SHADER_APPLY_CHANGES), msg_hash_to_str(MENU_ENUM_LABEL_SHADER_APPLY_CHANGES),
MENU_ENUM_LABEL_SHADER_APPLY_CHANGES, MENU_ENUM_LABEL_SHADER_APPLY_CHANGES,
MENU_SETTING_ACTION, 0, 0); MENU_SETTING_ACTION, 0, 0);
if (frontend_driver_can_watch_for_changes())
{
menu_entries_append_enum(info->list,
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SHADER_WATCH_FOR_CHANGES),
msg_hash_to_str(MENU_ENUM_LABEL_SHADER_WATCH_FOR_CHANGES),
MENU_ENUM_LABEL_SHADER_WATCH_FOR_CHANGES,
0, 0, 0);
}
menu_entries_append_enum(info->list, menu_entries_append_enum(info->list,
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET),
msg_hash_to_str(MENU_ENUM_LABEL_VIDEO_SHADER_PRESET), msg_hash_to_str(MENU_ENUM_LABEL_VIDEO_SHADER_PRESET),

View File

@ -1467,12 +1467,12 @@ enum msg_hash_enums
MENU_ENUM_LABEL_ONSCREEN_KEYBOARD_OVERLAY_SETTINGS, MENU_ENUM_LABEL_ONSCREEN_KEYBOARD_OVERLAY_SETTINGS,
MENU_LABEL(SHADER_PLACEHOLDER),
MENU_LABEL(MULTIMEDIA_SETTINGS), MENU_LABEL(MULTIMEDIA_SETTINGS),
MENU_LABEL(PLAYLIST_SETTINGS), MENU_LABEL(PLAYLIST_SETTINGS),
MENU_LABEL(CORE_UPDATER_SETTINGS), MENU_LABEL(CORE_UPDATER_SETTINGS),
MENU_LABEL(LAKKA_SERVICES), MENU_LABEL(LAKKA_SERVICES),
MENU_LABEL(SHADER_APPLY_CHANGES), MENU_LABEL(SHADER_APPLY_CHANGES),
MENU_LABEL(SHADER_WATCH_FOR_CHANGES),
MENU_LABEL(SAVE_NEW_CONFIG), MENU_LABEL(SAVE_NEW_CONFIG),
MENU_LABEL(ONSCREEN_DISPLAY_SETTINGS), MENU_LABEL(ONSCREEN_DISPLAY_SETTINGS),
MENU_LABEL(ONSCREEN_OVERLAY_SETTINGS), MENU_LABEL(ONSCREEN_OVERLAY_SETTINGS),

View File

@ -130,6 +130,8 @@
#define DEFAULT_EXT "" #define DEFAULT_EXT ""
#endif #endif
#define SHADER_FILE_WATCH_DELAY_FRAMES 5
/* Descriptive names for options without short variant. /* Descriptive names for options without short variant.
* *
* Please keep the name in sync with the option name. * Please keep the name in sync with the option name.
@ -2994,6 +2996,35 @@ static enum runloop_state runloop_check_state(
old_cheat_index_toggle = cheat_index_toggle; old_cheat_index_toggle = cheat_index_toggle;
} }
if (settings->bools.video_shader_watch_files)
{
static bool need_to_apply = false;
static int elapsed_frames = 0;
if (video_shader_check_for_changes())
{
need_to_apply = true;
elapsed_frames = 0;
}
/* If a file is modified atomically (moved/renamed from a different file), we have no idea how long that might take.
* If we're trying to re-apply shaders immediately after changes are made to the original file(s), the filesystem might be in an in-between
* state where the new file hasn't been moved over yet and the original file was already deleted. This leaves us no choice
* but to wait an arbitrary amount of time and hope for the best.
*/
if (need_to_apply)
{
if (elapsed_frames > SHADER_FILE_WATCH_DELAY_FRAMES)
{
need_to_apply = false;
elapsed_frames = 0;
command_event(CMD_EVENT_SHADERS_APPLY_CHANGES, NULL);
}
else
elapsed_frames++;
}
}
return RUNLOOP_STATE_ITERATE; return RUNLOOP_STATE_ITERATE;
} }

View File

@ -811,6 +811,9 @@ video_message_bgcolor_opacity = 1.0
# Screenshots output of GPU shaded material if available. # Screenshots output of GPU shaded material if available.
# video_gpu_screenshot = true # video_gpu_screenshot = true
# Watch content shader files for changes and auto-apply as necessary.
# video_shader_watch_files = false
# Block SRAM from being overwritten when loading save states. # Block SRAM from being overwritten when loading save states.
# Might potentially lead to buggy games. # Might potentially lead to buggy games.
# block_sram_overwrite = false # block_sram_overwrite = false