From 94e1b397cae7ab0c6473cffcba1bdb2cb2f2b08b Mon Sep 17 00:00:00 2001 From: Maximilian Mader Date: Sat, 5 Oct 2019 00:57:03 +0200 Subject: [PATCH] [GTK3] Implement palette viewer --- gtk3/main.c | 119 +++++++++++++++++- gtk3/main.h | 2 + gtk3/resources/ui/window.ui | 243 ++++++++++++++++-------------------- 3 files changed, 227 insertions(+), 137 deletions(-) diff --git a/gtk3/main.c b/gtk3/main.c index add97d3..7984917 100644 --- a/gtk3/main.c +++ b/gtk3/main.c @@ -1006,6 +1006,42 @@ static void handle_events(GB_gameboy_t *gb) { GB_set_key_state(gb, GB_KEY_START, pressed_buttons & BUTTON_MASK_START); } +static uint32_t convert_color(uint16_t color) { + const uint8_t r = ((uint16_t)(color & 0x1F) * 255) / 31; + const uint8_t g = ((uint16_t)((color >> 5) & 0x1F) * 255) / 31; + const uint8_t b = ((uint16_t)((color >> 10) & 0x1F) * 255) / 31; + + return (r << 16) | (g << 8) | b; +} + +static void palette_color_data_func(GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data) { + 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 void vblank(GB_gameboy_t *gb) { flip(); GB_set_pixels_output(gb, get_pixels()); @@ -1068,10 +1104,20 @@ static void vblank(GB_gameboy_t *gb) { }; } else if (g_strcmp0("vram_viewer_sprites", active) == 0) { - GtkListStore *store = builder_get(GTK_LIST_STORE, "sprite_list_store"); 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_list_store_clear(store); gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter); oamCount = GB_get_oam_info(gb, oamInfo, &oamHeight); @@ -1090,8 +1136,6 @@ static void vblank(GB_gameboy_t *gb) { GDK_INTERP_NEAREST ); - g_object_unref(pixbuf); - gtk_list_store_insert_with_values(store, &iter, -1, 0, dest, 1, itoa(oamInfo[row].x - 8), @@ -1113,10 +1157,77 @@ static void vblank(GB_gameboy_t *gb) { oamInfo[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", active) == 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 *palette_data = GB_get_direct_access(gb, row >= 8? GB_DIRECT_ACCESS_OBP : GB_DIRECT_ACCESS_BGP, NULL, NULL); + uint8_t offset = (row & 7) * 4; + + uint16_t color_0 = (palette_data[((0 + offset) << 1) + 1] << 8) | palette_data[((0 + offset) << 1)]; + uint16_t color_1 = (palette_data[((1 + offset) << 1) + 1] << 8) | palette_data[((1 + offset) << 1)]; + uint16_t color_2 = (palette_data[((2 + offset) << 1) + 1] << 8) | palette_data[((2 + offset) << 1)]; + uint16_t color_3 = (palette_data[((3 + offset) << 1) + 1] << 8) | palette_data[((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 diff --git a/gtk3/main.h b/gtk3/main.h index b5e2a40..b597863 100644 --- a/gtk3/main.h +++ b/gtk3/main.h @@ -108,6 +108,8 @@ static void update_viewport(void); static void update_window_geometry(); static void handle_events(GB_gameboy_t *gb); +static uint32_t convert_color(uint16_t color); +static void palette_color_data_func(GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data); static void vblank(GB_gameboy_t *gb); static void run(GApplication *app, UserData *user_data); diff --git a/gtk3/resources/ui/window.ui b/gtk3/resources/ui/window.ui index 816a3f4..de839b1 100644 --- a/gtk3/resources/ui/window.ui +++ b/gtk3/resources/ui/window.ui @@ -595,23 +595,6 @@ Maximilian Mader https://github.com/max-m 3 - - - Use Integer Scaling - True - True - False - 5 - 10 - True - - - - False - True - 4 - - Keep Aspect Ratio @@ -629,6 +612,23 @@ Maximilian Mader https://github.com/max-m 4 + + + Use Integer Scaling + True + True + False + 5 + 10 + True + + + + False + True + 4 + + False @@ -1120,35 +1120,6 @@ Maximilian Mader https://github.com/max-m - - - - - - - - - - - - - - - - - - - - - 148 - 2 - $7f - $87f0 - $fe20 - ---01 - - - False VRAM Viewer @@ -1426,91 +1397,98 @@ Maximilian Mader https://github.com/max-m - + + 512 + 512 True True - sprite_list_store - False - True - False - horizontal - - - + in - - 32 - - - - 0 - + + True + True + False + False + False + + - - - - - X - - - 1 - + + 32 + + + + 0 + + + - - - - - Y - - - 2 - + + X + + + + 1 + + + - - - - - Tile - - - 3 - + + Y + + + + 2 + + + - - - - - Tile Addr. - - - 4 - + + Tile + + + + 3 + + + - - - - - OAM Addr. - - - 5 - + + Tile Addr. + + + + 4 + + + - - - - - Attributes - - - 6 - + + OAM Addr. + + + + 5 + + + + + + + Attributes + + + + 6 + + + @@ -1525,11 +1503,10 @@ Maximilian Mader https://github.com/max-m True True + False False - True False False - both @@ -1548,7 +1525,7 @@ Maximilian Mader https://github.com/max-m Color 0 - + 1 @@ -1559,31 +1536,31 @@ Maximilian Mader https://github.com/max-m Color 1 - - - 2 - - - - - - - Color 2 - - + 3 + + + Color 2 + + + + 5 + + + + Color 3 - + - 4 + 7