[GTK3] Run the emulation in its own thread
The code has not been checked for thread safety yet!
This commit is contained in:
parent
b23399c9ca
commit
5d68673843
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_application_add_window(GTK_APPLICATION(app), GTK_WINDOW(main_window));
|
||||||
gtk_widget_show_all(GTK_WIDGET(main_window));
|
gtk_widget_show_all(GTK_WIDGET(main_window));
|
||||||
|
|
||||||
// Start the emulation loop.
|
g_thread_new("CoreLoop", run, user_data);
|
||||||
// This loop takes care of the GTK main loop.
|
|
||||||
run(app, user_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function gets called when the application is closed.
|
// 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);
|
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
|
// We have handled the files, now activate the application
|
||||||
activate(app, user_data_gptr);
|
activate(app, user_data_gptr);
|
||||||
@ -1106,10 +1104,6 @@ static void update_window_geometry() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void handle_events(GB_gameboy_t *gb) {
|
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_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_LEFT, pressed_buttons & BUTTON_MASK_LEFT);
|
||||||
GB_set_key_state(gb, GB_KEY_UP, pressed_buttons & BUTTON_MASK_UP);
|
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);
|
g_free(color_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vblank(GB_gameboy_t *gb) {
|
static void on_vblank(gpointer data) {
|
||||||
flip();
|
|
||||||
GB_set_pixels_output(gb, get_pixels());
|
|
||||||
|
|
||||||
// Queue drawing of the current frame
|
// Queue drawing of the current frame
|
||||||
if (fallback_canvas) {
|
if (fallback_canvas) {
|
||||||
gtk_widget_queue_draw(GTK_WIDGET(main_window));
|
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;
|
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]);
|
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_type,
|
||||||
palette_index
|
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;
|
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_type,
|
||||||
palette_index,
|
palette_index,
|
||||||
map_type,
|
map_type,
|
||||||
@ -1212,8 +1203,8 @@ static void vblank(GB_gameboy_t *gb) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
scrollRect = (Rect){
|
scrollRect = (Rect){
|
||||||
GB_read_memory(gb, 0xFF00 | GB_IO_SCX),
|
GB_read_memory(&gb, 0xFF00 | GB_IO_SCX),
|
||||||
GB_read_memory(gb, 0xFF00 | GB_IO_SCY),
|
GB_read_memory(&gb, 0xFF00 | GB_IO_SCY),
|
||||||
160, 144
|
160, 144
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -1234,7 +1225,7 @@ static void vblank(GB_gameboy_t *gb) {
|
|||||||
|
|
||||||
gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
|
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) {
|
for (unsigned row = 0; row < oamCount; ++row) {
|
||||||
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_bytes(
|
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),
|
3, g_strdup_printf("$%02x", oamInfo[row].tile),
|
||||||
4, g_strdup_printf("$%04x", 0x8000 + oamInfo[row].tile * 0x10),
|
4, g_strdup_printf("$%04x", 0x8000 + oamInfo[row].tile * 0x10),
|
||||||
5, g_strdup_printf("$%04x", oamInfo[row].oam_addr),
|
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",
|
? g_strdup_printf("%c%c%c%d%d",
|
||||||
oamInfo[row].flags & 0x80? 'P' : '-',
|
oamInfo[row].flags & 0x80? 'P' : '-',
|
||||||
oamInfo[row].flags & 0x40? 'Y' : '-',
|
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);
|
gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
|
||||||
|
|
||||||
for (unsigned row = 0; row < 16; ++row) {
|
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;
|
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_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 prev_model = GB_get_model(&gb);
|
||||||
GB_model_t model = user_data->model? user_data->model : GB_MODEL_CGB_E; // TODO: Model from config
|
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 */
|
/* Run emulation */
|
||||||
while (running) {
|
while (running) {
|
||||||
if (paused || rewind_paused) {
|
if (paused || rewind_paused) {
|
||||||
while (gtk_events_pending()) {
|
|
||||||
gtk_main_iteration();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (do_rewind) {
|
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 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 palette_color_data_func(GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data);
|
||||||
static void vblank(GB_gameboy_t *gb);
|
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 */
|
#endif /* main_h */
|
||||||
|
Loading…
Reference in New Issue
Block a user