From ec7b7821fadf1fafa9f65a815dbf06b18b2a50f2 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 29 Oct 2021 14:13:16 +0200 Subject: [PATCH] Move code out of retroarch.c --- command.c | 32 +++++ gfx/video_shader_parse.c | 98 ++++++++++++++ gfx/video_shader_parse.h | 5 + menu/menu_driver.c | 153 ++++++++++++++++++++- retroarch.c | 279 +-------------------------------------- retroarch_fwd_decls.h | 5 - 6 files changed, 288 insertions(+), 284 deletions(-) diff --git a/command.c b/command.c index dc4c5d2272..fabae82340 100644 --- a/command.c +++ b/command.c @@ -45,6 +45,9 @@ #endif #include "audio/audio_driver.h" +#if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL) +#include "gfx/video_shader_parse.h" +#endif #include "command.h" #include "core_info.h" #include "cheat_manager.h" @@ -1273,3 +1276,32 @@ void command_event_set_savestate_garbage_collect( dir_list_free(dir_list); } + +#if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL) +bool command_set_shader(command_t *cmd, const char *arg) +{ + enum rarch_shader_type type = video_shader_parse_type(arg); + settings_t *settings = config_get_ptr(); + + if (!string_is_empty(arg)) + { + if (!video_shader_is_supported(type)) + return false; + + /* rebase on shader directory */ + if (!path_is_absolute(arg)) + { + static char abs_arg[PATH_MAX_LENGTH]; + const char *ref_path = settings->paths.directory_video_shader; + fill_pathname_join(abs_arg, + ref_path, arg, sizeof(abs_arg)); + /* TODO/FIXME - pointer to local variable - + * making abs_arg static for now to workaround this + */ + arg = abs_arg; + } + } + + return apply_shader(settings, type, arg, true); +} +#endif diff --git a/gfx/video_shader_parse.c b/gfx/video_shader_parse.c index e8ace368f2..d5d89ec61c 100644 --- a/gfx/video_shader_parse.c +++ b/gfx/video_shader_parse.c @@ -45,6 +45,11 @@ #include "../file_path_special.h" #include "../paths.h" #include "../retroarch.h" + +#if defined(HAVE_GFX_WIDGETS) +#include "gfx_widgets.h" +#endif + #include "video_shader_parse.h" #if defined(HAVE_SLANG) && defined(HAVE_SPIRV_CROSS) @@ -2402,3 +2407,96 @@ success: return true; } +bool apply_shader( + settings_t *settings, + enum rarch_shader_type type, + const char *preset_path, bool message) +{ + char msg[256]; + video_driver_state_t + *video_st = video_state_get_ptr(); + runloop_state_t *runloop_st = runloop_state_get_ptr(); + const char *core_name = runloop_st->system.info.library_name; + const char *preset_file = NULL; +#ifdef HAVE_MENU + struct video_shader *shader = menu_shader_get(); +#endif + + /* Disallow loading shaders when no core is loaded */ + if (string_is_empty(core_name)) + return false; + + if (!string_is_empty(preset_path)) + preset_file = path_basename_nocompression(preset_path); + + /* TODO/FIXME - This loads the shader into the video driver + * But then we load the shader from disk twice more to put it in the menu + * We need to reconfigure this at some point to only load it once */ + if (video_st->current_video->set_shader) + { + if ((video_st->current_video->set_shader( + video_st->data, type, preset_path))) + { + configuration_set_bool(settings, settings->bools.video_shader_enable, true); + if (!string_is_empty(preset_path)) + { + strlcpy(runloop_st->runtime_shader_preset_path, preset_path, + sizeof(runloop_st->runtime_shader_preset_path)); +#ifdef HAVE_MENU + /* reflect in shader manager */ + if (menu_shader_manager_set_preset( + shader, type, preset_path, false)) + shader->modified = false; +#endif + } + else + runloop_st->runtime_shader_preset_path[0] = '\0'; + + if (message) + { + /* Display message */ + if (preset_file) + snprintf(msg, sizeof(msg), + "%s: \"%s\"", + msg_hash_to_str(MSG_SHADER), + preset_file); + else + snprintf(msg, sizeof(msg), + "%s: %s", + msg_hash_to_str(MSG_SHADER), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NONE) + ); +#ifdef HAVE_GFX_WIDGETS + if (dispwidget_get_ptr()->active) + gfx_widget_set_generic_message(msg, 2000); + else +#endif + runloop_msg_queue_push(msg, 1, 120, true, NULL, + MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + } + + RARCH_LOG("%s \"%s\".\n", + msg_hash_to_str(MSG_APPLYING_SHADER), + preset_path ? preset_path : "null"); + + return true; + } + } + +#ifdef HAVE_MENU + /* reflect in shader manager */ + menu_shader_manager_set_preset(shader, type, NULL, false); +#endif + + /* Display error message */ + fill_pathname_join_delim(msg, + msg_hash_to_str(MSG_FAILED_TO_APPLY_SHADER_PRESET), + preset_file ? preset_file : "null", + ' ', + sizeof(msg)); + + runloop_msg_queue_push( + msg, 1, 180, true, NULL, + MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_ERROR); + return false; +} diff --git a/gfx/video_shader_parse.h b/gfx/video_shader_parse.h index 248db32141..1c13e90e05 100644 --- a/gfx/video_shader_parse.h +++ b/gfx/video_shader_parse.h @@ -299,6 +299,11 @@ void dir_check_shader( */ bool load_shader_preset(settings_t *settings, const char *core_name, char *s, size_t len); +bool apply_shader( + settings_t *settings, + enum rarch_shader_type type, + const char *preset_path, bool message); + const char *video_shader_get_preset_extension(enum rarch_shader_type type); RETRO_END_DECLS diff --git a/menu/menu_driver.c b/menu/menu_driver.c index 41048fb2d1..2efcd64567 100644 --- a/menu/menu_driver.c +++ b/menu/menu_driver.c @@ -6952,7 +6952,7 @@ void retroarch_menu_running_finished(bool quit) bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data) { gfx_display_t *p_disp = disp_get_ptr(); - struct menu_state *menu_st = menu_state_get_ptr(); + struct menu_state *menu_st = &menu_driver_state; switch (state) { @@ -7202,3 +7202,154 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data) return true; } + +#if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL) +struct video_shader *menu_shader_get(void) +{ + video_driver_state_t + *video_st = video_state_get_ptr(); + if (video_shader_any_supported()) + if (video_st) + return video_st->menu_driver_shader; + return NULL; +} + +void menu_shader_manager_free(void) +{ + video_driver_state_t + *video_st = video_state_get_ptr(); + if (video_st->menu_driver_shader) + free(video_st->menu_driver_shader); + video_st->menu_driver_shader = NULL; +} + +/** + * menu_shader_manager_init: + * + * Initializes shader manager. + **/ +bool menu_shader_manager_init(void) +{ + video_driver_state_t + *video_st = video_state_get_ptr(); + enum rarch_shader_type type = RARCH_SHADER_NONE; + bool ret = true; + bool is_preset = false; + const char *path_shader = NULL; + struct video_shader *menu_shader = NULL; + + /* We get the shader preset directly from the video driver, so that + * we are in sync with it (it could fail loading an auto-shader) + * If we can't (e.g. get_current_shader is not implemented), + * we'll load retroarch_get_shader_preset() like always */ + video_shader_ctx_t shader_info = {0}; + + video_shader_driver_get_current_shader(&shader_info); + + if (shader_info.data) + /* Use the path of the originally loaded preset because it could + * have been a preset with a #reference in it to another preset */ + path_shader = shader_info.data->loaded_preset_path; + else + path_shader = retroarch_get_shader_preset(); + + menu_shader_manager_free(); + + menu_shader = (struct video_shader*) + calloc(1, sizeof(*menu_shader)); + + if (!menu_shader) + { + ret = false; + goto end; + } + + if (string_is_empty(path_shader)) + goto end; + + type = video_shader_get_type_from_ext(path_get_extension(path_shader), + &is_preset); + + if (!video_shader_is_supported(type)) + { + ret = false; + goto end; + } + + if (is_preset) + { + if (!video_shader_load_preset_into_shader(path_shader, menu_shader)) + { + ret = false; + goto end; + } + menu_shader->modified = false; + } + else + { + strlcpy(menu_shader->pass[0].source.path, path_shader, + sizeof(menu_shader->pass[0].source.path)); + menu_shader->passes = 1; + } + +end: + video_st->menu_driver_shader = menu_shader; + command_event(CMD_EVENT_SHADER_PRESET_LOADED, NULL); + return ret; +} + +/** + * menu_shader_manager_set_preset: + * @shader : Shader handle. + * @type : Type of shader. + * @preset_path : Preset path to load from. + * @apply : Whether to apply the shader or just update shader information + * + * Sets shader preset. + **/ +bool menu_shader_manager_set_preset(struct video_shader *shader, + enum rarch_shader_type type, const char *preset_path, bool apply) +{ + bool refresh = false; + bool ret = false; + settings_t *settings = config_get_ptr(); + + if (apply && !apply_shader(settings, type, preset_path, true)) + goto clear; + + if (string_is_empty(preset_path)) + { + ret = true; + goto clear; + } + + /* Load stored Preset into menu on success. + * Used when a preset is directly loaded. + * No point in updating when the Preset was + * created from the menu itself. */ + if ( !shader || + !(video_shader_load_preset_into_shader(preset_path, shader))) + goto end; + + RARCH_LOG("Menu shader set to: %s.\n", preset_path); + + ret = true; + +end: + menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); + command_event(CMD_EVENT_SHADER_PRESET_LOADED, NULL); + return ret; + +clear: + /* We don't want to disable shaders entirely here, + * just reset number of passes + * > Note: Disabling shaders at this point would in + * fact be dangerous, since it changes the number of + * entries in the shader options menu which can in + * turn lead to the menu selection pointer going out + * of bounds. This causes undefined behaviour/segfaults */ + menu_shader_manager_clear_num_passes(shader); + command_event(CMD_EVENT_SHADER_PRESET_LOADED, NULL); + return ret; +} +#endif diff --git a/retroarch.c b/retroarch.c index 708fcc8b8d..7b529bc467 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1291,160 +1291,6 @@ static const void *find_driver_nonempty( return NULL; } -#ifdef HAVE_MENU -#if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL) -struct video_shader *menu_shader_get(void) -{ - video_driver_state_t - *video_st = video_state_get_ptr(); - if (video_shader_any_supported()) - if (video_st) - return video_st->menu_driver_shader; - return NULL; -} - -void menu_shader_manager_free(void) -{ - video_driver_state_t - *video_st = video_state_get_ptr(); - if (video_st->menu_driver_shader) - free(video_st->menu_driver_shader); - video_st->menu_driver_shader = NULL; -} - -/** - * menu_shader_manager_init: - * - * Initializes shader manager. - **/ -bool menu_shader_manager_init(void) -{ - video_driver_state_t - *video_st = video_state_get_ptr(); - enum rarch_shader_type type = RARCH_SHADER_NONE; - bool ret = true; - bool is_preset = false; - const char *path_shader = NULL; - struct video_shader *menu_shader = NULL; - - /* We get the shader preset directly from the video driver, so that - * we are in sync with it (it could fail loading an auto-shader) - * If we can't (e.g. get_current_shader is not implemented), - * we'll load retroarch_get_shader_preset() like always */ - video_shader_ctx_t shader_info = {0}; - - video_shader_driver_get_current_shader(&shader_info); - - if (shader_info.data) - /* Use the path of the originally loaded preset because it could - * have been a preset with a #reference in it to another preset */ - path_shader = shader_info.data->loaded_preset_path; - else - path_shader = retroarch_get_shader_preset(); - - menu_shader_manager_free(); - - menu_shader = (struct video_shader*) - calloc(1, sizeof(*menu_shader)); - - if (!menu_shader) - { - ret = false; - goto end; - } - - if (string_is_empty(path_shader)) - goto end; - - type = video_shader_get_type_from_ext(path_get_extension(path_shader), - &is_preset); - - if (!video_shader_is_supported(type)) - { - ret = false; - goto end; - } - - if (is_preset) - { - if (!video_shader_load_preset_into_shader(path_shader, menu_shader)) - { - ret = false; - goto end; - } - menu_shader->modified = false; - } - else - { - strlcpy(menu_shader->pass[0].source.path, path_shader, - sizeof(menu_shader->pass[0].source.path)); - menu_shader->passes = 1; - } - -end: - video_st->menu_driver_shader = menu_shader; - command_event(CMD_EVENT_SHADER_PRESET_LOADED, NULL); - return ret; -} - -/** - * menu_shader_manager_set_preset: - * @shader : Shader handle. - * @type : Type of shader. - * @preset_path : Preset path to load from. - * @apply : Whether to apply the shader or just update shader information - * - * Sets shader preset. - **/ -bool menu_shader_manager_set_preset(struct video_shader *shader, - enum rarch_shader_type type, const char *preset_path, bool apply) -{ - bool refresh = false; - bool ret = false; - settings_t *settings = config_get_ptr(); - - if (apply && !retroarch_apply_shader(settings, - type, preset_path, true)) - goto clear; - - if (string_is_empty(preset_path)) - { - ret = true; - goto clear; - } - - /* Load stored Preset into menu on success. - * Used when a preset is directly loaded. - * No point in updating when the Preset was - * created from the menu itself. */ - if ( !shader || - !(video_shader_load_preset_into_shader(preset_path, shader))) - goto end; - - RARCH_LOG("Menu shader set to: %s.\n", preset_path); - - ret = true; - -end: - menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); - command_event(CMD_EVENT_SHADER_PRESET_LOADED, NULL); - return ret; - -clear: - /* We don't want to disable shaders entirely here, - * just reset number of passes - * > Note: Disabling shaders at this point would in - * fact be dangerous, since it changes the number of - * entries in the shader options menu which can in - * turn lead to the menu selection pointer going out - * of bounds. This causes undefined behaviour/segfaults */ - menu_shader_manager_clear_num_passes(shader); - command_event(CMD_EVENT_SHADER_PRESET_LOADED, NULL); - return ret; -} -#endif -#endif - #ifdef HAVE_DISCORD bool discord_is_ready(void) { @@ -4236,129 +4082,6 @@ bool command_get_config_param(command_t *cmd, const char* arg) } #endif -#if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL) -static bool retroarch_apply_shader( - settings_t *settings, - enum rarch_shader_type type, - const char *preset_path, bool message) -{ - char msg[256]; - video_driver_state_t - *video_st = video_state_get_ptr(); - runloop_state_t *runloop_st = &runloop_state; - const char *core_name = runloop_st->system.info.library_name; - const char *preset_file = NULL; -#ifdef HAVE_MENU - struct video_shader *shader = menu_shader_get(); -#endif - - /* Disallow loading shaders when no core is loaded */ - if (string_is_empty(core_name)) - return false; - - if (!string_is_empty(preset_path)) - preset_file = path_basename_nocompression(preset_path); - - /* TODO/FIXME - This loads the shader into the video driver - * But then we load the shader from disk twice more to put it in the menu - * We need to reconfigure this at some point to only load it once */ - if (video_st->current_video->set_shader) - { - if ((video_st->current_video->set_shader( - video_st->data, type, preset_path))) - { - configuration_set_bool(settings, settings->bools.video_shader_enable, true); - if (!string_is_empty(preset_path)) - { - strlcpy(runloop_st->runtime_shader_preset_path, preset_path, - sizeof(runloop_st->runtime_shader_preset_path)); -#ifdef HAVE_MENU - /* reflect in shader manager */ - if (menu_shader_manager_set_preset( - shader, type, preset_path, false)) - shader->modified = false; -#endif - } - else - runloop_st->runtime_shader_preset_path[0] = '\0'; - - if (message) - { - /* Display message */ - if (preset_file) - snprintf(msg, sizeof(msg), - "%s: \"%s\"", - msg_hash_to_str(MSG_SHADER), - preset_file); - else - snprintf(msg, sizeof(msg), - "%s: %s", - msg_hash_to_str(MSG_SHADER), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NONE) - ); -#ifdef HAVE_GFX_WIDGETS - if (dispwidget_get_ptr()->active) - gfx_widget_set_generic_message(msg, 2000); - else -#endif - runloop_msg_queue_push(msg, 1, 120, true, NULL, - MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); - } - - RARCH_LOG("%s \"%s\".\n", - msg_hash_to_str(MSG_APPLYING_SHADER), - preset_path ? preset_path : "null"); - - return true; - } - } - -#ifdef HAVE_MENU - /* reflect in shader manager */ - menu_shader_manager_set_preset(shader, type, NULL, false); -#endif - - /* Display error message */ - fill_pathname_join_delim(msg, - msg_hash_to_str(MSG_FAILED_TO_APPLY_SHADER_PRESET), - preset_file ? preset_file : "null", - ' ', - sizeof(msg)); - - runloop_msg_queue_push( - msg, 1, 180, true, NULL, - MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_ERROR); - return false; -} - -bool command_set_shader(command_t *cmd, const char *arg) -{ - enum rarch_shader_type type = video_shader_parse_type(arg); - settings_t *settings = config_get_ptr(); - - if (!string_is_empty(arg)) - { - if (!video_shader_is_supported(type)) - return false; - - /* rebase on shader directory */ - if (!path_is_absolute(arg)) - { - static char abs_arg[PATH_MAX_LENGTH]; - const char *ref_path = settings->paths.directory_video_shader; - fill_pathname_join(abs_arg, - ref_path, arg, sizeof(abs_arg)); - /* TODO/FIXME - pointer to local variable - - * making abs_arg static for now to workaround this - */ - arg = abs_arg; - } - } - - return retroarch_apply_shader(settings, type, arg, true); -} -#endif - /* TRANSLATION */ #ifdef HAVE_TRANSLATE static void task_auto_translate_handler(retro_task_t *task) @@ -20088,7 +19811,7 @@ static enum runloop_state_enum runloop_check_state( { const char *preset = retroarch_get_shader_preset(); enum rarch_shader_type type = video_shader_parse_type(preset); - retroarch_apply_shader(settings, type, preset, false); + apply_shader(settings, type, preset, false); } } } diff --git a/retroarch_fwd_decls.h b/retroarch_fwd_decls.h index 8cc6349bdf..ff62fc37da 100644 --- a/retroarch_fwd_decls.h +++ b/retroarch_fwd_decls.h @@ -94,11 +94,6 @@ static bool accessibility_speak_priority( const char* speak_text, int priority); #endif -static bool retroarch_apply_shader( - settings_t *settings, - enum rarch_shader_type type, const char *preset_path, - bool message); - static const void *find_driver_nonempty( const char *label, int i, char *s, size_t len);