Move shader parameters to main menu and make dialog box non-modal so we can see changes in real time.

This commit is contained in:
Brandon Wright 2018-05-24 12:18:59 -05:00
parent 636ac85b85
commit d39e7af6d0
6 changed files with 136 additions and 60 deletions

View File

@ -10,6 +10,7 @@
#include "gtk_display.h" #include "gtk_display.h"
#include "gtk_display_driver_opengl.h" #include "gtk_display_driver_opengl.h"
#include "gtk_shader_parameters.h"
#include "shaders/shader_helpers.h" #include "shaders/shader_helpers.h"
#include "shaders/CGLCG.h" #include "shaders/CGLCG.h"
@ -446,6 +447,10 @@ S9xOpenGLDisplayDriver::load_shaders (const char *shader_file)
{ {
using_glsl_shaders = 1; using_glsl_shaders = 1;
dyn_resizing = TRUE; dyn_resizing = TRUE;
if (glsl_shader->param.size () > 0)
window->enable_widget ("shader_parameters_item", TRUE);
return 1; return 1;
} }
delete glsl_shader; delete glsl_shader;
@ -874,6 +879,8 @@ S9xOpenGLDisplayDriver::deinit (void)
if (using_shaders && using_glsl_shaders) if (using_shaders && using_glsl_shaders)
{ {
window->enable_widget ("shader_parameters_item", FALSE);
gtk_shader_parameters_dialog_close ();
glsl_shader->destroy(); glsl_shader->destroy();
delete glsl_shader; delete glsl_shader;
} }

View File

@ -622,7 +622,6 @@ Snes9xPreferences::Snes9xPreferences (Snes9xConfig *config) :
{ "game_data_clear", G_CALLBACK (event_game_data_clear) }, { "game_data_clear", G_CALLBACK (event_game_data_clear) },
{ "about_clicked", G_CALLBACK (event_about_clicked) }, { "about_clicked", G_CALLBACK (event_about_clicked) },
{ "auto_input_rate_toggled", G_CALLBACK (event_auto_input_rate_toggled) }, { "auto_input_rate_toggled", G_CALLBACK (event_auto_input_rate_toggled) },
{ "shader_parameters", G_CALLBACK (event_shader_parameters) },
#ifdef USE_JOYSTICK #ifdef USE_JOYSTICK
{ "calibrate", G_CALLBACK (event_calibrate) }, { "calibrate", G_CALLBACK (event_calibrate) },
#endif #endif

View File

