void gameboy_stop() { global_quit = 1; /* wake up */ if (global_pause) { global_pause = 0; sem_post(&gameboy_sem); } /* unlock threads stuck during reading */ sound_term(); /* shutdown semaphore limitator */ cycles_term(); }
void moviemng_play(const char *fname, SCRN_T *scrn) { static const char ext[][5] = { "", ".AVI", ".MPG", ".avi", ".mpg" }; char movie_file[MAX_PATH] = ""; char path[MAX_PATH]; struct stat st; SDL_SysWMinfo info; ARCFILEH arch; int i; UNUSED(scrn); if (!nomovie_flag) return; memset(&info, 0, sizeof(info)); info.version.major = SDL_MAJOR_VERSION; info.version.minor = SDL_MINOR_VERSION; if (SDL_GetWMInfo(&info) <= 0) return; /* * 1. とりあえずデータディレクトリから検索 */ for (i = 0; i < NELEMENTS(ext); ++i) { milstr_ncpy(path, gamecore.suf.scriptpath, sizeof(path)); milstr_ncat(path, fname, sizeof(path)); cutExtName(path); milstr_ncat(path, ext[i], sizeof(path)); if (stat(path, &st) < 0) continue; if (st.st_mode & S_IFDIR) continue; if (access(path, R_OK) < 0) continue; /* OK */ goto run; } /* * 2. アーカイブ内に存在するか確認 * (こんなあったら嫌だなぁ…) */ for (arch = NULL, i = 0; i < ARCTYPES; ++i) { arch = arcfile_open(i, fname); if (arch) break; } if (arch) { int fd; char *buf; sprintf(path, "/tmp/." APP_NAME "-%s-XXXXXXX", fname); #if defined(HAVE_MKSTEMP) || defined(__NetBSD__) fd = mkstemp(path); #else mktemp(path); fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0600); #endif if (fd >= 0) { buf = (char *)_MALLOC(arch->size, "movie temp file"); arcfile_seek(arch, arch->pos, SEEK_SET); if (arcfile_read(arch, buf, arch->size) == arch->size) { write(fd, buf, arch->size); close(fd); _MFREE(buf); milstr_ncpy(movie_file,path,sizeof(movie_file)); goto run; } close(fd); _MFREE(buf); } } return; run: inputmng_resetmouse(0); sound_term(); info.info.x11.lock_func(); movie_play(path); info.info.x11.unlock_func(); if (movie_file[0] != '\0') { unlink(movie_file); } sound_init(audio_rate); sound_play(); }
void gameboy_run() { uint8_t op; /* reset counter */ cycles.cnt = 0; /* get interrupt flags and interrupt enables */ uint8_t *int_e; uint8_t *int_f; /* pointers to memory location of interrupt enables/flags */ int_e = mmu_addr(0xFFFF); int_f = mmu_addr(0xFF0F); /* start at normal speed */ global_cpu_double_speed = 0; /* run stuff! */ /* mechanism is simple. */ /* 1) execute instruction 2) update cycles counter 3) check interrupts */ /* and repeat forever */ while (!global_quit) { /*if (global_slow_down) { usleep(100000); global_slow_down = 0; }*/ /* pause? */ while (global_pause) sem_wait(&gameboy_sem); /* get op */ op = mmu_read(state.pc); /* print out CPU state if enabled by debug flag */ if (global_debug) { utils_log("OP: %02x F: %02x PC: %04x:%02x:%02x SP: %04x:%02x:%02x ", op, *state.f & 0xd0, state.pc, mmu_read_no_cyc(state.pc + 1), mmu_read_no_cyc(state.pc + 2), state.sp, mmu_read_no_cyc(state.sp), mmu_read_no_cyc(state.sp + 1)); utils_log("A: %02x BC: %04x DE: %04x HL: %04x FF41: %02x " "FF44: %02x ENAB: %02x INTE: %02x INTF: %02x\n", state.a, *state.bc, *state.de, *state.hl, mmu_read_no_cyc(0xFF41), mmu_read_no_cyc(0xFF44), state.int_enable, *int_e, *int_f); } /* execute instruction by the GB Z80 version */ z80_execute(op); /* if last op was Interrupt Enable (0xFB) */ /* we need to check for INTR on next cycle */ if (op == 0xFB) continue; /* interrupts filtered by enable flags */ uint8_t int_r = (*int_f & *int_e); /* check for interrupts */ if ((state.int_enable || op == 0x76) && (int_r != 0)) { /* discard useless bits */ if ((int_r & 0x1F) == 0x00) continue; /* beware of instruction that doesn't move PC! */ /* like HALT (0x76) */ if (op == 0x76) { state.pc++; if (state.int_enable == 0) continue; } /* reset int-enable flag, it will be restored after a RETI op */ state.int_enable = 0; if ((int_r & 0x01) == 0x01) { /* vblank interrupt triggers RST 5 */ /* reset flag */ *int_f &= 0xFE; /* handle the interrupt */ z80_intr(0x0040); } else if ((int_r & 0x02) == 0x02) { /* LCD Stat interrupt */ /* reset flag */ *int_f &= 0xFD; /* handle the interrupt! */ z80_intr(0x0048); } else if ((int_r & 0x04) == 0x04) { /* timer interrupt */ /* reset flag */ *int_f &= 0xFB; /* handle the interrupt! */ z80_intr(0x0050); } else if ((int_r & 0x08) == 0x08) { /* serial interrupt */ /* reset flag */ *int_f &= 0xF7; /* handle the interrupt! */ z80_intr(0x0058); } } } /* terminate all the stuff */ cartridge_term(); sound_term(); mmu_term(); return; }