[GTK3] Try to reset VRAM viewer when closing a ROM

This commit is contained in:
Maximilian Mader 2020-04-12 01:35:15 +02:00
parent c00946ea2e
commit 15d949e338
Signed by: Max
GPG Key ID: F71D56A3151C4FB3
1 changed files with 50 additions and 31 deletions

View File

@ -65,9 +65,11 @@ static volatile bool stopping = false;
#define tileset_buffer_length 256 * 192 * 4 #define tileset_buffer_length 256 * 192 * 4
static uint32_t tileset_buffer[tileset_buffer_length] = {0}; static uint32_t tileset_buffer[tileset_buffer_length] = {0};
static GMutex tileset_buffer_mutex;
#define tilemap_buffer_length 256 * 256 * 4 #define tilemap_buffer_length 256 * 256 * 4
static uint32_t tilemap_buffer[tilemap_buffer_length] = {0}; static uint32_t tilemap_buffer[tilemap_buffer_length] = {0};
static GMutex tilemap_buffer_mutex;
static GB_oam_info_t oamInfo[40]; static GB_oam_info_t oamInfo[40];
static uint16_t oamCount; 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 // and the context it uses is a legacy OpenGL 1.4 context because
// GTK3 calls OpenGL 2.0+ functions on it. // GTK3 calls OpenGL 2.0+ functions on it.
gboolean test_gl_support(void) { gboolean test_gl_support(void) {
gboolean result = FALSE; gboolean result = false;
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(window, "realize", G_CALLBACK(gl_check_realize), &result); 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) { if (error != NULL) {
g_warning("Failed to create context: %s", error->message); g_warning("Failed to create context: %s", error->message);
g_error_free(error); g_error_free(error);
*result = FALSE; *result = false;
} }
else { else {
gdk_gl_context_make_current(context); gdk_gl_context_make_current(context);
@ -283,7 +285,7 @@ void gl_check_realize(GtkWidget *w, gpointer user_data_gptr) {
static gboolean init_controllers() { static gboolean init_controllers() {
if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) < 0) { if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) < 0) {
g_warning("Failed to initialize game controller support: %s", SDL_GetError()); g_warning("Failed to initialize game controller support: %s", SDL_GetError());
return FALSE; return false;
} }
SDL_QuitSubSystem(SDL_INIT_EVENTS); SDL_QuitSubSystem(SDL_INIT_EVENTS);
@ -319,7 +321,7 @@ static gboolean init_controllers() {
} }
} }
return TRUE; return true;
} }
static gboolean init_audio() { static gboolean init_audio() {
@ -330,7 +332,7 @@ static gboolean init_audio() {
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
g_warning("Failed to initialize audio: %s", SDL_GetError()); g_warning("Failed to initialize audio: %s", SDL_GetError());
return FALSE; return false;
} }
memset(&want_aspec, 0, sizeof(want_aspec)); memset(&want_aspec, 0, sizeof(want_aspec));
@ -364,7 +366,7 @@ static gboolean init_audio() {
SDL_PauseAudioDevice(device_id, audio_playing? 0 : 1); SDL_PauseAudioDevice(device_id, audio_playing? 0 : 1);
GB_set_sample_rate(&gb, have_aspec.freq); GB_set_sample_rate(&gb, have_aspec.freq);
return TRUE; return true;
} }
static GB_model_t get_model() { 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_iter_set_line_offset(&iter, 0);
gtk_text_buffer_move_mark(buffer, mark, &iter); 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); gtk_text_buffer_delete_mark(buffer, mark);
return TRUE; return true;
} }
static void append_pending_output(void) { static void append_pending_output(void) {
@ -539,7 +541,7 @@ static void append_pending_output(void) {
if (should_clear_sidebar) { if (should_clear_sidebar) {
clear_sidebar(); clear_sidebar();
should_clear_sidebar = FALSE; should_clear_sidebar = false;
} }
if (gtk_text_buffer_get_char_count(pending_console_output) > 0) { 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_get_end_iter(text_buf, &iter);
gtk_text_buffer_insert_range(text_buf, &iter, &start, &end); 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); 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 // Append attributed text to "pending_console_output" GtkTextBuffer
gtk_text_buffer_get_end_iter(pending_console_output, &iter); 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_insert(pending_console_output, &iter, g_strdup(string), -1);
gtk_text_buffer_get_iter_at_mark(pending_console_output, &start, start_mark); 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()); 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, "draw", G_CALLBACK(on_draw_fallback), NULL);
g_signal_connect(fallback_canvas, "size-allocate", G_CALLBACK(resize), 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 applications menu. // Create our applications menu.
@ -642,11 +644,11 @@ static void setup_menu(GApplication *app) {
if (desktop != NULL && show_in_shell) { if (desktop != NULL && show_in_shell) {
menubar_type = MENUBAR_SHOW_IN_SHELL; menubar_type = MENUBAR_SHOW_IN_SHELL;
} }
else if (desktop != NULL && g_str_match_string("GNOME", 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)) { if (g_str_match_string("GNOME-Flashback", desktop, false) || g_str_match_string("GNOME-Classic", desktop, false)) {
menubar_type = MENUBAR_SHOW_IN_WINDOW; 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; menubar_type = MENUBAR_SHOW_IN_WINDOW;
} }
else { else {
@ -671,7 +673,7 @@ static void setup_menu(GApplication *app) {
case MENUBAR_SHOW_IN_WINDOW: { case MENUBAR_SHOW_IN_WINDOW: {
g_debug("Showing menu in the window"); g_debug("Showing menu in the window");
GtkMenuBar *menubar = GTK_MENU_BAR(gtk_menu_bar_new_from_model(menubar_model)); 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; break;
} }
@ -916,7 +918,7 @@ static void create_canvas() {
gtk_gl_area_set_has_depth_buffer(gl_area, false); gtk_gl_area_set_has_depth_buffer(gl_area, false);
gtk_gl_area_set_has_stencil_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); 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 { else {
create_fallback_canvas(); 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, "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, "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, "dashed_underline", "underline", PANGO_UNDERLINE_DOUBLE, "underline-set", true, NULL);
g_mutex_init(&debugger_input_mutex); g_mutex_init(&debugger_input_mutex);
g_cond_init(&debugger_input_cond); g_cond_init(&debugger_input_cond);
@ -1085,7 +1087,7 @@ static gboolean on_key_press(GtkWidget *w, GdkEventKey *event, gpointer data) {
pressed_buttons &= ~mask; pressed_buttons &= ~mask;
} }
return FALSE; return false;
} }
static void on_window_state_change(GtkWidget *w, GdkEventWindowState *event, gpointer data) { 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 // Clear the screen as side effect
update_window_geometry(); update_window_geometry();
gtk_widget_queue_draw(fallback_canvas ? GTK_WIDGET(fallback_canvas) : GTK_WIDGET(gl_area));
if (fallback_canvas) { // Clear the VRAM viewer
gtk_widget_queue_draw(GTK_WIDGET(main_window)); g_mutex_lock(&tileset_buffer_mutex);
} memset(tileset_buffer, 0, sizeof tileset_buffer);
else if (gl_area) { g_mutex_unlock(&tileset_buffer_mutex);
gtk_gl_area_queue_render(gl_area);
} 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_set_enabled(main_application, "close", false);
action_entries_set_enabled(emulation_entries, G_N_ELEMENTS(emulation_entries), 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_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
cairo_paint(cr); cairo_paint(cr);
return FALSE; return false;
} }
// TODO: Comment // TODO: Comment
@ -1365,6 +1378,8 @@ static void on_vram_viewer_unrealize() {
// Gets called when the tileset viewer should be redrawn // Gets called when the tileset viewer should be redrawn
static gboolean on_draw_vram_viewer_tileset(GtkWidget *widget, cairo_t *cr, gpointer data) { static gboolean on_draw_vram_viewer_tileset(GtkWidget *widget, cairo_t *cr, gpointer data) {
g_mutex_lock(&tileset_buffer_mutex);
guint width, height; guint width, height;
GtkStyleContext *context; GtkStyleContext *context;
@ -1411,11 +1426,14 @@ static gboolean on_draw_vram_viewer_tileset(GtkWidget *widget, cairo_t *cr, gpoi
cairo_stroke(cr); cairo_stroke(cr);
} }
return FALSE; g_mutex_unlock(&tileset_buffer_mutex);
return false;
} }
// Gets called when the tilemap viewer should be redrawn // Gets called when the tilemap viewer should be redrawn
static gboolean on_draw_vram_viewer_tilemap(GtkWidget *widget, cairo_t *cr, gpointer data) { static gboolean on_draw_vram_viewer_tilemap(GtkWidget *widget, cairo_t *cr, gpointer data) {
g_mutex_lock(&tilemap_buffer_mutex);
guint width, height; guint width, height;
GtkStyleContext *context; GtkStyleContext *context;
@ -1479,7 +1497,8 @@ static gboolean on_draw_vram_viewer_tilemap(GtkWidget *widget, cairo_t *cr, gpoi
cairo_stroke(cr); cairo_stroke(cr);
} }
return FALSE; g_mutex_unlock(&tilemap_buffer_mutex);
return false;
} }
static gboolean on_motion_vram_viewer_tileset(GtkWidget *widget, GdkEventMotion *event) { 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"); 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)); 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) { 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) { static void on_vram_tab_change(GtkWidget *widget, GParamSpec *pspec, GtkStackSwitcher *self) {