From 89080ef47e9eafd19647c5f601b02d664b572d68 Mon Sep 17 00:00:00 2001 From: Maximilian Mader Date: Thu, 30 Apr 2020 04:53:45 +0200 Subject: [PATCH] [GTK3] Move loose state variables into GuiData struct --- gtk3/macros.h | 11 - gtk3/main.c | 763 +++++++++++++++++++++++++----------------------- gtk3/settings.c | 7 +- gtk3/settings.h | 1 - 4 files changed, 400 insertions(+), 382 deletions(-) delete mode 100644 gtk3/macros.h diff --git a/gtk3/macros.h b/gtk3/macros.h deleted file mode 100644 index d02ef7a..0000000 --- a/gtk3/macros.h +++ /dev/null @@ -1,11 +0,0 @@ -#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 builder_get(type, id) type(gtk_builder_get_object(builder, id)) -#define action_set_enabled(map, name, value) g_simple_action_set_enabled(G_SIMPLE_ACTION(g_action_map_lookup_action(G_ACTION_MAP(map), name)), value); -#define itoa(val) g_strdup_printf("%i", val) - -#endif /* macros_h */ diff --git a/gtk3/main.c b/gtk3/main.c index 1b0b313..3d1df2e 100644 --- a/gtk3/main.c +++ b/gtk3/main.c @@ -8,7 +8,6 @@ #include #include -#include "macros.h" #include "settings.h" #include "shader.h" @@ -28,100 +27,131 @@ #define BUTTON_MASK_LEFT 0x40 #define BUTTON_MASK_RIGHT 0x80 -typedef struct GuiData { - struct CliOptionData { - gchar *config_path; - gchar *boot_rom_path; - gboolean fullscreen; - GB_model_t model; - gchar *prefix; - } cli_options; +#define tileset_buffer_length 256 * 192 * 4 +#define tilemap_buffer_length 256 * 256 * 4 - GFile *file; - gint sample_rate; - - bool stopped; - GB_model_t prev_model; -} GuiData; +#define str(x) #x +#define xstr(x) str(x) +#define get_object(id) gtk_builder_get_object(gui_data.builder, id) +#define builder_get(type, id) type(get_object(id)) +#define action_set_enabled(map, name, value) g_simple_action_set_enabled(G_SIMPLE_ACTION(g_action_map_lookup_action(G_ACTION_MAP(map), name)), value); typedef struct{ int16_t x, y; uint16_t w, h; } Rect; -typedef struct LogData { - GB_gameboy_t *gb; - const char *string; - GB_log_attributes attributes; -} LogData; +typedef struct GuiData { + struct CliOptionData { + gchar *config_path; + gchar *boot_rom_path; + gchar *prefix; + gboolean fullscreen; + GB_model_t model; + } cli_options; -static SDL_GameController *controller = NULL; + GFile *file; + gint sample_rate; -static const GThread *main_thread; + GB_model_t prev_model; -static GtkApplication *main_application; -static GtkBuilder *builder; -static GtkGLArea *gl_area; -static GtkDrawingArea *fallback_canvas; + const GThread *main_thread; + volatile bool running; + volatile bool stopping; + volatile bool stopped; -static GtkApplicationWindow *main_window; -static GtkBox *main_window_container; -static GtkWindow *preferences; -static GtkWindow *vram_viewer; -static GtkWindow *memory_viewer; -static GtkWindow *console; -static GtkWindow *printer; + // Input + SDL_GameController *controller; + uint8_t pressed_buttons; -static shader_t shader; + // GTK pointers + GtkApplication *main_application; + GtkBuilder *builder; + GtkApplicationWindow *main_window; + GtkBox *main_window_container; + GtkGLArea *gl_area; + GtkDrawingArea *fallback_canvas; + GtkWindow *preferences; + GtkWindow *vram_viewer; + GtkWindow *memory_viewer; + GtkWindow *console; + GtkWindow *printer; -static GuiData gui_data = { { NULL }, NULL }; -static GB_gameboy_t gb; -static uint32_t *image_buffers[3]; -static unsigned char current_buffer; + // Debugger state + GtkTextBuffer *pending_console_output; + gboolean in_sync_input; + gchar *last_console_input; + gboolean log_to_sidebar; + gboolean should_clear_sidebar; + GMutex debugger_input_mutex; + GCond debugger_input_cond; + GRecMutex console_output_lock; + GPtrArray *debugger_input_queue; + bool vram_viewer_visible; + bool vram_viewer_updating; + gchar *vram_viewer_active_tab; + gboolean vram_viewer_is_cgb; + uint8_t vram_viewer_palette_data[16][0x40]; + GB_oam_info_t oam_info[40]; + uint16_t oam_count; + uint8_t oam_height; + uint32_t tileset_buffer[tileset_buffer_length]; + uint32_t tilemap_buffer[tilemap_buffer_length]; + GMutex tileset_buffer_mutex; + GMutex tilemap_buffer_mutex; + Rect scroll_rect; -static bool supports_gl; -static bool is_fullscreen; + // Audio and video + bool audio_initialized; + uint32_t *image_buffers[3]; + unsigned char current_buffer; + Rect viewport; + bool border_mode_changed; + bool is_fullscreen; + bool supports_gl; + shader_t shader; -static bool underclock_down = false, rewind_down = false, do_rewind = false, rewind_paused = false, turbo_down = false; -static double clock_mutliplier = 1.0; -static char *battery_save_path_ptr; -static Rect viewport = {0}; -static Rect scrollRect = {0}; -static bool vram_viewer_visible = false; -static bool vram_viewer_updating = false; -static gchar *vram_viewer_active_tab = ""; -static gboolean vram_viewer_is_cgb = false; -static uint8_t vram_viewer_palette_data[16][0x40]; -static bool border_mode_changed = false; -static bool audio_initialized = false; + // Fast forward / slow motion + bool underclock_down; + bool rewind_down; + bool do_rewind; + bool rewind_paused; + bool turbo_down; + double clock_mutliplier; +} GuiData; -static volatile bool running = false; -static volatile bool stopping = false; +// Initialize the GuiData +static GuiData gui_data = { + .cli_options = { + .fullscreen = false, + .model = -1, + }, -#define tileset_buffer_length 256 * 192 * 4 -static uint32_t tileset_buffer[tileset_buffer_length] = {0}; -static GMutex tileset_buffer_mutex; + .prev_model = -1, -#define tilemap_buffer_length 256 * 256 * 4 -static uint32_t tilemap_buffer[tilemap_buffer_length] = {0}; -static GMutex tilemap_buffer_mutex; + .running = false, + .stopping = false, + .stopped = false, -static GB_oam_info_t oamInfo[40]; -static uint16_t oamCount; -static uint8_t oamHeight; + .in_sync_input = false, + .log_to_sidebar = false, + .should_clear_sidebar = false, -static uint8_t pressed_buttons; + .vram_viewer_visible = false, + .vram_viewer_updating = false, + .vram_viewer_active_tab = "", + .vram_viewer_is_cgb = false, -static GtkTextBuffer *pending_console_output = NULL; -static gboolean in_sync_input = false; -static gchar *last_console_input = NULL; -static gboolean log_to_sidebar = false; -static gboolean should_clear_sidebar = false; + .audio_initialized = false, + .border_mode_changed = false, -static GMutex debugger_input_mutex; -static GCond debugger_input_cond; -static GRecMutex console_output_lock; -static GPtrArray *debugger_input_queue; + .underclock_down = false, + .rewind_down = false, + .rewind_paused = false, + .turbo_down = false, + .clock_mutliplier = 1.0, +}; +GB_gameboy_t gb; // Forward declarations of the actions static void activate_open(GSimpleAction *action, GVariant *parameter, gpointer app); @@ -364,8 +394,8 @@ static gboolean init_controllers(void) { // Open the first available controller for (int i = 0; i < SDL_NumJoysticks(); ++i) { if (SDL_IsGameController(i)) { - controller = SDL_GameControllerOpen(i); - if (controller) { + gui_data.controller = SDL_GameControllerOpen(i); + if (gui_data.controller) { break; } else { @@ -380,8 +410,9 @@ static gboolean init_controllers(void) { static gboolean init_audio(void) { bool audio_playing = GB_audio_is_playing(); - if (audio_initialized) { + if (gui_data.audio_initialized) { GB_audio_destroy(); + gui_data.audio_initialized = false; } #ifdef USE_SDL_AUDIO @@ -397,7 +428,7 @@ static gboolean init_audio(void) { // restore playing state GB_audio_set_paused(!audio_playing); - return audio_initialized = true; + return gui_data.audio_initialized = true; } static GB_model_t get_model(void) { @@ -405,7 +436,7 @@ static GB_model_t get_model(void) { return gui_data.cli_options.model; } - GAction *action = g_action_map_lookup_action(G_ACTION_MAP(main_application), "change_model"); + GAction *action = g_action_map_lookup_action(G_ACTION_MAP(gui_data.main_application), "change_model"); GVariant *value = g_action_get_state(action); const gchar *family = g_variant_get_string(value, NULL); @@ -423,7 +454,7 @@ static GB_model_t get_model(void) { } static void gb_audio_callback(GB_gameboy_t *gb, GB_sample_t *sample) { - if (turbo_down) { + if (gui_data.turbo_down) { static unsigned skip = 0; skip++; @@ -465,20 +496,20 @@ static gboolean scroll_to_bottom(GtkTextView *textview, GtkTextMark *mark) { } static void append_pending_output(void) { - g_rec_mutex_lock(&console_output_lock); + g_rec_mutex_lock(&gui_data.console_output_lock); - if (should_clear_sidebar) { + if (gui_data.should_clear_sidebar) { clear_sidebar(); - should_clear_sidebar = false; + gui_data.should_clear_sidebar = false; } - if (gtk_text_buffer_get_char_count(pending_console_output) > 0) { - GtkTextView *text_view = builder_get(GTK_TEXT_VIEW, log_to_sidebar? "console_sidebar_output" : "console_screen"); + if (gtk_text_buffer_get_char_count(gui_data.pending_console_output) > 0) { + GtkTextView *text_view = builder_get(GTK_TEXT_VIEW, gui_data.log_to_sidebar? "console_sidebar_output" : "console_screen"); GtkTextBuffer *text_buf = gtk_text_view_get_buffer(text_view); GtkTextIter start; GtkTextIter end; - gtk_text_buffer_get_start_iter(pending_console_output, &start); - gtk_text_buffer_get_end_iter(pending_console_output, &end); + gtk_text_buffer_get_start_iter(gui_data.pending_console_output, &start); + gtk_text_buffer_get_end_iter(gui_data.pending_console_output, &end); GtkTextIter iter; gtk_text_buffer_get_end_iter(text_buf, &iter); @@ -486,10 +517,10 @@ static void append_pending_output(void) { scroll_to_bottom(text_view, gtk_text_buffer_create_mark(text_buf, NULL, &iter, true)); - gtk_text_buffer_set_text(pending_console_output, "", -1); + gtk_text_buffer_set_text(gui_data.pending_console_output, "", -1); } - g_rec_mutex_unlock(&console_output_lock); + g_rec_mutex_unlock(&gui_data.console_output_lock); } static void update_debugger_sidebar(GB_gameboy_t *gb) { @@ -497,16 +528,16 @@ static void update_debugger_sidebar(GB_gameboy_t *gb) { return; } - if (main_thread != g_thread_self()) { + if (gui_data.main_thread != g_thread_self()) { g_idle_add((GSourceFunc) update_debugger_sidebar, gb); return; } - g_rec_mutex_lock(&console_output_lock); - should_clear_sidebar = true; + g_rec_mutex_lock(&gui_data.console_output_lock); + gui_data.should_clear_sidebar = true; append_pending_output(); - log_to_sidebar = true; - g_rec_mutex_unlock(&console_output_lock); + gui_data.log_to_sidebar = true; + g_rec_mutex_unlock(&gui_data.console_output_lock); GtkTextView *sidebar_input = builder_get(GTK_TEXT_VIEW, "console_sidebar_input"); GtkTextBuffer *sidebar_input_text_buf = gtk_text_view_get_buffer(sidebar_input); @@ -544,43 +575,43 @@ static void update_debugger_sidebar(GB_gameboy_t *gb) { g_free(cmd); } - g_rec_mutex_lock(&console_output_lock); + g_rec_mutex_lock(&gui_data.console_output_lock); append_pending_output(); - log_to_sidebar = false; - g_rec_mutex_unlock(&console_output_lock); + gui_data.log_to_sidebar = false; + g_rec_mutex_unlock(&gui_data.console_output_lock); } static void console_log(GB_gameboy_t *gb, const char *string, GB_log_attributes attributes) { - g_rec_mutex_lock(&console_output_lock); + g_rec_mutex_lock(&gui_data.console_output_lock); if (string != NULL && !g_str_equal("", string)) { GtkTextIter iter; GtkTextIter start; - // Append attributed text to "pending_console_output" GtkTextBuffer - gtk_text_buffer_get_end_iter(pending_console_output, &iter); - GtkTextMark *start_mark = gtk_text_buffer_create_mark(pending_console_output, NULL, &iter, true); - gtk_text_buffer_insert(pending_console_output, &iter, g_strdup(string), -1); - gtk_text_buffer_get_iter_at_mark(pending_console_output, &start, start_mark); + // Append attributed text to "gui_data.pending_console_output" GtkTextBuffer + gtk_text_buffer_get_end_iter(gui_data.pending_console_output, &iter); + GtkTextMark *start_mark = gtk_text_buffer_create_mark(gui_data.pending_console_output, NULL, &iter, true); + gtk_text_buffer_insert(gui_data.pending_console_output, &iter, g_strdup(string), -1); + gtk_text_buffer_get_iter_at_mark(gui_data.pending_console_output, &start, start_mark); if (attributes & GB_LOG_BOLD) { - gtk_text_buffer_apply_tag_by_name(pending_console_output, "bold", &start, &iter); + gtk_text_buffer_apply_tag_by_name(gui_data.pending_console_output, "bold", &start, &iter); } if (attributes & GB_LOG_DASHED_UNDERLINE) { - gtk_text_buffer_apply_tag_by_name(pending_console_output, "dashed_underline", &start, &iter); + gtk_text_buffer_apply_tag_by_name(gui_data.pending_console_output, "dashed_underline", &start, &iter); } if (attributes & GB_LOG_UNDERLINE) { - gtk_text_buffer_apply_tag_by_name(pending_console_output, "underline", &start, &iter); + gtk_text_buffer_apply_tag_by_name(gui_data.pending_console_output, "underline", &start, &iter); } - gtk_text_buffer_delete_mark(pending_console_output, start_mark); + gtk_text_buffer_delete_mark(gui_data.pending_console_output, start_mark); g_idle_add((GSourceFunc) append_pending_output, NULL); } - g_rec_mutex_unlock(&console_output_lock); + g_rec_mutex_unlock(&gui_data.console_output_lock); } // Console TODO: @@ -591,20 +622,20 @@ static void console_log(GB_gameboy_t *gb, const char *string, GB_log_attributes static char *sync_console_input(GB_gameboy_t *gb) { update_debugger_sidebar(gb); console_log(gb, "> ", 0); - in_sync_input = true; + gui_data.in_sync_input = true; - g_mutex_lock(&debugger_input_mutex); - g_cond_wait(&debugger_input_cond, &debugger_input_mutex); + g_mutex_lock(&gui_data.debugger_input_mutex); + g_cond_wait(&gui_data.debugger_input_cond, &gui_data.debugger_input_mutex); gchar *input = NULL; - const gchar *_input = g_ptr_array_index(debugger_input_queue, 0); + const gchar *_input = g_ptr_array_index(gui_data.debugger_input_queue, 0); input = g_strdup(_input); - gpointer ptr = g_ptr_array_remove_index(debugger_input_queue, 0); + gpointer ptr = g_ptr_array_remove_index(gui_data.debugger_input_queue, 0); if (ptr) g_free(ptr); - g_mutex_unlock(&debugger_input_mutex); + g_mutex_unlock(&gui_data.debugger_input_mutex); - in_sync_input = false; + gui_data.in_sync_input = false; return input; } @@ -613,19 +644,19 @@ static char *async_console_input(GB_gameboy_t *gb) { // TODO: This is rather ugly g_idle_add((GSourceFunc) clear_sidebar, NULL); - if (debugger_input_queue->len == 0) return NULL; + if (gui_data.debugger_input_queue->len == 0) return NULL; - g_mutex_lock(&debugger_input_mutex); + g_mutex_lock(&gui_data.debugger_input_mutex); gchar *input = NULL; - const gchar *_input = g_ptr_array_index(debugger_input_queue, 0); + const gchar *_input = g_ptr_array_index(gui_data.debugger_input_queue, 0); if (_input) { input = g_strdup(_input); - gpointer ptr = g_ptr_array_remove_index(debugger_input_queue, 0); + gpointer ptr = g_ptr_array_remove_index(gui_data.debugger_input_queue, 0); if (ptr) g_free(ptr); } - g_mutex_unlock(&debugger_input_mutex); + g_mutex_unlock(&gui_data.debugger_input_mutex); return input; } @@ -698,7 +729,7 @@ static void setup_menu(GApplication *app) { case MENUBAR_SHOW_IN_WINDOW: { g_debug("Showing menu in the window"); GtkMenuBar *menubar = GTK_MENU_BAR(gtk_menu_bar_new_from_model(menubar_model)); - gtk_box_pack_start(GTK_BOX(main_window_container), GTK_WIDGET(menubar), false, false, 0); + gtk_box_pack_start(GTK_BOX(gui_data.main_window_container), GTK_WIDGET(menubar), false, false, 0); break; } @@ -706,8 +737,8 @@ static void setup_menu(GApplication *app) { g_debug("Showing hamburger"); // Attach a custom title bar GtkWidget *titlebar = builder_get(GTK_WIDGET, "main_header_bar"); - gtk_header_bar_set_title(GTK_HEADER_BAR(titlebar), gtk_window_get_title(GTK_WINDOW(main_window))); - gtk_window_set_titlebar(GTK_WINDOW(main_window), titlebar); + gtk_header_bar_set_title(GTK_HEADER_BAR(titlebar), gtk_window_get_title(GTK_WINDOW(gui_data.main_window))); + gtk_window_set_titlebar(GTK_WINDOW(gui_data.main_window), titlebar); // Disable menubar gtk_application_set_menubar(GTK_APPLICATION(app), NULL); @@ -752,7 +783,7 @@ static void set_combo_box_row_separator_func(GtkContainer *container) { // Determines how many frame buffers to use static unsigned char number_of_buffers(void) { - if (fallback_canvas) return 2; + if (gui_data.fallback_canvas) return 2; bool should_blend = get_frame_blending_mode() != GB_FRAME_BLENDING_MODE_DISABLED; @@ -761,22 +792,22 @@ static unsigned char number_of_buffers(void) { // Returns the buffer that should be used by the Core to render a new frame to static uint32_t *get_pixels(void) { - return image_buffers[(current_buffer + 1) % number_of_buffers()]; + return gui_data.image_buffers[(gui_data.current_buffer + 1) % number_of_buffers()]; } // Returns the current finished frame static uint32_t *get_current_buffer(void) { - return image_buffers[current_buffer]; + return gui_data.image_buffers[gui_data.current_buffer]; } // Returns the previous finished frame static uint32_t *get_previous_buffer(void) { - return image_buffers[(current_buffer + 2) % number_of_buffers()]; + return gui_data.image_buffers[(gui_data.current_buffer + 2) % number_of_buffers()]; } // Cycles the buffers static void flip(void) { - current_buffer = (current_buffer + 1) % number_of_buffers(); + gui_data.current_buffer = (gui_data.current_buffer + 1) % number_of_buffers(); } // WHY DO WE NEED SUCH AN UGLY METHOD, GTK?! @@ -786,7 +817,7 @@ static void action_entries_set_enabled(const GActionEntry *entries, unsigned n_e const GActionEntry *entry = &entries[i]; if (entry->name == NULL) continue; - action_set_enabled(main_application, entry->name, value); + action_set_enabled(gui_data.main_application, entry->name, value); } } @@ -797,27 +828,27 @@ static void update_window_geometry(void) { hints.min_height = GB_get_screen_height(&gb); gtk_window_set_geometry_hints( - GTK_WINDOW(main_window), + GTK_WINDOW(gui_data.main_window), NULL, &hints, (GdkWindowHints)(GDK_HINT_MIN_SIZE) ); - gtk_window_resize(GTK_WINDOW(main_window), + gtk_window_resize(GTK_WINDOW(gui_data.main_window), GB_get_screen_width(&gb) * 2, GB_get_screen_height(&gb) * 2 ); // Setup our image buffers - if (image_buffers[0]) g_free(image_buffers[0]); - if (image_buffers[1]) g_free(image_buffers[1]); - if (image_buffers[2]) g_free(image_buffers[2]); + if (gui_data.image_buffers[0]) g_free(gui_data.image_buffers[0]); + if (gui_data.image_buffers[1]) g_free(gui_data.image_buffers[1]); + if (gui_data.image_buffers[2]) g_free(gui_data.image_buffers[2]); - size_t buffer_size = sizeof(image_buffers[0][0]) * GB_get_screen_width(&gb) * GB_get_screen_height(&gb); + size_t buffer_size = sizeof(gui_data.image_buffers[0][0]) * GB_get_screen_width(&gb) * GB_get_screen_height(&gb); - image_buffers[0] = g_malloc0(buffer_size); - image_buffers[1] = g_malloc0(buffer_size); - image_buffers[2] = g_malloc0(buffer_size); + gui_data.image_buffers[0] = g_malloc0(buffer_size); + gui_data.image_buffers[1] = g_malloc0(buffer_size); + gui_data.image_buffers[2] = g_malloc0(buffer_size); if (GB_is_inited(&gb)) { GB_set_pixels_output(&gb, get_pixels()); @@ -825,7 +856,7 @@ static void update_window_geometry(void) { } static void stop(void) { - if (!running) return; + if (!gui_data.running) return; GB_audio_set_paused(true); GB_debugger_set_disabled(&gb, true); @@ -834,19 +865,19 @@ static void stop(void) { // [self interruptDebugInputRead]; } - stopping = true; - running = false; - while (stopping); + gui_data.stopping = true; + gui_data.running = false; + while (gui_data.stopping); GB_debugger_set_disabled(&gb, false); gui_data.stopped = true; } static void on_vblank(gpointer data) { - if (!vram_viewer_updating && vram_viewer_visible) { - vram_viewer_updating = true; + if (!gui_data.vram_viewer_updating && gui_data.vram_viewer_visible) { + gui_data.vram_viewer_updating = true; - if (g_strcmp0("vram_viewer_sprites", vram_viewer_active_tab) == 0) { + if (g_strcmp0("vram_viewer_sprites", gui_data.vram_viewer_active_tab) == 0) { GtkTreeIter iter; GtkTreeView *tree_view = builder_get(GTK_TREE_VIEW, "vram_viewer_sprites"); // gtk_tree_view_set_model(tree_view, NULL); // Do we need this? @@ -863,39 +894,39 @@ static void on_vblank(gpointer data) { gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter); - for (unsigned row = 0; row < oamCount; ++row) { + for (unsigned row = 0; row < gui_data.oam_count; ++row) { GdkPixbuf *pixbuf = gdk_pixbuf_new_from_bytes( - g_bytes_new(oamInfo[row].image, 128 * sizeof(uint32_t)), - GDK_COLORSPACE_RGB, true, 8, 8, oamHeight, 8 * sizeof(uint32_t) + g_bytes_new(gui_data.oam_info[row].image, 128 * sizeof(uint32_t)), + GDK_COLORSPACE_RGB, true, 8, 8, gui_data.oam_height, 8 * sizeof(uint32_t) ); - GdkPixbuf *dest = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, 8 * 2, oamHeight * 2); + GdkPixbuf *dest = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, 8 * 2, gui_data.oam_height * 2); gdk_pixbuf_scale(pixbuf, dest, - 0, 0, 8 * 2, oamHeight * 2, + 0, 0, 8 * 2, gui_data.oam_height * 2, 0, 0, 2.0, 2.0, GDK_INTERP_NEAREST ); gtk_list_store_insert_with_values(store, &iter, -1, 0, dest, - 1, itoa(oamInfo[row].x - 8), - 2, itoa(oamInfo[row].y - 16), - 3, g_strdup_printf("$%02x", oamInfo[row].tile), - 4, g_strdup_printf("$%04x", 0x8000 + oamInfo[row].tile * 0x10), - 5, g_strdup_printf("$%04x", oamInfo[row].oam_addr), - 6, vram_viewer_is_cgb + 1, g_strdup_printf("%i", gui_data.oam_info[row].x - 8), + 2, g_strdup_printf("%i", gui_data.oam_info[row].y - 16), + 3, g_strdup_printf("$%02x", gui_data.oam_info[row].tile), + 4, g_strdup_printf("$%04x", 0x8000 + gui_data.oam_info[row].tile * 0x10), + 5, g_strdup_printf("$%04x", gui_data.oam_info[row].oam_addr), + 6, gui_data.vram_viewer_is_cgb ? g_strdup_printf("%c%c%c%d%d", - oamInfo[row].flags & 0x80? 'P' : '-', - oamInfo[row].flags & 0x40? 'Y' : '-', - oamInfo[row].flags & 0x20? 'X' : '-', - oamInfo[row].flags & 0x08? 1 : 0, - oamInfo[row].flags & 0x07) + gui_data.oam_info[row].flags & 0x80? 'P' : '-', + gui_data.oam_info[row].flags & 0x40? 'Y' : '-', + gui_data.oam_info[row].flags & 0x20? 'X' : '-', + gui_data.oam_info[row].flags & 0x08? 1 : 0, + gui_data.oam_info[row].flags & 0x07) : g_strdup_printf("%c%c%c%d", - oamInfo[row].flags & 0x80? 'P' : '-', - oamInfo[row].flags & 0x40? 'Y' : '-', - oamInfo[row].flags & 0x20? 'X' : '-', - oamInfo[row].flags & 0x10? 1 : 0), + gui_data.oam_info[row].flags & 0x80? 'P' : '-', + gui_data.oam_info[row].flags & 0x40? 'Y' : '-', + gui_data.oam_info[row].flags & 0x20? 'X' : '-', + gui_data.oam_info[row].flags & 0x10? 1 : 0), -1 ); @@ -906,7 +937,7 @@ static void on_vblank(gpointer data) { gtk_tree_view_set_model(tree_view, GTK_TREE_MODEL(store)); g_object_unref(store); } - else if (g_strcmp0("vram_viewer_palettes", vram_viewer_active_tab) == 0) { + else if (g_strcmp0("vram_viewer_palettes", gui_data.vram_viewer_active_tab) == 0) { GtkTreeIter iter; GtkTreeView *tree_view = builder_get(GTK_TREE_VIEW, "vram_viewer_palettes"); // gtk_tree_view_set_model(tree_view, NULL); // Do we need this? @@ -932,10 +963,10 @@ static void on_vblank(gpointer data) { for (unsigned row = 0; row < 16; ++row) { uint8_t offset = (row & 7) * 4; - uint16_t color_0 = (vram_viewer_palette_data[row][((0 + offset) << 1) + 1] << 8) | vram_viewer_palette_data[row][((0 + offset) << 1)]; - uint16_t color_1 = (vram_viewer_palette_data[row][((1 + offset) << 1) + 1] << 8) | vram_viewer_palette_data[row][((1 + offset) << 1)]; - uint16_t color_2 = (vram_viewer_palette_data[row][((2 + offset) << 1) + 1] << 8) | vram_viewer_palette_data[row][((2 + offset) << 1)]; - uint16_t color_3 = (vram_viewer_palette_data[row][((3 + offset) << 1) + 1] << 8) | vram_viewer_palette_data[row][((3 + offset) << 1)]; + uint16_t color_0 = (gui_data.vram_viewer_palette_data[row][((0 + offset) << 1) + 1] << 8) | gui_data.vram_viewer_palette_data[row][((0 + offset) << 1)]; + uint16_t color_1 = (gui_data.vram_viewer_palette_data[row][((1 + offset) << 1) + 1] << 8) | gui_data.vram_viewer_palette_data[row][((1 + offset) << 1)]; + uint16_t color_2 = (gui_data.vram_viewer_palette_data[row][((2 + offset) << 1) + 1] << 8) | gui_data.vram_viewer_palette_data[row][((2 + offset) << 1)]; + uint16_t color_3 = (gui_data.vram_viewer_palette_data[row][((3 + offset) << 1) + 1] << 8) | gui_data.vram_viewer_palette_data[row][((3 + offset) << 1)]; gtk_list_store_insert_with_values(store, &iter, -1, 0, g_strdup_printf("%s %d", row >=8 ? "Object" : "Background", row & 7), @@ -971,53 +1002,53 @@ static void on_vblank(gpointer data) { } // Queue a redraw of the VRAM viewer - gtk_widget_queue_draw(GTK_WIDGET(vram_viewer)); + gtk_widget_queue_draw(GTK_WIDGET(gui_data.vram_viewer)); - vram_viewer_updating = false; + gui_data.vram_viewer_updating = false; } // Queue drawing of the current frame - if (fallback_canvas) { - gtk_widget_queue_draw(GTK_WIDGET(main_window)); + if (gui_data.fallback_canvas) { + gtk_widget_queue_draw(GTK_WIDGET(gui_data.main_window)); } - else if (gl_area) { - gtk_gl_area_queue_render(gl_area); + else if (gui_data.gl_area) { + gtk_gl_area_queue_render(gui_data.gl_area); } } static void vblank(GB_gameboy_t *gb) { flip(); - if (border_mode_changed) { + if (gui_data.border_mode_changed) { GB_set_border_mode(gb, get_display_border_mode()); update_window_geometry(); - border_mode_changed = false; + gui_data.border_mode_changed = false; } GB_set_pixels_output(gb, get_pixels()); - if (underclock_down && clock_mutliplier > 0.5) { - clock_mutliplier -= 1.0/16; - GB_set_clock_multiplier(gb, clock_mutliplier); + if (gui_data.underclock_down && gui_data.clock_mutliplier > 0.5) { + gui_data.clock_mutliplier -= 1.0/16; + GB_set_clock_multiplier(gb, gui_data.clock_mutliplier); } - else if (!underclock_down && clock_mutliplier < 1.0) { - clock_mutliplier += 1.0/16; - GB_set_clock_multiplier(gb, clock_mutliplier); + else if (!gui_data.underclock_down && gui_data.clock_mutliplier < 1.0) { + gui_data.clock_mutliplier += 1.0/16; + GB_set_clock_multiplier(gb, gui_data.clock_mutliplier); } - if (g_strcmp0("vram_viewer_tileset", vram_viewer_active_tab) == 0) { + if (g_strcmp0("vram_viewer_tileset", gui_data.vram_viewer_active_tab) == 0) { const gchar *palette_id = gtk_combo_box_get_active_id(builder_get(GTK_COMBO_BOX, "vram_viewer_tileset_palette_selector")); GB_palette_type_t palette_type = g_str_has_prefix(palette_id, "bg")? GB_PALETTE_BACKGROUND : GB_PALETTE_OAM; uint8_t palette_index = g_ascii_digit_value(palette_id[palette_type == GB_PALETTE_OAM ? 3 : 2]); - GB_draw_tileset(gb, tileset_buffer, + GB_draw_tileset(gb, gui_data.tileset_buffer, palette_type, palette_index ); } - else if (g_strcmp0("vram_viewer_tilemap", vram_viewer_active_tab) == 0) { + else if (g_strcmp0("vram_viewer_tilemap", gui_data.vram_viewer_active_tab) == 0) { const gchar *palette_id = gtk_combo_box_get_active_id(builder_get(GTK_COMBO_BOX, "vram_viewer_tilemap_palette_selector")); uint8_t palette_index = 0; GB_palette_type_t palette_type = GB_PALETTE_AUTO; @@ -1039,33 +1070,33 @@ static void vblank(GB_gameboy_t *gb) { tileset_type = (g_strcmp0("8800", tileset_type_id) == 0)? GB_TILESET_8800 : GB_TILESET_8000; } - GB_draw_tilemap(gb, tilemap_buffer, + GB_draw_tilemap(gb, gui_data.tilemap_buffer, palette_type, palette_index, map_type, tileset_type ); - scrollRect = (Rect){ + gui_data.scroll_rect = (Rect){ GB_read_memory(gb, 0xFF00 | GB_IO_SCX), GB_read_memory(gb, 0xFF00 | GB_IO_SCY), 160, 144 }; } - else if (g_strcmp0("vram_viewer_sprites", vram_viewer_active_tab) == 0) { - oamCount = GB_get_oam_info(gb, oamInfo, &oamHeight); - vram_viewer_is_cgb = GB_is_cgb(gb); + else if (g_strcmp0("vram_viewer_sprites", gui_data.vram_viewer_active_tab) == 0) { + gui_data.oam_count = GB_get_oam_info(gb, gui_data.oam_info, &gui_data.oam_height); + gui_data.vram_viewer_is_cgb = GB_is_cgb(gb); } - else if (g_strcmp0("vram_viewer_palettes", vram_viewer_active_tab) == 0) { + else if (g_strcmp0("vram_viewer_palettes", gui_data.vram_viewer_active_tab) == 0) { size_t size; for (unsigned row = 0; row < 16; ++row) { uint8_t *palette_data = GB_get_direct_access(gb, row >= 8? GB_DIRECT_ACCESS_OBP : GB_DIRECT_ACCESS_BGP, &size, NULL); - memcpy(vram_viewer_palette_data[row], palette_data, size); + memcpy(gui_data.vram_viewer_palette_data[row], palette_data, size); } } - do_rewind = rewind_down; + gui_data.do_rewind = gui_data.rewind_down; g_idle_add((GSourceFunc) on_vblank, NULL); } @@ -1075,9 +1106,9 @@ static void handle_events(GB_gameboy_t *gb) { uint8_t controller_state = 0; - if (controller) { - int16_t x_axis = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTX); - int16_t y_axis = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTY); + if (gui_data.controller) { + int16_t x_axis = SDL_GameControllerGetAxis(gui_data.controller, SDL_CONTROLLER_AXIS_LEFTX); + int16_t y_axis = SDL_GameControllerGetAxis(gui_data.controller, SDL_CONTROLLER_AXIS_LEFTY); if (x_axis >= JOYSTICK_HIGH) { controller_state |= BUTTON_MASK_RIGHT; @@ -1093,24 +1124,24 @@ static void handle_events(GB_gameboy_t *gb) { controller_state |= BUTTON_MASK_UP; } - if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) controller_state |= BUTTON_MASK_RIGHT; - if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_LEFT)) controller_state |= BUTTON_MASK_LEFT; - if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_UP)) controller_state |= BUTTON_MASK_UP; - if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_DOWN)) controller_state |= BUTTON_MASK_DOWN; - if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_A)) controller_state |= BUTTON_MASK_A; - if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_B)) controller_state |= BUTTON_MASK_B; - if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_BACK)) controller_state |= BUTTON_MASK_SELECT; - if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_START)) controller_state |= BUTTON_MASK_START; + if (SDL_GameControllerGetButton(gui_data.controller, SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) controller_state |= BUTTON_MASK_RIGHT; + if (SDL_GameControllerGetButton(gui_data.controller, SDL_CONTROLLER_BUTTON_DPAD_LEFT)) controller_state |= BUTTON_MASK_LEFT; + if (SDL_GameControllerGetButton(gui_data.controller, SDL_CONTROLLER_BUTTON_DPAD_UP)) controller_state |= BUTTON_MASK_UP; + if (SDL_GameControllerGetButton(gui_data.controller, SDL_CONTROLLER_BUTTON_DPAD_DOWN)) controller_state |= BUTTON_MASK_DOWN; + if (SDL_GameControllerGetButton(gui_data.controller, SDL_CONTROLLER_BUTTON_A)) controller_state |= BUTTON_MASK_A; + if (SDL_GameControllerGetButton(gui_data.controller, SDL_CONTROLLER_BUTTON_B)) controller_state |= BUTTON_MASK_B; + if (SDL_GameControllerGetButton(gui_data.controller, SDL_CONTROLLER_BUTTON_BACK)) controller_state |= BUTTON_MASK_SELECT; + if (SDL_GameControllerGetButton(gui_data.controller, SDL_CONTROLLER_BUTTON_START)) controller_state |= BUTTON_MASK_START; } - GB_set_key_state(gb, GB_KEY_RIGHT, (pressed_buttons & BUTTON_MASK_RIGHT) | (controller_state & BUTTON_MASK_RIGHT)); - GB_set_key_state(gb, GB_KEY_LEFT, (pressed_buttons & BUTTON_MASK_LEFT) | (controller_state & BUTTON_MASK_LEFT)); - GB_set_key_state(gb, GB_KEY_UP, (pressed_buttons & BUTTON_MASK_UP) | (controller_state & BUTTON_MASK_UP)); - GB_set_key_state(gb, GB_KEY_DOWN, (pressed_buttons & BUTTON_MASK_DOWN) | (controller_state & BUTTON_MASK_DOWN)); - GB_set_key_state(gb, GB_KEY_A, (pressed_buttons & BUTTON_MASK_A) | (controller_state & BUTTON_MASK_A)); - GB_set_key_state(gb, GB_KEY_B, (pressed_buttons & BUTTON_MASK_B) | (controller_state & BUTTON_MASK_B)); - GB_set_key_state(gb, GB_KEY_SELECT, (pressed_buttons & BUTTON_MASK_SELECT) | (controller_state & BUTTON_MASK_SELECT)); - GB_set_key_state(gb, GB_KEY_START, (pressed_buttons & BUTTON_MASK_START) | (controller_state & BUTTON_MASK_START)); + GB_set_key_state(gb, GB_KEY_RIGHT, (gui_data.pressed_buttons & BUTTON_MASK_RIGHT) | (controller_state & BUTTON_MASK_RIGHT)); + GB_set_key_state(gb, GB_KEY_LEFT, (gui_data.pressed_buttons & BUTTON_MASK_LEFT) | (controller_state & BUTTON_MASK_LEFT)); + GB_set_key_state(gb, GB_KEY_UP, (gui_data.pressed_buttons & BUTTON_MASK_UP) | (controller_state & BUTTON_MASK_UP)); + GB_set_key_state(gb, GB_KEY_DOWN, (gui_data.pressed_buttons & BUTTON_MASK_DOWN) | (controller_state & BUTTON_MASK_DOWN)); + GB_set_key_state(gb, GB_KEY_A, (gui_data.pressed_buttons & BUTTON_MASK_A) | (controller_state & BUTTON_MASK_A)); + GB_set_key_state(gb, GB_KEY_B, (gui_data.pressed_buttons & BUTTON_MASK_B) | (controller_state & BUTTON_MASK_B)); + GB_set_key_state(gb, GB_KEY_SELECT, (gui_data.pressed_buttons & BUTTON_MASK_SELECT) | (controller_state & BUTTON_MASK_SELECT)); + GB_set_key_state(gb, GB_KEY_START, (gui_data.pressed_buttons & BUTTON_MASK_START) | (controller_state & BUTTON_MASK_START)); } static void load_boot_rom(GB_gameboy_t *gb, GB_boot_rom_t type) { @@ -1217,7 +1248,7 @@ static void reset(void) { GtkRequisition minimum_size; GtkRequisition natural_size; - gtk_widget_get_preferred_size(GTK_WIDGET(main_window), &minimum_size, &natural_size); + gtk_widget_get_preferred_size(GTK_WIDGET(gui_data.main_window), &minimum_size, &natural_size); // Check SGB -> non-SGB and non-SGB to SGB transitions if (GB_get_screen_width(&gb) != minimum_size.width || GB_get_screen_height(&gb) != minimum_size.height) { @@ -1238,39 +1269,39 @@ static void reset(void) { g_free(path); } - action_set_enabled(main_application, "close", success); + action_set_enabled(gui_data.main_application, "close", success); action_entries_set_enabled(emulation_entries, G_N_ELEMENTS(emulation_entries), success); } static void start(void) { - running = true; + gui_data.running = true; gui_data.stopped = false; GB_audio_clear_queue(); GB_audio_set_paused(false); /* Run emulation */ - while (running) { - if (rewind_paused) { + while (gui_data.running) { + if (gui_data.rewind_paused) { handle_events(&gb); g_usleep(G_USEC_PER_SEC / 8); } else { - if (do_rewind) { + if (gui_data.do_rewind) { GB_rewind_pop(&gb); - if (turbo_down) { + if (gui_data.turbo_down) { GB_rewind_pop(&gb); } if (!GB_rewind_pop(&gb)) { - rewind_paused = true; + gui_data.rewind_paused = true; } - do_rewind = false; + gui_data.do_rewind = false; } GB_run(&gb); } } - stopping = false; + gui_data.stopping = false; } // Prevent dependency loop @@ -1304,8 +1335,8 @@ static gpointer run_thread(gpointer null_ptr) { } static void run(void) { - if (running) return; - while (stopping); + if (gui_data.running) return; + while (gui_data.stopping); g_thread_new("CoreLoop", run_thread, NULL); } @@ -1319,7 +1350,7 @@ static void quit(void) { // Quit our application properly. // This fires the “shutdown” signal. - g_application_quit(G_APPLICATION(main_application)); + g_application_quit(G_APPLICATION(gui_data.main_application)); } static void quit_interrupt(int ignored) { @@ -1360,66 +1391,66 @@ static gboolean on_key_press(GtkWidget *w, GdkEventKey *event, gpointer data) { case GDK_KEY_l: mask = BUTTON_MASK_A; break; case GDK_KEY_Tab: { - rewind_down = event->type == GDK_KEY_PRESS; - GB_set_turbo_mode(&gb, turbo_down, turbo_down && rewind_down); + gui_data.rewind_down = event->type == GDK_KEY_PRESS; + GB_set_turbo_mode(&gb, gui_data.turbo_down, gui_data.turbo_down && gui_data.rewind_down); if (event->type == GDK_KEY_RELEASE) { - rewind_paused = false; + gui_data.rewind_paused = false; } break; } case GDK_KEY_space: { - turbo_down = event->type == GDK_KEY_PRESS; + gui_data.turbo_down = event->type == GDK_KEY_PRESS; GB_audio_clear_queue(); - GB_set_turbo_mode(&gb, turbo_down, turbo_down && rewind_down); + GB_set_turbo_mode(&gb, gui_data.turbo_down, gui_data.turbo_down && gui_data.rewind_down); break; } case GDK_KEY_dead_acute: // fall through case GDK_KEY_acute: // fall through case GDK_KEY_apostrophe: - underclock_down = event->type == GDK_KEY_PRESS; + gui_data.underclock_down = event->type == GDK_KEY_PRESS; break; case GDK_KEY_F11: { if (event->type == GDK_KEY_RELEASE) { - if (is_fullscreen) { - gtk_window_unfullscreen(GTK_WINDOW(main_window)); + if (gui_data.is_fullscreen) { + gtk_window_unfullscreen(GTK_WINDOW(gui_data.main_window)); } else { - gtk_window_fullscreen(GTK_WINDOW(main_window)); + gtk_window_fullscreen(GTK_WINDOW(gui_data.main_window)); } } break; } } if (event->type == GDK_KEY_PRESS) { - pressed_buttons |= mask; + gui_data.pressed_buttons |= mask; } else if (event->type == GDK_KEY_RELEASE) { - pressed_buttons &= ~mask; + gui_data.pressed_buttons &= ~mask; } return false; } static void on_window_state_change(GtkWidget *w, GdkEventWindowState *event, gpointer data) { - is_fullscreen = event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN; + gui_data.is_fullscreen = event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN; } // Gets called when the VRAM viewer gets realized static void on_vram_viewer_realize(void) { - vram_viewer_visible = true; - vram_viewer_active_tab = (gchar *)gtk_stack_get_visible_child_name(builder_get(GTK_STACK, "vram_viewer_stack")); + gui_data.vram_viewer_visible = true; + gui_data.vram_viewer_active_tab = (gchar *)gtk_stack_get_visible_child_name(builder_get(GTK_STACK, "vram_viewer_stack")); } // Gets called when the VRAM viewer gets unrealized static void on_vram_viewer_unrealize(void) { - vram_viewer_visible = false; + gui_data.vram_viewer_visible = false; } // Gets called when the tileset viewer should be redrawn static gboolean on_draw_vram_viewer_tileset(GtkWidget *widget, cairo_t *cr, gpointer data) { - g_mutex_lock(&tileset_buffer_mutex); + g_mutex_lock(&gui_data.tileset_buffer_mutex); guint width, height; GtkStyleContext *context; @@ -1431,7 +1462,7 @@ static gboolean on_draw_vram_viewer_tileset(GtkWidget *widget, cairo_t *cr, gpoi gtk_render_background(context, cr, 0, 0, width, height); cairo_surface_t *surface = cairo_image_surface_create_for_data( - (unsigned char *) tileset_buffer, + (unsigned char *) gui_data.tileset_buffer, CAIRO_FORMAT_RGB24, 256, 192, @@ -1467,13 +1498,13 @@ static gboolean on_draw_vram_viewer_tileset(GtkWidget *widget, cairo_t *cr, gpoi cairo_stroke(cr); } - g_mutex_unlock(&tileset_buffer_mutex); + g_mutex_unlock(&gui_data.tileset_buffer_mutex); return false; } // Gets called when the tilemap viewer should be redrawn static gboolean on_draw_vram_viewer_tilemap(GtkWidget *widget, cairo_t *cr, gpointer data) { - g_mutex_lock(&tilemap_buffer_mutex); + g_mutex_lock(&gui_data.tilemap_buffer_mutex); guint width, height; GtkStyleContext *context; @@ -1485,7 +1516,7 @@ static gboolean on_draw_vram_viewer_tilemap(GtkWidget *widget, cairo_t *cr, gpoi gtk_render_background(context, cr, 0, 0, width, height); cairo_surface_t *surface = cairo_image_surface_create_for_data( - (unsigned char *) tilemap_buffer, + (unsigned char *) gui_data.tilemap_buffer, CAIRO_FORMAT_RGB24, 256, 256, @@ -1520,7 +1551,7 @@ static gboolean on_draw_vram_viewer_tilemap(GtkWidget *widget, cairo_t *cr, gpoi for (unsigned x = 0; x < 2; x++) { for (unsigned y = 0; y < 2; y++) { - Rect rect = scrollRect; + Rect rect = gui_data.scroll_rect; rect.x -= 256 * x; rect.y += 256 * y; @@ -1538,7 +1569,7 @@ static gboolean on_draw_vram_viewer_tilemap(GtkWidget *widget, cairo_t *cr, gpoi cairo_stroke(cr); } - g_mutex_unlock(&tilemap_buffer_mutex); + g_mutex_unlock(&gui_data.tilemap_buffer_mutex); return false; } @@ -1646,7 +1677,7 @@ static gboolean on_motion_vram_viewer_tilemap(GtkWidget *widget, GdkEventMotion static void on_vram_tab_change(GtkWidget *widget, GParamSpec *pspec, GtkStackSwitcher *self) { gtk_label_set_text(builder_get(GTK_LABEL, "vram_viewer_status"), ""); - vram_viewer_active_tab = (gchar *)gtk_stack_get_visible_child_name(builder_get(GTK_STACK, "vram_viewer_stack")); + gui_data.vram_viewer_active_tab = (gchar *)gtk_stack_get_visible_child_name(builder_get(GTK_STACK, "vram_viewer_stack")); } // This functions gets called immediately after registration of the GApplication @@ -1659,16 +1690,16 @@ static void startup(GApplication *app, gpointer null_ptr) { // So we initialize GTK, create a dummy GtkWindow object, attach a `realize` callback and // in this callback create a GdkGLContext on this window. But instead of running the GTK main loop // we just realize and destroy the dummy window and compare the context’s version in the realize callback. - supports_gl = test_gl_support(); - g_debug("OpenGL supported: %s", supports_gl? "Yes" : "No"); + gui_data.supports_gl = test_gl_support(); + g_debug("OpenGL supported: %s", gui_data.supports_gl? "Yes" : "No"); - builder = gtk_builder_new_from_resource(RESOURCE_PREFIX "ui/window.ui"); - gtk_builder_connect_signals(builder, NULL); + gui_data.builder = gtk_builder_new_from_resource(RESOURCE_PREFIX "ui/window.ui"); + gtk_builder_connect_signals(gui_data.builder, NULL); create_action_groups(app); if (gui_data.cli_options.prefix != NULL) { - GAction *action = g_action_map_lookup_action(G_ACTION_MAP(main_application), "change_model"); + GAction *action = g_action_map_lookup_action(G_ACTION_MAP(gui_data.main_application), "change_model"); g_action_change_state(action, g_variant_new_string(gui_data.cli_options.prefix)); } @@ -1681,16 +1712,16 @@ static void startup(GApplication *app, gpointer null_ptr) { gtk_widget_destroy(builder_get(GTK_WIDGET, "menubar_override_selector")); #endif - preferences = GTK_WINDOW(get_object("preferences")); + gui_data.preferences = GTK_WINDOW(get_object("preferences")); - g_signal_connect(preferences, "realize", G_CALLBACK(on_preferences_realize), (gpointer) builder); - init_settings(gui_data.cli_options.config_path, preferences); + g_signal_connect(gui_data.preferences, "realize", G_CALLBACK(on_preferences_realize), (gpointer) gui_data.builder); + init_settings(gui_data.cli_options.config_path, gui_data.preferences); - vram_viewer = GTK_WINDOW(get_object("vram_viewer")); - memory_viewer = GTK_WINDOW(get_object("memory_viewer")); + gui_data.vram_viewer = GTK_WINDOW(get_object("vram_viewer")); + gui_data.memory_viewer = GTK_WINDOW(get_object("memory_viewer")); - console = GTK_WINDOW(get_object("console")); - printer = GTK_WINDOW(get_object("printer")); + gui_data.console = GTK_WINDOW(get_object("console")); + gui_data.printer = GTK_WINDOW(get_object("printer")); if (config.sample_rate == -1) { gui_data.sample_rate = GB_audio_default_sample_rate(); @@ -1700,19 +1731,19 @@ static void startup(GApplication *app, gpointer null_ptr) { } // setup main window - main_window = GTK_APPLICATION_WINDOW(gtk_application_window_new(GTK_APPLICATION(app))); - main_window_container = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL, 0)); + gui_data.main_window = GTK_APPLICATION_WINDOW(gtk_application_window_new(GTK_APPLICATION(app))); + gui_data.main_window_container = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL, 0)); - gtk_window_set_title(GTK_WINDOW(main_window), "SameBoy"); - gtk_application_window_set_show_menubar(main_window, false); - gtk_container_add(GTK_CONTAINER(main_window), GTK_WIDGET(main_window_container)); + gtk_window_set_title(GTK_WINDOW(gui_data.main_window), "SameBoy"); + gtk_application_window_set_show_menubar(gui_data.main_window, false); + gtk_container_add(GTK_CONTAINER(gui_data.main_window), GTK_WIDGET(gui_data.main_window_container)); setup_menu(app); // 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)); + set_combo_box_row_separator_func(GTK_CONTAINER(gui_data.preferences)); + set_combo_box_row_separator_func(GTK_CONTAINER(gui_data.vram_viewer)); + set_combo_box_row_separator_func(GTK_CONTAINER(gui_data.memory_viewer)); // Define a set of window icons GList *icon_list = NULL; @@ -1734,7 +1765,7 @@ static void startup(GApplication *app, gpointer null_ptr) { } // Let GTK choose the proper icon - gtk_window_set_icon_list(GTK_WINDOW(main_window), icon_list); + gtk_window_set_icon_list(GTK_WINDOW(gui_data.main_window), icon_list); // Add missing information to the about dialog GtkAboutDialog *about_dialog = GTK_ABOUT_DIALOG(get_object("about_dialog")); @@ -1745,23 +1776,23 @@ static void startup(GApplication *app, gpointer null_ptr) { static void connect_signal_handlers(GApplication *app) { // Connect signal handlers - gtk_widget_add_events(GTK_WIDGET(main_window), GDK_KEY_PRESS_MASK); - gtk_widget_add_events(GTK_WIDGET(main_window), GDK_KEY_RELEASE_MASK); + gtk_widget_add_events(GTK_WIDGET(gui_data.main_window), GDK_KEY_PRESS_MASK); + gtk_widget_add_events(GTK_WIDGET(gui_data.main_window), GDK_KEY_RELEASE_MASK); - g_signal_connect(main_window, "destroy", G_CALLBACK(on_quit), app); - g_signal_connect(main_window, "key_press_event", G_CALLBACK(on_key_press), NULL); - g_signal_connect(main_window, "key_release_event", G_CALLBACK(on_key_press), NULL); - g_signal_connect(main_window, "window-state-event", G_CALLBACK(on_window_state_change), NULL); + g_signal_connect(gui_data.main_window, "destroy", G_CALLBACK(on_quit), app); + g_signal_connect(gui_data.main_window, "key_press_event", G_CALLBACK(on_key_press), NULL); + g_signal_connect(gui_data.main_window, "key_release_event", G_CALLBACK(on_key_press), NULL); + g_signal_connect(gui_data.main_window, "window-state-event", G_CALLBACK(on_window_state_change), NULL); - g_signal_connect(vram_viewer, "realize", G_CALLBACK(on_vram_viewer_realize), NULL); - g_signal_connect(vram_viewer, "unrealize", G_CALLBACK(on_vram_viewer_unrealize), NULL); + g_signal_connect(gui_data.vram_viewer, "realize", G_CALLBACK(on_vram_viewer_realize), NULL); + g_signal_connect(gui_data.vram_viewer, "unrealize", G_CALLBACK(on_vram_viewer_unrealize), NULL); // Just hide our sub-windows when closing them - g_signal_connect(preferences, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); - g_signal_connect(vram_viewer, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); - g_signal_connect(memory_viewer, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); - g_signal_connect(console, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); - g_signal_connect(printer, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); + g_signal_connect(gui_data.preferences, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); + g_signal_connect(gui_data.vram_viewer, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); + g_signal_connect(gui_data.memory_viewer, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); + g_signal_connect(gui_data.console, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); + g_signal_connect(gui_data.printer, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); g_signal_connect(get_object("vram_viewer_tileset_canvas"), "draw", G_CALLBACK(on_draw_vram_viewer_tileset), NULL); g_signal_connect(get_object("vram_viewer_tilemap_canvas"), "draw", G_CALLBACK(on_draw_vram_viewer_tilemap), NULL); @@ -1776,7 +1807,7 @@ static void connect_signal_handlers(GApplication *app) { } static void update_viewport(void) { - GtkWidget *w = fallback_canvas ? GTK_WIDGET(fallback_canvas) : GTK_WIDGET(gl_area); + GtkWidget *w = gui_data.fallback_canvas ? GTK_WIDGET(gui_data.fallback_canvas) : GTK_WIDGET(gui_data.gl_area); int win_width = gtk_widget_get_allocated_width(w); int win_height = gtk_widget_get_allocated_height(w); @@ -1801,14 +1832,14 @@ static void update_viewport(void) { unsigned new_width = x_factor * GB_get_screen_width(&gb); unsigned new_height = y_factor * GB_get_screen_height(&gb); - viewport = (Rect){ + gui_data.viewport = (Rect){ (win_width - new_width) / 2, (win_height - new_height) / 2, new_width, new_height }; - if (!fallback_canvas) glViewport(viewport.x, viewport.y, viewport.w, viewport.h); + if (!gui_data.fallback_canvas) glViewport(gui_data.viewport.x, gui_data.viewport.y, gui_data.viewport.w, gui_data.viewport.h); } // TODO: Comment @@ -1839,9 +1870,9 @@ static void gl_draw(void) { } render_bitmap_with_shader( - &shader, _pixels, previous, + &gui_data.shader, _pixels, previous, GB_get_screen_width(&gb), GB_get_screen_height(&gb), - viewport.x, viewport.y, viewport.w, viewport.h, + gui_data.viewport.x, gui_data.viewport.y, gui_data.viewport.w, gui_data.viewport.h, mode ); } @@ -1873,8 +1904,8 @@ static gboolean on_draw_fallback(GtkWidget *widget, cairo_t *cr, gpointer data) cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, screen_width) ); - cairo_translate(cr, viewport.x, viewport.y); - cairo_scale(cr, viewport.w / screen_width, viewport.h / screen_height); + cairo_translate(cr, gui_data.viewport.x, gui_data.viewport.y); + cairo_scale(cr, gui_data.viewport.w / screen_width, gui_data.viewport.h / screen_height); cairo_set_source_surface(cr, surface, 0, 0); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST); cairo_paint(cr); @@ -1884,10 +1915,10 @@ static gboolean on_draw_fallback(GtkWidget *widget, cairo_t *cr, gpointer data) // Create a GtkDrawingArea as a fallback in case we can’t use OpenGL static void create_fallback_canvas(void) { - fallback_canvas = GTK_DRAWING_AREA(gtk_drawing_area_new()); - g_signal_connect(fallback_canvas, "draw", G_CALLBACK(on_draw_fallback), NULL); - g_signal_connect(fallback_canvas, "size-allocate", G_CALLBACK(resize), NULL); - gtk_box_pack_end(GTK_BOX(main_window_container), GTK_WIDGET(fallback_canvas), true, true, 0); + gui_data.fallback_canvas = GTK_DRAWING_AREA(gtk_drawing_area_new()); + g_signal_connect(gui_data.fallback_canvas, "draw", G_CALLBACK(on_draw_fallback), NULL); + g_signal_connect(gui_data.fallback_canvas, "size-allocate", G_CALLBACK(resize), NULL); + gtk_box_pack_end(GTK_BOX(gui_data.main_window_container), GTK_WIDGET(gui_data.fallback_canvas), true, true, 0); } // TODO: Comment @@ -1908,7 +1939,7 @@ static void gl_init(GtkWidget *w) { renderer = (char *)glGetString(GL_RENDERER); g_debug("GtkGLArea on %s", renderer ? renderer : "Unknown"); - if (config.shader == NULL || (!init_shader_with_name(&shader, config.shader) && !init_shader_with_name(&shader, "NearestNeighbor"))) { + if (config.shader == NULL || (!init_shader_with_name(&gui_data.shader, config.shader) && !init_shader_with_name(&gui_data.shader, "NearestNeighbor"))) { GError *error = g_error_new_literal(g_quark_from_string("sameboy-gl-error"), 1, "Failed to initialize shaders"); gtk_gl_area_set_error(gl_area, error); } @@ -1929,15 +1960,15 @@ static void gl_init(GtkWidget *w) { static void create_canvas(void) { // create our renderer area - if (supports_gl) { - gl_area = GTK_GL_AREA(gtk_gl_area_new()); - gtk_gl_area_set_required_version(gl_area, 3, 2); - gtk_gl_area_set_auto_render(gl_area, false); - gtk_gl_area_set_has_alpha(gl_area, false); - gtk_gl_area_set_has_depth_buffer(gl_area, false); - gtk_gl_area_set_has_stencil_buffer(gl_area, false); - g_signal_connect(gl_area, "realize", G_CALLBACK(gl_init), NULL); - gtk_box_pack_end(GTK_BOX(main_window_container), GTK_WIDGET(gl_area), true, true, 0); + if (gui_data.supports_gl) { + gui_data.gl_area = GTK_GL_AREA(gtk_gl_area_new()); + gtk_gl_area_set_required_version(gui_data.gl_area, 3, 2); + gtk_gl_area_set_auto_render(gui_data.gl_area, false); + gtk_gl_area_set_has_alpha(gui_data.gl_area, false); + gtk_gl_area_set_has_depth_buffer(gui_data.gl_area, false); + gtk_gl_area_set_has_stencil_buffer(gui_data.gl_area, false); + g_signal_connect(gui_data.gl_area, "realize", G_CALLBACK(gl_init), NULL); + gtk_box_pack_end(GTK_BOX(gui_data.main_window_container), GTK_WIDGET(gui_data.gl_area), true, true, 0); } else { create_fallback_canvas(); @@ -1962,16 +1993,16 @@ static void setup_console(void) { gtk_text_buffer_create_tag(text_buf, "underline", "underline", PANGO_UNDERLINE_SINGLE, "underline-set", true, NULL); gtk_text_buffer_create_tag(text_buf, "dashed_underline", "underline", PANGO_UNDERLINE_DOUBLE, "underline-set", true, NULL); - g_mutex_init(&debugger_input_mutex); - g_cond_init(&debugger_input_cond); - g_rec_mutex_init(&console_output_lock); + g_mutex_init(&gui_data.debugger_input_mutex); + g_cond_init(&gui_data.debugger_input_cond); + g_rec_mutex_init(&gui_data.console_output_lock); - if (!debugger_input_queue) { - debugger_input_queue = g_ptr_array_sized_new(4); + if (!gui_data.debugger_input_queue) { + gui_data.debugger_input_queue = g_ptr_array_sized_new(4); } - if (!pending_console_output) { - pending_console_output = gtk_text_buffer_new(gtk_text_buffer_get_tag_table(text_buf)); + if (!gui_data.pending_console_output) { + gui_data.pending_console_output = gtk_text_buffer_new(gtk_text_buffer_get_tag_table(text_buf)); } } @@ -1988,11 +2019,11 @@ static void activate(GApplication *app, gpointer null_ptr) { setup_console(); if (gui_data.cli_options.fullscreen) { - gtk_window_fullscreen(GTK_WINDOW(main_window)); + gtk_window_fullscreen(GTK_WINDOW(gui_data.main_window)); } - gtk_application_add_window(GTK_APPLICATION(app), GTK_WINDOW(main_window)); - gtk_widget_show_all(GTK_WIDGET(main_window)); + gtk_application_add_window(GTK_APPLICATION(app), GTK_WINDOW(gui_data.main_window)); + gtk_widget_show_all(GTK_WIDGET(gui_data.main_window)); // Start the emulation thread run(); @@ -2003,18 +2034,18 @@ static void shutdown(GApplication *app, GFile **files, gint n_files, const gchar g_debug("SHUTDOWN"); stop(); - while (stopping); + while (gui_data.stopping); - g_object_unref(builder); + g_object_unref(gui_data.builder); save_settings(); free_settings(); SDL_Quit(); - if (image_buffers[0]) g_free(image_buffers[0]); - if (image_buffers[1]) g_free(image_buffers[1]); - if (image_buffers[2]) g_free(image_buffers[2]); - free_shader(&shader); + if (gui_data.image_buffers[0]) g_free(gui_data.image_buffers[0]); + if (gui_data.image_buffers[1]) g_free(gui_data.image_buffers[1]); + if (gui_data.image_buffers[2]) g_free(gui_data.image_buffers[2]); + free_shader(&gui_data.shader); free_master_shader(); GB_free(&gb); @@ -2045,9 +2076,9 @@ static void activate_about(GSimpleAction *action, GVariant *parameter, gpointer // app.show_console GAction // Opens the console static void activate_show_console(GSimpleAction *action, GVariant *parameter, gpointer app) { - if (debugger_input_queue) { - while (debugger_input_queue->len) { - g_ptr_array_remove_index_fast(debugger_input_queue, debugger_input_queue->len - 1); + if (gui_data.debugger_input_queue) { + while (gui_data.debugger_input_queue->len) { + g_ptr_array_remove_index_fast(gui_data.debugger_input_queue, gui_data.debugger_input_queue->len - 1); } } @@ -2063,13 +2094,13 @@ static void activate_open_gtk_debugger(GSimpleAction *action, GVariant *paramete // app.open_memory_viewer GAction // Opens the memory viewer window static void activate_open_memory_viewer(GSimpleAction *action, GVariant *parameter, gpointer app) { - gtk_widget_show_all(GTK_WIDGET(memory_viewer)); + gtk_widget_show_all(GTK_WIDGET(gui_data.memory_viewer)); } // app.open_vram_viewer GAction // Opens the VRAM viewer window static void activate_open_vram_viewer(GSimpleAction *action, GVariant *parameter, gpointer app) { - gtk_widget_show_all(GTK_WIDGET(vram_viewer)); + gtk_widget_show_all(GTK_WIDGET(gui_data.vram_viewer)); } // app.open GAction @@ -2077,7 +2108,7 @@ static void activate_open_vram_viewer(GSimpleAction *action, GVariant *parameter static void activate_open(GSimpleAction *action, GVariant *parameter, gpointer app) { stop(); - GtkFileChooserNative *native = gtk_file_chooser_native_new("Open File", GTK_WINDOW(main_window), GTK_FILE_CHOOSER_ACTION_OPEN, "_Open", "_Cancel"); + GtkFileChooserNative *native = gtk_file_chooser_native_new("Open File", GTK_WINDOW(gui_data.main_window), GTK_FILE_CHOOSER_ACTION_OPEN, "_Open", "_Cancel"); gint res = gtk_native_dialog_run(GTK_NATIVE_DIALOG(native)); if (res == GTK_RESPONSE_ACCEPT) { @@ -2101,26 +2132,26 @@ static void activate_close(GSimpleAction *action, GVariant *parameter, gpointer // Clear the screen as side effect update_window_geometry(); - gtk_widget_queue_draw(fallback_canvas ? GTK_WIDGET(fallback_canvas) : GTK_WIDGET(gl_area)); + gtk_widget_queue_draw(gui_data.fallback_canvas ? GTK_WIDGET(gui_data.fallback_canvas) : GTK_WIDGET(gui_data.gl_area)); // Clear the VRAM viewer - g_mutex_lock(&tileset_buffer_mutex); - memset(tileset_buffer, 0, sizeof tileset_buffer); - g_mutex_unlock(&tileset_buffer_mutex); + g_mutex_lock(&gui_data.tileset_buffer_mutex); + memset(gui_data.tileset_buffer, 0, sizeof gui_data.tileset_buffer); + g_mutex_unlock(&gui_data.tileset_buffer_mutex); - g_mutex_lock(&tilemap_buffer_mutex); - memset(tilemap_buffer, 0, sizeof tilemap_buffer); - g_mutex_unlock(&tilemap_buffer_mutex); + g_mutex_lock(&gui_data.tilemap_buffer_mutex); + memset(gui_data.tilemap_buffer, 0, sizeof gui_data.tilemap_buffer); + g_mutex_unlock(&gui_data.tilemap_buffer_mutex); gtk_stack_set_visible_child_name(builder_get(GTK_STACK, "vram_viewer_stack"), "vram_viewer_tileset"); gtk_tree_view_set_model(builder_get(GTK_TREE_VIEW, "vram_viewer_sprites"), NULL); gtk_tree_view_set_model(builder_get(GTK_TREE_VIEW, "vram_viewer_palettes"), NULL); // Redraw the VRAM viewer - gtk_widget_queue_draw(GTK_WIDGET(vram_viewer)); + gtk_widget_queue_draw(GTK_WIDGET(gui_data.vram_viewer)); // Update menu action states - action_set_enabled(main_application, "close", false); + action_set_enabled(gui_data.main_application, "close", false); action_entries_set_enabled(emulation_entries, G_N_ELEMENTS(emulation_entries), false); } @@ -2139,13 +2170,13 @@ static void activate_quit(GSimpleAction *action, GVariant *parameter, gpointer a // app.clear_console GAction // Clears the debugger console static void activate_clear_console(GSimpleAction *action, GVariant *parameter, gpointer app) { - g_rec_mutex_lock(&console_output_lock); + g_rec_mutex_lock(&gui_data.console_output_lock); GtkTextView *text_view = builder_get(GTK_TEXT_VIEW, "console_screen"); GtkTextBuffer *text_buf = gtk_text_view_get_buffer(text_view); gtk_text_buffer_set_text(text_buf, "", -1); - g_rec_mutex_unlock(&console_output_lock); + g_rec_mutex_unlock(&gui_data.console_output_lock); } static void on_model_changed(GSimpleAction *action, GVariant *value, gpointer user_data_ptr) { @@ -2157,7 +2188,7 @@ static void on_model_changed(GSimpleAction *action, GVariant *value, gpointer us const gchar *model_str = g_variant_get_string(value, NULL); GtkMessageDialog *dialog = GTK_MESSAGE_DIALOG(gtk_message_dialog_new( - GTK_WINDOW(main_window), + GTK_WINDOW(gui_data.main_window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, @@ -2208,12 +2239,12 @@ G_MODULE_EXPORT void on_boot_rom_location_changed(GtkWidget *w, gpointer user_da if (id == NULL) return; if (g_strcmp0(id, "other") == 0) { - GtkFileChooserNative *native = gtk_file_chooser_native_new("Select Folder", preferences, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, "_Select", "_Cancel"); + GtkFileChooserNative *native = gtk_file_chooser_native_new("Select Folder", gui_data.preferences, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, "_Select", "_Cancel"); gint res = gtk_native_dialog_run(GTK_NATIVE_DIALOG(native)); if (res == GTK_RESPONSE_ACCEPT) { config.boot_rom_path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(native)); - update_boot_rom_selector(builder); + update_boot_rom_selector(gui_data.builder); } g_object_unref(native); @@ -2246,7 +2277,7 @@ G_MODULE_EXPORT void on_display_border_changed(GtkWidget *w, gpointer user_data_ GtkComboBox *box = GTK_COMBO_BOX(w); config.display_border_mode = (gchar *)gtk_combo_box_get_active_id(box); - border_mode_changed = true; + gui_data.border_mode_changed = true; } G_MODULE_EXPORT void on_monochrome_palette_changed(GtkWidget *w, gpointer user_data_ptr) { @@ -2269,8 +2300,8 @@ G_MODULE_EXPORT void on_graphic_filter_changed(GtkWidget *w, gpointer user_data_ GtkComboBox *box = GTK_COMBO_BOX(w); config.shader = (gchar *)gtk_combo_box_get_active_id(box); - free_shader(&shader); - init_shader_with_name(&shader, config.shader); + free_shader(&gui_data.shader); + init_shader_with_name(&gui_data.shader, config.shader); } G_MODULE_EXPORT void on_highpass_filter_changed(GtkWidget *w, gpointer user_data_ptr) { @@ -2325,39 +2356,35 @@ G_MODULE_EXPORT void console_on_enter(GtkWidget *w, gpointer user_data_ptr) { const gchar *_text = gtk_entry_get_text(input); gchar *text = g_strdup(_text); - if (g_strcmp0("", text) == 0 && g_strcmp0("", last_console_input) < 0) { - text = g_strdup(last_console_input); + if (g_strcmp0("", text) == 0 && g_strcmp0("", gui_data.last_console_input) < 0) { + text = g_strdup(gui_data.last_console_input); } else if (text) { - if (last_console_input != NULL) g_free(last_console_input); - last_console_input = g_strdup(text); + if (gui_data.last_console_input != NULL) g_free(gui_data.last_console_input); + gui_data.last_console_input = g_strdup(text); } - if (!in_sync_input) { + if (!gui_data.in_sync_input) { console_log(&gb, "> ", 0); } console_log(&gb, text, 0); console_log(&gb, "\n", 0); - g_mutex_lock(&debugger_input_mutex); - g_ptr_array_add(debugger_input_queue, (gpointer)text); - g_cond_signal(&debugger_input_cond); - g_mutex_unlock(&debugger_input_mutex); + g_mutex_lock(&gui_data.debugger_input_mutex); + g_ptr_array_add(gui_data.debugger_input_queue, (gpointer)text); + g_cond_signal(&gui_data.debugger_input_cond); + g_mutex_unlock(&gui_data.debugger_input_mutex); // clear input gtk_entry_set_text(input, ""); } int main(int argc, char *argv[]) { - main_thread = g_thread_self(); - - // initialize GB_model_t to invalid value - gui_data.cli_options.model = -1; - gui_data.prev_model = -1; + gui_data.main_thread = g_thread_self(); // Create our GApplication and tell GTK that we are able to handle files - main_application = gtk_application_new(APP_ID, G_APPLICATION_NON_UNIQUE | G_APPLICATION_HANDLES_OPEN); + gui_data.main_application = gtk_application_new(APP_ID, G_APPLICATION_NON_UNIQUE | G_APPLICATION_HANDLES_OPEN); // Define our command line parameters GOptionEntry entries[] = { @@ -2369,20 +2396,20 @@ int main(int argc, char *argv[]) { { NULL } }; // Setup our command line information - g_application_add_main_option_entries(G_APPLICATION(main_application), entries); - g_application_set_option_context_parameter_string(G_APPLICATION(main_application), "[FILE…]"); - g_application_set_option_context_summary(G_APPLICATION(main_application), "SameBoy is an open source Game Boy (DMG) and Game Boy Color (CGB) emulator."); + g_application_add_main_option_entries(G_APPLICATION(gui_data.main_application), entries); + g_application_set_option_context_parameter_string(G_APPLICATION(gui_data.main_application), "[FILE…]"); + g_application_set_option_context_summary(G_APPLICATION(gui_data.main_application), "SameBoy is an open source Game Boy (DMG) and Game Boy Color (CGB) emulator."); // Add signal handlers - g_signal_connect(main_application, "handle-local-options", G_CALLBACK(handle_local_options), NULL); - g_signal_connect(main_application, "startup", G_CALLBACK(startup), NULL); - g_signal_connect(main_application, "activate", G_CALLBACK(activate), NULL); - g_signal_connect(main_application, "open", G_CALLBACK(open), NULL); - g_signal_connect(main_application, "shutdown", G_CALLBACK(shutdown), NULL); + g_signal_connect(gui_data.main_application, "handle-local-options", G_CALLBACK(handle_local_options), NULL); + g_signal_connect(gui_data.main_application, "startup", G_CALLBACK(startup), NULL); + g_signal_connect(gui_data.main_application, "activate", G_CALLBACK(activate), NULL); + g_signal_connect(gui_data.main_application, "open", G_CALLBACK(open), NULL); + g_signal_connect(gui_data.main_application, "shutdown", G_CALLBACK(shutdown), NULL); // Start our GApplication main loop - int status = g_application_run(G_APPLICATION(main_application), argc, argv); - g_object_unref(main_application); + int status = g_application_run(G_APPLICATION(gui_data.main_application), argc, argv); + g_object_unref(gui_data.main_application); return status; } diff --git a/gtk3/settings.c b/gtk3/settings.c index ab37c2d..267ec41 100644 --- a/gtk3/settings.c +++ b/gtk3/settings.c @@ -1,5 +1,8 @@ #include "settings.h" +#define get_object(id) gtk_builder_get_object(builder, id) +#define builder_get(type, id) type(get_object(id)) + static void print_config_error(GError *error) { if (error == NULL) return; @@ -102,7 +105,7 @@ void on_preferences_realize(GtkWidget *w, gpointer builder_ptr) { update_boot_rom_selector(builder); // Hook up the static preferences - gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "rewind_duration_selector"), itoa(config.rewind_duration)); + gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "rewind_duration_selector"), g_strdup_printf("%i", config.rewind_duration)); gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "dmg_revision_selector"), config.dmg_revision_name); gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "sgb_revision_selector"), config.sgb_revision_name); gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "cgb_revision_selector"), config.cgb_revision_name); @@ -114,7 +117,7 @@ void on_preferences_realize(GtkWidget *w, gpointer builder_ptr) { gtk_toggle_button_set_active(builder_get(GTK_TOGGLE_BUTTON, "integer_scaling_toggle"), config.use_integer_scaling); gtk_toggle_button_set_active(builder_get(GTK_TOGGLE_BUTTON, "aspect_ratio_toggle"), config.keep_aspect_ratio); gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "highpass_filter_selector"), config.high_pass_filter_id); - gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "sample_rate_selector"), itoa(config.sample_rate)); + gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "sample_rate_selector"), g_strdup_printf("%i", config.sample_rate)); #if ! NDEBUG gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "menubar_override_selector"), config.menubar_override); diff --git a/gtk3/settings.h b/gtk3/settings.h index 0c34d5b..00264cd 100644 --- a/gtk3/settings.h +++ b/gtk3/settings.h @@ -3,7 +3,6 @@ #include #include -#include "macros.h" #include "shader.h" #define SETTINGS_FILE "sameboy-gtk3-settings.ini"