From 8a90af4d980f3c63e57583962ae4cde327160cba Mon Sep 17 00:00:00 2001 From: Maximilian Mader Date: Sat, 5 Oct 2019 21:09:30 +0200 Subject: [PATCH] [GTK3] Run the emulation in its own thread The code has not been checked for thread safety yet! --- gtk3/main.c | 48 ++++++++++++++++++++++++------------------------ gtk3/main.h | 2 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/gtk3/main.c b/gtk3/main.c index 9f20fed..d5c203d 100644 --- a/gtk3/main.c +++ b/gtk3/main.c @@ -499,9 +499,7 @@ static void activate(GApplication *app, gpointer user_data_gptr) { gtk_application_add_window(GTK_APPLICATION(app), GTK_WINDOW(main_window)); gtk_widget_show_all(GTK_WIDGET(main_window)); - // Start the emulation loop. - // This loop takes care of the GTK main loop. - run(app, user_data); + g_thread_new("CoreLoop", run, user_data); } // This function gets called when the application is closed. @@ -522,7 +520,7 @@ static void open(GApplication *app, GFile **files, gint n_files, const gchar *hi exit(EXIT_FAILURE); } - user_data->file = files[0]; + user_data->file = g_file_dup(files[0]); // We have handled the files, now activate the application activate(app, user_data_gptr); @@ -1106,10 +1104,6 @@ static void update_window_geometry() { } static void handle_events(GB_gameboy_t *gb) { - while (gtk_events_pending()) { - gtk_main_iteration(); - } - GB_set_key_state(gb, GB_KEY_RIGHT, pressed_buttons & BUTTON_MASK_RIGHT); GB_set_key_state(gb, GB_KEY_LEFT, pressed_buttons & BUTTON_MASK_LEFT); GB_set_key_state(gb, GB_KEY_UP, pressed_buttons & BUTTON_MASK_UP); @@ -1156,10 +1150,7 @@ static void palette_color_data_func(GtkTreeViewColumn *col, GtkCellRenderer *ren g_free(color_string); } -static void vblank(GB_gameboy_t *gb) { - flip(); - GB_set_pixels_output(gb, get_pixels()); - +static void on_vblank(gpointer data) { // Queue drawing of the current frame if (fallback_canvas) { gtk_widget_queue_draw(GTK_WIDGET(main_window)); @@ -1177,7 +1168,7 @@ static void vblank(GB_gameboy_t *gb) { 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, + GB_draw_tileset(&gb, tileset_buffer, palette_type, palette_index ); @@ -1204,7 +1195,7 @@ static void vblank(GB_gameboy_t *gb) { tileset_type = (g_strcmp0("8800", tileset_type_id) == 0)? GB_TILESET_8800 : GB_TILESET_8000; } - GB_draw_tilemap(gb, tilemap_buffer, + GB_draw_tilemap(&gb, tilemap_buffer, palette_type, palette_index, map_type, @@ -1212,8 +1203,8 @@ static void vblank(GB_gameboy_t *gb) { ); scrollRect = (Rect){ - GB_read_memory(gb, 0xFF00 | GB_IO_SCX), - GB_read_memory(gb, 0xFF00 | GB_IO_SCY), + GB_read_memory(&gb, 0xFF00 | GB_IO_SCX), + GB_read_memory(&gb, 0xFF00 | GB_IO_SCY), 160, 144 }; } @@ -1234,7 +1225,7 @@ static void vblank(GB_gameboy_t *gb) { 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); for (unsigned row = 0; row < oamCount; ++row) { GdkPixbuf *pixbuf = gdk_pixbuf_new_from_bytes( @@ -1257,7 +1248,7 @@ static void vblank(GB_gameboy_t *gb) { 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, GB_is_cgb(&gb) ? g_strdup_printf("%c%c%c%d%d", oamInfo[row].flags & 0x80? 'P' : '-', oamInfo[row].flags & 0x40? 'Y' : '-', @@ -1303,7 +1294,7 @@ static void vblank(GB_gameboy_t *gb) { 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 *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)]; @@ -1349,7 +1340,16 @@ static void vblank(GB_gameboy_t *gb) { } } -static void run(GApplication *app, UserData *user_data) { +static void vblank(GB_gameboy_t *gb) { + flip(); + GB_set_pixels_output(gb, get_pixels()); + + g_idle_add((GSourceFunc) on_vblank, NULL); +} + +static gpointer run(gpointer user_data_gptr) { + UserData *user_data = user_data_gptr; + GB_model_t prev_model = GB_get_model(&gb); GB_model_t model = user_data->model? user_data->model : GB_MODEL_CGB_E; // TODO: Model from config @@ -1444,14 +1444,12 @@ static void run(GApplication *app, UserData *user_data) { GB_load_boot_rom_from_buffer(&gb, boot_rom_data, boot_rom_size); } } - + if (user_data->file != NULL && GB_load_rom(&gb, g_file_get_path(user_data->file)) == 0) { /* Run emulation */ while (running) { if (paused || rewind_paused) { - while (gtk_events_pending()) { - gtk_main_iteration(); - } + } else { if (do_rewind) { @@ -1468,4 +1466,6 @@ static void run(GApplication *app, UserData *user_data) { } } } + + return NULL; } diff --git a/gtk3/main.h b/gtk3/main.h index 08292e5..09217d7 100644 --- a/gtk3/main.h +++ b/gtk3/main.h @@ -114,6 +114,6 @@ 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); +static gpointer run(gpointer user_data_gptr); #endif /* main_h */