#include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 #include #else #include #include #endif static emu_context ctx; static HANDLE thread; emu_context *emu_get_context() { return &ctx; } #ifdef _WIN32 DWORD WINAPI cpu_run(void *p) { #else void *cpu_run(void *p) { #endif ctx.running = true; ctx.paused = false; ctx.ticks = 0; while (ctx.running) { if (ctx.paused) { delay(10); continue; } if (!cpu_step()) { printf("CPU stopped\n"); return 0; } } return 0; } void sleep_ms(int milis) { #ifdef _WIN32 Sleep(milis); #else usleep(milis * 1000); #endif } void emu_stop() { ctx.running = false; WaitForSingleObject(thread, INFINITE); } void emu_reset() { ppu_init(); timer_init(); cpu_init(); audio_init(); cart_init(); } void emu_start() { thread = CreateThread(NULL, 0, cpu_run, NULL, 0, NULL); if(!thread) { fprintf(stderr, "Unable to create main CPU thread!\n"); } } int emu_run(int argc, char **argv) { if (argc < 2) { printf("Usage: gbemu \n"); return -1; } if(!cart_load(argv[1])) { printf("Failed to load ROM file: %s\n", argv[1]); return -2; } char fn[1048]; char *profile = getenv("USERPROFILE"); sprintf(fn, "%s\\Documents\\gbemu", profile); CreateDirectory(fn, NULL); sprintf(fn, "%s\\Documents\\gbemu\\saves", profile); CreateDirectory(fn, NULL); sprintf(fn, "%s\\Documents\\gbemu\\states", profile); CreateDirectory(fn, NULL); printf("Cart loaded..\n"); ctx.app_path = argv[0]; ui_init(); #ifdef _WIN32 emu_reset(); emu_start(); #else pthread_t t1; if(pthread_create(&t1, NULL, cpu_run, NULL)) { fprintf(stderr, "Unable to create main CPU thread!\n"); return -1; } #endif u32 prev_frame = 0; while(!ctx.die) { sleep_ms(1); ui_handle_events(); //if (prev_frame != ppu_get_context()->current_frame) { ui_update(); //} //prev_frame = ppu_get_context()->current_frame; } return 0; } void emu_cycles(int cpu_cycles) { for (int i = 0; i < cpu_cycles; i++){ for(int n = 0; n < 4; n++){ ctx.ticks++; timer_tick(); ppu_tick(); } dma_tick(); } }