[GTK3] Implement palette viewer
This commit is contained in:
parent
36299d124a
commit
94e1b397ca
119
gtk3/main.c
119
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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -595,23 +595,6 @@ Maximilian Mader https://github.com/max-m</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="integer_scaling_toggle">
|
||||
<property name="label" translatable="yes">Use Integer Scaling</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">10</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_use_integer_scaling_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="aspect_ratio_toggle">
|
||||
<property name="label" translatable="yes">Keep Aspect Ratio</property>
|
||||
@ -629,6 +612,23 @@ Maximilian Mader https://github.com/max-m</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="integer_scaling_toggle">
|
||||
<property name="label" translatable="yes">Use Integer Scaling</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">10</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_use_integer_scaling_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="menubar_override_selector_label">
|
||||
<property name="can_focus">False</property>
|
||||
@ -1120,35 +1120,6 @@ Maximilian Mader https://github.com/max-m</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkListStore" id="sprite_list_store">
|
||||
<columns>
|
||||
<!-- column-name Sprite -->
|
||||
<column type="GdkPixbuf"/>
|
||||
<!-- column-name X -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name Y -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name Tile -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name Tile1 -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name OAM -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name Attributes -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0"/>
|
||||
<col id="1" translatable="yes">148</col>
|
||||
<col id="2" translatable="yes">2</col>
|
||||
<col id="3" translatable="yes">$7f</col>
|
||||
<col id="4" translatable="yes">$87f0</col>
|
||||
<col id="5" translatable="yes">$fe20</col>
|
||||
<col id="6" translatable="yes">---01</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkWindow" id="vram_viewer">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">VRAM Viewer</property>
|
||||
@ -1426,91 +1397,98 @@ Maximilian Mader https://github.com/max-m</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="vram_viewer_sprites">
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="width_request">512</property>
|
||||
<property name="height_request">512</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="model">sprite_list_store</property>
|
||||
<property name="headers_clickable">False</property>
|
||||
<property name="rules_hint">True</property>
|
||||
<property name="enable_search">False</property>
|
||||
<property name="enable_grid_lines">horizontal</property>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection"/>
|
||||
</child>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="min_width">32</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererPixbuf"/>
|
||||
<attributes>
|
||||
<attribute name="pixbuf">0</attribute>
|
||||
</attributes>
|
||||
<object class="GtkTreeView" id="vram_viewer_sprites">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="headers_clickable">False</property>
|
||||
<property name="enable_search">False</property>
|
||||
<property name="show_expanders">False</property>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">X</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
<attribute name="text">1</attribute>
|
||||
</attributes>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="min_width">32</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererPixbuf"/>
|
||||
<attributes>
|
||||
<attribute name="pixbuf">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">Y</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
<attribute name="text">2</attribute>
|
||||
</attributes>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">X</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
<attribute name="text">1</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">Tile</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
<attribute name="text">3</attribute>
|
||||
</attributes>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">Y</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
<attribute name="text">2</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">Tile Addr.</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
<attribute name="text">4</attribute>
|
||||
</attributes>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">Tile</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
<attribute name="text">3</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">OAM Addr.</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
<attribute name="text">5</attribute>
|
||||
</attributes>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">Tile Addr.</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
<attribute name="text">4</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">Attributes</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
<attribute name="text">6</attribute>
|
||||
</attributes>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">OAM Addr.</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
<attribute name="text">5</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">Attributes</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
<attribute name="text">6</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
@ -1525,11 +1503,10 @@ Maximilian Mader https://github.com/max-m</property>
|
||||
<object class="GtkTreeView" id="vram_viewer_palettes">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="headers_visible">False</property>
|
||||
<property name="headers_clickable">False</property>
|
||||
<property name="rules_hint">True</property>
|
||||
<property name="enable_search">False</property>
|
||||
<property name="show_expanders">False</property>
|
||||
<property name="enable_grid_lines">both</property>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection"/>
|
||||
</child>
|
||||
@ -1548,7 +1525,7 @@ Maximilian Mader https://github.com/max-m</property>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">Color 0</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<object class="GtkCellRendererText" id="vram_viewer_palette_cell_renderer_0"/>
|
||||
<attributes>
|
||||
<attribute name="text">1</attribute>
|
||||
</attributes>
|
||||
@ -1559,31 +1536,31 @@ Maximilian Mader https://github.com/max-m</property>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">Color 1</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
<attribute name="text">2</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">Color 2</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<object class="GtkCellRendererText" id="vram_viewer_palette_cell_renderer_1"/>
|
||||
<attributes>
|
||||
<attribute name="text">3</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">Color 2</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="vram_viewer_palette_cell_renderer_2"/>
|
||||
<attributes>
|
||||
<attribute name="text">5</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">Color 3</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<object class="GtkCellRendererText" id="vram_viewer_palette_cell_renderer_3"/>
|
||||
<attributes>
|
||||
<attribute name="text">4</attribute>
|
||||
<attribute name="text">7</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
|
Loading…
Reference in New Issue
Block a user