From 863e6de420334f911d60f5840dd9b12f172b940d Mon Sep 17 00:00:00 2001 From: Maximilian Mader Date: Fri, 1 Jan 2021 18:12:32 +0100 Subject: [PATCH] [GTK3] Add color temperature slider --- gtk3/config.h | 1 + gtk3/main.c | 14 +++++- gtk3/preferences_window.c | 30 +++++++++++- gtk3/resources/ui/preferences_window.ui | 62 ++++++++++++++++++++----- gtk3/util.c | 10 ++++ gtk3/util.h | 1 + 6 files changed, 103 insertions(+), 15 deletions(-) diff --git a/gtk3/config.h b/gtk3/config.h index 850e0b0..5ad4f93 100644 --- a/gtk3/config.h +++ b/gtk3/config.h @@ -38,6 +38,7 @@ EXPAND_GROUP(video, \ EXPAND_GROUP_MEMBER(shader, string, "NearestNeighbor") \ EXPAND_GROUP_MEMBER(color_correction_id, string, "emulate_hardware") \ + EXPAND_GROUP_MEMBER(light_temperature, integer, 0) \ EXPAND_GROUP_MEMBER(frame_blending_mode, string, "disabled") \ EXPAND_GROUP_MEMBER(display_border_mode, string, "never") \ EXPAND_GROUP_MEMBER(monochrome_palette_id, string, "greyscale") \ diff --git a/gtk3/main.c b/gtk3/main.c index 6325e35..84e11ae 100644 --- a/gtk3/main.c +++ b/gtk3/main.c @@ -693,6 +693,7 @@ static void init(void) { GB_set_pixels_output(&gb, gb_screen_get_current_buffer(gui_data.screen)); GB_set_color_correction_mode(&gb, config_get_color_correction_mode()); + GB_set_light_temperature(&gb, (double) config.video.light_temperature / 256.0); if (config_get_display_border_mode() <= GB_BORDER_ALWAYS) { GB_set_border_mode(&gb, config_get_display_border_mode()); } @@ -701,7 +702,7 @@ static void init(void) { GB_set_sample_rate(&gb, GB_audio_get_sample_rate()); GB_set_highpass_filter_mode(&gb, config_get_highpass_mode()); - GB_set_interference_volume(&gb, (double) config.audio.interference_volume / 255.0); + GB_set_interference_volume(&gb, (double) config.audio.interference_volume / 256.0); GB_set_log_callback(&gb, wrapped_console_log); GB_set_input_callback(&gb, wrapped_console_get_sync_input); @@ -1110,6 +1111,13 @@ void on_preferences_notify_shader(PreferencesWindow *pref, const gchar *name) { gb_screen_set_shader(gui_data.screen, name); } +void on_preferences_notify_light_temperature(PreferencesWindow *pref, const gint *light_temperature) { + if (GB_is_inited(&gb)) { + // wouldn’t it be nice to use the value set in the GtkAdjustment of the slider instead of 256.0 here? + GB_set_light_temperature(&gb, (double) *light_temperature / 256.0); + } +} + void on_preferences_notify_sample_rate(PreferencesWindow *pref, const guint *sample_rate) { if (*sample_rate == -1) { gui_data.sample_rate = GB_audio_default_sample_rate(); @@ -1123,7 +1131,8 @@ void on_preferences_notify_sample_rate(PreferencesWindow *pref, const guint *sam void on_preferences_notify_interference_volume(PreferencesWindow *pref, const guint *interference_volume) { if (GB_is_inited(&gb)) { - GB_set_interference_volume(&gb, (double) *interference_volume / 255.0); + // wouldn’t it be nice to use the value set in the GtkAdjustment of the slider instead of 256.0 here? + GB_set_interference_volume(&gb, (double) *interference_volume / 256.0); } } @@ -1146,6 +1155,7 @@ static void connect_signal_handlers(GApplication *app) { g_signal_connect(gui_data.preferences, "pref-update::video-display-border-mode", G_CALLBACK(on_preferences_notify_border), NULL); g_signal_connect(gui_data.preferences, "pref-update::video-shader", G_CALLBACK(on_preferences_notify_shader), NULL); + g_signal_connect(gui_data.preferences, "pref-update::video-color-temperature", G_CALLBACK(on_preferences_notify_light_temperature), NULL); g_signal_connect(gui_data.preferences, "pref-update::audio-sample-rate", G_CALLBACK(on_preferences_notify_sample_rate), NULL); g_signal_connect(gui_data.preferences, "pref-update::audio-interference-volume", G_CALLBACK(on_preferences_notify_interference_volume), NULL); } diff --git a/gtk3/preferences_window.c b/gtk3/preferences_window.c index aa73526..0d5cd60 100644 --- a/gtk3/preferences_window.c +++ b/gtk3/preferences_window.c @@ -12,6 +12,7 @@ struct _PreferencesWindow { GtkComboBox *cgb_revision_selector; GtkComboBoxText *shader_selector; GtkComboBoxText *color_correction_selector; + GtkScale *light_temperature_slider; GtkComboBoxText *frame_blending_selector; GtkComboBoxText *monochrome_palette_selector; GtkComboBoxText *display_border_selector; @@ -65,6 +66,15 @@ static void preferences_window_get_property(GObject *object, guint property_id, static void preferences_window_init(PreferencesWindow *self) { gtk_widget_init_template(GTK_WIDGET(self)); + // Add a couple of "snapping points" to the sliders + for (signed i = -3; i < 4; i++) { + gtk_scale_add_mark(self->light_temperature_slider, ((double) i / 4.0) * 256.0, GTK_POS_BOTTOM, NULL); + } + + for (unsigned i = 1; i < 8; i++) { + gtk_scale_add_mark(self->interference_volume_slider, ((double) i / 8.0) * 256.0, GTK_POS_BOTTOM, NULL); + } + preferences_window_update_boot_rom_selector(self); } @@ -136,6 +146,19 @@ static void on_color_correction_changed(GtkWidget *w, PreferencesWindow *self) { } } +static void on_light_temperature_changed(GtkWidget *w, PreferencesWindow *self) { + GtkRange *range = GTK_RANGE(w); + gdouble value = gtk_range_get_value(range); + config.video.light_temperature = (guint32) value; + + g_signal_emit( + self, + preferences_signals[PREF_UPDATE], + g_quark_from_static_string("video-color-temperature"), + &config.video.light_temperature + ); +} + static void on_monochrome_palette_changed(GtkWidget *w, PreferencesWindow *self) { GtkComboBox *box = GTK_COMBO_BOX(w); config.video.monochrome_palette_id = (gchar *)gtk_combo_box_get_active_id(box); @@ -156,7 +179,7 @@ static void on_highpass_filter_changed(GtkWidget *w, PreferencesWindow *self) { static void on_rewind_duration_changed(GtkWidget *w, PreferencesWindow *self) { GtkComboBox *box = GTK_COMBO_BOX(w); config.emulation.rewind_duration = g_ascii_strtoll(gtk_combo_box_get_active_id(box), NULL, 10); - + if (self->gb) { GB_set_rewind_length(self->gb, config.emulation.rewind_duration); } @@ -210,7 +233,7 @@ static void on_sample_rate_changed(GtkWidget *w, PreferencesWindow *self) { static void on_interference_volume_changed(GtkWidget *w, PreferencesWindow *self) { GtkRange *range = GTK_RANGE(w); gdouble value = gtk_range_get_value(range); - config.audio.interference_volume = (guint32) clamp_double(0, 255, value); + config.audio.interference_volume = (guint32) value; g_signal_emit( self, @@ -230,6 +253,7 @@ static void preferences_window_realize(GtkWidget *widget) { gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->shader_selector), config.video.shader); gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->color_correction_selector), config.video.color_correction_id); + gtk_range_set_value(GTK_RANGE(self->light_temperature_slider), (double) config.video.light_temperature); gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->frame_blending_selector), config.video.frame_blending_mode); gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->display_border_selector), config.video.display_border_mode); gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->monochrome_palette_selector), config.video.monochrome_palette_id); @@ -258,6 +282,7 @@ static void preferences_window_class_init(PreferencesWindowClass *class) { gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, cgb_revision_selector); gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, shader_selector); gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, color_correction_selector); + gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, light_temperature_slider); gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, frame_blending_selector); gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, monochrome_palette_selector); gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, display_border_selector); @@ -277,6 +302,7 @@ static void preferences_window_class_init(PreferencesWindowClass *class) { gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_cgb_model_changed); gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_graphic_filter_changed); gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_color_correction_changed); + gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_light_temperature_changed); gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_frame_blending_changed); gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_monochrome_palette_changed); gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_display_border_changed); diff --git a/gtk3/resources/ui/preferences_window.ui b/gtk3/resources/ui/preferences_window.ui index c6ed5b6..e5d0b20 100644 --- a/gtk3/resources/ui/preferences_window.ui +++ b/gtk3/resources/ui/preferences_window.ui @@ -351,7 +351,7 @@ Author: Maximilian Mader True False - Frame blending: + Ambient Light Temperature: False @@ -359,6 +359,37 @@ Author: Maximilian Mader 4 + + + True + False + colorTemperatureAdjustment + 0 + 0 + left + 5 + 10 + + + + + False + True + 5 + + + + + True + False + Frame blending: + + + False + True + 6 + + True @@ -375,7 +406,7 @@ Author: Maximilian Mader False True - 5 + 7 @@ -387,7 +418,7 @@ Author: Maximilian Mader False True - 6 + 8 @@ -407,7 +438,7 @@ Author: Maximilian Mader False True - 7 + 9 @@ -419,7 +450,7 @@ Author: Maximilian Mader False True - 8 + 10 @@ -438,7 +469,7 @@ Author: Maximilian Mader False True - 9 + 11 @@ -456,7 +487,7 @@ Author: Maximilian Mader False True - 10 + 12 @@ -474,7 +505,7 @@ Author: Maximilian Mader False True - 11 + 13 @@ -608,10 +639,12 @@ Author: Maximilian Mader True False - byteAdjustment + volumeAdjustment 0 0 left + 5 + 10 @@ -1008,8 +1041,15 @@ Author: Maximilian Mader - - 255 + + 256 + 1 + 8 + + + + -256 + 256 1 8 diff --git a/gtk3/util.c b/gtk3/util.c index 76f75e7..58a436e 100644 --- a/gtk3/util.c +++ b/gtk3/util.c @@ -166,3 +166,13 @@ gchar* format_scale_value_pct(GtkScale *scale, gdouble value) { gdouble pct = (value / range) * 100.0; return g_strdup_printf ("%.1f%% ", pct); } + +gchar* format_scale_color_temperature(GtkScale *scale, gdouble value) { + GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(scale)); + gdouble lower = gtk_adjustment_get_lower(adj); + gdouble upper = gtk_adjustment_get_upper(adj); + gdouble range = fabs(upper - lower); + gdouble normalized = (value + lower) / range; + gdouble kelvin = 12000 + normalized * (12000 - 1000); + return g_strdup_printf ("%.1fK ", kelvin); +} diff --git a/gtk3/util.h b/gtk3/util.h index 9050160..b1163ae 100644 --- a/gtk3/util.h +++ b/gtk3/util.h @@ -28,5 +28,6 @@ void set_combo_box_row_separator_func(GtkContainer *container); gboolean scroll_to_bottom(GtkTextView *textview, GtkTextMark *mark); gchar* format_scale_value_pct(GtkScale *scale, gdouble value); +gchar* format_scale_color_temperature(GtkScale *scale, gdouble value); #endif \ No newline at end of file