[GTK3] Implement VRAM tile information on hover
This commit is contained in:
parent
67248e2520
commit
ee6881285a
114
gtk3/main.c
114
gtk3/main.c
@ -468,6 +468,14 @@ static void activate(GApplication *app, gpointer user_data_gptr) {
|
|||||||
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_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);
|
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);
|
||||||
|
|
||||||
// create our renderer area
|
// create our renderer area
|
||||||
if (supports_gl) {
|
if (supports_gl) {
|
||||||
gl_area = GTK_GL_AREA(gtk_gl_area_new());
|
gl_area = GTK_GL_AREA(gtk_gl_area_new());
|
||||||
@ -826,6 +834,112 @@ static gboolean on_draw_vram_viewer_tilemap(GtkWidget *widget, cairo_t *cr, gpoi
|
|||||||
return FALSE;
|
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"), "");
|
||||||
|
}
|
||||||
|
|
||||||
G_MODULE_EXPORT void on_boot_rom_location_changed(GtkWidget *w, gpointer user_data_gptr) {
|
G_MODULE_EXPORT void on_boot_rom_location_changed(GtkWidget *w, gpointer user_data_gptr) {
|
||||||
GtkComboBox *box = GTK_COMBO_BOX(w);
|
GtkComboBox *box = GTK_COMBO_BOX(w);
|
||||||
const gchar *id = gtk_combo_box_get_active_id(box);
|
const gchar *id = gtk_combo_box_get_active_id(box);
|
||||||
|
@ -88,6 +88,9 @@ static void on_vram_viewer_realize();
|
|||||||
static void on_vram_viewer_unrealize();
|
static void on_vram_viewer_unrealize();
|
||||||
static gboolean on_draw_vram_viewer_tilemap(GtkWidget *widget, cairo_t *cr, gpointer data);
|
static gboolean on_draw_vram_viewer_tilemap(GtkWidget *widget, cairo_t *cr, gpointer data);
|
||||||
static gboolean on_draw_vram_viewer_tileset(GtkWidget *widget, cairo_t *cr, gpointer data);
|
static gboolean on_draw_vram_viewer_tileset(GtkWidget *widget, cairo_t *cr, gpointer data);
|
||||||
|
static gboolean on_motion_vram_viewer_tileset(GtkWidget *widget, GdkEventMotion *event);
|
||||||
|
static gboolean on_motion_vram_viewer_tilemap(GtkWidget *widget, GdkEventMotion *event);
|
||||||
|
static void on_vram_tab_change(GtkWidget *widget, GParamSpec *pspec, GtkStackSwitcher *self);
|
||||||
|
|
||||||
// Option bindings
|
// Option bindings
|
||||||
G_MODULE_EXPORT void on_boot_rom_location_changed(GtkWidget *w, gpointer user_data_gptr);
|
G_MODULE_EXPORT void on_boot_rom_location_changed(GtkWidget *w, gpointer user_data_gptr);
|
||||||
|
@ -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="aspect_ratio_toggle">
|
|
||||||
<property name="label" translatable="yes">Keep Aspect Ratio</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_keep_aspect_ratio_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="integer_scaling_toggle">
|
<object class="GtkCheckButton" id="integer_scaling_toggle">
|
||||||
<property name="label" translatable="yes">Use Integer Scaling</property>
|
<property name="label" translatable="yes">Use Integer Scaling</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="aspect_ratio_toggle">
|
||||||
|
<property name="label" translatable="yes">Keep Aspect Ratio</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_keep_aspect_ratio_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>
|
||||||
@ -1580,20 +1580,16 @@ Maximilian Mader https://github.com/max-m</property>
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkStatusbar" id="vram_viewer_status">
|
<object class="GtkLabel" id="vram_viewer_status">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="margin_left">10</property>
|
<property name="margin_bottom">5</property>
|
||||||
<property name="margin_right">10</property>
|
<property name="justify">center</property>
|
||||||
<property name="margin_start">10</property>
|
<property name="single_line_mode">True</property>
|
||||||
<property name="margin_end">10</property>
|
<property name="track_visited_links">False</property>
|
||||||
<property name="margin_top">6</property>
|
|
||||||
<property name="margin_bottom">6</property>
|
|
||||||
<property name="orientation">vertical</property>
|
|
||||||
<property name="spacing">2</property>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">True</property>
|
||||||
<property name="fill">True</property>
|
<property name="fill">True</property>
|
||||||
<property name="position">2</property>
|
<property name="position">2</property>
|
||||||
</packing>
|
</packing>
|
||||||
|
Loading…
Reference in New Issue
Block a user