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
+
+
+
+ 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 */