[GTK3] Move &gb accesses on vblank to emu thread

This commit is contained in:
Maximilian Mader 2019-10-14 21:28:39 +02:00
parent a1b464bd23
commit 29ce04ff8a
Signed by: Max
GPG Key ID: F71D56A3151C4FB3
1 changed files with 87 additions and 69 deletions

View File

@ -52,6 +52,10 @@ static char *battery_save_path_ptr;
static Rect viewport = {0};
static Rect scrollRect = {0};
static bool vram_viewer_visible = false;
static bool vram_viewer_updating = false;
static gchar *vram_viewer_active_tab = "";
static gboolean vram_viewer_is_cgb = false;
static uint8_t vram_viewer_palette_data[16][0x40];
static bool running = false;
static bool stopping = false;
@ -1124,6 +1128,7 @@ static void resize() {
// Gets called when the VRAM viewer gets realized
static void on_vram_viewer_realize() {
vram_viewer_visible = true;
vram_viewer_active_tab = (gchar *)gtk_stack_get_visible_child_name(builder_get(GTK_STACK, "vram_viewer_stack"));
}
// Gets called when the VRAM viewer gets unrealized
@ -1354,6 +1359,7 @@ static gboolean on_motion_vram_viewer_tilemap(GtkWidget *widget, GdkEventMotion
static void on_vram_tab_change(GtkWidget *widget, GParamSpec *pspec, GtkStackSwitcher *self) {
gtk_label_set_text(builder_get(GTK_LABEL, "vram_viewer_status"), "");
vram_viewer_active_tab = (gchar *)gtk_stack_get_visible_child_name(builder_get(GTK_STACK, "vram_viewer_stack"));
}
G_MODULE_EXPORT void on_boot_rom_location_changed(GtkWidget *w, gpointer user_data_gptr) {
@ -1651,64 +1657,10 @@ static void palette_color_data_func(GtkTreeViewColumn *col, GtkCellRenderer *ren
}
static void on_vblank(gpointer data) {
// Queue drawing of the current frame
if (fallback_canvas) {
gtk_widget_queue_draw(GTK_WIDGET(main_window));
}
else if (gl_area) {
gtk_gl_area_queue_render(gl_area);
}
if (vram_viewer_visible) {
const gchar *active = gtk_stack_get_visible_child_name(builder_get(GTK_STACK, "vram_viewer_stack"));
if (!vram_viewer_updating && vram_viewer_visible) {
vram_viewer_updating = true;
if (g_strcmp0("vram_viewer_tileset", active) == 0) {
const gchar *palette_id = gtk_combo_box_get_active_id(builder_get(GTK_COMBO_BOX, "vram_viewer_tileset_palette_selector"));
GB_palette_type_t palette_type = g_str_has_prefix(palette_id, "bg")? GB_PALETTE_BACKGROUND : GB_PALETTE_OAM;
uint8_t palette_index = g_ascii_digit_value(palette_id[palette_type == GB_PALETTE_OAM ? 3 : 2]);
GB_draw_tileset(&gb, tileset_buffer,
palette_type,
palette_index
);
}
else if (g_strcmp0("vram_viewer_tilemap", active) == 0) {
const gchar *palette_id = gtk_combo_box_get_active_id(builder_get(GTK_COMBO_BOX, "vram_viewer_tilemap_palette_selector"));
uint8_t palette_index = 0;
GB_palette_type_t palette_type = GB_PALETTE_AUTO;
if (g_strcmp0("auto", palette_id) != 0) {
palette_type = g_str_has_prefix(palette_id, "bg")? GB_PALETTE_BACKGROUND : GB_PALETTE_OAM;
palette_index = g_ascii_digit_value(palette_id[palette_type == GB_PALETTE_OAM ? 3 : 2]);
}
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;
}
GB_draw_tilemap(&gb, tilemap_buffer,
palette_type,
palette_index,
map_type,
tileset_type
);
scrollRect = (Rect){
GB_read_memory(&gb, 0xFF00 | GB_IO_SCX),
GB_read_memory(&gb, 0xFF00 | GB_IO_SCY),
160, 144
};
}
else if (g_strcmp0("vram_viewer_sprites", active) == 0) {
if (g_strcmp0("vram_viewer_sprites", vram_viewer_active_tab) == 0) {
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?
@ -1725,8 +1677,6 @@ static void on_vblank(gpointer data) {
gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
oamCount = GB_get_oam_info(&gb, oamInfo, &oamHeight);
for (unsigned row = 0; row < oamCount; ++row) {
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_bytes(
g_bytes_new(oamInfo[row].image, 128 * sizeof(uint32_t)),
@ -1748,7 +1698,7 @@ static void on_vblank(gpointer data) {
3, g_strdup_printf("$%02x", oamInfo[row].tile),
4, g_strdup_printf("$%04x", 0x8000 + oamInfo[row].tile * 0x10),
5, g_strdup_printf("$%04x", oamInfo[row].oam_addr),
6, GB_is_cgb(&gb)
6, vram_viewer_is_cgb
? g_strdup_printf("%c%c%c%d%d",
oamInfo[row].flags & 0x80? 'P' : '-',
oamInfo[row].flags & 0x40? 'Y' : '-',
@ -1770,7 +1720,7 @@ static void on_vblank(gpointer data) {
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", vram_viewer_active_tab) == 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?
@ -1794,13 +1744,12 @@ static void on_vblank(gpointer data) {
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)];
uint16_t color_0 = (vram_viewer_palette_data[row][((0 + offset) << 1) + 1] << 8) | vram_viewer_palette_data[row][((0 + offset) << 1)];
uint16_t color_1 = (vram_viewer_palette_data[row][((1 + offset) << 1) + 1] << 8) | vram_viewer_palette_data[row][((1 + offset) << 1)];
uint16_t color_2 = (vram_viewer_palette_data[row][((2 + offset) << 1) + 1] << 8) | vram_viewer_palette_data[row][((2 + offset) << 1)];
uint16_t color_3 = (vram_viewer_palette_data[row][((3 + offset) << 1) + 1] << 8) | vram_viewer_palette_data[row][((3 + offset) << 1)];
gtk_list_store_insert_with_values(store, &iter, -1,
0, g_strdup_printf("%s %d", row >=8 ? "Object" : "Background", row & 7),
@ -1815,7 +1764,7 @@ static void on_vblank(gpointer data) {
-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);
@ -1837,6 +1786,16 @@ static void on_vblank(gpointer data) {
// Queue a redraw of the VRAM viewer
gtk_widget_queue_draw(GTK_WIDGET(vram_viewer));
vram_viewer_updating = false;
}
// Queue drawing of the current frame
if (fallback_canvas) {
gtk_widget_queue_draw(GTK_WIDGET(main_window));
}
else if (gl_area) {
gtk_gl_area_queue_render(gl_area);
}
}
@ -1844,8 +1803,6 @@ static void vblank(GB_gameboy_t *gb) {
flip();
GB_set_pixels_output(gb, get_pixels());
g_idle_add((GSourceFunc) on_vblank, NULL);
if (underclock_down && clock_mutliplier > 0.5) {
clock_mutliplier -= 1.0/16;
GB_set_clock_multiplier(gb, clock_mutliplier);
@ -1855,7 +1812,68 @@ static void vblank(GB_gameboy_t *gb) {
GB_set_clock_multiplier(gb, clock_mutliplier);
}
if (g_strcmp0("vram_viewer_tileset", vram_viewer_active_tab) == 0) {
const gchar *palette_id = gtk_combo_box_get_active_id(builder_get(GTK_COMBO_BOX, "vram_viewer_tileset_palette_selector"));
GB_palette_type_t palette_type = g_str_has_prefix(palette_id, "bg")? GB_PALETTE_BACKGROUND : GB_PALETTE_OAM;
uint8_t palette_index = g_ascii_digit_value(palette_id[palette_type == GB_PALETTE_OAM ? 3 : 2]);
GB_draw_tileset(gb, tileset_buffer,
palette_type,
palette_index
);
}
else if (g_strcmp0("vram_viewer_tilemap", vram_viewer_active_tab) == 0) {
const gchar *palette_id = gtk_combo_box_get_active_id(builder_get(GTK_COMBO_BOX, "vram_viewer_tilemap_palette_selector"));
uint8_t palette_index = 0;
GB_palette_type_t palette_type = GB_PALETTE_AUTO;
if (g_strcmp0("auto", palette_id) != 0) {
palette_type = g_str_has_prefix(palette_id, "bg")? GB_PALETTE_BACKGROUND : GB_PALETTE_OAM;
palette_index = g_ascii_digit_value(palette_id[palette_type == GB_PALETTE_OAM ? 3 : 2]);
}
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;
}
GB_draw_tilemap(gb, tilemap_buffer,
palette_type,
palette_index,
map_type,
tileset_type
);
scrollRect = (Rect){
GB_read_memory(gb, 0xFF00 | GB_IO_SCX),
GB_read_memory(gb, 0xFF00 | GB_IO_SCY),
160, 144
};
}
else if (g_strcmp0("vram_viewer_sprites", vram_viewer_active_tab) == 0) {
oamCount = GB_get_oam_info(gb, oamInfo, &oamHeight);
vram_viewer_is_cgb = GB_is_cgb(gb);
}
else if (g_strcmp0("vram_viewer_palettes", vram_viewer_active_tab) == 0) {
size_t size;
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, &size, NULL);
memcpy(vram_viewer_palette_data[row], palette_data, size);
}
}
do_rewind = rewind_down;
g_idle_add((GSourceFunc) on_vblank, NULL);
}
static void run(GuiData *gui_data) {