diff --git a/gtk3/main.c b/gtk3/main.c index 77d7a6e..8e4619f 100644 --- a/gtk3/main.c +++ b/gtk3/main.c @@ -65,9 +65,11 @@ static volatile bool stopping = false; #define tileset_buffer_length 256 * 192 * 4 static uint32_t tileset_buffer[tileset_buffer_length] = {0}; +static GMutex tileset_buffer_mutex; #define tilemap_buffer_length 256 * 256 * 4 static uint32_t tilemap_buffer[tilemap_buffer_length] = {0}; +static GMutex tilemap_buffer_mutex; static GB_oam_info_t oamInfo[40]; static uint16_t oamCount; @@ -240,7 +242,7 @@ static gint handle_local_options(GApplication *app, GVariantDict *options, gpoin // and the context it uses is a legacy OpenGL 1.4 context because // GTK3 calls OpenGL 2.0+ functions on it. gboolean test_gl_support(void) { - gboolean result = FALSE; + gboolean result = false; GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); g_signal_connect(window, "realize", G_CALLBACK(gl_check_realize), &result); @@ -262,7 +264,7 @@ void gl_check_realize(GtkWidget *w, gpointer user_data_gptr) { if (error != NULL) { g_warning("Failed to create context: %s", error->message); g_error_free(error); - *result = FALSE; + *result = false; } else { gdk_gl_context_make_current(context); @@ -283,7 +285,7 @@ void gl_check_realize(GtkWidget *w, gpointer user_data_gptr) { static gboolean init_controllers() { if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) < 0) { g_warning("Failed to initialize game controller support: %s", SDL_GetError()); - return FALSE; + return false; } SDL_QuitSubSystem(SDL_INIT_EVENTS); @@ -319,7 +321,7 @@ static gboolean init_controllers() { } } - return TRUE; + return true; } static gboolean init_audio() { @@ -330,7 +332,7 @@ static gboolean init_audio() { if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { g_warning("Failed to initialize audio: %s", SDL_GetError()); - return FALSE; + return false; } memset(&want_aspec, 0, sizeof(want_aspec)); @@ -364,7 +366,7 @@ static gboolean init_audio() { SDL_PauseAudioDevice(device_id, audio_playing? 0 : 1); GB_set_sample_rate(&gb, have_aspec.freq); - return TRUE; + return true; } static GB_model_t get_model() { @@ -527,11 +529,11 @@ static gboolean scroll_to_bottom(GtkTextView *textview, GtkTextMark *mark) { gtk_text_iter_set_line_offset(&iter, 0); gtk_text_buffer_move_mark(buffer, mark, &iter); - gtk_text_view_scroll_to_mark(textview, mark, 0.0, TRUE, 0.0, 0.10); + gtk_text_view_scroll_to_mark(textview, mark, 0.0, true, 0.0, 0.10); gtk_text_buffer_delete_mark(buffer, mark); - return TRUE; + return true; } static void append_pending_output(void) { @@ -539,7 +541,7 @@ static void append_pending_output(void) { if (should_clear_sidebar) { clear_sidebar(); - should_clear_sidebar = FALSE; + should_clear_sidebar = false; } if (gtk_text_buffer_get_char_count(pending_console_output) > 0) { @@ -554,7 +556,7 @@ static void append_pending_output(void) { gtk_text_buffer_get_end_iter(text_buf, &iter); gtk_text_buffer_insert_range(text_buf, &iter, &start, &end); - scroll_to_bottom(text_view, gtk_text_buffer_create_mark(text_buf, NULL, &iter, TRUE)); + scroll_to_bottom(text_view, gtk_text_buffer_create_mark(text_buf, NULL, &iter, true)); gtk_text_buffer_set_text(pending_console_output, "", -1); } @@ -571,7 +573,7 @@ static void console_log(GB_gameboy_t *gb, const char *string, GB_log_attributes // 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); + 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); @@ -610,7 +612,7 @@ 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); + gtk_box_pack_end(GTK_BOX(main_window_container), GTK_WIDGET(fallback_canvas), true, true, 0); } // Create our application’s menu. @@ -642,11 +644,11 @@ static void setup_menu(GApplication *app) { if (desktop != NULL && show_in_shell) { menubar_type = MENUBAR_SHOW_IN_SHELL; } - else if (desktop != NULL && g_str_match_string("GNOME", desktop, FALSE)) { - if (g_str_match_string("GNOME-Flashback", desktop, FALSE) || g_str_match_string("GNOME-Classic", desktop, FALSE)) { + else if (desktop != NULL && g_str_match_string("GNOME", desktop, false)) { + if (g_str_match_string("GNOME-Flashback", desktop, false) || g_str_match_string("GNOME-Classic", desktop, false)) { menubar_type = MENUBAR_SHOW_IN_WINDOW; } - else if (gdm_session != NULL && (g_str_match_string("gnome-classic", gdm_session, FALSE) || g_str_match_string("gnome-flashback", gdm_session, FALSE))) { + else if (gdm_session != NULL && (g_str_match_string("gnome-classic", gdm_session, false) || g_str_match_string("gnome-flashback", gdm_session, false))) { menubar_type = MENUBAR_SHOW_IN_WINDOW; } else { @@ -671,7 +673,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(main_window_container), GTK_WIDGET(menubar), false, false, 0); break; } @@ -916,7 +918,7 @@ static void create_canvas() { 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); + gtk_box_pack_end(GTK_BOX(main_window_container), GTK_WIDGET(gl_area), true, true, 0); } else { create_fallback_canvas(); @@ -938,8 +940,8 @@ static void setup_console() { ); gtk_text_buffer_create_tag(text_buf, "bold", "weight", PANGO_WEIGHT_BOLD, NULL); - 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); + 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); @@ -1085,7 +1087,7 @@ static gboolean on_key_press(GtkWidget *w, GdkEventKey *event, gpointer data) { pressed_buttons &= ~mask; } - return FALSE; + return false; } static void on_window_state_change(GtkWidget *w, GdkEventWindowState *event, gpointer data) { @@ -1159,14 +1161,25 @@ 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)); - if (fallback_canvas) { - gtk_widget_queue_draw(GTK_WIDGET(main_window)); - } - else if (gl_area) { - gtk_gl_area_queue_render(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(&tilemap_buffer_mutex); + memset(tilemap_buffer, 0, sizeof tilemap_buffer); + g_mutex_unlock(&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)); + + // Update menu action states action_set_enabled(main_application, "close", false); action_entries_set_enabled(emulation_entries, G_N_ELEMENTS(emulation_entries), false); } @@ -1344,7 +1357,7 @@ static gboolean on_draw_fallback(GtkWidget *widget, cairo_t *cr, gpointer data) cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST); cairo_paint(cr); - return FALSE; + return false; } // TODO: Comment @@ -1365,6 +1378,8 @@ static void on_vram_viewer_unrealize() { // 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); + guint width, height; GtkStyleContext *context; @@ -1411,11 +1426,14 @@ static gboolean on_draw_vram_viewer_tileset(GtkWidget *widget, cairo_t *cr, gpoi cairo_stroke(cr); } - return FALSE; + g_mutex_unlock(&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); + guint width, height; GtkStyleContext *context; @@ -1479,7 +1497,8 @@ static gboolean on_draw_vram_viewer_tilemap(GtkWidget *widget, cairo_t *cr, gpoi cairo_stroke(cr); } - return FALSE; + g_mutex_unlock(&tilemap_buffer_mutex); + return false; } static gboolean on_motion_vram_viewer_tileset(GtkWidget *widget, GdkEventMotion *event) { @@ -1504,7 +1523,7 @@ static gboolean on_motion_vram_viewer_tileset(GtkWidget *widget, GdkEventMotion GtkLabel *status = builder_get(GTK_LABEL, "vram_viewer_status"); gtk_label_set_text(status, g_strdup_printf("Tile number $%02x at %d:$%04x", tile & 0xFF, bank, 0x8000 + tile * 0x10)); - return TRUE; + return true; } static gboolean on_motion_vram_viewer_tilemap(GtkWidget *widget, GdkEventMotion *event) { @@ -1581,7 +1600,7 @@ static gboolean on_motion_vram_viewer_tilemap(GtkWidget *widget, GdkEventMotion )); } - return TRUE; + return true; } static void on_vram_tab_change(GtkWidget *widget, GParamSpec *pspec, GtkStackSwitcher *self) {