[GTK3] Run the emulation in its own thread

The code has not been checked for thread safety yet!
This commit is contained in:
Maximilian Mader 2019-10-05 21:09:30 +02:00
parent ee6881285a
commit 8a90af4d98
Signed by: Max
GPG Key ID: F71D56A3151C4FB3
2 changed files with 25 additions and 25 deletions

View File

@ -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;
}

View File

@ -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 */