From 2887110e99ee872e4dee46e03c95d69446739518 Mon Sep 17 00:00:00 2001 From: Maximilian Mader Date: Tue, 12 May 2020 20:55:29 +0200 Subject: [PATCH] [GTK3] Restructure config_t by using sub structs --- gtk3/main.c | 80 ++++++------ gtk3/settings.c | 314 +++++++++++++++++++++++++----------------------- gtk3/settings.h | 22 ++-- 3 files changed, 214 insertions(+), 202 deletions(-) diff --git a/gtk3/main.c b/gtk3/main.c index 2ad51cb..4b6283a 100644 --- a/gtk3/main.c +++ b/gtk3/main.c @@ -1220,7 +1220,7 @@ static void vblank(GB_gameboy_t *gb) { //gui_data.clock_mutliplier = clamp_double(0.5, 1.0, gui_data.clock_mutliplier + 1.0 / 16); GB_set_clock_multiplier(gb, gui_data.clock_mutliplier); } - else if (config.analog_speed_controls && gui_data.analog_clock_multiplier_valid) { + else if (config.controls.analog_speed_controls && gui_data.analog_clock_multiplier_valid) { GB_set_clock_multiplier(gb, gui_data.analog_clock_multiplier); if (gui_data.analog_clock_multiplier == 1.0) { @@ -1296,7 +1296,7 @@ static void handle_events(GB_gameboy_t *gb) { SDL_GameControllerUpdate(); uint8_t controller_state = 0; - double analog_clock_multiplier = 1.0; + gui_data.analog_clock_multiplier = 1.0; for (unsigned i = 0; i < gui_data.controller_count; i++) { struct Controller_t *s = &gui_data.controllers[i]; @@ -1307,16 +1307,16 @@ static void handle_events(GB_gameboy_t *gb) { int16_t right_x_axis = SDL_GameControllerGetAxis(s->controller, SDL_CONTROLLER_AXIS_RIGHTX); int16_t right_y_axis = SDL_GameControllerGetAxis(s->controller, SDL_CONTROLLER_AXIS_RIGHTY); - if (config.analog_speed_controls) { + if (config.controls.analog_speed_controls) { double left_trigger = (double) SDL_GameControllerGetAxis(s->controller, SDL_CONTROLLER_AXIS_TRIGGERLEFT) / (double) 32767; double right_trigger = (double) SDL_GameControllerGetAxis(s->controller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT) / (double) 32767; if (left_trigger > 0.0) { - analog_clock_multiplier = min_double(analog_clock_multiplier, clamp_double(1.0 / 3, 1.0, 1 - left_trigger + 0.2)); + gui_data.analog_clock_multiplier = min_double(gui_data.analog_clock_multiplier, clamp_double(1.0 / 3, 1.0, 1 - left_trigger + 0.2)); gui_data.analog_clock_multiplier_valid = true; } else if (right_trigger > 0.0) { - analog_clock_multiplier = max_double(analog_clock_multiplier, clamp_double(1.0, 3.0, right_trigger * 3 + 0.8)); + gui_data.analog_clock_multiplier = max_double(gui_data.analog_clock_multiplier, clamp_double(1.0, 3.0, right_trigger * 3 + 0.8)); gui_data.analog_clock_multiplier_valid = true; } } @@ -1380,8 +1380,6 @@ static void handle_events(GB_gameboy_t *gb) { } } - gui_data.analog_clock_multiplier = analog_clock_multiplier; - GB_set_key_state(gb, GB_KEY_RIGHT, (gui_data.pressed_buttons & BUTTON_MASK_RIGHT) | (controller_state & BUTTON_MASK_RIGHT)); GB_set_key_state(gb, GB_KEY_LEFT, (gui_data.pressed_buttons & BUTTON_MASK_LEFT) | (controller_state & BUTTON_MASK_LEFT)); GB_set_key_state(gb, GB_KEY_UP, (gui_data.pressed_buttons & BUTTON_MASK_UP) | (controller_state & BUTTON_MASK_UP)); @@ -1420,8 +1418,8 @@ static void load_boot_rom(GB_gameboy_t *gb, GB_boot_rom_t type) { } } else { config_boot_rom: - if (config.boot_rom_path != NULL && g_strcmp0(config.boot_rom_path, "other") != 0 && g_strcmp0(config.boot_rom_path, "auto") != 0) { - boot_rom_path = g_build_filename(config.boot_rom_path, boot_rom_name, NULL); + if (config.emulation.boot_rom_path != NULL && g_strcmp0(config.emulation.boot_rom_path, "other") != 0 && g_strcmp0(config.emulation.boot_rom_path, "auto") != 0) { + boot_rom_path = g_build_filename(config.emulation.boot_rom_path, boot_rom_name, NULL); g_message("Trying to load boot ROM from %s", boot_rom_path); if (GB_load_boot_rom(gb, boot_rom_path)) { @@ -1464,7 +1462,7 @@ static void init(void) { GB_set_sample_rate(&gb, GB_audio_get_sample_rate()); GB_set_color_correction_mode(&gb, get_color_correction_mode()); GB_set_highpass_filter_mode(&gb, get_highpass_mode()); - GB_set_rewind_length(&gb, config.rewind_duration); + GB_set_rewind_length(&gb, config.emulation.rewind_duration); GB_set_update_input_hint_callback(&gb, handle_events); GB_apu_set_sample_callback(&gb, gb_audio_callback); GB_set_input_callback(&gb, sync_console_input); @@ -1604,11 +1602,14 @@ static gpointer run_thread(gpointer null_ptr) { gui_data.battery_save_path = battery_save_path; gui_data.cheats_save_path = cheats_save_path; + if (!GB_is_inited(&gb)) { + init(); + } + if (gui_data.stopped) { start(); } else { - init(); reset(); start(); } @@ -2015,11 +2016,11 @@ static void startup(GApplication *app, gpointer null_ptr) { gui_data.console = GTK_WINDOW(get_object("console")); gui_data.printer = GTK_WINDOW(get_object("printer")); - if (config.sample_rate == -1) { + if (config.audio.sample_rate == -1) { gui_data.sample_rate = GB_audio_default_sample_rate(); } else { - gui_data.sample_rate = config.sample_rate; + gui_data.sample_rate = config.audio.sample_rate; } // setup main window @@ -2107,12 +2108,12 @@ static void update_viewport(void) { double x_factor = win_width / (double) GB_get_screen_width(&gb); double y_factor = win_height / (double) GB_get_screen_height(&gb); - if (config.use_integer_scaling) { + if (config.video.use_integer_scaling) { x_factor = (int)(x_factor); y_factor = (int)(y_factor); } - if (config.keep_aspect_ratio) { + if (config.video.keep_aspect_ratio) { if (x_factor > y_factor) { x_factor = y_factor; } @@ -2231,7 +2232,7 @@ static void gl_init(GtkWidget *w) { renderer = (char *)glGetString(GL_RENDERER); g_debug("GtkGLArea on %s", renderer ? renderer : "Unknown"); - if (config.shader == NULL || (!init_shader_with_name(&gui_data.shader, config.shader) && !init_shader_with_name(&gui_data.shader, "NearestNeighbor"))) { + if (config.video.shader == NULL || (!init_shader_with_name(&gui_data.shader, config.video.shader) && !init_shader_with_name(&gui_data.shader, "NearestNeighbor"))) { GError *error = g_error_new_literal(g_quark_from_string("sameboy-gl-error"), 1, "Failed to initialize shaders"); gtk_gl_area_set_error(gl_area, error); } @@ -2300,9 +2301,6 @@ static void setup_console(void) { // This function gets called when the GApplication gets activated, i.e. it is ready to show widgets. static void activate(GApplication *app, gpointer null_ptr) { - // initialize SameBoy core - init(); - init_audio(); init_controllers(); @@ -2535,25 +2533,25 @@ G_MODULE_EXPORT void on_boot_rom_location_changed(GtkWidget *w, gpointer user_da gint res = gtk_native_dialog_run(GTK_NATIVE_DIALOG(native)); if (res == GTK_RESPONSE_ACCEPT) { - config.boot_rom_path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(native)); + config.emulation.boot_rom_path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(native)); update_boot_rom_selector(gui_data.builder); } g_object_unref(native); } else { - config.boot_rom_path = (gchar *)id; + config.emulation.boot_rom_path = (gchar *)id; } } G_MODULE_EXPORT void on_cgb_model_changed(GtkWidget *w, gpointer user_data_ptr) { GtkComboBox *box = GTK_COMBO_BOX(w); - config.cgb_revision_name = (gchar *)gtk_combo_box_get_active_id(box); + config.emulation.cgb_revision_name = (gchar *)gtk_combo_box_get_active_id(box); } G_MODULE_EXPORT void on_color_correction_changed(GtkWidget *w, gpointer user_data_ptr) { GtkComboBox *box = GTK_COMBO_BOX(w); - config.color_correction_id = (gchar *)gtk_combo_box_get_active_id(box); + config.video.color_correction_id = (gchar *)gtk_combo_box_get_active_id(box); if (GB_is_inited(&gb)) { GB_set_color_correction_mode(&gb, get_color_correction_mode()); @@ -2562,42 +2560,42 @@ G_MODULE_EXPORT void on_color_correction_changed(GtkWidget *w, gpointer user_dat G_MODULE_EXPORT void on_frame_blending_changed(GtkWidget *w, gpointer user_data_ptr) { GtkComboBox *box = GTK_COMBO_BOX(w); - config.frame_blending_mode = (gchar *)gtk_combo_box_get_active_id(box); + config.video.frame_blending_mode = (gchar *)gtk_combo_box_get_active_id(box); } G_MODULE_EXPORT void on_display_border_changed(GtkWidget *w, gpointer user_data_ptr) { GtkComboBox *box = GTK_COMBO_BOX(w); - config.display_border_mode = (gchar *)gtk_combo_box_get_active_id(box); + config.video.display_border_mode = (gchar *)gtk_combo_box_get_active_id(box); gui_data.border_mode_changed = true; } G_MODULE_EXPORT void on_monochrome_palette_changed(GtkWidget *w, gpointer user_data_ptr) { GtkComboBox *box = GTK_COMBO_BOX(w); - config.monochrome_palette_id = (gchar *)gtk_combo_box_get_active_id(box); + config.video.monochrome_palette_id = (gchar *)gtk_combo_box_get_active_id(box); GB_set_palette(&gb, get_monochrome_palette()); } G_MODULE_EXPORT void on_color_menubar_override_changed(GtkWidget *w, gpointer user_data_ptr) { - config.menubar_override = (gchar *)gtk_combo_box_get_active_id(GTK_COMBO_BOX(w)); + config.video.menubar_override = (gchar *)gtk_combo_box_get_active_id(GTK_COMBO_BOX(w)); } G_MODULE_EXPORT void on_dmg_model_changed(GtkWidget *w, gpointer user_data_ptr) { GtkComboBox *box = GTK_COMBO_BOX(w); - config.dmg_revision_name = (gchar *)gtk_combo_box_get_active_id(box); + config.emulation.dmg_revision_name = (gchar *)gtk_combo_box_get_active_id(box); } G_MODULE_EXPORT void on_graphic_filter_changed(GtkWidget *w, gpointer user_data_ptr) { GtkComboBox *box = GTK_COMBO_BOX(w); - config.shader = (gchar *)gtk_combo_box_get_active_id(box); + config.video.shader = (gchar *)gtk_combo_box_get_active_id(box); free_shader(&gui_data.shader); - init_shader_with_name(&gui_data.shader, config.shader); + init_shader_with_name(&gui_data.shader, config.video.shader); } G_MODULE_EXPORT void on_highpass_filter_changed(GtkWidget *w, gpointer user_data_ptr) { - config.high_pass_filter_id = (gchar *)gtk_combo_box_get_active_id(GTK_COMBO_BOX(w)); + config.audio.high_pass_filter_id = (gchar *)gtk_combo_box_get_active_id(GTK_COMBO_BOX(w)); if (GB_is_inited(&gb)) { GB_set_highpass_filter_mode(&gb, get_highpass_mode()); @@ -2607,25 +2605,25 @@ G_MODULE_EXPORT void on_highpass_filter_changed(GtkWidget *w, gpointer user_data G_MODULE_EXPORT void on_keep_aspect_ratio_changed(GtkWidget *w, gpointer user_data_ptr) { GtkCheckButton *button = GTK_CHECK_BUTTON(w); gboolean value = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); - config.keep_aspect_ratio = value; + config.video.keep_aspect_ratio = value; update_viewport(); } G_MODULE_EXPORT void on_rewind_duration_changed(GtkWidget *w, gpointer user_data_ptr) { GtkComboBox *box = GTK_COMBO_BOX(w); - config.rewind_duration = g_ascii_strtoll(gtk_combo_box_get_active_id(box), NULL, 10); - GB_set_rewind_length(&gb, config.rewind_duration); + config.emulation.rewind_duration = g_ascii_strtoll(gtk_combo_box_get_active_id(box), NULL, 10); + GB_set_rewind_length(&gb, config.emulation.rewind_duration); } G_MODULE_EXPORT void on_sample_rate_changed(GtkWidget *w, gpointer user_data_ptr) { GtkComboBox *box = GTK_COMBO_BOX(w); - config.sample_rate = g_ascii_strtoll(gtk_combo_box_get_active_id(box), NULL, 10); + config.audio.sample_rate = g_ascii_strtoll(gtk_combo_box_get_active_id(box), NULL, 10); - if (config.sample_rate == -1) { + if (config.audio.sample_rate == -1) { gui_data.sample_rate = GB_audio_default_sample_rate(); } else { - gui_data.sample_rate = config.sample_rate; + gui_data.sample_rate = config.audio.sample_rate; } init_audio(); @@ -2633,13 +2631,13 @@ G_MODULE_EXPORT void on_sample_rate_changed(GtkWidget *w, gpointer user_data_ptr G_MODULE_EXPORT void on_sgb_model_changed(GtkWidget *w, gpointer user_data_ptr) { GtkComboBox *box = GTK_COMBO_BOX(w); - config.sgb_revision_name = (gchar *)gtk_combo_box_get_active_id(box); + config.emulation.sgb_revision_name = (gchar *)gtk_combo_box_get_active_id(box); } G_MODULE_EXPORT void on_use_integer_scaling_changed(GtkWidget *w, gpointer user_data_ptr) { GtkCheckButton *button = GTK_CHECK_BUTTON(w); gboolean value = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); - config.use_integer_scaling = value; + config.video.use_integer_scaling = value; update_viewport(); } @@ -2674,7 +2672,7 @@ G_MODULE_EXPORT void console_on_enter(GtkWidget *w, gpointer user_data_ptr) { G_MODULE_EXPORT void on_rumble_mode_changed(GtkWidget *w, gpointer user_data_ptr) { GtkComboBox *box = GTK_COMBO_BOX(w); - config.rumble_mode = (gchar *)gtk_combo_box_get_active_id(box); + config.controls.rumble_mode = (gchar *)gtk_combo_box_get_active_id(box); GB_set_rumble_mode(&gb, get_rumble_mode()); } @@ -2682,7 +2680,7 @@ G_MODULE_EXPORT void on_rumble_mode_changed(GtkWidget *w, gpointer user_data_ptr G_MODULE_EXPORT void on_analog_speed_controls_changed(GtkWidget *w, gpointer user_data_ptr) { GtkCheckButton *button = GTK_CHECK_BUTTON(w); gboolean value = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); - config.analog_speed_controls = value; + config.controls.analog_speed_controls = value; } int main(int argc, char *argv[]) { diff --git a/gtk3/settings.c b/gtk3/settings.c index 5609ddd..68b3c12 100644 --- a/gtk3/settings.c +++ b/gtk3/settings.c @@ -12,44 +12,54 @@ static void print_config_error(GError *error) { } void _print_config(config_t *config, GLogLevelFlags log_level) { -#define EXPAND_GROUP(group_name, members) \ - g_log(G_LOG_DOMAIN, log_level, "[%s]", #group_name); \ - members + #define EXPAND_GROUP(name, members) { \ + g_log(G_LOG_DOMAIN, log_level, "[%s]", #name); \ + struct config_ ## name ## _t *group = &config->name; \ + members \ + } -#define EXPAND_GROUP_MEMBER(member, key_type, default_value) \ - g_log(G_LOG_DOMAIN, log_level, "%s="FORMAT_FOR_KEY_TYPE(key_type)"", #member, config->member); + #define EXPAND_GROUP_MEMBER(member, key_type, default_value) \ + g_log(G_LOG_DOMAIN, log_level, "%s="FORMAT_FOR_KEY_TYPE(key_type)"", #member, group->member); EXPAND_CONFIG + #undef EXPAND_GROUP + #undef EXPAND_GROUP_MEMBER +} -#undef EXPAND_GROUP -#undef EXPAND_GROUP_MEMBER +// Duplicates the input and converts the first character to uppercase +gchar* ascii_ucfirst(gchar *str) { + gchar *out = g_strdup(str); + out[0] = g_ascii_toupper(str[0]); + + return out; } void load_config_from_key_file(config_t *config, GKeyFile *key_file) { g_message("Loading config from key file"); GError *error = NULL; - gchar *group_name; -#define EXPAND_GROUP(name, members) \ - group_name = #name; \ - members - -#define EXPAND_GROUP_MEMBER(member, key_type, default_value) \ - config->member = g_key_file_get_##key_type(key_file, group_name, #member, &error); \ - if (error != NULL) { \ - config->member = default_value; \ - print_config_error(error); \ - g_clear_error(&error); \ + #define EXPAND_GROUP(name_arg, members) { \ + struct config_ ## name_arg ## _t *group = &config->name_arg; \ + g_autofree gchar *group_name = ascii_ucfirst(#name_arg); \ + members \ } + #define EXPAND_GROUP_MEMBER(member, key_type, default_value) \ + group->member = g_key_file_get_##key_type(key_file, group_name, #member, &error); \ + if (error != NULL) { \ + group->member = default_value; \ + print_config_error(error); \ + g_clear_error(&error); \ + } + EXPAND_CONFIG - if (config->rewind_duration > 600) { + if (config->emulation.rewind_duration > 600) { g_warning("Setting Emulation.rewind_duration too high might affect performance."); } -#undef EXPAND_GROUP -#undef EXPAND_GROUP_MEMBER + #undef EXPAND_GROUP + #undef EXPAND_GROUP_MEMBER } void print_config(config_t *config) { @@ -61,41 +71,43 @@ void save_config_to_key_file(config_t *config, GKeyFile *key_file) { GError *error = NULL; gchar *group_name; -#define EXPAND_GROUP(name, members) \ - group_name = #name; \ - members - -#define EXPAND_GROUP_MEMBER_IF_0(member, key_type, default_value) \ - g_key_file_set_##key_type(key_file, group_name, #member, config->member); - -#define EXPAND_GROUP_MEMBER_IF_1(member, key_type, default_value) \ - if (config->member != NULL) { \ - g_key_file_set_##key_type(key_file, group_name, #member, config->member); \ - } \ - else if (g_key_file_has_key(key_file, group_name, #member, &error)) { \ - if (error != NULL) { \ - g_warning("%s", error->message); \ - g_clear_error(&error); \ - } \ - g_key_file_remove_key(key_file, group_name, #member, &error); \ - if (error != NULL) { \ - g_warning("%s", error->message); \ - g_clear_error(&error); \ - } \ + #define EXPAND_GROUP(name_arg, members) { \ + struct config_ ## name_arg ## _t *group = &config->name_arg; \ + g_autofree gchar *group_name = ascii_ucfirst(#name_arg); \ + members \ } -#define EXPAND_GROUP_MEMBER_IF_EVAL(y, member, key_type, default_value) EXPAND_GROUP_MEMBER_IF_ ## y(member, key_type, default_value) -#define EXPAND_GROUP_MEMBER_IF(member, key_type, is_pointer, default_value) EXPAND_GROUP_MEMBER_IF_EVAL(is_pointer, member, key_type, default_value) -#define EXPAND_GROUP_MEMBER(member, key_type, default_value) EXPAND_GROUP_MEMBER_IF(member, key_type, GTYPE_IS_POINTER(key_type), default_value) - + #define EXPAND_GROUP_MEMBER_IF_0(member, key_type, default_value) \ + g_key_file_set_##key_type(key_file, group_name, #member, group->member); + + #define EXPAND_GROUP_MEMBER_IF_1(member, key_type, default_value) \ + if (group->member != NULL) { \ + g_key_file_set_##key_type(key_file, group_name, #member, group->member); \ + } \ + else if (g_key_file_has_key(key_file, group_name, #member, &error)) { \ + if (error != NULL) { \ + g_warning("%s", error->message); \ + g_clear_error(&error); \ + } \ + g_key_file_remove_key(key_file, group_name, #member, &error); \ + if (error != NULL) { \ + g_warning("%s", error->message); \ + g_clear_error(&error); \ + } \ + } + + #define EXPAND_GROUP_MEMBER_IF_EVAL(y, member, key_type, default_value) EXPAND_GROUP_MEMBER_IF_ ## y(member, key_type, default_value) + #define EXPAND_GROUP_MEMBER_IF(member, key_type, is_pointer, default_value) EXPAND_GROUP_MEMBER_IF_EVAL(is_pointer, member, key_type, default_value) + #define EXPAND_GROUP_MEMBER(member, key_type, default_value) EXPAND_GROUP_MEMBER_IF(member, key_type, GTYPE_IS_POINTER(key_type), default_value) + EXPAND_CONFIG -#undef EXPAND_GROUP -#undef EXPAND_GROUP_MEMBER -#undef EXPAND_GROUP_MEMBER_IF -#undef EXPAND_GROUP_MEMBER_IF_EVAL -#undef EXPAND_GROUP_MEMBER_IF_0 -#undef EXPAND_GROUP_MEMBER_IF_1 + #undef EXPAND_GROUP + #undef EXPAND_GROUP_MEMBER + #undef EXPAND_GROUP_MEMBER_IF + #undef EXPAND_GROUP_MEMBER_IF_EVAL + #undef EXPAND_GROUP_MEMBER_IF_0 + #undef EXPAND_GROUP_MEMBER_IF_1 } void on_preferences_realize(GtkWidget *w, gpointer builder_ptr) { @@ -105,30 +117,30 @@ void on_preferences_realize(GtkWidget *w, gpointer builder_ptr) { update_boot_rom_selector(builder); // Hook up the static preferences - gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "rewind_duration_selector"), g_strdup_printf("%i", config.rewind_duration)); - gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "dmg_revision_selector"), config.dmg_revision_name); - gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "sgb_revision_selector"), config.sgb_revision_name); - gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "cgb_revision_selector"), config.cgb_revision_name); - gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "shader_selector"), config.shader); - gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "color_correction_selector"), config.color_correction_id); - gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "frame_blending_selector"), config.frame_blending_mode); - gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "display_border_selector"), config.display_border_mode); - gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "monochrome_palette_selector"), config.monochrome_palette_id); - gtk_toggle_button_set_active(builder_get(GTK_TOGGLE_BUTTON, "integer_scaling_toggle"), config.use_integer_scaling); - gtk_toggle_button_set_active(builder_get(GTK_TOGGLE_BUTTON, "aspect_ratio_toggle"), config.keep_aspect_ratio); - gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "highpass_filter_selector"), config.high_pass_filter_id); - gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "sample_rate_selector"), g_strdup_printf("%i", config.sample_rate)); - gtk_toggle_button_set_active(builder_get(GTK_TOGGLE_BUTTON, "analog_speed_controls_toggle"), config.analog_speed_controls); - gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "rumble_mode_selector"), config.rumble_mode); + gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "rewind_duration_selector"), g_strdup_printf("%i", config.emulation.rewind_duration)); + gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "dmg_revision_selector"), config.emulation.dmg_revision_name); + gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "sgb_revision_selector"), config.emulation.sgb_revision_name); + gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "cgb_revision_selector"), config.emulation.cgb_revision_name); + gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "shader_selector"), config.video.shader); + gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "color_correction_selector"), config.video.color_correction_id); + gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "frame_blending_selector"), config.video.frame_blending_mode); + gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "display_border_selector"), config.video.display_border_mode); + gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "monochrome_palette_selector"), config.video.monochrome_palette_id); + gtk_toggle_button_set_active(builder_get(GTK_TOGGLE_BUTTON, "integer_scaling_toggle"), config.video.use_integer_scaling); + gtk_toggle_button_set_active(builder_get(GTK_TOGGLE_BUTTON, "aspect_ratio_toggle"), config.video.keep_aspect_ratio); + gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "highpass_filter_selector"), config.audio.high_pass_filter_id); + gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "sample_rate_selector"), g_strdup_printf("%i", config.audio.sample_rate)); + gtk_toggle_button_set_active(builder_get(GTK_TOGGLE_BUTTON, "analog_speed_controls_toggle"), config.controls.analog_speed_controls); + gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "rumble_mode_selector"), config.controls.rumble_mode); -#if ! NDEBUG - gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "menubar_override_selector"), config.menubar_override); -#else - if (builder_get(GTK_COMBO_BOX, "menubar_override_selector") != NULL) { - gtk_widget_destroy(GTK_WIDGET(builder_get(GTK_COMBO_BOX, "menubar_override_selector"))); - gtk_widget_destroy(GTK_WIDGET(builder_get(GTK_COMBO_BOX, "menubar_override_selector_label"))); - } -#endif + #if ! NDEBUG + gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "menubar_override_selector"), config.video.menubar_override); + #else + if (builder_get(GTK_COMBO_BOX, "menubar_override_selector") != NULL) { + gtk_widget_destroy(GTK_WIDGET(builder_get(GTK_COMBO_BOX, "menubar_override_selector"))); + gtk_widget_destroy(GTK_WIDGET(builder_get(GTK_COMBO_BOX, "menubar_override_selector_label"))); + } + #endif } void init_settings(gchar *path, GtkWindow *preferences) { @@ -192,9 +204,9 @@ void update_boot_rom_selector(GtkBuilder *builder) { GtkComboBoxText *combo_box = builder_get(GTK_COMBO_BOX_TEXT, "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.boot_rom_path != NULL && !g_str_equal(config.boot_rom_path, "auto") && !g_str_equal(config.boot_rom_path, "other")) { - gtk_combo_box_text_append(combo_box, config.boot_rom_path, config.boot_rom_path); - gtk_combo_box_set_active_id(GTK_COMBO_BOX(combo_box), config.boot_rom_path); + 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"); @@ -204,170 +216,170 @@ void update_boot_rom_selector(GtkBuilder *builder) { } enum menubar_type_t get_show_menubar(void) { - if (config.menubar_override == NULL) goto default_value; + if (config.video.menubar_override == NULL) goto default_value; - if (g_strcmp0(config.menubar_override, "auto") == 0) { + if (g_strcmp0(config.video.menubar_override, "auto") == 0) { return MENUBAR_AUTO; } - else if (g_strcmp0(config.menubar_override, "show_in_shell") == 0) { + else if (g_strcmp0(config.video.menubar_override, "show_in_shell") == 0) { return MENUBAR_SHOW_IN_SHELL; } - else if (g_strcmp0(config.menubar_override, "show_in_window") == 0) { + else if (g_strcmp0(config.video.menubar_override, "show_in_window") == 0) { return MENUBAR_SHOW_IN_WINDOW; } - else if (g_strcmp0(config.menubar_override, "show_hamburger") == 0) { + else if (g_strcmp0(config.video.menubar_override, "show_hamburger") == 0) { return MENUBAR_SHOW_HAMBURGER; } // This should not happen - g_warning("Unknown menubar setting: %s\nFalling back to “Auto”", config.menubar_override); + g_warning("Unknown menubar setting: %s\nFalling back to “Auto”", config.video.menubar_override); default_value: return MENUBAR_AUTO; } void set_show_menubar(enum menubar_type_t value) { switch (value) { case MENUBAR_AUTO: - config.menubar_override = "auto"; + config.video.menubar_override = "auto"; break; case MENUBAR_SHOW_IN_SHELL: - config.menubar_override = "show_in_shell"; + config.video.menubar_override = "show_in_shell"; break; case MENUBAR_SHOW_IN_WINDOW: - config.menubar_override = "show_in_window"; + config.video.menubar_override = "show_in_window"; break; case MENUBAR_SHOW_HAMBURGER: - config.menubar_override = "show_hamburger"; + config.video.menubar_override = "show_hamburger"; break; } } GB_color_correction_mode_t get_color_correction_mode(void) { - if (config.color_correction_id == NULL) goto default_value; + if (config.video.color_correction_id == NULL) goto default_value; - if (g_strcmp0(config.color_correction_id, "disabled") == 0) { + if (g_strcmp0(config.video.color_correction_id, "disabled") == 0) { return GB_COLOR_CORRECTION_DISABLED; } - else if (g_strcmp0(config.color_correction_id, "correct_color_curves") == 0) { + else if (g_strcmp0(config.video.color_correction_id, "correct_color_curves") == 0) { return GB_COLOR_CORRECTION_CORRECT_CURVES; } - else if (g_strcmp0(config.color_correction_id, "emulate_hardware") == 0) { + else if (g_strcmp0(config.video.color_correction_id, "emulate_hardware") == 0) { return GB_COLOR_CORRECTION_EMULATE_HARDWARE; } - else if (g_strcmp0(config.color_correction_id, "preserve_brightness") == 0) { + else if (g_strcmp0(config.video.color_correction_id, "preserve_brightness") == 0) { return GB_COLOR_CORRECTION_PRESERVE_BRIGHTNESS; } - else if (g_strcmp0(config.color_correction_id, "reduce_contrast") == 0) { + else if (g_strcmp0(config.video.color_correction_id, "reduce_contrast") == 0) { return GB_COLOR_CORRECTION_REDUCE_CONTRAST; } // This should not happen - g_warning("Unknown color correction mode: %s\nFalling back to “Emulate Hardware”", config.color_correction_id); + g_warning("Unknown color correction mode: %s\nFalling back to “Emulate Hardware”", config.video.color_correction_id); default_value: return GB_COLOR_CORRECTION_EMULATE_HARDWARE; } void set_color_correction_mode(GB_color_correction_mode_t mode) { switch (mode) { case GB_COLOR_CORRECTION_DISABLED: - config.color_correction_id = "disabled"; + config.video.color_correction_id = "disabled"; break; case GB_COLOR_CORRECTION_CORRECT_CURVES: - config.color_correction_id = "correct_color_curves"; + config.video.color_correction_id = "correct_color_curves"; break; case GB_COLOR_CORRECTION_EMULATE_HARDWARE: - config.color_correction_id = "emulate_hardware"; + config.video.color_correction_id = "emulate_hardware"; break; case GB_COLOR_CORRECTION_PRESERVE_BRIGHTNESS: - config.color_correction_id = "preserve_brightness"; + config.video.color_correction_id = "preserve_brightness"; break; case GB_COLOR_CORRECTION_REDUCE_CONTRAST: - config.color_correction_id = "reduce_contrast"; + config.video.color_correction_id = "reduce_contrast"; break; } } GB_frame_blending_mode_t get_frame_blending_mode(void) { - if (config.frame_blending_mode == NULL) goto default_value; + if (config.video.frame_blending_mode == NULL) goto default_value; - if (g_strcmp0(config.frame_blending_mode, "disabled") == 0) { + if (g_strcmp0(config.video.frame_blending_mode, "disabled") == 0) { return GB_FRAME_BLENDING_MODE_DISABLED; } - else if (g_strcmp0(config.frame_blending_mode, "simple") == 0) { + else if (g_strcmp0(config.video.frame_blending_mode, "simple") == 0) { return GB_FRAME_BLENDING_MODE_SIMPLE; } - else if (g_strcmp0(config.frame_blending_mode, "accurate") == 0) { + else if (g_strcmp0(config.video.frame_blending_mode, "accurate") == 0) { return GB_FRAME_BLENDING_MODE_ACCURATE; } // This should not happen - g_warning("Unknown frame blending mode: %s\nFalling back to “Disabled”", config.frame_blending_mode); + g_warning("Unknown frame blending mode: %s\nFalling back to “Disabled”", config.video.frame_blending_mode); default_value: return GB_FRAME_BLENDING_MODE_DISABLED; } void set_frame_blending_mode(GB_frame_blending_mode_t mode) { switch (mode) { case GB_FRAME_BLENDING_MODE_DISABLED: - config.frame_blending_mode = "disabled"; + config.video.frame_blending_mode = "disabled"; break; case GB_FRAME_BLENDING_MODE_SIMPLE: - config.frame_blending_mode = "simple"; + config.video.frame_blending_mode = "simple"; break; case GB_FRAME_BLENDING_MODE_ACCURATE: case GB_FRAME_BLENDING_MODE_ACCURATE_ODD: - config.frame_blending_mode = "accurate"; + config.video.frame_blending_mode = "accurate"; break; } } GB_border_mode_t get_display_border_mode(void) { - if (config.display_border_mode == NULL) goto default_value; + if (config.video.display_border_mode == NULL) goto default_value; - if (g_strcmp0(config.display_border_mode, "never") == 0) { + if (g_strcmp0(config.video.display_border_mode, "never") == 0) { return GB_BORDER_NEVER; } - else if (g_strcmp0(config.display_border_mode, "sgb_only") == 0) { + else if (g_strcmp0(config.video.display_border_mode, "sgb_only") == 0) { return GB_BORDER_SGB; } - else if (g_strcmp0(config.display_border_mode, "always") == 0) { + else if (g_strcmp0(config.video.display_border_mode, "always") == 0) { return GB_BORDER_ALWAYS; } // This should not happen - g_warning("Unknown SGB border mode: %s\nFalling back to “Never”", config.display_border_mode); + g_warning("Unknown SGB border mode: %s\nFalling back to “Never”", config.video.display_border_mode); default_value: return GB_BORDER_NEVER; } void set_display_border_mode(GB_border_mode_t mode) { switch (mode) { case GB_BORDER_NEVER: - config.display_border_mode = "never"; + config.video.display_border_mode = "never"; break; case GB_BORDER_SGB: - config.display_border_mode = "sgb_only"; + config.video.display_border_mode = "sgb_only"; break; case GB_BORDER_ALWAYS: - config.display_border_mode = "always"; + config.video.display_border_mode = "always"; break; } } const GB_palette_t* get_monochrome_palette(void) { - if (config.monochrome_palette_id == NULL) goto default_value; + if (config.video.monochrome_palette_id == NULL) goto default_value; - if (g_strcmp0(config.monochrome_palette_id, "greyscale") == 0) { + if (g_strcmp0(config.video.monochrome_palette_id, "greyscale") == 0) { return &GB_PALETTE_GREY; } - else if (g_strcmp0(config.monochrome_palette_id, "lime") == 0) { + else if (g_strcmp0(config.video.monochrome_palette_id, "lime") == 0) { return &GB_PALETTE_DMG; } - else if (g_strcmp0(config.monochrome_palette_id, "olive") == 0) { + else if (g_strcmp0(config.video.monochrome_palette_id, "olive") == 0) { return &GB_PALETTE_MGB; } - else if (g_strcmp0(config.monochrome_palette_id, "teal") == 0) { + else if (g_strcmp0(config.video.monochrome_palette_id, "teal") == 0) { return &GB_PALETTE_GBL; } // This should not happen - g_warning("Unknown monochrome palette: %s\nFalling back to “Greyscale”", config.monochrome_palette_id); + g_warning("Unknown monochrome palette: %s\nFalling back to “Greyscale”", config.video.monochrome_palette_id); default_value: return &GB_PALETTE_GREY; } @@ -375,90 +387,90 @@ void set_monochrome_palette(const GB_palette_t *mode) { g_message("%p | %p | %p | %p | %p", mode, &GB_PALETTE_GREY, &GB_PALETTE_DMG, &GB_PALETTE_MGB, &GB_PALETTE_GBL); if (mode == &GB_PALETTE_GREY) { - config.monochrome_palette_id = "greyscale"; + config.video.monochrome_palette_id = "greyscale"; } else if (mode == &GB_PALETTE_DMG) { - config.monochrome_palette_id = "lime"; + config.video.monochrome_palette_id = "lime"; } else if (mode == &GB_PALETTE_MGB) { - config.monochrome_palette_id = "olive"; + config.video.monochrome_palette_id = "olive"; } else if (mode == &GB_PALETTE_GBL) { - config.monochrome_palette_id = "teal"; + config.video.monochrome_palette_id = "teal"; } } GB_highpass_mode_t get_highpass_mode(void) { - if (config.high_pass_filter_id == NULL) goto default_value; + if (config.audio.high_pass_filter_id == NULL) goto default_value; - if (g_strcmp0(config.high_pass_filter_id, "disabled") == 0) { + if (g_strcmp0(config.audio.high_pass_filter_id, "disabled") == 0) { return GB_HIGHPASS_OFF; } - else if (g_strcmp0(config.high_pass_filter_id, "emulate_hardware") == 0) { + else if (g_strcmp0(config.audio.high_pass_filter_id, "emulate_hardware") == 0) { return GB_HIGHPASS_ACCURATE; } - else if (g_strcmp0(config.high_pass_filter_id, "preserve_waveform") == 0) { + else if (g_strcmp0(config.audio.high_pass_filter_id, "preserve_waveform") == 0) { return GB_HIGHPASS_REMOVE_DC_OFFSET; } // This should not happen - g_warning("Unknown highpass mode: %s\nFalling back to “Accurate”", config.high_pass_filter_id); + g_warning("Unknown highpass mode: %s\nFalling back to “Accurate”", config.audio.high_pass_filter_id); default_value: return GB_HIGHPASS_ACCURATE; } void set_highpass_mode(GB_highpass_mode_t mode) { switch (mode) { case GB_HIGHPASS_OFF: - config.high_pass_filter_id = "disabled"; + config.audio.high_pass_filter_id = "disabled"; break; case GB_HIGHPASS_MAX: g_warning("GB_HIGHPASS_MAX is not a valid highpass mode, falling back to “Accurate”."); case GB_HIGHPASS_ACCURATE: - config.high_pass_filter_id = "emulate_hardware"; + config.audio.high_pass_filter_id = "emulate_hardware"; break; case GB_HIGHPASS_REMOVE_DC_OFFSET: - config.high_pass_filter_id = "preserve_waveform"; + config.audio.high_pass_filter_id = "preserve_waveform"; break; } } const GB_rumble_mode_t get_rumble_mode(void) { - if (config.rumble_mode == NULL) goto default_value; + if (config.controls.rumble_mode == NULL) goto default_value; - if (g_strcmp0(config.rumble_mode, "never") == 0) { + if (g_strcmp0(config.controls.rumble_mode, "never") == 0) { return GB_RUMBLE_DISABLED; } - else if (g_strcmp0(config.rumble_mode, "rumble_cartridges") == 0) { + else if (g_strcmp0(config.controls.rumble_mode, "rumble_cartridges") == 0) { return GB_RUMBLE_CARTRIDGE_ONLY; } - else if (g_strcmp0(config.rumble_mode, "always") == 0) { + else if (g_strcmp0(config.controls.rumble_mode, "always") == 0) { return GB_RUMBLE_ALL_GAMES; } // This should not happen - g_warning("Unknown highpass mode: %s\nFalling back to “Never”", config.rumble_mode); + g_warning("Unknown highpass mode: %s\nFalling back to “Never”", config.controls.rumble_mode); default_value: return GB_RUMBLE_DISABLED; } void set_rumble_mode(GB_rumble_mode_t mode) { switch (mode) { case GB_RUMBLE_DISABLED: - config.rumble_mode = "never"; + config.controls.rumble_mode = "never"; break; case GB_RUMBLE_CARTRIDGE_ONLY: - config.rumble_mode = "rumble_cartridges"; + config.controls.rumble_mode = "rumble_cartridges"; break; case GB_RUMBLE_ALL_GAMES: - config.rumble_mode = "always"; + config.controls.rumble_mode = "always"; break; } } GB_model_t get_dmg_model(void) { - if (config.dmg_revision_name == NULL) goto default_value; + if (config.emulation.dmg_revision_name == NULL) goto default_value; // TODO: Synchronize with GB_model_t (Core/gb.h) - if (g_strcmp0(config.dmg_revision_name, "DMG_CPU_B") == 0) { + if (g_strcmp0(config.emulation.dmg_revision_name, "DMG_CPU_B") == 0) { return GB_MODEL_DMG_B; } @@ -466,16 +478,16 @@ GB_model_t get_dmg_model(void) { } GB_model_t get_sgb_model(void) { - if (config.sgb_revision_name == NULL) goto default_value; + if (config.emulation.sgb_revision_name == NULL) goto default_value; // TODO: Synchronize with GB_model_t (Core/gb.h) - if (g_strcmp0(config.sgb_revision_name, "SGB1_NTSC") == 0) { + if (g_strcmp0(config.emulation.sgb_revision_name, "SGB1_NTSC") == 0) { return GB_MODEL_SGB_NTSC; } - else if (g_strcmp0(config.sgb_revision_name, "SGB1_PAL") == 0) { + else if (g_strcmp0(config.emulation.sgb_revision_name, "SGB1_PAL") == 0) { return GB_MODEL_SGB_PAL; } - else if (g_strcmp0(config.sgb_revision_name, "SGB2") == 0) { + else if (g_strcmp0(config.emulation.sgb_revision_name, "SGB2") == 0) { return GB_MODEL_SGB2; } @@ -483,13 +495,13 @@ GB_model_t get_sgb_model(void) { } GB_model_t get_cgb_model(void) { - if (config.cgb_revision_name == NULL) goto default_value; + if (config.emulation.cgb_revision_name == NULL) goto default_value; // TODO: Synchronize with GB_model_t (Core/gb.h) - if (g_strcmp0(config.cgb_revision_name, "CPU_CGB_C") == 0) { + if (g_strcmp0(config.emulation.cgb_revision_name, "CPU_CGB_C") == 0) { return GB_MODEL_CGB_C; } - else if (g_strcmp0(config.cgb_revision_name, "CPU_CGB_E") == 0) { + else if (g_strcmp0(config.emulation.cgb_revision_name, "CPU_CGB_E") == 0) { return GB_MODEL_CGB_E; } diff --git a/gtk3/settings.h b/gtk3/settings.h index 47dd44f..7f81057 100644 --- a/gtk3/settings.h +++ b/gtk3/settings.h @@ -22,21 +22,19 @@ #define GTYPE_IS_POINTER_integer 0 #define GTYPE_IS_POINTER_boolean 0 -// Note: Make sure to use a member name only once for the whole config struct -// // Macro usage: // EXPAND_CONFIG(EXPAND_GROUP(…) EXPAND_GROUP(…) …) // EXPAND_GROUP(group_name, group_members) // EXPAND_GROUP_MEMBER(member_name, key_type, default_value) #define EXPAND_CONFIG \ - EXPAND_GROUP(Emulation, \ + EXPAND_GROUP(emulation, \ EXPAND_GROUP_MEMBER(boot_rom_path, string, "auto") /* overrides search location for boot ROMs by name */ \ EXPAND_GROUP_MEMBER(rewind_duration, integer, 10) \ EXPAND_GROUP_MEMBER(dmg_revision_name, string, "DMG_CPU_C") \ EXPAND_GROUP_MEMBER(sgb_revision_name, string, "SGB2") \ EXPAND_GROUP_MEMBER(cgb_revision_name, string, "CPU_CGB_E") \ ) \ - EXPAND_GROUP(Video, \ + EXPAND_GROUP(video, \ EXPAND_GROUP_MEMBER(shader, string, "NearestNeighbor") \ EXPAND_GROUP_MEMBER(color_correction_id, string, "emulate_hardware") \ EXPAND_GROUP_MEMBER(frame_blending_mode, string, "disabled") \ @@ -46,21 +44,25 @@ EXPAND_GROUP_MEMBER(use_integer_scaling, boolean, true) \ EXPAND_GROUP_MEMBER(menubar_override, string, "auto") \ ) \ - EXPAND_GROUP(Audio, \ + EXPAND_GROUP(audio, \ EXPAND_GROUP_MEMBER(high_pass_filter_id, string, "emulate_hardware") \ EXPAND_GROUP_MEMBER(sample_rate, integer, -1) \ ) \ - EXPAND_GROUP(Controls, \ + EXPAND_GROUP(controls, \ EXPAND_GROUP_MEMBER(analog_speed_controls, boolean, false) \ EXPAND_GROUP_MEMBER(rumble_mode, string, "Never") \ ) typedef struct config_t { -#define EXPAND_GROUP(group_name, members) members -#define EXPAND_GROUP_MEMBER(member, key_type, default_value) GTYPE_OF_KEY_TYPE(key_type) member; + #define EXPAND_GROUP(group_name, members) struct config_ ## group_name ## _t { \ + members \ + } group_name; + #define EXPAND_GROUP_MEMBER(member, key_type, default_value) GTYPE_OF_KEY_TYPE(key_type) member; + EXPAND_CONFIG -#undef EXPAND_GROUP -#undef EXPAND_GROUP_MEMBER + + #undef EXPAND_GROUP + #undef EXPAND_GROUP_MEMBER } config_t; enum menubar_type_t {