@ -10,6 +10,10 @@
#include <X11/extensions/Xvlib.h> #include <X11/extensions/Xvlib.h>
#endif #endif
#ifdef USE_OPENGL
#include "gtk_shader_parameters.h"
#endif
#include "gtk_s9x.h" #include "gtk_s9x.h"
#include "gtk_preferences.h" #include "gtk_preferences.h"
#include "gtk_icon.h" #include "gtk_icon.h"
@ -376,6 +380,17 @@ event_open_movie (GtkWidget *widget, gpointer data)
return; return;
} }
static void
event_shader_parameters (GtkWidget *widget, gpointer data)
{
#ifdef USE_OPENGL
Snes9xWindow *window = (Snes9xWindow *) data;
gtk_shader_parameters_dialog (window->get_window ());
#endif
return;
}
static void static void
event_stop_recording (GtkWidget *widget, gpointer data) event_stop_recording (GtkWidget *widget, gpointer data)
{ {
@ -565,6 +580,7 @@ Snes9xWindow::Snes9xWindow (Snes9xConfig *config) :
{ "on_fullscreen_item_activate", G_CALLBACK (event_fullscreen) }, { "on_fullscreen_item_activate", G_CALLBACK (event_fullscreen) },
{ "on_open_rom_activate", G_CALLBACK (event_open_rom) }, { "on_open_rom_activate", G_CALLBACK (event_open_rom) },
{ "on_reset_item_activate", G_CALLBACK (event_reset) }, { "on_reset_item_activate", G_CALLBACK (event_reset) },
{ "on_shader_parameters_item_activate", G_CALLBACK (event_shader_parameters) },
{ "hard_reset", G_CALLBACK (event_hard_reset) }, { "hard_reset", G_CALLBACK (event_hard_reset) },
{ "on_port_activate", G_CALLBACK (event_port) }, { "on_port_activate", G_CALLBACK (event_port) },
{ "load_save_state", G_CALLBACK (event_load_state) }, { "load_save_state", G_CALLBACK (event_load_state) },
@ -653,6 +669,13 @@ Snes9xWindow::Snes9xWindow (Snes9xConfig *config) :
gtk_widget_hide (get_widget ("sync_clients_separator")); gtk_widget_hide (get_widget ("sync_clients_separator"));
#endif #endif
#ifndef USE_OPENGL
gtk_widget_hide (get_widget ("shader_parameters_separator"));
gtk_widget_hide (get_widget ("shader_parameters_item"));
#else
enable_widget ("shader_parameters_item", FALSE);
#endif
#if GTK_MAJOR_VERSION >= 3 #if GTK_MAJOR_VERSION >= 3
g_signal_connect_data (drawing_area, g_signal_connect_data (drawing_area,
"draw", "draw",

View File

@ -7,13 +7,18 @@
#include "gtk_shader_parameters.h" #include "gtk_shader_parameters.h"
#include "shaders/glsl.h" #include "shaders/glsl.h"
static GtkWidget *dialog = NULL;
static std::vector<GLSLParam> *params = NULL;
static std::vector<GLSLParam> saved_params;
static inline double snap_to_interval (double value, double interval) static inline double snap_to_interval (double value, double interval)
{ {
return round (value / interval) * interval; return round (value / interval) * interval;
} }
void value_changed (GtkRange *range, gpointer user_data) static void value_changed (GtkRange *range, gpointer user_data)
{ {
GLSLParam *p = (GLSLParam *) user_data;
GtkAdjustment *adj = gtk_range_get_adjustment (range); GtkAdjustment *adj = gtk_range_get_adjustment (range);
double interval = gtk_adjustment_get_step_increment (adj); double interval = gtk_adjustment_get_step_increment (adj);
double value = gtk_range_get_value (range); double value = gtk_range_get_value (range);
@ -21,26 +26,100 @@ void value_changed (GtkRange *range, gpointer user_data)
value = snap_to_interval (value, interval); value = snap_to_interval (value, interval);
gtk_range_set_value (range, value); gtk_range_set_value (range, value);
if (p->val != value)
{
p->val = value;
if (Settings.Paused)
S9xDeinitUpdate (top_level->last_width, top_level->last_height);
}
} }
static void toggled (GtkToggleButton *togglebutton, gpointer user_data)
{
GLSLParam *p = (GLSLParam *) user_data;
double value = (double) gtk_toggle_button_get_active (togglebutton);
if (p->val != value)
{
p->val = value;
if (Settings.Paused)
S9xDeinitUpdate (top_level->last_width, top_level->last_height);
}
}
static void dialog_response (GtkDialog *pdialog, gint response_id, gpointer user_data)
{
std::vector<GLSLParam> * params = (std::vector<GLSLParam> *) user_data;
char *config_dir;
char *config_file;
switch (response_id)
{
case GTK_RESPONSE_OK:
config_dir = get_config_dir();
config_file = new char[strlen (config_dir) + 14];
sprintf(config_file, "%s/snes9x.glslp", config_dir);
delete[] config_dir;
S9xDisplayGetDriver ()->save (config_file);
realpath (config_file, gui_config->fragment_shader);
if (dialog)
gtk_widget_destroy (GTK_WIDGET (dialog));
dialog = NULL;
break;
case GTK_RESPONSE_CANCEL:
case GTK_RESPONSE_DELETE_EVENT:
case GTK_RESPONSE_NONE:
if (dialog)
gtk_widget_destroy (GTK_WIDGET (dialog));
dialog = NULL;
*params = saved_params;
if (Settings.Paused)
S9xDeinitUpdate (top_level->last_width, top_level->last_height);
break;
default:
break;
}
}
void gtk_shader_parameters_dialog_close (void)
{
if (dialog)
{
*params = saved_params;
gtk_widget_destroy (GTK_WIDGET (dialog));
dialog = NULL;
}
}
bool gtk_shader_parameters_dialog (GtkWindow *parent) bool gtk_shader_parameters_dialog (GtkWindow *parent)
{ {
GtkWidget *dialog; if (dialog)
std::vector<GLSLParam> *params = (std::vector<GLSLParam> *) S9xDisplayGetDriver()->get_parameters(); {
gtk_window_present (GTK_WINDOW (dialog));
return false;
}
params = (std::vector<GLSLParam> *) S9xDisplayGetDriver()->get_parameters();
saved_params = *params;
if (!params || params->size() == 0) if (!params || params->size() == 0)
return false; return false;
dialog = gtk_dialog_new_with_buttons (_("GLSL Shader Parameters"), dialog = gtk_dialog_new_with_buttons (_("GLSL Shader Parameters"),
parent, parent,
GTK_DIALOG_MODAL, GTK_DIALOG_DESTROY_WITH_PARENT,
"gtk-cancel", "gtk-cancel",
GTK_RESPONSE_CANCEL, GTK_RESPONSE_CANCEL,
"gtk-apply", "gtk-save",
GTK_RESPONSE_APPLY, GTK_RESPONSE_OK,
NULL); NULL);
g_signal_connect_data (G_OBJECT (dialog), "response", G_CALLBACK (dialog_response), (gpointer) params, NULL, (GConnectFlags) 0);
GtkWidget *scrolled_window; GtkWidget *scrolled_window;
gtk_widget_set_size_request(dialog, 640, 480); gtk_widget_set_size_request(dialog, 640, 480);
@ -64,8 +143,6 @@ bool gtk_shader_parameters_dialog (GtkWindow *parent)
gtk_container_add (GTK_CONTAINER (vbox), grid); gtk_container_add (GTK_CONTAINER (vbox), grid);
gtk_container_add (GTK_CONTAINER (scrolled_window), vbox); gtk_container_add (GTK_CONTAINER (scrolled_window), vbox);
GtkWidget **value_holders = new GtkWidget*[params->size()];
for (unsigned int i = 0; i < params->size(); i++) for (unsigned int i = 0; i < params->size(); i++)
{ {
GLSLParam *p = &(*params)[i]; GLSLParam *p = &(*params)[i];
@ -80,7 +157,7 @@ bool gtk_shader_parameters_dialog (GtkWindow *parent)
GtkWidget *check = gtk_check_button_new (); GtkWidget *check = gtk_check_button_new ();
gtk_grid_attach (GTK_GRID (grid), check, 1, i, 1, 1); gtk_grid_attach (GTK_GRID (grid), check, 1, i, 1, 1);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), (int) p->val); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), (int) p->val);
value_holders[i] = check; g_signal_connect_data (G_OBJECT (check), "toggled", G_CALLBACK (toggled), (gpointer) p, NULL, (GConnectFlags) 0);
} }
else else
{ {
@ -94,11 +171,9 @@ bool gtk_shader_parameters_dialog (GtkWindow *parent)
g_signal_connect_data (G_OBJECT (scale), g_signal_connect_data (G_OBJECT (scale),
"value-changed", "value-changed",
G_CALLBACK (value_changed), G_CALLBACK (value_changed),
NULL, (gpointer) p,
NULL, NULL,
(GConnectFlags) 0); (GConnectFlags) 0);
value_holders[i] = scale;
} }
} }
#else #else
@ -111,8 +186,6 @@ bool gtk_shader_parameters_dialog (GtkWindow *parent)
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), vbox); gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), vbox);
gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 5); gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 5);
GtkWidget **value_holders = new GtkWidget*[params->size()];
for (unsigned int i = 0; i < params->size(); i++) for (unsigned int i = 0; i < params->size(); i++)
{ {
GLSLParam *p = &(*params)[i]; GLSLParam *p = &(*params)[i];
@ -127,7 +200,7 @@ bool gtk_shader_parameters_dialog (GtkWindow *parent)
GtkWidget *check = gtk_check_button_new (); GtkWidget *check = gtk_check_button_new ();
gtk_table_attach (GTK_TABLE (table), check, 1, 2, i, i + 1, GTK_FILL, GTK_FILL, 0, 0); gtk_table_attach (GTK_TABLE (table), check, 1, 2, i, i + 1, GTK_FILL, GTK_FILL, 0, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), (int) p->val); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), (int) p->val);
value_holders[i] = check; g_signal_connect_data (G_OBJECT (check), "toggled", G_CALLBACK (toggled), (gpointer) p, NULL, (GConnectFlags) 0);
} }
else else
{ {
@ -140,43 +213,14 @@ bool gtk_shader_parameters_dialog (GtkWindow *parent)
g_signal_connect_data (G_OBJECT (scale), g_signal_connect_data (G_OBJECT (scale),
"value-changed", "value-changed",
G_CALLBACK (value_changed), G_CALLBACK (value_changed),
NULL, (gpointer) p,
NULL, NULL,
(GConnectFlags) 0); (GConnectFlags) 0);
value_holders[i] = scale;
} }
} }
#endif #endif
gtk_widget_show_all (dialog); gtk_widget_show_all (dialog);
int response = gtk_dialog_run (GTK_DIALOG(dialog));
if (response == GTK_RESPONSE_APPLY)
{
for (unsigned int i = 0; i < params->size(); i++)
{
GLSLParam *p = &(*params)[i];
if (p->min == 0.0 && p->max == 1.0 && p->step == 1.0)
{
int val = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (value_holders[i]));
p->val = (float) val;
}
else
{
p->val = gtk_range_get_value (GTK_RANGE (value_holders[i]));
}
p->val = snap_to_interval (p->val, p->step);
p->val = CLAMP (p->val, p->min, p->max);
}
S9xDeinitUpdate (top_level->last_width, top_level->last_height);
}
delete[] value_holders;
gtk_widget_destroy (dialog);
return true; return true;
} }

View File

@ -4,5 +4,6 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
bool gtk_shader_parameters_dialog (GtkWindow *parent); bool gtk_shader_parameters_dialog (GtkWindow *parent);
void gtk_shader_parameters_dialog_close (void);
#endif // __GTK_SHADER_PARAMETERS_H #endif // __GTK_SHADER_PARAMETERS_H

View File

@ -1843,6 +1843,22 @@
<signal name="activate" handler="open_cheats" swapped="no"/> <signal name="activate" handler="open_cheats" swapped="no"/>
</object> </object>
</child> </child>
<child>
<object class="GtkSeparatorMenuItem" id="shader_parameters_separator">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="shader_parameters_item">
<property name="label" translatable="yes">_Shader Parameters...</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_shader_parameters_item_activate" swapped="no"/>
</object>
</child>
<child> <child>
<object class="GtkSeparatorMenuItem" id="separatormenuitem3"> <object class="GtkSeparatorMenuItem" id="separatormenuitem3">
<property name="visible">True</property> <property name="visible">True</property>
@ -3867,20 +3883,6 @@
<property name="position">2</property> <property name="position">2</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkButton" id="shader_parameters_button">
<property name="label" translatable="yes">Customize...</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="shader_parameters" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>