void replay_init(REPLAY *rep) { // init replay mode strcpy(rep->fname, getenv("TEMP")); strcat(rep->fname, "\\lastreplay"); rep->mode = NES_REPLAY_RECORD; replay_reset(rep); // reset replay }
// 内部函数实现 static void nes_do_reset(NES *nes) { // mmc need reset first mmc_reset(&(nes->mmc)); // reset cpu & ppu & apu cpu_reset(&(nes->cpu)); ppu_reset(&(nes->ppu)); apu_reset(&(nes->apu)); // reset joypad joypad_reset(&(nes->pad)); // reset replay replay_reset(&(nes->replay)); // restart ndb ndb_set_debug(&(nes->ndb), NDB_DEBUG_MODE_RESTART); }
int nes_load_game(NES *nes, char *file) { NES_SAVE_FILE save; void *fp; NES buf; int start, end, i; int oldapuaclk; int newapuaclk; int running; int length; // protected member list static int plist[][2] = { { offsetof(NES, cpu.cbus ), sizeof(BUS ) }, { offsetof(NES, ppu.vdev ), sizeof(VDEV* ) }, { offsetof(NES, ppu.vctxt ), sizeof(void* ) }, { offsetof(NES, apu.adev ), sizeof(ADEV* ) }, { offsetof(NES, apu.actxt ), sizeof(void* ) }, { offsetof(NES, mmc.cart ), sizeof(CARTRIDGE*) }, { offsetof(NES, mmc.cbus ), sizeof(BUS ) }, { offsetof(NES, mmc.pbus ), sizeof(BUS ) }, { offsetof(NES, cart ), sizeof(CARTRIDGE ) }, { offsetof(NES, extra ), sizeof(DWORD ) }, { offsetof(NES, cbus ), (offsetof(NES, ndb) - offsetof(NES, cbus)) }, { offsetof(NES, ndb.nes ), sizeof(NES* ) }, { sizeof(NES) , 0 }, }; // open save file fp = fopen(file, "rb"); if (!fp) return 0; // pause nes thread if running running = nes_getrun(nes); if (running) nes_setrun(nes, 0); // read .sav file header fread(&save, sizeof(save), 1, fp); length = save.head_size + save.neso_size + save.sram_size + save.cram_size; if (save.neso_size) { fseek(fp, save.head_size, SEEK_SET); fread(&buf, sizeof(buf), 1, fp); } if (save.sram_size && cartridge_has_sram(&nes->cart)) { fseek(fp, save.head_size + save.neso_size, SEEK_SET); fread(nes->cart.buf_sram, 0x2000, 1, fp); } if (save.cram_size && nes->cart.ischrram) { fseek(fp, save.head_size + save.neso_size + save.sram_size, SEEK_SET); fread(nes->cart.buf_crxm, nes->cart.crom_count * 0x2000, 1, fp); } // get ppu & apu old/new pclk oldapuaclk = nes->apu.aclk_counter; newapuaclk = buf. apu.aclk_counter; //++ restore nes context data from save file data ++// i = start = 0; do { end = plist[i][0]; memcpy((BYTE*)nes + start, (BYTE*)&buf + start, end - start); start = end; start += plist[i][1]; } while (plist[i++][1]); //-- restore nes context data from save file data --// // restore ppu & mmc restore_apu(&nes->apu, oldapuaclk, newapuaclk); restore_ppu(&nes->ppu); restore_mmc(&nes->mmc); // reset replay if record modes if (nes->replay.mode == NES_REPLAY_RECORD) { replay_reset(&nes->replay); } // resume running if (running) nes_setrun(nes, 1); // close save file fclose(fp); return length; }