diff --git a/gtk3/main.c b/gtk3/main.c
index be6e436..db7cc86 100644
--- a/gtk3/main.c
+++ b/gtk3/main.c
@@ -14,6 +14,8 @@
#include "shader.h"
#include "check_menu_radio_group.h"
+#include "vram_viewer.h"
+
// used for audio and game controllers
#include "SDL.h"
#include "../SDL/audio/audio.h"
@@ -53,11 +55,6 @@ static GuiData gui_data = {
.log_to_sidebar = false,
.should_clear_sidebar = false,
- .vram_viewer_visible = false,
- .vram_viewer_updating = false,
- .vram_viewer_active_tab = "",
- .vram_viewer_is_cgb = false,
-
.audio_initialized = false,
.border_mode_changed = false,
@@ -118,34 +115,6 @@ static const GActionEntry app_entries[] = {
{ "toggle_mute", NULL, NULL, "false", on_mute_changed },
};
-static void palette_color_data_func(GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data_ptr) {
- const gchar *title = gtk_tree_view_column_get_title(col);
- const uint8_t color_index = g_ascii_strtoll(&title[6], NULL, 10);
- const uint8_t column_index = 2 + (2 * color_index);
-
- GValue color_val = G_VALUE_INIT;
- gtk_tree_model_get_value(model, iter, column_index, &color_val);
- gint color = g_value_get_int(&color_val);
- gchar *color_string = g_strdup_printf("#%06x", color);
-
- gint lightness = 0.299 * ((color >> 16) & 0xFF) + 0.587 * ((color >> 8) & 0xFF) + 0.114 * (color & 0xFF);
-
- GValue color_str = G_VALUE_INIT;
- g_value_init(&color_str, G_TYPE_STRING);
- g_value_set_string(&color_str, color_string);
- g_object_set_property(G_OBJECT(renderer), "background", &color_str);
-
- GValue fg_color_str = G_VALUE_INIT;
- g_value_init(&fg_color_str, G_TYPE_STRING);
- g_value_set_static_string(&fg_color_str, (lightness > 0x7F)? "#000000" : "#FFFFFF");
- g_object_set_property(G_OBJECT(renderer), "foreground", &fg_color_str);
-
- g_value_unset(&color_val);
- g_value_unset(&color_str);
- g_value_unset(&fg_color_str);
- g_free(color_string);
-}
-
static const char* get_sdl_joystick_power_level_name(SDL_JoystickPowerLevel level) {
switch (level) {
case SDL_JOYSTICK_POWER_EMPTY: return "Empty";
@@ -718,17 +687,20 @@ 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);
- gui_data.viewport = (Rect){
- (win_width - new_width) / 2,
- (win_height - new_height) / 2,
- new_width,
- new_height
- };
+ if (gui_data.gl_area) {
+ unsigned new_width = x_factor * GB_get_screen_width(&gb);
+ unsigned new_height = y_factor * GB_get_screen_height(&gb);
+
+ gui_data.viewport = (Rect){
+ (win_width - new_width) / 2,
+ (win_height - new_height) / 2,
+ new_width,
+ new_height
+ };
- if (!gui_data.fallback_canvas) glViewport(gui_data.viewport.x, gui_data.viewport.y, gui_data.viewport.w, gui_data.viewport.h);
+ glViewport(gui_data.viewport.x, gui_data.viewport.y, gui_data.viewport.width, gui_data.viewport.height);
+ }
}
// WHY DO WE NEED SUCH AN UGLY METHOD, GTK?!
@@ -789,8 +761,6 @@ static void update_window_geometry(void) {
if (GB_is_inited(&gb)) {
GB_set_pixels_output(&gb, get_pixels());
}
-
- update_viewport();
}
static void stop(void) {
@@ -811,140 +781,7 @@ static void stop(void) {
gui_data.stopped = true;
}
-static void on_vblank(gpointer data) {
- if (!gui_data.vram_viewer_updating && gui_data.vram_viewer_visible) {
- gui_data.vram_viewer_updating = true;
-
- 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?
-
- GtkListStore *store = gtk_list_store_new(7,
- GDK_TYPE_PIXBUF, // Preview image
- G_TYPE_STRING, // X position
- G_TYPE_STRING, // Y position
- G_TYPE_STRING, // Tile
- G_TYPE_STRING, // Tile Address
- G_TYPE_STRING, // OAM Address
- G_TYPE_STRING // Attributes
- );
-
- gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
-
- for (unsigned row = 0; row < gui_data.oam_count; ++row) {
- GdkPixbuf *pixbuf = gdk_pixbuf_new_from_bytes(
- 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, gui_data.oam_height * 2);
-
- gdk_pixbuf_scale(pixbuf, dest,
- 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, 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",
- 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",
- 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
- );
-
- g_object_unref(pixbuf);
- g_object_unref(dest);
- }
-
- gtk_tree_view_set_model(tree_view, GTK_TREE_MODEL(store));
- g_object_unref(store);
- }
- 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?
-
- GtkListStore *store = gtk_list_store_new(9,
- G_TYPE_STRING, // Name
-
- G_TYPE_STRING, // Color 0 string
- G_TYPE_INT, // Color 0 integer
-
- G_TYPE_STRING, // Color 1 string
- G_TYPE_INT, // Color 1 integer
-
- G_TYPE_STRING, // Color 2 string
- G_TYPE_INT, // Color 2 integer
-
- G_TYPE_STRING, // Color 3 string
- G_TYPE_INT // Color 3 integer
- );
-
- gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
-
- for (unsigned row = 0; row < 16; ++row) {
- uint8_t offset = (row & 7) * 4;
-
- 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),
- 1, g_strdup_printf("$%04x", color_0 & 0x7FFF),
- 2, convert_color(color_0),
- 3, g_strdup_printf("$%04x", color_1 & 0x7FFF),
- 4, convert_color(color_1),
- 5, g_strdup_printf("$%04x", color_2 & 0x7FFF),
- 6, convert_color(color_2),
- 7, g_strdup_printf("$%04x", color_3 & 0x7FFF),
- 8, convert_color(color_3),
- -1
- );
- }
-
- GtkTreeViewColumn *column_0 = gtk_tree_view_get_column(tree_view, 1);
- GtkTreeViewColumn *column_1 = gtk_tree_view_get_column(tree_view, 2);
- GtkTreeViewColumn *column_2 = gtk_tree_view_get_column(tree_view, 3);
- GtkTreeViewColumn *column_3 = gtk_tree_view_get_column(tree_view, 4);
-
- GtkCellRendererText *cell_renderer_0 = builder_get(GTK_CELL_RENDERER_TEXT, "vram_viewer_palette_cell_renderer_0");
- GtkCellRendererText *cell_renderer_1 = builder_get(GTK_CELL_RENDERER_TEXT, "vram_viewer_palette_cell_renderer_1");
- GtkCellRendererText *cell_renderer_2 = builder_get(GTK_CELL_RENDERER_TEXT, "vram_viewer_palette_cell_renderer_2");
- GtkCellRendererText *cell_renderer_3 = builder_get(GTK_CELL_RENDERER_TEXT, "vram_viewer_palette_cell_renderer_3");
-
- gtk_tree_view_column_set_cell_data_func(column_0, GTK_CELL_RENDERER(cell_renderer_0), palette_color_data_func, NULL, NULL);
- gtk_tree_view_column_set_cell_data_func(column_1, GTK_CELL_RENDERER(cell_renderer_1), palette_color_data_func, NULL, NULL);
- gtk_tree_view_column_set_cell_data_func(column_2, GTK_CELL_RENDERER(cell_renderer_2), palette_color_data_func, NULL, NULL);
- gtk_tree_view_column_set_cell_data_func(column_3, GTK_CELL_RENDERER(cell_renderer_3), palette_color_data_func, NULL, NULL);
-
- gtk_tree_view_set_model(tree_view, GTK_TREE_MODEL(store));
- g_object_unref(store);
- }
-
- // Queue a redraw of the VRAM viewer
- gtk_widget_queue_draw(GTK_WIDGET(gui_data.vram_viewer));
-
- gui_data.vram_viewer_updating = false;
- }
-
+static void on_vblank(GB_gameboy_t *gb) {
// Queue drawing of the current frame
if (gui_data.fallback_canvas) {
gtk_widget_queue_draw(GTK_WIDGET(gui_data.main_window));
@@ -952,6 +789,8 @@ static void on_vblank(gpointer data) {
else if (gui_data.gl_area) {
gtk_gl_area_queue_render(gui_data.gl_area);
}
+
+ gtk_widget_queue_draw(GTK_WIDGET(gui_data.vram_viewer));
}
static void vblank(GB_gameboy_t *gb) {
@@ -987,68 +826,11 @@ static void vblank(GB_gameboy_t *gb) {
}
}
- 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, gui_data.tileset_buffer,
- palette_type,
- palette_index
- );
- }
- 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;
-
- if (g_strcmp0("auto", palette_id) != 0) {
- palette_type = g_str_has_prefix(palette_id, "bg")? GB_PALETTE_BACKGROUND : GB_PALETTE_OAM;
- palette_index = g_ascii_digit_value(palette_id[palette_type == GB_PALETTE_OAM ? 3 : 2]);
- }
-
- GB_map_type_t map_type = GB_MAP_AUTO;
- const gchar *map_type_id = gtk_combo_box_get_active_id(builder_get(GTK_COMBO_BOX, "vram_viewer_tilemap_tilemap_selector"));
- if (g_strcmp0("auto", map_type_id) != 0) {
- map_type = (g_strcmp0("9800", map_type_id) == 0)? GB_MAP_9800 : GB_MAP_9C00;
- }
-
- GB_tileset_type_t tileset_type = GB_TILESET_AUTO;
- const gchar *tileset_type_id = gtk_combo_box_get_active_id(builder_get(GTK_COMBO_BOX, "vram_viewer_tilemap_tileset_selector"));
- if (g_strcmp0("auto", tileset_type_id) != 0) {
- tileset_type = (g_strcmp0("8800", tileset_type_id) == 0)? GB_TILESET_8800 : GB_TILESET_8000;
- }
-
- GB_draw_tilemap(gb, gui_data.tilemap_buffer,
- palette_type,
- palette_index,
- map_type,
- tileset_type
- );
-
- 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", 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", 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(gui_data.vram_viewer_palette_data[row], palette_data, size);
- }
- }
-
gui_data.do_rewind = gui_data.rewind_down;
- g_idle_add((GSourceFunc) on_vblank, NULL);
+ vram_viewer_update(gui_data.vram_viewer, gb);
+
+ g_idle_add((GSourceFunc) on_vblank, gb);
}
static void handle_events(GB_gameboy_t *gb) {
@@ -1402,7 +1184,6 @@ static void quit(void) {
g_debug("quit(void);");
stop();
- while (gui_data.stopping);
GtkWindow *window = gui_data.main_window ? GTK_WINDOW(gui_data.main_window) : NULL;
save_config(window, gui_data.config_modification_date);
@@ -1496,249 +1277,6 @@ static void on_window_state_change(GtkWidget *w, GdkEventWindowState *event, gpo
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) {
- 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) {
- 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(&gui_data.tileset_buffer_mutex);
-
- guint width, height;
- GtkStyleContext *context;
-
- context = gtk_widget_get_style_context(widget);
- width = gtk_widget_get_allocated_width(widget);
- height = gtk_widget_get_allocated_height(widget);
-
- gtk_render_background(context, cr, 0, 0, width, height);
-
- cairo_surface_t *surface = cairo_image_surface_create_for_data(
- (unsigned char *) gui_data.tileset_buffer,
- CAIRO_FORMAT_RGB24,
- 256,
- 192,
- cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, 256)
- );
-
- cairo_scale(cr, 2.0, 2.0);
- cairo_set_source_surface(cr, surface, 0, 0);
- cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
- cairo_paint(cr);
-
- if (gtk_toggle_button_get_active(builder_get(GTK_TOGGLE_BUTTON, "vram_viewer_tileset_toggle_grid_button"))) {
- cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.25);
- cairo_set_line_width(cr, 1);
-
- const int divisions_x = 256 / 8;
- const int divisions_y = 192 / 8;
-
- for (int i = 0; i < divisions_x; i++) {
- const int j = 256 * i;
-
- cairo_move_to(cr, j / divisions_x, 0);
- cairo_line_to(cr, j / divisions_x, 192);
- }
-
- for (int i = 0; i < divisions_y; i++) {
- const int j = 192 * i;
-
- cairo_move_to(cr, 0, j / divisions_y);
- cairo_line_to(cr, 256, j / divisions_y);
- }
-
- cairo_stroke(cr);
- }
-
- 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(&gui_data.tilemap_buffer_mutex);
-
- guint width, height;
- GtkStyleContext *context;
-
- context = gtk_widget_get_style_context(widget);
- width = gtk_widget_get_allocated_width(widget);
- height = gtk_widget_get_allocated_height(widget);
-
- gtk_render_background(context, cr, 0, 0, width, height);
-
- cairo_surface_t *surface = cairo_image_surface_create_for_data(
- (unsigned char *) gui_data.tilemap_buffer,
- CAIRO_FORMAT_RGB24,
- 256,
- 256,
- cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, 256)
- );
-
- cairo_scale(cr, 2.0, 2.0);
- cairo_set_source_surface(cr, surface, 0, 0);
- cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
- cairo_paint(cr);
-
- if (gtk_toggle_button_get_active(builder_get(GTK_TOGGLE_BUTTON, "vram_viewer_tilemap_toggle_grid_button"))) {
- cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.25);
- cairo_set_line_width(cr, 1);
-
- const int divisions = 256 / 8;
-
- for (int i = 0; i < divisions; i++) {
- const int j = 256 * i;
-
- cairo_move_to(cr, j / divisions, 0);
- cairo_line_to(cr, j / divisions, 256);
- cairo_move_to(cr, 0, j / divisions);
- cairo_line_to(cr, 256, j / divisions);
- }
-
- cairo_stroke(cr);
- }
-
- if (gtk_toggle_button_get_active(builder_get(GTK_TOGGLE_BUTTON, "vram_viewer_tilemap_toggle_scrolling_button"))) {
- cairo_rectangle(cr, -2, -2, width + 2, height + 2);
-
- for (unsigned x = 0; x < 2; x++) {
- for (unsigned y = 0; y < 2; y++) {
- Rect rect = gui_data.scroll_rect;
- rect.x -= 256 * x;
- rect.y += 256 * y;
-
- cairo_rectangle(cr, rect.x, rect.y, rect.w, rect.h);
- }
- }
-
- cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
- cairo_set_line_width(cr, 2);
- cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);
- cairo_set_source_rgba(cr, 0.2, 0.2, 0.2, 0.5);
- cairo_fill_preserve(cr);
- cairo_clip_preserve(cr);
- cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.6);
- cairo_stroke(cr);
- }
-
- g_mutex_unlock(&gui_data.tilemap_buffer_mutex);
- return false;
-}
-
-static gboolean on_motion_vram_viewer_tileset(GtkWidget *widget, GdkEventMotion *event) {
- int x, y;
-
- if (event->is_hint) {
- gdk_window_get_pointer (event->window, &x, &y, NULL);
- }
- else {
- x = event->x;
- y = event->y;
- }
-
- // Compensate for our canvas scale
- x /= 2;
- y /= 2;
-
- uint8_t bank = x >= 128? 1 : 0;
- x &= 127;
- uint16_t tile = x / 8 + y / 8 * 16;
-
- 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;
-}
-
-static gboolean on_motion_vram_viewer_tilemap(GtkWidget *widget, GdkEventMotion *event) {
- int x, y;
-
- if (event->is_hint) {
- gdk_window_get_pointer (event->window, &x, &y, NULL);
- }
- else {
- x = event->x;
- y = event->y;
- }
-
- // Compensate for our canvas scale
- x /= 2;
- y /= 2;
-
- GtkLabel *status = builder_get(GTK_LABEL, "vram_viewer_status");
-
- uint16_t map_offset = x / 8 + y / 8 * 32;
- uint16_t map_base = 0x1800;
-
- GB_map_type_t map_type = GB_MAP_AUTO;
- const gchar *map_type_id = gtk_combo_box_get_active_id(builder_get(GTK_COMBO_BOX, "vram_viewer_tilemap_tilemap_selector"));
- if (g_strcmp0("auto", map_type_id) != 0) {
- map_type = (g_strcmp0("9800", map_type_id) == 0)? GB_MAP_9800 : GB_MAP_9C00;
- }
-
- GB_tileset_type_t tileset_type = GB_TILESET_AUTO;
- const gchar *tileset_type_id = gtk_combo_box_get_active_id(builder_get(GTK_COMBO_BOX, "vram_viewer_tilemap_tileset_selector"));
- if (g_strcmp0("auto", tileset_type_id) != 0) {
- tileset_type = (g_strcmp0("8800", tileset_type_id) == 0)? GB_TILESET_8800 : GB_TILESET_8000;
- }
-
- uint8_t lcdc = ((uint8_t *)GB_get_direct_access(&gb, GB_DIRECT_ACCESS_IO, NULL, NULL))[GB_IO_LCDC];
- uint8_t *vram = GB_get_direct_access(&gb, GB_DIRECT_ACCESS_VRAM, NULL, NULL);
-
- if (map_type == GB_MAP_9C00 || (map_type == GB_MAP_AUTO && lcdc & 0x08)) {
- map_base = 0x1c00;
- }
-
- if (tileset_type == GB_TILESET_AUTO) {
- tileset_type = (lcdc & 0x10)? GB_TILESET_8800 : GB_TILESET_8000;
- }
-
- uint8_t tile = vram[map_base + map_offset];
- uint16_t tile_address = 0;
- if (tileset_type == GB_TILESET_8000) {
- tile_address = 0x8000 + tile * 0x10;
- }
- else {
- tile_address = 0x9000 + (int8_t)tile * 0x10;
- }
-
- if (GB_is_cgb(&gb)) {
- uint8_t attributes = vram[map_base + map_offset + 0x2000];
- gtk_label_set_text(status, g_strdup_printf("Tile number $%02x (%d:$%04x) at map address $%04x (Attributes: %c%c%c%d%d)",
- tile,
- attributes & 0x8? 1 : 0,
- tile_address,
- 0x8000 + map_base + map_offset,
- (attributes & 0x80) ? 'P' : '-',
- (attributes & 0x40) ? 'V' : '-',
- (attributes & 0x20) ? 'H' : '-',
- attributes & 0x8? 1 : 0,
- attributes & 0x7
- ));
- }
- else {
- gtk_label_set_text(status, g_strdup_printf("Tile number $%02x ($%04x) at map address $%04x",
- tile,
- tile_address,
- 0x8000 + map_base + map_offset
- ));
- }
-
- return true;
-}
-
-static void on_vram_tab_change(GtkWidget *widget, GParamSpec *pspec, GtkStackSwitcher *self) {
- gtk_label_set_text(builder_get(GTK_LABEL, "vram_viewer_status"), "");
- 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
static void startup(GApplication *app, gpointer null_ptr) {
signal(SIGINT, quit_interrupt);
@@ -1774,7 +1312,7 @@ static void startup(GApplication *app, gpointer null_ptr) {
g_signal_connect(gui_data.preferences, "realize", G_CALLBACK(on_preferences_realize), (gpointer) gui_data.builder);
init_config(app, gui_data.cli_options.config_path, &gui_data.config_modification_date, gui_data.preferences);
- gui_data.vram_viewer = GTK_WINDOW(get_object("vram_viewer"));
+ gui_data.vram_viewer = vram_viewer_new();
gui_data.memory_viewer = GTK_WINDOW(get_object("memory_viewer"));
gui_data.console = GTK_WINDOW(get_object("console"));
@@ -1890,26 +1428,12 @@ static void connect_signal_handlers(GApplication *app) {
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(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(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);
-
- gtk_widget_add_events(builder_get(GTK_WIDGET, "vram_viewer_tileset_canvas"), GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
- gtk_widget_add_events(builder_get(GTK_WIDGET, "vram_viewer_tilemap_canvas"), GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
-
- g_signal_connect(get_object("vram_viewer_tileset_canvas"), "motion_notify_event", G_CALLBACK(on_motion_vram_viewer_tileset), NULL);
- g_signal_connect(get_object("vram_viewer_tilemap_canvas"), "motion_notify_event", G_CALLBACK(on_motion_vram_viewer_tilemap), NULL);
-
- g_signal_connect(get_object("vram_viewer_stack"), "notify::visible-child", G_CALLBACK(on_vram_tab_change), NULL);
}
// TODO: Comment
@@ -1942,7 +1466,7 @@ static void gl_draw(void) {
render_bitmap_with_shader(
&gui_data.shader, _pixels, previous,
GB_get_screen_width(&gb), GB_get_screen_height(&gb),
- gui_data.viewport.x, gui_data.viewport.y, gui_data.viewport.w, gui_data.viewport.h,
+ gui_data.viewport.x, gui_data.viewport.y, gui_data.viewport.width, gui_data.viewport.height,
mode
);
}
@@ -1965,6 +1489,7 @@ static gboolean on_draw_fallback(GtkWidget *widget, cairo_t *cr, gpointer data)
guint screen_height = GB_get_screen_height(&gb);
gtk_render_background(context, cr, 0, 0, width, height);
+ gtk_render_frame(context, cr, 0, 0, width, height);
cairo_surface_t *surface = cairo_image_surface_create_for_data(
(unsigned char *) get_current_buffer(),
@@ -1975,7 +1500,7 @@ static gboolean on_draw_fallback(GtkWidget *widget, cairo_t *cr, gpointer data)
);
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_scale(cr, gui_data.viewport.width / screen_width, gui_data.viewport.height / screen_height);
cairo_set_source_surface(cr, surface, 0, 0);
cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
cairo_paint(cr);
@@ -2103,7 +1628,6 @@ static void shutdown(GApplication *app, GFile **files, gint n_files, const gchar
g_debug("SHUTDOWN");
stop();
- while (gui_data.stopping);
SDL_Quit();
if (gui_data.image_buffers[0]) g_free(gui_data.image_buffers[0]);
@@ -2185,13 +1709,13 @@ static void close_rom(void) {
}
// Clear the VRAM viewer
- 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(&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(&gui_data.tilemap_buffer_mutex);
- memset(gui_data.tilemap_buffer, 0, sizeof gui_data.tilemap_buffer);
- g_mutex_unlock(&gui_data.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);
diff --git a/gtk3/resources/ui/vram_viewer.ui b/gtk3/resources/ui/vram_viewer.ui
new file mode 100644
index 0000000..574d3ed
--- /dev/null
+++ b/gtk3/resources/ui/vram_viewer.ui
@@ -0,0 +1,516 @@
+
+
+
+
+
+
+
+
+
+
+ False
+ VRAM Viewer
+ False
+
+
+
+
+
+
+
+
diff --git a/gtk3/resources/ui/window.ui b/gtk3/resources/ui/window.ui
index b275a65..6ff6464 100644
--- a/gtk3/resources/ui/window.ui
+++ b/gtk3/resources/ui/window.ui
@@ -1624,479 +1624,4 @@ Maximilian Mader https://github.com/max-m
-
- False
- VRAM Viewer
- False
-
-
- True
- False
- 3
- vertical
- 6
-
-
- True
- False
- center
- vram_viewer_stack
-
-
- False
- True
- 0
-
-
-
-
- True
- False
- False
- False
- slide-left-right
- True
-
-
- True
- False
- vertical
-
-
- True
- False
- 6
- 6
- 3
-
-
- True
- False
- 0
- bg0
-
- - Background Palette 0
- - Background Palette 1
- - Background Palette 2
- - Background Palette 3
- - Background Palette 4
- - Background Palette 5
- - Background Palette 6
- - Background Palette 7
- - <separator>
- - Object Palette 0
- - Object Palette 1
- - Object Palette 2
- - Object Palette 3
- - Object Palette 4
- - Object Palette 5
- - Object Palette 6
- - Object Palette 7
-
-
-
- False
- True
- 0
-
-
-
-
- Grid
- 70
- True
- True
- True
-
-
- False
- True
- end
- 2
-
-
-
-
-
- False
- True
- 0
-
-
-
-
- 512
- 384
- True
- True
- False
-
-
- True
- True
- 1
-
-
-
-
- vram_viewer_tileset
- Tileset
-
-
-
-
- True
- False
- vertical
-
-
- True
- False
- 6
- 6
- 3
-
-
- True
- False
- 0
- auto
-
- - Effective Palettes
- - <separator>
- - Background Palette 0
- - Background Palette 1
- - Background Palette 2
- - Background Palette 3
- - Background Palette 4
- - Background Palette 5
- - Background Palette 6
- - Background Palette 7
- - <separator>
- - Object Palette 0
- - Object Palette 1
- - Object Palette 2
- - Object Palette 3
- - Object Palette 4
- - Object Palette 5
- - Object Palette 6
- - Object Palette 7
-
-
-
- False
- False
- 0
-
-
-
-
- True
- False
- 0
- auto
-
- - Effective Tilemap
- - <separator>
- - Tilemap at $9800
- - Tilemap at $9C00
-
-
-
- False
- True
- 1
-
-
-
-
- Grid
- True
- True
- True
- 2
-
-
- False
- True
- end
- 2
-
-
-
-
- Scrolling
- True
- True
- True
- 2
- 2
-
-
- False
- True
- end
- 3
-
-
-
-
- True
- False
- 0
- auto
-
- - Effective Tileset
- - <separator>
- - Tileset at $8800
- - Tileset at $8000
-
-
-
- False
- True
- 4
-
-
-
-
-
- False
- False
- 0
-
-
-
-
- 512
- 512
- True
- True
- False
- start
- start
- False
- False
-
-
- True
- True
- 1
-
-
-
-
- vram_viewer_tilemap
- Tilemap
- 1
-
-
-
-
- 512
- 512
- True
- True
- in
-
-
- True
- True
- False
- False
- False
-
-
-
-
-
- 32
-
-
-
- 0
-
-
-
-
-
-
- X
-
-
-
- 1
-
-
-
-
-
-
- Y
-
-
-
- 2
-
-
-
-
-
-
- Tile
-
-
-
- 3
-
-
-
-
-
-
- Tile Addr.
-
-
-
- 4
-
-
-
-
-
-
- OAM Addr.
-
-
-
- 5
-
-
-
-
-
-
- Attributes
-
-
-
- 6
-
-
-
-
-
-
-
-
- vram_viewer_sprites
- Sprites
- 2
-
-
-
-
- True
- True
- False
- False
- False
- False
-
-
-
-
-
- Type
-
-
-
- 0
-
-
-
-
-
-
- Color 0
-
-
-
- 1
-
-
-
-
-
-
- Color 1
-
-
-
- 3
-
-
-
-
-
-
- Color 2
-
-
-
- 5
-
-
-
-
-
-
- Color 3
-
-
-
- 7
-
-
-
-
-
-
- vram_viewer_palettes
- Palettes
- 3
-
-
-
-
- True
- True
- 1
-
-
-
-
- True
- False
- 5
- center
- True
- False
-
-
- True
- True
- 2
-
-
-
-
-
-
-
-
diff --git a/gtk3/sameboy.gresource.xml b/gtk3/sameboy.gresource.xml
index 289a671..3a8cf41 100644
--- a/gtk3/sameboy.gresource.xml
+++ b/gtk3/sameboy.gresource.xml
@@ -2,6 +2,7 @@
ui/window.ui
+ ui/vram_viewer.ui