SameBoy/gtk3/settings.c

251 lines
7.0 KiB
C
Raw Normal View History

#include "settings.h"
2019-09-25 00:48:07 +00:00
static void print_config_error(GError *error) {
if (error == NULL) return;
2019-09-25 20:47:04 +00:00
if (!g_error_matches(error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND) && !g_error_matches(error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) {
2019-09-25 00:48:07 +00:00
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) {
g_print("Loading config from key file\n");
2019-09-25 20:47:04 +00:00
GError *error = NULL;
2019-09-25 00:48:07 +00:00
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); \
2019-09-25 20:47:04 +00:00
g_clear_error(&error);
2019-09-25 00:48:07 +00:00
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
}
2019-09-25 20:47:04 +00:00
void save_config_to_key_file(config_t *config, GKeyFile *key_file) {
g_print("Saving config to key file\n");
2019-09-25 20:47:04 +00:00
GError *error = NULL;
gchar *group_name;
#define EXPAND_GROUP(name, members) \
group_name = #name; \
members
#define EXPAND_GROUP_MEMBER_IF_0(member, key_type) \
g_key_file_set_##key_type(key_file, group_name, #member, config->member);
#define EXPAND_GROUP_MEMBER_IF_1(member, key_type) \
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_printerr("%s\n", error->message); \
g_clear_error(&error); \
} \
2019-09-25 20:47:04 +00:00
g_key_file_remove_key(key_file, group_name, #member, &error); \
if (error != NULL) { \
g_printerr("%s\n", error->message); \
g_clear_error(&error); \
} \
}
#define EXPAND_GROUP_MEMBER_IF_EVAL(y, member, key_type) EXPAND_GROUP_MEMBER_IF_ ## y(member, key_type)
#define EXPAND_GROUP_MEMBER_IF(member, key_type, is_pointer) EXPAND_GROUP_MEMBER_IF_EVAL(is_pointer, member, key_type)
#define EXPAND_GROUP_MEMBER(member, key_type) EXPAND_GROUP_MEMBER_IF(member, key_type, GTYPE_IS_POINTER(key_type))
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
}
void init_settings(gchar *path, GtkWindow *preferences) {
2019-09-25 00:48:07 +00:00
free_settings();
key_file = g_key_file_new();
if (path != NULL) {
settings_file_path = path;
}
else {
settings_file_path = g_build_filename(g_get_user_config_dir(), SETTINGS_FILE, NULL);
}
load_settings();
}
2019-09-25 00:48:07 +00:00
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)) {
2019-09-25 00:48:07 +00:00
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);
2019-09-25 00:48:07 +00:00
return -1;
}
2019-09-25 00:48:07 +00:00
load_config_from_key_file(&config, key_file);
print_config(&config);
return 0;
}
void save_settings(void) {
GError *error = NULL;
g_print("Trying to save settings to %s\n", settings_file_path);
2019-09-25 20:47:04 +00:00
save_config_to_key_file(&config, key_file);
if (!g_key_file_save_to_file(key_file, settings_file_path, &error)) {
2019-09-25 00:48:07 +00:00
g_warning ("Failed to save %s: %s", settings_file_path, error->message);
g_error_free(error);
return;
}
}
2019-09-25 00:48:07 +00:00
void free_settings(void) {
if (key_file != NULL) {
g_key_file_free(key_file);
key_file = NULL;
}
}
2019-09-25 20:47:04 +00:00
enum menubar_override get_show_menubar(void) {
if (config.menubar_override == NULL) goto default_value;
2019-09-25 20:47:04 +00:00
if (g_strcmp0(config.menubar_override, "show") == 0) {
return MENUBAR_SHOW;
}
else if (g_strcmp0(config.menubar_override, "hide") == 0) {
return MENUBAR_HIDE;
}
// This should not happen
g_warning("Unknown menubar setting: %s\nFalling back to “Auto”\n", config.menubar_override);
default_value: return MENUBAR_AUTO;
2019-09-25 20:47:04 +00:00
}
void set_show_menubar(enum menubar_override value) {
switch (value) {
case MENUBAR_AUTO:
config.menubar_override = "auto";
break;
case MENUBAR_SHOW:
config.menubar_override = "show";
break;
case MENUBAR_HIDE:
config.menubar_override = "hide";
break;
}
}
GB_color_correction_mode_t get_color_correction_mode(void) {
if (config.color_correction_id == NULL) goto default_value;
if (g_strcmp0(config.color_correction_id, "disabled") == 0) {
return GB_COLOR_CORRECTION_DISABLED;
}
else if (g_strcmp0(config.color_correction_id, "correct_color_curves") == 0) {
return GB_COLOR_CORRECTION_CORRECT_CURVES;
}
else if (g_strcmp0(config.color_correction_id, "emulate_hardware") == 0) {
return GB_COLOR_CORRECTION_EMULATE_HARDWARE;
}
else if (g_strcmp0(config.color_correction_id, "preserve_brightness") == 0) {
return GB_COLOR_CORRECTION_PRESERVE_BRIGHTNESS;
}
// This should not happen
g_warning("Unknown color correction mode: %s\nFalling back to “Emulate Hardware”\n", config.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";
break;
case GB_COLOR_CORRECTION_CORRECT_CURVES:
config.color_correction_id = "correct_color_curves";
break;
case GB_COLOR_CORRECTION_EMULATE_HARDWARE:
config.color_correction_id = "emulate_hardware";
break;
case GB_COLOR_CORRECTION_PRESERVE_BRIGHTNESS:
config.color_correction_id = "preserve_brightness";
break;
}
}
GB_highpass_mode_t get_highpass_mode(void) {
if (config.high_pass_filter_id == NULL) goto default_value;
if (g_strcmp0(config.high_pass_filter_id, "disabled") == 0) {
return GB_HIGHPASS_OFF;
}
else if (g_strcmp0(config.high_pass_filter_id, "emulate_hardware") == 0) {
return GB_HIGHPASS_ACCURATE;
}
else if (g_strcmp0(config.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”\n", config.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";
break;
case GB_HIGHPASS_MAX:
g_warning("GB_HIGHPASS_MAX is not a valid highpass mode, falling back to “Accurate”.\n");
case GB_HIGHPASS_ACCURATE:
config.high_pass_filter_id = "emulate_hardware";
break;
case GB_HIGHPASS_REMOVE_DC_OFFSET:
config.high_pass_filter_id = "preserve_waveform";
2019-09-25 20:47:04 +00:00
break;
}
}