SameBoy/gtk3/widgets/preferences_window.c

345 lines
15 KiB
C

#include "preferences_window.h"
#include "../config.h"
#include "../util.h"
struct _PreferencesWindow {
GtkWindowClass parent_class;
GtkComboBoxText *boot_rom_selector;
GtkComboBoxText *rewind_duration_selector;
GtkComboBox *dmg_revision_selector;
GtkComboBoxText *sgb_revision_selector;
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;
GtkCheckButton *integer_scaling_toggle;
GtkCheckButton *aspect_ratio_toggle;
GtkComboBoxText *highpass_filter_selector;
GtkComboBoxText *sample_rate_selector;
GtkScale *interference_volume_slider;
GtkCheckButton *analog_speed_controls_toggle;
GtkComboBoxText *rumble_mode_selector;
GtkButton *configure_joypad_skip;
GB_gameboy_t *gb;
};
G_DEFINE_TYPE(PreferencesWindow, preferences_window, GTK_TYPE_WINDOW);
typedef enum {
PREF_UPDATE,
N_SIGNALS
} PreferencesWindowSignals;
static guint preferences_signals[N_SIGNALS] = { 0, };
static void preferences_window_init(PreferencesWindow *self) {
gtk_widget_init_template(GTK_WIDGET(self));
// Add a couple of "snapping points" to the sliders
gtk_scale_add_mark(self->light_temperature_slider, 0.0, GTK_POS_BOTTOM, NULL);
for (unsigned i = 1; i < 10; i++) {
gtk_scale_add_mark(self->interference_volume_slider, ((double) i / 10.0) * 100.0, GTK_POS_BOTTOM, NULL);
}
preferences_window_update_boot_rom_selector(self);
}
static void on_boot_rom_location_changed(GtkWidget *w, PreferencesWindow *self) {
GtkComboBox *box = GTK_COMBO_BOX(w);
const gchar *id = gtk_combo_box_get_active_id(box);
if (id == NULL) return;
if (g_strcmp0(id, "other") == 0) {
GtkFileChooserNative *native = gtk_file_chooser_native_new("Select Folder", GTK_WINDOW(self), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, "_Select", "_Cancel");
gint res = gtk_native_dialog_run(GTK_NATIVE_DIALOG(native));
if (res == GTK_RESPONSE_ACCEPT) {
config.emulation.boot_rom_path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(native));
preferences_window_update_boot_rom_selector(self);
}
g_object_unref(native);
}
else {
config.emulation.boot_rom_path = (gchar *)id;
}
}
static void on_cgb_model_changed(GtkWidget *w, PreferencesWindow *self) {
GtkComboBox *box = GTK_COMBO_BOX(w);
config.emulation.cgb_revision_name = (gchar *)gtk_combo_box_get_active_id(box);
}
static void on_frame_blending_changed(GtkWidget *w, PreferencesWindow *self) {
GtkComboBox *box = GTK_COMBO_BOX(w);
config.video.frame_blending_mode = (gchar *)gtk_combo_box_get_active_id(box);
}
static void on_dmg_model_changed(GtkWidget *w, PreferencesWindow *self) {
GtkComboBox *box = GTK_COMBO_BOX(w);
config.emulation.dmg_revision_name = (gchar *)gtk_combo_box_get_active_id(box);
}
static void on_keep_aspect_ratio_changed(GtkWidget *w, PreferencesWindow *self) {
GtkCheckButton *button = GTK_CHECK_BUTTON(w);
gboolean value = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
config.video.keep_aspect_ratio = value;
}
static void on_sgb_model_changed(GtkWidget *w, PreferencesWindow *self) {
GtkComboBox *box = GTK_COMBO_BOX(w);
config.emulation.sgb_revision_name = (gchar *)gtk_combo_box_get_active_id(box);
}
static void on_use_integer_scaling_changed(GtkWidget *w, PreferencesWindow *self) {
GtkCheckButton *button = GTK_CHECK_BUTTON(w);
gboolean value = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
config.video.use_integer_scaling = value;
}
static void on_analog_speed_controls_changed(GtkWidget *w, PreferencesWindow *self) {
GtkCheckButton *button = GTK_CHECK_BUTTON(w);
gboolean value = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
config.controls.analog_speed_controls = value;
}
static void on_color_correction_changed(GtkWidget *w, PreferencesWindow *self) {
GtkComboBox *box = GTK_COMBO_BOX(w);
config.video.color_correction_id = (gchar *)gtk_combo_box_get_active_id(box);
g_signal_emit(
self,
preferences_signals[PREF_UPDATE],
g_quark_from_static_string("color-correction"),
config_get_color_correction_mode()
);
}
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);
g_signal_emit(
self,
preferences_signals[PREF_UPDATE],
g_quark_from_static_string("monochrome-palette"),
config_get_monochrome_palette()
);
}
static void on_highpass_filter_changed(GtkWidget *w, PreferencesWindow *self) {
config.audio.high_pass_filter_id = (gchar *)gtk_combo_box_get_active_id(GTK_COMBO_BOX(w));
g_signal_emit(
self,
preferences_signals[PREF_UPDATE],
g_quark_from_static_string("highpass"),
config_get_highpass_mode()
);
}
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);
g_signal_emit(
self,
preferences_signals[PREF_UPDATE],
g_quark_from_static_string("rewind-duration"),
config.emulation.rewind_duration
);
}
static void on_rumble_mode_changed(GtkWidget *w, PreferencesWindow *self) {
GtkComboBox *box = GTK_COMBO_BOX(w);
config.controls.rumble_mode = (gchar *)gtk_combo_box_get_active_id(box);
g_signal_emit(
self,
preferences_signals[PREF_UPDATE],
g_quark_from_static_string("rumble-mode"),
config_get_rumble_mode()
);
}
static void on_display_border_changed(GtkWidget *w, PreferencesWindow *self) {
GtkComboBox *box = GTK_COMBO_BOX(w);
config.video.display_border_mode = (gchar *)gtk_combo_box_get_active_id(box);
g_signal_emit(
self,
preferences_signals[PREF_UPDATE],
g_quark_from_static_string("video-display-border-mode"),
config.video.display_border_mode
);
}
static void on_graphic_filter_changed(GtkWidget *w, PreferencesWindow *self) {
GtkComboBox *box = GTK_COMBO_BOX(w);
config.video.shader = (gchar *)gtk_combo_box_get_active_id(box);
g_signal_emit(
self,
preferences_signals[PREF_UPDATE],
g_quark_from_static_string("video-shader"),
config.video.shader
);
}
static void on_sample_rate_changed(GtkWidget *w, PreferencesWindow *self) {
GtkComboBox *box = GTK_COMBO_BOX(w);
config.audio.sample_rate = g_ascii_strtoll(gtk_combo_box_get_active_id(box), NULL, 10);
g_signal_emit(
self,
preferences_signals[PREF_UPDATE],
g_quark_from_static_string("audio-sample-rate"),
config.audio.sample_rate
);
}
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) value;
g_signal_emit(
self,
preferences_signals[PREF_UPDATE],
g_quark_from_static_string("audio-interference-volume"),
&config.audio.interference_volume
);
}
static void preferences_window_realize(GtkWidget *widget) {
PreferencesWindow *self = (PreferencesWindow *)widget;
gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->rewind_duration_selector), g_strdup_printf("%i", config.emulation.rewind_duration));
gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->dmg_revision_selector), config.emulation.dmg_revision_name);
gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->sgb_revision_selector), config.emulation.sgb_revision_name);
gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->cgb_revision_selector), config.emulation.cgb_revision_name);
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);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->integer_scaling_toggle), config.video.use_integer_scaling);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->aspect_ratio_toggle), config.video.keep_aspect_ratio);
gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->highpass_filter_selector), config.audio.high_pass_filter_id);
gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->sample_rate_selector), g_strdup_printf("%i", config.audio.sample_rate));
gtk_range_set_value(GTK_RANGE(self->interference_volume_slider), (double) config.audio.interference_volume);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->analog_speed_controls_toggle), config.controls.analog_speed_controls);
gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->rumble_mode_selector), config.controls.rumble_mode);
set_combo_box_row_separator_func(GTK_CONTAINER(self));
GTK_WIDGET_CLASS(preferences_window_parent_class)->realize(widget);
}
static void preferences_window_class_init(PreferencesWindowClass *class) {
gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(class), RESOURCE_PREFIX "ui/preferences_window.ui");
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, boot_rom_selector);
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, rewind_duration_selector);
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, dmg_revision_selector);
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, sgb_revision_selector);
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);
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, integer_scaling_toggle);
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, aspect_ratio_toggle);
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, highpass_filter_selector);
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, sample_rate_selector);
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, interference_volume_slider);
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, analog_speed_controls_toggle);
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, rumble_mode_selector);
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, configure_joypad_skip);
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_boot_rom_location_changed);
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_rewind_duration_changed);
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_dmg_model_changed);
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_sgb_model_changed);
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);
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_use_integer_scaling_changed);
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_keep_aspect_ratio_changed);
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_highpass_filter_changed);
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_sample_rate_changed);
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_interference_volume_changed);
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_analog_speed_controls_changed);
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_rumble_mode_changed);
// gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), do_refresh_joypad_menu);
// gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_default_joypad_changed);
// gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), do_configure_joypad);
// gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), do_skip_configure_joypad);
GTK_WIDGET_CLASS(class)->realize = preferences_window_realize;
preferences_signals[PREF_UPDATE] = g_signal_new(
"pref-update", // signal name
G_TYPE_FROM_CLASS(G_OBJECT_CLASS(class)), // itype
G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED, // signal_flags
0, // class_offset
NULL, // accumulator
NULL, // accumulator_data
NULL, // c_marshaller,
G_TYPE_NONE, // return_type
1, // n_params,
G_TYPE_POINTER
);
}
PreferencesWindow *preferences_window_new(void) {
return g_object_new(PREFERENCES_WINDOW_TYPE, NULL);
}
void preferences_window_update_boot_rom_selector(PreferencesWindow *self) {
GtkComboBoxText *combo_box = self->boot_rom_selector;
gtk_combo_box_text_remove_all(combo_box);
gtk_combo_box_text_append(combo_box, "auto", "Use Built-in Boot ROMs");
if (config.emulation.boot_rom_path != NULL && !g_str_equal(config.emulation.boot_rom_path, "auto") && !g_str_equal(config.emulation.boot_rom_path, "other")) {
gtk_combo_box_text_append(combo_box, config.emulation.boot_rom_path, config.emulation.boot_rom_path);
gtk_combo_box_set_active_id(GTK_COMBO_BOX(combo_box), config.emulation.boot_rom_path);
}
else {
gtk_combo_box_set_active_id(GTK_COMBO_BOX(combo_box), "auto");
}
gtk_combo_box_text_append_text(combo_box, "<separator>");
gtk_combo_box_text_append(combo_box, "other", "Other");
}