[GTK3] More work on preferences done

This commit is contained in:
Maximilian Mader 2019-09-27 23:10:28 +02:00
parent 4b15dc9cdf
commit f3f2e66faf
Signed by: Max
GPG Key ID: F71D56A3151C4FB3
6 changed files with 182 additions and 80 deletions

10
gtk3/macros.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef macros_h
#define macros_h
#define str(x) #x
#define xstr(x) str(x)
#define get_object(id) gtk_builder_get_object(builder, id)
#define gtkget(type, id) type(gtk_builder_get_object(builder, id))
#define itoa(val) g_strdup_printf("%i", val)
#endif /* macros_h */

View File

@ -6,12 +6,10 @@
#include <string.h> #include <string.h>
#include <Core/gb.h> #include <Core/gb.h>
#include "macros.h"
#include "settings.h" #include "settings.h"
#include "shader.h" #include "shader.h"
#define str(x) #x
#define xstr(x) str(x)
typedef struct UserData { typedef struct UserData {
bool fullscreen; bool fullscreen;
GFile *file; GFile *file;
@ -57,11 +55,6 @@ static uint32_t tileset_buffer[tileset_buffer_length] = {0};
static const size_t tilemap_buffer_length = 256 * 256 * 4; static const size_t tilemap_buffer_length = 256 * 256 * 4;
static uint32_t tilemap_buffer[tilemap_buffer_length] = {0}; static uint32_t tilemap_buffer[tilemap_buffer_length] = {0};
// Returns a GObject by ID from our GtkBuilder instance
static GObject *get_object(gchararray id) {
return gtk_builder_get_object(builder, id);
}
static unsigned char number_of_buffers(void) { static unsigned char number_of_buffers(void) {
bool should_blend = true; bool should_blend = true;
@ -296,11 +289,11 @@ G_MODULE_EXPORT void gl_draw() {
G_MODULE_EXPORT void gl_finish() { } G_MODULE_EXPORT void gl_finish() { }
G_MODULE_EXPORT void on_vram_viewer_realize(gpointer visible) { G_MODULE_EXPORT void on_vram_viewer_realize() {
vram_viewer_visible = true; vram_viewer_visible = true;
} }
G_MODULE_EXPORT void on_vram_viewer_unrealize(gpointer visible) { G_MODULE_EXPORT void on_vram_viewer_unrealize() {
vram_viewer_visible = false; vram_viewer_visible = false;
} }
@ -412,7 +405,19 @@ G_MODULE_EXPORT void on_rewind_duration_changed(GtkWidget *w, gpointer user_data
G_MODULE_EXPORT void on_boot_rom_location_changed(GtkWidget *w, gpointer user_data_gptr) { G_MODULE_EXPORT void on_boot_rom_location_changed(GtkWidget *w, gpointer user_data_gptr) {
GtkComboBox *box = GTK_COMBO_BOX(w); GtkComboBox *box = GTK_COMBO_BOX(w);
g_print("New value: %s\n", gtk_combo_box_get_active_id(box)); const gchar *id = gtk_combo_box_get_active_id(box);
if (g_strcmp0(id, "other") == 0) {
g_print("TODO: Open path picker\n");
update_boot_rom_selector(builder);
}
else {
config.boot_rom_path = (gchar *)id;
}
}
G_MODULE_EXPORT void on_color_menubar_override_changed(GtkWidget *w, gpointer user_data_gptr) {
config.menubar_override = (gchar *)gtk_combo_box_get_active_id(GTK_COMBO_BOX(w));
} }
// This functions gets called immediately after registration of the GApplication // This functions gets called immediately after registration of the GApplication
@ -422,18 +427,25 @@ static void startup(GApplication *app, gpointer user_data_gptr) {
builder = gtk_builder_new_from_resource(RESOURCE_PREFIX "ui/window.ui"); builder = gtk_builder_new_from_resource(RESOURCE_PREFIX "ui/window.ui");
gtk_builder_connect_signals(builder, NULL); gtk_builder_connect_signals(builder, NULL);
// Setup application actions
g_action_map_add_action_entries(G_ACTION_MAP(app), app_entries, G_N_ELEMENTS(app_entries), app); g_action_map_add_action_entries(G_ACTION_MAP(app), app_entries, G_N_ELEMENTS(app_entries), app);
GtkWindow *preferences = GTK_WINDOW(get_object("preferences")); #if NDEBUG
set_combo_box_row_separator_func(GTK_CONTAINER(preferences)); // Disable when not compiled in debug mode
g_simple_action_set_enabled(G_SIMPLE_ACTION(g_action_map_lookup_action(G_ACTION_MAP(app), "open_gtk_debugger")), false);
// Remove the menubar override
gtk_widget_destroy(gtkget(GTK_WIDGET, "menubar_override_selector_label"));
gtk_widget_destroy(gtkget(GTK_WIDGET, "menubar_override_selector"));
#endif
GtkWindow *preferences = GTK_WINDOW(get_object("preferences"));
g_signal_connect(preferences, "realize", G_CALLBACK(on_preferences_realize), (gpointer) builder);
init_settings(user_data->config_path, preferences); init_settings(user_data->config_path, preferences);
vram_viewer = GTK_WINDOW(get_object("vram_viewer")); vram_viewer = GTK_WINDOW(get_object("vram_viewer"));
set_combo_box_row_separator_func(GTK_CONTAINER(vram_viewer));
memory_viewer = GTK_WINDOW(get_object("memory_viewer")); memory_viewer = GTK_WINDOW(get_object("memory_viewer"));
set_combo_box_row_separator_func(GTK_CONTAINER(memory_viewer));
console = GTK_WINDOW(get_object("console")); console = GTK_WINDOW(get_object("console"));
printer = GTK_WINDOW(get_object("printer")); printer = GTK_WINDOW(get_object("printer"));
@ -446,6 +458,11 @@ static void startup(GApplication *app, gpointer user_data_gptr) {
gl_area = GTK_GL_AREA(gtk_gl_area_new()); gl_area = GTK_GL_AREA(gtk_gl_area_new());
gtk_gl_area_set_auto_render(gl_area, false); gtk_gl_area_set_auto_render(gl_area, false);
// Insert separators into `GtkComboBox`es
set_combo_box_row_separator_func(GTK_CONTAINER(preferences));
set_combo_box_row_separator_func(GTK_CONTAINER(vram_viewer));
set_combo_box_row_separator_func(GTK_CONTAINER(memory_viewer));
// Connect signal handlers // Connect signal handlers
g_signal_connect(gl_area, "realize", G_CALLBACK(gl_init), NULL); g_signal_connect(gl_area, "realize", G_CALLBACK(gl_init), NULL);
g_signal_connect(gl_area, "render", G_CALLBACK(gl_draw), NULL); g_signal_connect(gl_area, "render", G_CALLBACK(gl_draw), NULL);
@ -468,9 +485,10 @@ static void startup(GApplication *app, gpointer user_data_gptr) {
gtk_container_add(GTK_CONTAINER(main_window), GTK_WIDGET(gl_area)); gtk_container_add(GTK_CONTAINER(main_window), GTK_WIDGET(gl_area));
// Handle the whole menubar situation … // Handle the whole menubar situation …
GMenuModel *menubar = get_menu_model(app, "menubar");
if (show_menubar()) { if (show_menubar()) {
// Show a classic menubar // Show a classic menubar
GMenuModel *menubar = get_menu_model(app, "menubar");
gtk_application_set_menubar(GTK_APPLICATION(app), menubar); gtk_application_set_menubar(GTK_APPLICATION(app), menubar);
} }
else { else {
@ -483,8 +501,7 @@ static void startup(GApplication *app, gpointer user_data_gptr) {
// Hook menubar up to the hamburger button // Hook menubar up to the hamburger button
GtkMenuButton *hamburger_button = GTK_MENU_BUTTON(get_object("hamburger_button")); GtkMenuButton *hamburger_button = GTK_MENU_BUTTON(get_object("hamburger_button"));
GMenuModel *hamburger_menu = get_menu_model(app, "menubar"); gtk_menu_button_set_menu_model(hamburger_button, menubar);
gtk_menu_button_set_menu_model(hamburger_button, hamburger_menu);
} }
gtk_window_set_title(GTK_WINDOW(main_window), "SameBoy"); gtk_window_set_title(GTK_WINDOW(main_window), "SameBoy");

View File

@ -388,6 +388,7 @@ Author: Maximilian Mader
<item> <item>
<attribute name="label" translatable="yes">Show GTK Debugger</attribute> <attribute name="label" translatable="yes">Show GTK Debugger</attribute>
<attribute name="action">app.open_gtk_debugger</attribute> <attribute name="action">app.open_gtk_debugger</attribute>
<attribute name="hidden-when">action-disabled</attribute>
</item> </item>
</section> </section>
</submenu> </submenu>

View File

@ -318,13 +318,7 @@ Maximilian Mader https://github.com/max-m</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_top">5</property> <property name="margin_top">5</property>
<property name="margin_bottom">10</property> <property name="margin_bottom">10</property>
<property name="active">0</property> <items></items>
<property name="active_id">auto</property>
<items>
<item id="auto" translatable="yes">Use Built-in Boot ROMs</item>
<item translatable="yes">&lt;separator&gt;</item>
<item id="other" translatable="yes">Other</item>
</items>
<signal name="changed" handler="on_boot_rom_location_changed" swapped="no"/> <signal name="changed" handler="on_boot_rom_location_changed" swapped="no"/>
</object> </object>
<packing> <packing>
@ -346,13 +340,11 @@ Maximilian Mader https://github.com/max-m</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkComboBoxText"> <object class="GtkComboBoxText" id="rewind_duration_selector">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_top">5</property> <property name="margin_top">5</property>
<property name="margin_bottom">10</property> <property name="margin_bottom">10</property>
<property name="active">0</property>
<property name="active_id">10</property>
<items> <items>
<item id="10" translatable="yes">10 Seconds</item> <item id="10" translatable="yes">10 Seconds</item>
<item id="30" translatable="yes">30 Seconds</item> <item id="30" translatable="yes">30 Seconds</item>
@ -394,13 +386,12 @@ Maximilian Mader https://github.com/max-m</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkComboBox"> <object class="GtkComboBox" id="dmg_revision_selector">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_top">5</property> <property name="margin_top">5</property>
<property name="margin_bottom">10</property> <property name="margin_bottom">10</property>
<property name="model">dmg_models</property> <property name="model">dmg_models</property>
<property name="active">3</property>
<property name="id_column">0</property> <property name="id_column">0</property>
<signal name="changed" handler="on_dmg_model_changed" swapped="no"/> <signal name="changed" handler="on_dmg_model_changed" swapped="no"/>
<child> <child>
@ -431,13 +422,11 @@ Maximilian Mader https://github.com/max-m</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkComboBoxText"> <object class="GtkComboBoxText" id="sgb_revision_selector">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_top">5</property> <property name="margin_top">5</property>
<property name="margin_bottom">10</property> <property name="margin_bottom">10</property>
<property name="active">0</property>
<property name="active_id">SGB1_NTSC</property>
<items> <items>
<item id="SGB1_NTSC" translatable="yes">Super Game Boy (NTSC)</item> <item id="SGB1_NTSC" translatable="yes">Super Game Boy (NTSC)</item>
<item id="SGB1_PAL" translatable="yes">Super Game Boy (PAL)</item> <item id="SGB1_PAL" translatable="yes">Super Game Boy (PAL)</item>
@ -464,13 +453,12 @@ Maximilian Mader https://github.com/max-m</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkComboBox"> <object class="GtkComboBox" id="cgb_revision_selector">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_top">5</property> <property name="margin_top">5</property>
<property name="margin_bottom">10</property> <property name="margin_bottom">10</property>
<property name="model">cgb_models</property> <property name="model">cgb_models</property>
<property name="active">5</property>
<property name="id_column">0</property> <property name="id_column">0</property>
<signal name="changed" handler="on_cgb_model_changed" swapped="no"/> <signal name="changed" handler="on_cgb_model_changed" swapped="no"/>
<child> <child>
@ -548,13 +536,11 @@ Maximilian Mader https://github.com/max-m</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkComboBoxText"> <object class="GtkComboBoxText" id="shader_selector">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_top">5</property> <property name="margin_top">5</property>
<property name="margin_bottom">10</property> <property name="margin_bottom">10</property>
<property name="active">0</property>
<property name="active_id">nearest_neighbour</property>
<items> <items>
<item id="NearestNeighbor" 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>
@ -591,13 +577,11 @@ Maximilian Mader https://github.com/max-m</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkComboBoxText"> <object class="GtkComboBoxText" id="color_correction_selector">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_top">5</property> <property name="margin_top">5</property>
<property name="margin_bottom">10</property> <property name="margin_bottom">10</property>
<property name="active">2</property>
<property name="active_id">emulate_hardware</property>
<items> <items>
<item id="disabled" translatable="yes">Disabled</item> <item id="disabled" translatable="yes">Disabled</item>
<item id="correct_color_curves" translatable="yes">Correct Color Curves</item> <item id="correct_color_curves" translatable="yes">Correct Color Curves</item>
@ -613,14 +597,30 @@ Maximilian Mader https://github.com/max-m</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkCheckButton"> <object class="GtkCheckButton" id="aspect_ratio_toggle">
<property name="label" translatable="yes">Keep Aspect Ratio</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="draw_indicator">True</property>
<signal name="toggled" handler="on_keep_aspect_ratio_changed" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="integer_scaling_toggle">
<property name="label" translatable="yes">Use Integer Scaling</property> <property name="label" translatable="yes">Use Integer Scaling</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="margin_top">5</property> <property name="margin_top">5</property>
<property name="margin_bottom">10</property> <property name="margin_bottom">10</property>
<property name="active">True</property>
<property name="draw_indicator">True</property> <property name="draw_indicator">True</property>
<signal name="toggled" handler="on_use_integer_scaling_changed" swapped="no"/> <signal name="toggled" handler="on_use_integer_scaling_changed" swapped="no"/>
</object> </object>
@ -631,21 +631,32 @@ Maximilian Mader https://github.com/max-m</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkCheckButton"> <object class="GtkLabel" id="menubar_override_selector_label">
<property name="label" translatable="yes">Keep Aspect Ratio</property> <property name="visible">False</property>
<property name="visible">True</property> <property name="can_focus">False</property>
<property name="can_focus">True</property> <property name="label" translatable="yes">Main Menu Override</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_keep_aspect_ratio_changed" swapped="no"/>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="position">4</property> <property name="position">6</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="menubar_override_selector">
<property name="visible">False</property>
<property name="can_focus">False</property>
<items>
<item id="auto" translatable="yes">Automatic</item>
<item id="show" translatable="yes">Force Menubar</item>
<item id="hide" translatable="yes">Force Hamburger Menu</item>
</items>
<signal name="changed" handler="on_color_menubar_override_changed" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">7</property>
</packing> </packing>
</child> </child>
</object> </object>
@ -712,12 +723,11 @@ Maximilian Mader https://github.com/max-m</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkComboBoxText"> <object class="GtkComboBoxText" id="highpass_filter_selector">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_top">5</property> <property name="margin_top">5</property>
<property name="margin_bottom">10</property> <property name="margin_bottom">10</property>
<property name="active">0</property>
<items> <items>
<item id="disabled" translatable="yes">Disabled (Keep DC Offset)</item> <item id="disabled" translatable="yes">Disabled (Keep DC Offset)</item>
<item id="emulate_hardware" translatable="yes">Accurate (Emulate Hardware)</item> <item id="emulate_hardware" translatable="yes">Accurate (Emulate Hardware)</item>
@ -806,7 +816,6 @@ Maximilian Mader https://github.com/max-m</property>
<property name="margin_left">5</property> <property name="margin_left">5</property>
<property name="margin_right">5</property> <property name="margin_right">5</property>
<property name="active">0</property> <property name="active">0</property>
<property name="active_id">0</property>
<items> <items>
<item id="0" translatable="yes">Player 1</item> <item id="0" translatable="yes">Player 1</item>
<item id="1" translatable="yes">Player 2</item> <item id="1" translatable="yes">Player 2</item>
@ -873,7 +882,6 @@ Maximilian Mader https://github.com/max-m</property>
<property name="margin_top">5</property> <property name="margin_top">5</property>
<property name="margin_bottom">10</property> <property name="margin_bottom">10</property>
<property name="active">0</property> <property name="active">0</property>
<property name="active_id">none</property>
<items> <items>
<item id="none" translatable="yes">None</item> <item id="none" translatable="yes">None</item>
</items> </items>
@ -1098,6 +1106,19 @@ Maximilian Mader https://github.com/max-m</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="shadow_type">in</property> <property name="shadow_type">in</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkDrawingArea" id="printer_canvas">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
</object>
</child>
</object> </object>
</child> </child>
</object> </object>

View File

@ -13,7 +13,7 @@ void print_config(config_t *config) {
g_print("[%s]\n", #group_name); \ g_print("[%s]\n", #group_name); \
members members
#define EXPAND_GROUP_MEMBER(member, key_type) \ #define EXPAND_GROUP_MEMBER(member, key_type, default_value) \
g_print("%s="FORMAT_FOR_KEY_TYPE(key_type)"\n", #member, config->member); g_print("%s="FORMAT_FOR_KEY_TYPE(key_type)"\n", #member, config->member);
EXPAND_CONFIG EXPAND_CONFIG
@ -33,10 +33,13 @@ void load_config_from_key_file(config_t *config, GKeyFile *key_file) {
members \ members \
} }
#define EXPAND_GROUP_MEMBER(member, key_type) \ #define EXPAND_GROUP_MEMBER(member, key_type, default_value) \
config->member = g_key_file_get_##key_type(key_file, group_name, #member, &error); \ 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); config->member = default_value; \
print_config_error(error); \
g_clear_error(&error); \
}
EXPAND_CONFIG EXPAND_CONFIG
@ -57,10 +60,10 @@ void save_config_to_key_file(config_t *config, GKeyFile *key_file) {
group_name = #name; \ group_name = #name; \
members members
#define EXPAND_GROUP_MEMBER_IF_0(member, key_type) \ #define EXPAND_GROUP_MEMBER_IF_0(member, key_type, default_value) \
g_key_file_set_##key_type(key_file, group_name, #member, config->member); g_key_file_set_##key_type(key_file, group_name, #member, config->member);
#define EXPAND_GROUP_MEMBER_IF_1(member, key_type) \ #define EXPAND_GROUP_MEMBER_IF_1(member, key_type, default_value) \
if (config->member != NULL) { \ if (config->member != NULL) { \
g_key_file_set_##key_type(key_file, group_name, #member, config->member); \ g_key_file_set_##key_type(key_file, group_name, #member, config->member); \
} \ } \
@ -76,9 +79,9 @@ void save_config_to_key_file(config_t *config, GKeyFile *key_file) {
} \ } \
} }
#define EXPAND_GROUP_MEMBER_IF_EVAL(y, member, key_type) EXPAND_GROUP_MEMBER_IF_ ## y(member, key_type) #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) EXPAND_GROUP_MEMBER_IF_EVAL(is_pointer, member, key_type) #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) EXPAND_GROUP_MEMBER_IF(member, key_type, GTYPE_IS_POINTER(key_type)) #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 EXPAND_CONFIG
@ -90,6 +93,33 @@ void save_config_to_key_file(config_t *config, GKeyFile *key_file) {
#undef EXPAND_GROUP_MEMBER_IF_1 #undef EXPAND_GROUP_MEMBER_IF_1
} }
G_MODULE_EXPORT void on_preferences_realize(GtkWidget *w, gpointer builder_ptr) {
GtkWindow *preferences = GTK_WINDOW(w);
GtkBuilder *builder = (GtkBuilder *) builder_ptr;
update_boot_rom_selector(builder);
// Hook up the static preferences
gtk_combo_box_set_active_id(gtkget(GTK_COMBO_BOX, "rewind_duration_selector"), itoa(config.rewind_duration));
gtk_combo_box_set_active_id(gtkget(GTK_COMBO_BOX, "dmg_revision_selector"), config.dmg_revision_name);
gtk_combo_box_set_active_id(gtkget(GTK_COMBO_BOX, "sgb_revision_selector"), config.sgb_revision_name);
gtk_combo_box_set_active_id(gtkget(GTK_COMBO_BOX, "cgb_revision_selector"), config.cgb_revision_name);
gtk_combo_box_set_active_id(gtkget(GTK_COMBO_BOX, "shader_selector"), config.shader);
gtk_combo_box_set_active_id(gtkget(GTK_COMBO_BOX, "color_correction_selector"), config.color_correction_id);
gtk_toggle_button_set_active(gtkget(GTK_TOGGLE_BUTTON, "integer_scaling_toggle"), config.use_integer_scaling);
gtk_toggle_button_set_active(gtkget(GTK_TOGGLE_BUTTON, "aspect_ratio_toggle"), config.keep_aspect_ratio);
gtk_combo_box_set_active_id(gtkget(GTK_COMBO_BOX, "highpass_filter_selector"), config.high_pass_filter_id);
#if ! NDEBUG
gtk_combo_box_set_active_id(gtkget(GTK_COMBO_BOX, "menubar_override_selector"), config.menubar_override);
#else
if (gtkget(GTK_COMBO_BOX, "menubar_override_selector") != NULL) {
gtk_widget_destroy(GTK_WIDGET(gtkget(GTK_COMBO_BOX, "menubar_override_selector")));
gtk_widget_destroy(GTK_WIDGET(gtkget(GTK_COMBO_BOX, "menubar_override_selector_label")));
}
#endif
}
void init_settings(gchar *path, GtkWindow *preferences) { void init_settings(gchar *path, GtkWindow *preferences) {
free_settings(); free_settings();
key_file = g_key_file_new(); key_file = g_key_file_new();
@ -148,6 +178,19 @@ void free_settings(void) {
} }
} }
void update_boot_rom_selector(GtkBuilder *builder) {
GtkComboBoxText *combo_box = gtkget(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");
gtk_combo_box_set_active_id(GTK_COMBO_BOX(combo_box), "auto");
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);
}
gtk_combo_box_text_append_text(combo_box, "<separator>");
gtk_combo_box_text_append(combo_box, "other", "Other");
}
enum menubar_override get_show_menubar(void) { enum menubar_override get_show_menubar(void) {
if (config.menubar_override == NULL) goto default_value; if (config.menubar_override == NULL) goto default_value;

View File

@ -3,6 +3,7 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <Core/gb.h> #include <Core/gb.h>
#include "macros.h"
#define SETTINGS_FILE "sameboy-gtk3-settings.ini" #define SETTINGS_FILE "sameboy-gtk3-settings.ini"
@ -22,23 +23,28 @@
#define GTYPE_IS_POINTER_boolean 0 #define GTYPE_IS_POINTER_boolean 0
// Note: Make sure to use a member name only once for the whole config struct // 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 \ #define EXPAND_CONFIG \
EXPAND_GROUP(Emulation, \ EXPAND_GROUP(Emulation, \
EXPAND_GROUP_MEMBER(boot_rom_path, string) /* overrides search location for boot ROMs by name */ \ EXPAND_GROUP_MEMBER(boot_rom_path, string, "auto") /* overrides search location for boot ROMs by name */ \
EXPAND_GROUP_MEMBER(rewind_duration, integer) \ EXPAND_GROUP_MEMBER(rewind_duration, integer, 0) \
EXPAND_GROUP_MEMBER(dmg_revision_name, string) \ EXPAND_GROUP_MEMBER(dmg_revision_name, string, "DMG_CPU_C") \
EXPAND_GROUP_MEMBER(sgb_revision_name, string) \ EXPAND_GROUP_MEMBER(sgb_revision_name, string, "SGB2") \
EXPAND_GROUP_MEMBER(cgb_revision_name, string) \ EXPAND_GROUP_MEMBER(cgb_revision_name, string, "CPU_CGB_E") \
) \ ) \
EXPAND_GROUP(Video, \ EXPAND_GROUP(Video, \
EXPAND_GROUP_MEMBER(shader, string) \ EXPAND_GROUP_MEMBER(shader, string, "NearestNeighbour") \
EXPAND_GROUP_MEMBER(color_correction_id, string) \ EXPAND_GROUP_MEMBER(color_correction_id, string, "emulate_hardware") \
EXPAND_GROUP_MEMBER(keep_aspect_ratio, boolean) \ EXPAND_GROUP_MEMBER(keep_aspect_ratio, boolean, true) \
EXPAND_GROUP_MEMBER(use_integer_scaling, boolean) \ EXPAND_GROUP_MEMBER(use_integer_scaling, boolean, true) \
EXPAND_GROUP_MEMBER(menubar_override, string) \ EXPAND_GROUP_MEMBER(menubar_override, string, "auto") \
) \ ) \
EXPAND_GROUP(Audio, \ EXPAND_GROUP(Audio, \
EXPAND_GROUP_MEMBER(high_pass_filter_id, string) \ EXPAND_GROUP_MEMBER(high_pass_filter_id, string, "emulate_hardware") \
) \ ) \
EXPAND_GROUP(Controls, \ EXPAND_GROUP(Controls, \
\ \
@ -46,7 +52,7 @@
typedef struct config_t { typedef struct config_t {
#define EXPAND_GROUP(group_name, members) members #define EXPAND_GROUP(group_name, members) members
#define EXPAND_GROUP_MEMBER(member, key_type) GTYPE_OF_KEY_TYPE(key_type) member; #define EXPAND_GROUP_MEMBER(member, key_type, default_value) GTYPE_OF_KEY_TYPE(key_type) member;
EXPAND_CONFIG EXPAND_CONFIG
#undef EXPAND_GROUP #undef EXPAND_GROUP
#undef EXPAND_GROUP_MEMBER #undef EXPAND_GROUP_MEMBER
@ -62,6 +68,8 @@ gchar* settings_file_path;
GKeyFile *key_file; GKeyFile *key_file;
config_t config; config_t config;
G_MODULE_EXPORT void on_preferences_realize(GtkWidget *w, gpointer builder_ptr);
void print_config(config_t *config); void print_config(config_t *config);
void load_config_from_key_file(config_t *config, GKeyFile *key_file); void load_config_from_key_file(config_t *config, GKeyFile *key_file);
@ -70,6 +78,8 @@ int load_settings(void);
void save_settings(void); void save_settings(void);
void free_settings(void); void free_settings(void);
void update_boot_rom_selector(GtkBuilder *builder);
enum menubar_override get_show_menubar(void); enum menubar_override get_show_menubar(void);
void set_show_menubar(enum menubar_override); void set_show_menubar(enum menubar_override);