From 44ea60b5a90bf176c505493607ce2122763e35c9 Mon Sep 17 00:00:00 2001 From: Maximilian Mader Date: Wed, 25 Sep 2019 02:48:07 +0200 Subject: [PATCH] [GTK3] Load/save settings from/to file --- gtk3/main.c | 13 ++++--- gtk3/resources/ui/window.ui | 44 ++++++++++++++------- gtk3/settings.c | 77 ++++++++++++++++++++++++++++++++++--- gtk3/settings.h | 56 +++++++++++++++++++++++++-- 4 files changed, 161 insertions(+), 29 deletions(-) diff --git a/gtk3/main.c b/gtk3/main.c index bc8dd47..105a837 100644 --- a/gtk3/main.c +++ b/gtk3/main.c @@ -15,8 +15,8 @@ typedef struct UserData { bool fullscreen; GFile *file; - const gchar *bootrom_path; - const gchar *config_path; + gchar *bootrom_path; + gchar *config_path; GB_model_t model; } UserData; @@ -98,12 +98,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 (true /*configuration.scaling_mode == GB_SDL_SCALING_INTEGER_FACTOR*/) { + if (config.use_integer_scaling) { x_factor = (int)(x_factor); y_factor = (int)(y_factor); } - if (true /*configuration.scaling_mode != GB_SDL_SCALING_ENTIRE_WINDOW*/) { + if (config.keep_aspect_ratio) { if (x_factor > y_factor) { x_factor = y_factor; } @@ -245,7 +245,7 @@ G_MODULE_EXPORT void gl_init() { renderer = (char *) glGetString(GL_RENDERER); g_print("GtkGLArea on %s\n", renderer ? renderer : "Unknown"); - if (!init_shader_with_name(&shader, /*configuration.filter*/ "OmniScale")) { + if (config.shader == NULL || !init_shader_with_name(&shader, config.shader)) { init_shader_with_name(&shader, "NearestNeighbor"); } } @@ -380,6 +380,7 @@ static void shutdown(GApplication *app, GFile **files, gint n_files, const gchar g_print("SHUTDOWN\n"); save_settings(); + free_settings(); } // This function gets called after the parsing of the commandline options has occurred. @@ -520,7 +521,7 @@ static void run(UserData *user_data) { // GB_set_sample_rate(&gb, have_aspec.freq); // GB_set_color_correction_mode(&gb, configuration.color_correction_mode); // GB_set_highpass_filter_mode(&gb, configuration.highpass_mode); - // GB_set_rewind_length(&gb, configuration.rewind_length); + GB_set_rewind_length(&gb, config.rewind_duration); // GB_set_update_input_hint_callback(&gb, handle_events); // GB_apu_set_sample_callback(&gb, gb_audio_callback); } diff --git a/gtk3/resources/ui/window.ui b/gtk3/resources/ui/window.ui index 0c24227..44ce981 100644 --- a/gtk3/resources/ui/window.ui +++ b/gtk3/resources/ui/window.ui @@ -556,19 +556,19 @@ Maximilian Mader https://github.com/max-m 0 nearest_neighbour - Nearest Neighbor (Pixelated) - Bilinear (Blurry) - Smooth Bilinear (Less blurry) - LCD Display - CRT Display - Scale2x - Scale4x - Anti-aliased Scale2x - Anti-aliased Scale4x - HQ2x - OmniScale (Any factor) - OmniScale Legacy - Anti-aliased OmniScale Legacy + Nearest Neighbor (Pixelated) + Bilinear (Blurry) + Smooth Bilinear (Less blurry) + LCD Display + CRT Display + Scale2x + Scale4x + Anti-aliased Scale2x + Anti-aliased Scale4x + HQ2x + OmniScale (Any factor) + OmniScale Legacy + Anti-aliased OmniScale Legacy @@ -630,6 +630,24 @@ Maximilian Mader https://github.com/max-m 4 + + + Use Integer Scaling + True + True + False + 5 + 10 + True + True + + + + False + True + 4 + + 1 diff --git a/gtk3/settings.c b/gtk3/settings.c index 5463f88..c2620b8 100644 --- a/gtk3/settings.c +++ b/gtk3/settings.c @@ -1,9 +1,55 @@ #include "settings.h" -void init_settings(const gchar *path) { - key_file = g_key_file_new(); +static void print_config_error(GError *error) { + if (error == NULL) return; - GError *error = NULL; + if (error->domain != G_KEY_FILE_ERROR_GROUP_NOT_FOUND && error->domain != G_KEY_FILE_ERROR_KEY_NOT_FOUND) { + g_printerr("Config error: %s\n", error->message); + } +} + +void print_config(config_t *config) { +#define EXPAND_GROUP(group_name, members) \ + g_print("[%s]\n", #group_name); \ + members + +#define EXPAND_GROUP_MEMBER(member, key_type) \ + g_print("%s="FORMAT_FOR_KEY_TYPE(key_type)"\n", #member, config->member); + + EXPAND_CONFIG + +#undef EXPAND_GROUP +#undef EXPAND_GROUP_MEMBER +} + +void load_config_from_key_file(config_t *config, GKeyFile *key_file) { + static GError *error = NULL; + gchar *group_name; + +#define EXPAND_GROUP(name, members) \ + group_name = #name; \ + if (g_key_file_has_group(key_file, group_name)) { \ + members \ + } + +#define EXPAND_GROUP_MEMBER(member, key_type) \ + config->member = g_key_file_get_##key_type(key_file, group_name, #member, &error); \ + print_config_error(error); \ + if (error != NULL) g_clear_error(&error); + + EXPAND_CONFIG + + if (config->rewind_duration > 600) { + g_warning("Setting Emulation.rewind_duration too high might affect performance.\n"); + } + +#undef EXPAND_GROUP +#undef EXPAND_GROUP_MEMBER +} + +void init_settings(gchar *path) { + free_settings(); + key_file = g_key_file_new(); if (path != NULL) { settings_file_path = path; @@ -15,15 +61,27 @@ void init_settings(const gchar *path) { load_settings(); } -void load_settings(void) { +int load_settings(void) { GError *error = NULL; g_print("Trying to load settings from %s\n", settings_file_path); if (!g_key_file_load_from_file(key_file, settings_file_path, G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, &error)) { - g_warning("Error loading %s: %s", settings_file_path, error->message); + if (error->domain == G_FILE_ERROR) { + g_warning("Unable to load %s: %s", settings_file_path, error->message); + } + else if (error->domain == G_KEY_FILE_ERROR) { + g_warning("Failed to parse %s: %s", settings_file_path, error->message); + } + g_error_free(error); + return -1; } + + load_config_from_key_file(&config, key_file); + print_config(&config); + + return 0; } void save_settings(void) { @@ -32,8 +90,15 @@ void save_settings(void) { g_print("Trying to save settings to %s\n", settings_file_path); if (!g_key_file_save_to_file(key_file, settings_file_path, &error)) { - g_warning ("Error saving %s: %s", settings_file_path, error->message); + g_warning ("Failed to save %s: %s", settings_file_path, error->message); g_error_free(error); return; } } + +void free_settings(void) { + if (key_file != NULL) { + g_key_file_free(key_file); + key_file = NULL; + } +} diff --git a/gtk3/settings.h b/gtk3/settings.h index 92c3477..be84182 100644 --- a/gtk3/settings.h +++ b/gtk3/settings.h @@ -6,11 +6,59 @@ #define SETTINGS_FILE "sameboy-gtk3-settings.ini" -GKeyFile *key_file; -const gchar* settings_file_path; +#define FORMAT_FOR_KEY_TYPE(type) KEY_FORMAT_##type +#define KEY_FORMAT_string "%s" +#define KEY_FORMAT_integer "%d" +#define KEY_FORMAT_boolean "%d" -void init_settings(const gchar *path); -void load_settings(void); +#define GTYPE_FOR_KEY_TYPE(type) GTYPE_##type +#define GTYPE_string gchar * +#define GTYPE_integer gint +#define GTYPE_boolean gboolean + +// Note: Make sure to use a member name only once for the whole config struct +#define EXPAND_CONFIG \ + EXPAND_GROUP(Emulation, \ + EXPAND_GROUP_MEMBER(boot_rom_path, string) /* overrides search location for boot ROMs by name */ \ + EXPAND_GROUP_MEMBER(rewind_duration, integer) \ + EXPAND_GROUP_MEMBER(dmg_revision_name, string) \ + EXPAND_GROUP_MEMBER(sgb_revision_name, string) \ + EXPAND_GROUP_MEMBER(cgb_revision_name, string) \ + ) \ + EXPAND_GROUP(Video, \ + EXPAND_GROUP_MEMBER(shader, string) \ + EXPAND_GROUP_MEMBER(color_correction_id, string) \ + EXPAND_GROUP_MEMBER(keep_aspect_ratio, boolean) \ + EXPAND_GROUP_MEMBER(use_integer_scaling, boolean) \ + ) \ + EXPAND_GROUP(Audio, \ + EXPAND_GROUP_MEMBER(high_pass_filter_id, string) \ + ) \ + EXPAND_GROUP(Controls, \ + \ + ) + +typedef struct config_t { +#define EXPAND_GROUP(group_name, members) members +#define EXPAND_GROUP_MEMBER(member, key_type) GTYPE_FOR_KEY_TYPE(key_type) member; + EXPAND_CONFIG +#undef EXPAND_GROUP +#undef EXPAND_GROUP_MEMBER +} config_t; + +gchar* settings_file_path; +GKeyFile *key_file; +config_t config; + +void print_config(config_t *config); +void load_config_from_key_file(config_t *config, GKeyFile *key_file); + +void init_settings(gchar *path); +int load_settings(void); void save_settings(void); +void free_settings(void); + +enum scaling_mode get_scaling_mode(void); +void set_scaling_mode(enum scaling_mode); #endif /* settings_h */