[GTK3] Load/save settings from/to file
This commit is contained in:
parent
214ef9399d
commit
44ea60b5a9
13
gtk3/main.c
13
gtk3/main.c
@ -15,8 +15,8 @@
|
|||||||
typedef struct UserData {
|
typedef struct UserData {
|
||||||
bool fullscreen;
|
bool fullscreen;
|
||||||
GFile *file;
|
GFile *file;
|
||||||
const gchar *bootrom_path;
|
gchar *bootrom_path;
|
||||||
const gchar *config_path;
|
gchar *config_path;
|
||||||
GB_model_t model;
|
GB_model_t model;
|
||||||
} UserData;
|
} UserData;
|
||||||
|
|
||||||
@ -98,12 +98,12 @@ static void update_viewport(void) {
|
|||||||
double x_factor = win_width / (double) GB_get_screen_width(&gb);
|
double x_factor = win_width / (double) GB_get_screen_width(&gb);
|
||||||
double y_factor = win_height / (double) GB_get_screen_height(&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);
|
x_factor = (int)(x_factor);
|
||||||
y_factor = (int)(y_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) {
|
if (x_factor > y_factor) {
|
||||||
x_factor = y_factor;
|
x_factor = y_factor;
|
||||||
}
|
}
|
||||||
@ -245,7 +245,7 @@ G_MODULE_EXPORT void gl_init() {
|
|||||||
renderer = (char *) glGetString(GL_RENDERER);
|
renderer = (char *) glGetString(GL_RENDERER);
|
||||||
g_print("GtkGLArea on %s\n", renderer ? renderer : "Unknown");
|
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");
|
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");
|
g_print("SHUTDOWN\n");
|
||||||
|
|
||||||
save_settings();
|
save_settings();
|
||||||
|
free_settings();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function gets called after the parsing of the commandline options has occurred.
|
// 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_sample_rate(&gb, have_aspec.freq);
|
||||||
// GB_set_color_correction_mode(&gb, configuration.color_correction_mode);
|
// GB_set_color_correction_mode(&gb, configuration.color_correction_mode);
|
||||||
// GB_set_highpass_filter_mode(&gb, configuration.highpass_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_set_update_input_hint_callback(&gb, handle_events);
|
||||||
// GB_apu_set_sample_callback(&gb, gb_audio_callback);
|
// GB_apu_set_sample_callback(&gb, gb_audio_callback);
|
||||||
}
|
}
|
||||||
|
@ -556,19 +556,19 @@ Maximilian Mader https://github.com/max-m</property>
|
|||||||
<property name="active">0</property>
|
<property name="active">0</property>
|
||||||
<property name="active_id">nearest_neighbour</property>
|
<property name="active_id">nearest_neighbour</property>
|
||||||
<items>
|
<items>
|
||||||
<item id="nearest_neighbour" translatable="yes">Nearest Neighbor (Pixelated)</item>
|
<item id="NearestNeighbor" translatable="yes">Nearest Neighbor (Pixelated)</item>
|
||||||
<item id="bilinear" translatable="yes">Bilinear (Blurry)</item>
|
<item id="Bilinear" translatable="yes">Bilinear (Blurry)</item>
|
||||||
<item id="smooth_bilinear" translatable="yes">Smooth Bilinear (Less blurry)</item>
|
<item id="SmoothBilinear" translatable="yes">Smooth Bilinear (Less blurry)</item>
|
||||||
<item id="lcd" translatable="yes">LCD Display</item>
|
<item id="LCD" translatable="yes">LCD Display</item>
|
||||||
<item id="crt" translatable="yes">CRT Display</item>
|
<item id="CRT" translatable="yes">CRT Display</item>
|
||||||
<item id="scale2x" translatable="yes">Scale2x</item>
|
<item id="Scale2x" translatable="yes">Scale2x</item>
|
||||||
<item id="scale4x" translatable="yes">Scale4x</item>
|
<item id="Scale4x" translatable="yes">Scale4x</item>
|
||||||
<item id="scale2x_aa" translatable="yes">Anti-aliased Scale2x</item>
|
<item id="AAScale2x" translatable="yes">Anti-aliased Scale2x</item>
|
||||||
<item id="scale4x_aa" translatable="yes">Anti-aliased Scale4x</item>
|
<item id="AAScale4x" translatable="yes">Anti-aliased Scale4x</item>
|
||||||
<item id="hq2x" translatable="yes">HQ2x</item>
|
<item id="HQ2x" translatable="yes">HQ2x</item>
|
||||||
<item id="omniscale" translatable="yes">OmniScale (Any factor)</item>
|
<item id="OmniScale" translatable="yes">OmniScale (Any factor)</item>
|
||||||
<item id="omniscale_legacy" translatable="yes">OmniScale Legacy</item>
|
<item id="OmniScaleLegacy" translatable="yes">OmniScale Legacy</item>
|
||||||
<item id="omniscale_legacy_aa" translatable="yes">Anti-aliased OmniScale Legacy</item>
|
<item id="AAOmniScaleLegacy" translatable="yes">Anti-aliased OmniScale Legacy</item>
|
||||||
</items>
|
</items>
|
||||||
<signal name="changed" handler="on_graphic_filter_changed" swapped="no"/>
|
<signal name="changed" handler="on_graphic_filter_changed" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
@ -630,6 +630,24 @@ Maximilian Mader https://github.com/max-m</property>
|
|||||||
<property name="position">4</property>
|
<property name="position">4</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCheckButton">
|
||||||
|
<property name="label" translatable="yes">Use Integer Scaling</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">False</property>
|
||||||
|
<property name="margin_top">5</property>
|
||||||
|
<property name="margin_bottom">10</property>
|
||||||
|
<property name="active">True</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
<signal name="toggled" handler="on_use_integer_scaling_changed" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">4</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
|
@ -1,9 +1,55 @@
|
|||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
void init_settings(const gchar *path) {
|
static void print_config_error(GError *error) {
|
||||||
key_file = g_key_file_new();
|
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) {
|
if (path != NULL) {
|
||||||
settings_file_path = path;
|
settings_file_path = path;
|
||||||
@ -15,15 +61,27 @@ void init_settings(const gchar *path) {
|
|||||||
load_settings();
|
load_settings();
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_settings(void) {
|
int load_settings(void) {
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
g_print("Trying to load settings from %s\n", settings_file_path);
|
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)) {
|
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);
|
g_error_free(error);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
load_config_from_key_file(&config, key_file);
|
||||||
|
print_config(&config);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_settings(void) {
|
void save_settings(void) {
|
||||||
@ -32,8 +90,15 @@ void save_settings(void) {
|
|||||||
g_print("Trying to save settings to %s\n", settings_file_path);
|
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)) {
|
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);
|
g_error_free(error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free_settings(void) {
|
||||||
|
if (key_file != NULL) {
|
||||||
|
g_key_file_free(key_file);
|
||||||
|
key_file = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -6,11 +6,59 @@
|
|||||||
|
|
||||||
#define SETTINGS_FILE "sameboy-gtk3-settings.ini"
|
#define SETTINGS_FILE "sameboy-gtk3-settings.ini"
|
||||||
|
|
||||||
GKeyFile *key_file;
|
#define FORMAT_FOR_KEY_TYPE(type) KEY_FORMAT_##type
|
||||||
const gchar* settings_file_path;
|
#define KEY_FORMAT_string "%s"
|
||||||
|
#define KEY_FORMAT_integer "%d"
|
||||||
|
#define KEY_FORMAT_boolean "%d"
|
||||||
|
|
||||||
void init_settings(const gchar *path);
|
#define GTYPE_FOR_KEY_TYPE(type) GTYPE_##type
|
||||||
void load_settings(void);
|
#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 save_settings(void);
|
||||||
|
void free_settings(void);
|
||||||
|
|
||||||
|
enum scaling_mode get_scaling_mode(void);
|
||||||
|
void set_scaling_mode(enum scaling_mode);
|
||||||
|
|
||||||
#endif /* settings_h */
|
#endif /* settings_h */
|
||||||
|
Loading…
Reference in New Issue
Block a user