Move code out of retroarch.c

This commit is contained in:
twinaphex 2021-10-29 14:13:16 +02:00
parent 18707da360
commit ec7b7821fa
6 changed files with 288 additions and 284 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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