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
-
-
-
- False
- True
- 4
-
-
+
+
+
+ False
+ True
+ 4
+
+
-