[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);
|
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) {
|
static void vblank(GB_gameboy_t *gb) {
|
||||||
flip();
|
flip();
|
||||||
GB_set_pixels_output(gb, get_pixels());
|
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) {
|
else if (g_strcmp0("vram_viewer_sprites", active) == 0) {
|
||||||
GtkListStore *store = builder_get(GTK_LIST_STORE, "sprite_list_store");
|
|
||||||
GtkTreeIter iter;
|
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);
|
gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
|
||||||
|
|
||||||
oamCount = GB_get_oam_info(gb, oamInfo, &oamHeight);
|
oamCount = GB_get_oam_info(gb, oamInfo, &oamHeight);
|
||||||
@ -1090,8 +1136,6 @@ static void vblank(GB_gameboy_t *gb) {
|
|||||||
GDK_INTERP_NEAREST
|
GDK_INTERP_NEAREST
|
||||||
);
|
);
|
||||||
|
|
||||||
g_object_unref(pixbuf);
|
|
||||||
|
|
||||||
gtk_list_store_insert_with_values(store, &iter, -1,
|
gtk_list_store_insert_with_values(store, &iter, -1,
|
||||||
0, dest,
|
0, dest,
|
||||||
1, itoa(oamInfo[row].x - 8),
|
1, itoa(oamInfo[row].x - 8),
|
||||||
@ -1113,10 +1157,77 @@ static void vblank(GB_gameboy_t *gb) {
|
|||||||
oamInfo[row].flags & 0x10? 1 : 0),
|
oamInfo[row].flags & 0x10? 1 : 0),
|
||||||
-1
|
-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) {
|
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
|
// Queue a redraw of the VRAM viewer
|
||||||
|
@ -108,6 +108,8 @@ static void update_viewport(void);
|
|||||||
static void update_window_geometry();
|
static void update_window_geometry();
|
||||||
|
|
||||||
static void handle_events(GB_gameboy_t *gb);
|
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 vblank(GB_gameboy_t *gb);
|
||||||
static void run(GApplication *app, UserData *user_data);
|
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>
|
<property name="position">3</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</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>
|
<child>
|
||||||
<object class="GtkCheckButton" id="aspect_ratio_toggle">
|
<object class="GtkCheckButton" id="aspect_ratio_toggle">
|
||||||
<property name="label" translatable="yes">Keep Aspect Ratio</property>
|
<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>
|
<property name="position">4</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</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>
|
<child>
|
||||||
<object class="GtkLabel" id="menubar_override_selector_label">
|
<object class="GtkLabel" id="menubar_override_selector_label">
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
@ -1120,35 +1120,6 @@ Maximilian Mader https://github.com/max-m</property>
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</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">
|
<object class="GtkWindow" id="vram_viewer">
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="title" translatable="yes">VRAM Viewer</property>
|
<property name="title" translatable="yes">VRAM Viewer</property>
|
||||||
@ -1425,15 +1396,20 @@ Maximilian Mader https://github.com/max-m</property>
|
|||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<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="shadow_type">in</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkTreeView" id="vram_viewer_sprites">
|
<object class="GtkTreeView" id="vram_viewer_sprites">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="model">sprite_list_store</property>
|
|
||||||
<property name="headers_clickable">False</property>
|
<property name="headers_clickable">False</property>
|
||||||
<property name="rules_hint">True</property>
|
|
||||||
<property name="enable_search">False</property>
|
<property name="enable_search">False</property>
|
||||||
<property name="enable_grid_lines">horizontal</property>
|
<property name="show_expanders">False</property>
|
||||||
<child internal-child="selection">
|
<child internal-child="selection">
|
||||||
<object class="GtkTreeSelection"/>
|
<object class="GtkTreeSelection"/>
|
||||||
</child>
|
</child>
|
||||||
@ -1515,6 +1491,8 @@ Maximilian Mader https://github.com/max-m</property>
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="name">vram_viewer_sprites</property>
|
<property name="name">vram_viewer_sprites</property>
|
||||||
<property name="title" translatable="yes">Sprites</property>
|
<property name="title" translatable="yes">Sprites</property>
|
||||||
@ -1525,11 +1503,10 @@ Maximilian Mader https://github.com/max-m</property>
|
|||||||
<object class="GtkTreeView" id="vram_viewer_palettes">
|
<object class="GtkTreeView" id="vram_viewer_palettes">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
|
<property name="headers_visible">False</property>
|
||||||
<property name="headers_clickable">False</property>
|
<property name="headers_clickable">False</property>
|
||||||
<property name="rules_hint">True</property>
|
|
||||||
<property name="enable_search">False</property>
|
<property name="enable_search">False</property>
|
||||||
<property name="show_expanders">False</property>
|
<property name="show_expanders">False</property>
|
||||||
<property name="enable_grid_lines">both</property>
|
|
||||||
<child internal-child="selection">
|
<child internal-child="selection">
|
||||||
<object class="GtkTreeSelection"/>
|
<object class="GtkTreeSelection"/>
|
||||||
</child>
|
</child>
|
||||||
@ -1548,7 +1525,7 @@ Maximilian Mader https://github.com/max-m</property>
|
|||||||
<object class="GtkTreeViewColumn">
|
<object class="GtkTreeViewColumn">
|
||||||
<property name="title" translatable="yes">Color 0</property>
|
<property name="title" translatable="yes">Color 0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCellRendererText"/>
|
<object class="GtkCellRendererText" id="vram_viewer_palette_cell_renderer_0"/>
|
||||||
<attributes>
|
<attributes>
|
||||||
<attribute name="text">1</attribute>
|
<attribute name="text">1</attribute>
|
||||||
</attributes>
|
</attributes>
|
||||||
@ -1559,31 +1536,31 @@ Maximilian Mader https://github.com/max-m</property>
|
|||||||
<object class="GtkTreeViewColumn">
|
<object class="GtkTreeViewColumn">
|
||||||
<property name="title" translatable="yes">Color 1</property>
|
<property name="title" translatable="yes">Color 1</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCellRendererText"/>
|
<object class="GtkCellRendererText" id="vram_viewer_palette_cell_renderer_1"/>
|
||||||
<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"/>
|
|
||||||
<attributes>
|
<attributes>
|
||||||
<attribute name="text">3</attribute>
|
<attribute name="text">3</attribute>
|
||||||
</attributes>
|
</attributes>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</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>
|
<child>
|
||||||
<object class="GtkTreeViewColumn">
|
<object class="GtkTreeViewColumn">
|
||||||
<property name="title" translatable="yes">Color 3</property>
|
<property name="title" translatable="yes">Color 3</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCellRendererText"/>
|
<object class="GtkCellRendererText" id="vram_viewer_palette_cell_renderer_3"/>
|
||||||
<attributes>
|
<attributes>
|
||||||
<attribute name="text">4</attribute>
|
<attribute name="text">7</attribute>
|
||||||
</attributes>
|
</attributes>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
Loading…
Reference in New Issue
Block a user