[GTK3] Run the emulation in its own thread
The code has not been checked for thread safety yet!
This commit is contained in:
parent
ba82da5f49
commit
e38b0e40fa
46
gtk3/main.c
46
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
|
||||
|
||||
@ -1449,9 +1449,7 @@ static void run(GApplication *app, UserData *user_data) {
|
||||
/* 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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user