📄 snapshot.cpp
字号:
#undef OFFSET#define OFFSET(f) Offset(f,struct SPC7110EmuVars *)static FreezeData SnapSPC7110 [] = { {OFFSET (reg4800), 1, INT_V}, {OFFSET (reg4801), 1, INT_V}, {OFFSET (reg4802), 1, INT_V}, {OFFSET (reg4803), 1, INT_V}, {OFFSET (reg4804), 1, INT_V}, {OFFSET (reg4805), 1, INT_V}, {OFFSET (reg4806), 1, INT_V}, {OFFSET (reg4807), 1, INT_V}, {OFFSET (reg4808), 1, INT_V}, {OFFSET (reg4809), 1, INT_V}, {OFFSET (reg480A), 1, INT_V}, {OFFSET (reg480B), 1, INT_V}, {OFFSET (reg480C), 1, INT_V}, {OFFSET (reg4811), 1, INT_V}, {OFFSET (reg4812), 1, INT_V}, {OFFSET (reg4813), 1, INT_V}, {OFFSET (reg4814), 1, INT_V}, {OFFSET (reg4815), 1, INT_V}, {OFFSET (reg4816), 1, INT_V}, {OFFSET (reg4817), 1, INT_V}, {OFFSET (reg4818), 1, INT_V}, {OFFSET (reg4820), 1, INT_V}, {OFFSET (reg4821), 1, INT_V}, {OFFSET (reg4822), 1, INT_V}, {OFFSET (reg4823), 1, INT_V}, {OFFSET (reg4824), 1, INT_V}, {OFFSET (reg4825), 1, INT_V}, {OFFSET (reg4826), 1, INT_V}, {OFFSET (reg4827), 1, INT_V}, {OFFSET (reg4828), 1, INT_V}, {OFFSET (reg4829), 1, INT_V}, {OFFSET (reg482A), 1, INT_V}, {OFFSET (reg482B), 1, INT_V}, {OFFSET (reg482C), 1, INT_V}, {OFFSET (reg482D), 1, INT_V}, {OFFSET (reg482E), 1, INT_V}, {OFFSET (reg482F), 1, INT_V}, {OFFSET (reg4830), 1, INT_V}, {OFFSET (reg4831), 1, INT_V}, {OFFSET (reg4832), 1, INT_V}, {OFFSET (reg4833), 1, INT_V}, {OFFSET (reg4834), 1, INT_V}, {OFFSET (reg4840), 1, INT_V}, {OFFSET (reg4841), 1, INT_V}, {OFFSET (reg4842), 1, INT_V}, {OFFSET (AlignBy), 1, INT_V}, {OFFSET (written), 1, INT_V}, {OFFSET (offset_add), 1, INT_V}, {OFFSET (DataRomOffset), 4, INT_V}, {OFFSET (DataRomSize), 4, INT_V}, {OFFSET (bank50Internal), 4, INT_V}, {OFFSET (bank50), 0x10000, uint8_ARRAY_V}};#undef OFFSET#define OFFSET(f) Offset(f,struct SPC7110RTC *)static FreezeData SnapS7RTC [] = { {OFFSET (reg), 16, uint8_ARRAY_V}, {OFFSET (index), 2, INT_V}, {OFFSET (control), 1, INT_V}, {OFFSET (init), 1, INT_V}, {OFFSET (last_used),4,INT_V}};static char ROMFilename [_MAX_PATH];//static char SnapshotFilename [_MAX_PATH];void FreezeStruct (STREAM stream, char *name, void *base, FreezeData *fields, int num_fields);void FreezeBlock (STREAM stream, char *name, uint8 *block, int size);int UnfreezeStruct (STREAM stream, char *name, void *base, FreezeData *fields, int num_fields);int UnfreezeBlock (STREAM stream, char *name, uint8 *block, int size);int UnfreezeStructCopy (STREAM stream, char *name, uint8** block, FreezeData *fields, int num_fields);void UnfreezeStructFromCopy (void *base, FreezeData *fields, int num_fields, uint8* block);int UnfreezeBlockCopy (STREAM stream, char *name, uint8** block, int size);bool8 Snapshot (const char *filename){ return (S9xFreezeGame (filename));}bool8 S9xFreezeGame (const char *filename){ STREAM stream = NULL; if (S9xOpenSnapshotFile (filename, FALSE, &stream)) { S9xFreezeToStream (stream); S9xCloseSnapshotFile (stream); if(S9xMovieActive()) { sprintf(String, "Movie snapshot %s", S9xBasename (filename)); S9xMessage (S9X_INFO, S9X_FREEZE_FILE_INFO, String); } else { sprintf(String, "Saved %s", S9xBasename (filename)); S9xMessage (S9X_INFO, S9X_FREEZE_FILE_INFO, String); } return (TRUE); } return (FALSE);}bool8 S9xLoadSnapshot (const char *filename){ return (S9xUnfreezeGame (filename));}bool8 S9xUnfreezeGame (const char *filename){ if (S9xLoadOrigSnapshot (filename)) return (TRUE); if (S9xUnfreezeZSNES (filename)) return (TRUE); STREAM snapshot = NULL; if (S9xOpenSnapshotFile (filename, TRUE, &snapshot)) { int result; if ((result = S9xUnfreezeFromStream (snapshot)) != SUCCESS) { switch (result) { case WRONG_FORMAT: S9xMessage (S9X_ERROR, S9X_WRONG_FORMAT, "File not in Snes9x freeze format"); break; case WRONG_VERSION: S9xMessage (S9X_ERROR, S9X_WRONG_VERSION, "Incompatable Snes9x freeze file format version"); break; case WRONG_MOVIE_SNAPSHOT: S9xMessage (S9X_ERROR, S9X_WRONG_MOVIE_SNAPSHOT, MOVIE_ERR_SNAPSHOT_WRONG_MOVIE); break; case NOT_A_MOVIE_SNAPSHOT: S9xMessage (S9X_ERROR, S9X_NOT_A_MOVIE_SNAPSHOT, MOVIE_ERR_SNAPSHOT_NOT_MOVIE); break; default: case FILE_NOT_FOUND: sprintf (String, "ROM image \"%s\" for freeze file not found", ROMFilename); S9xMessage (S9X_ERROR, S9X_ROM_NOT_FOUND, String); break; } S9xCloseSnapshotFile (snapshot); return (FALSE); } if(!S9xMovieActive()) { sprintf(String, "Loaded %s", S9xBasename (filename)); S9xMessage (S9X_INFO, S9X_FREEZE_FILE_INFO, String); } S9xCloseSnapshotFile (snapshot); return (TRUE); } return (FALSE);}void S9xFreezeToStream (STREAM stream){ char buffer [1024]; int i; S9xSetSoundMute (TRUE);#ifdef ZSNES_FX if (Settings.SuperFX) S9xSuperFXPreSaveState ();#endif S9xUpdateRTC(); S9xSRTCPreSaveState (); for (i = 0; i < 8; i++) { SoundData.channels [i].previous16 [0] = (int16) SoundData.channels [i].previous [0]; SoundData.channels [i].previous16 [1] = (int16) SoundData.channels [i].previous [1]; } sprintf (buffer, "%s:%04d\n", SNAPSHOT_MAGIC, SNAPSHOT_VERSION); WRITE_STREAM (buffer, strlen (buffer), stream); sprintf (buffer, "NAM:%06d:%s%c", strlen (Memory.ROMFilename) + 1, Memory.ROMFilename, 0); WRITE_STREAM (buffer, strlen (buffer) + 1, stream); FreezeStruct (stream, "CPU", &CPU, SnapCPU, COUNT (SnapCPU)); FreezeStruct (stream, "REG", &Registers, SnapRegisters, COUNT (SnapRegisters)); FreezeStruct (stream, "PPU", &PPU, SnapPPU, COUNT (SnapPPU)); FreezeStruct (stream, "DMA", DMA, SnapDMA, COUNT (SnapDMA)); // RAM and VRAM FreezeBlock (stream, "VRA", Memory.VRAM, 0x10000); FreezeBlock (stream, "RAM", Memory.RAM, 0x20000); FreezeBlock (stream, "SRA", ::SRAM, 0x20000); FreezeBlock (stream, "FIL", Memory.FillRAM, 0x8000); if (Settings.APUEnabled) { // APU FreezeStruct (stream, "APU", &APU, SnapAPU, COUNT (SnapAPU)); FreezeStruct (stream, "ARE", &APURegisters, SnapAPURegisters, COUNT (SnapAPURegisters)); FreezeBlock (stream, "ARA", IAPU.RAM, 0x10000); FreezeStruct (stream, "SOU", &SoundData, SnapSoundData, COUNT (SnapSoundData)); } if (Settings.SA1) { SA1Registers.PC = SA1.PC - SA1.PCBase; S9xSA1PackStatus (); FreezeStruct (stream, "SA1", &SA1, SnapSA1, COUNT (SnapSA1)); FreezeStruct (stream, "SAR", &SA1Registers, SnapSA1Registers, COUNT (SnapSA1Registers)); } if (Settings.SPC7110) { FreezeStruct (stream, "SP7", &s7r, SnapSPC7110, COUNT (SnapSPC7110)); } if(Settings.SPC7110RTC) { FreezeStruct (stream, "RTC", &rtc_f9, SnapS7RTC, COUNT (SnapS7RTC)); } if (S9xMovieActive ()) { uint8* movie_freeze_buf; uint32 movie_freeze_size; S9xMovieFreeze(&movie_freeze_buf, &movie_freeze_size); if(movie_freeze_buf) { struct SnapshotMovieInfo mi; mi.MovieInputDataSize = movie_freeze_size; FreezeStruct (stream, "MOV", &mi, SnapMovie, COUNT (SnapMovie)); FreezeBlock (stream, "MID", movie_freeze_buf, movie_freeze_size); delete [] movie_freeze_buf; } } S9xSetSoundMute (FALSE);#ifdef ZSNES_FX if (Settings.SuperFX) S9xSuperFXPostSaveState ();#endif}int S9xUnfreezeFromStream (STREAM stream){ char buffer [_MAX_PATH + 1]; char rom_filename [_MAX_PATH + 1]; int result; int version; int len = strlen (SNAPSHOT_MAGIC) + 1 + 4 + 1; if (READ_STREAM (buffer, len, stream) != len) return (WRONG_FORMAT); if (strncmp (buffer, SNAPSHOT_MAGIC, strlen (SNAPSHOT_MAGIC)) != 0) return (WRONG_FORMAT); if ((version = atoi (&buffer [strlen (SNAPSHOT_MAGIC) + 1])) > SNAPSHOT_VERSION) return (WRONG_VERSION); if ((result = UnfreezeBlock (stream, "NAM", (uint8 *) rom_filename, _MAX_PATH)) != SUCCESS) return (result); if (strcasecmp (rom_filename, Memory.ROMFilename) != 0 && strcasecmp (S9xBasename (rom_filename), S9xBasename (Memory.ROMFilename)) != 0) { S9xMessage (S9X_WARNING, S9X_FREEZE_ROM_NAME, "Current loaded ROM image doesn't match that required by freeze-game file."); } // ## begin load ## uint8* local_cpu = NULL; uint8* local_registers = NULL; uint8* local_ppu = NULL; uint8* local_dma = NULL; uint8* local_vram = NULL; uint8* local_ram = NULL; uint8* local_sram = NULL; uint8* local_fillram = NULL; uint8* local_apu = NULL; uint8* local_apu_registers = NULL; uint8* local_apu_ram = NULL; uint8* local_apu_sounddata = NULL; uint8* local_sa1 = NULL; uint8* local_sa1_registers = NULL; uint8* local_spc = NULL; uint8* local_spc_rtc = NULL; uint8* local_movie_data = NULL; do { if ((result = UnfreezeStructCopy (stream, "CPU", &local_cpu, SnapCPU, COUNT (SnapCPU))) != SUCCESS) break; if ((result = UnfreezeStructCopy (stream, "REG", &local_registers, SnapRegisters, COUNT (SnapRegisters))) != SUCCESS) break; if ((result = UnfreezeStructCopy (stream, "PPU", &local_ppu, SnapPPU, COUNT (SnapPPU))) != SUCCESS) break; if ((result = UnfreezeStructCopy (stream, "DMA", &local_dma, SnapDMA, COUNT (SnapDMA))) != SUCCESS) break; if ((result = UnfreezeBlockCopy (stream, "VRA", &local_vram, 0x10000)) != SUCCESS) break; if ((result = UnfreezeBlockCopy (stream, "RAM", &local_ram, 0x20000)) != SUCCESS) break; if ((result = UnfreezeBlockCopy (stream, "SRA", &local_sram, 0x20000)) != SUCCESS) break; if ((result = UnfreezeBlockCopy (stream, "FIL", &local_fillram, 0x8000)) != SUCCESS) break; if (UnfreezeStructCopy (stream, "APU", &local_apu, SnapAPU, COUNT (SnapAPU)) == SUCCESS) { if ((result = UnfreezeStructCopy (stream, "ARE", &local_apu_registers, SnapAPURegisters, COUNT (SnapAPURegisters))) != SUCCESS) break; if ((result = UnfreezeBlockCopy (stream, "ARA", &local_apu_ram, 0x10000)) != SUCCESS) break; if ((result = UnfreezeStructCopy (stream, "SOU", &local_apu_sounddata, SnapSoundData, COUNT (SnapSoundData))) != SUCCESS) break; } if ((result = UnfreezeStructCopy (stream, "SA1", &local_sa1, SnapSA1, COUNT(SnapSA1))) == SUCCESS) { if ((result = UnfreezeStructCopy (stream, "SAR", &local_sa1_registers, SnapSA1Registers, COUNT (SnapSA1Registers))) != SUCCESS) break; } if ((result = UnfreezeStructCopy (stream, "SP7", &local_spc, SnapSPC7110, COUNT(SnapSPC7110))) != SUCCESS) { if(Settings.SPC7110) break; } if ((result = UnfreezeStructCopy (stream, "RTC", &local_spc_rtc, SnapS7RTC, COUNT (SnapS7RTC))) != SUCCESS) { if(Settings.SPC7110RTC) break; } if (S9xMovieActive ()) { SnapshotMovieInfo mi; if ((result = UnfreezeStruct (stream, "MOV", &mi, SnapMovie, COUNT(SnapMovie))) != SUCCESS) { result = NOT_A_MOVIE_SNAPSHOT; break; } if ((result = UnfreezeBlockCopy (stream, "MID", &local_movie_data, mi.MovieInputDataSize)) != SUCCESS) { result = NOT_A_MOVIE_SNAPSHOT; break; } if (!S9xMovieUnfreeze(local_movie_data, mi.MovieInputDataSize)) { result = WRONG_MOVIE_SNAPSHOT; break; } } result=SUCCESS; } while(false);// ## end load ## if (result == SUCCESS) { uint32 old_flags = CPU.Flags; uint32 sa1_old_flags = SA1.Flags; S9xReset (); S9xSetSoundMute (TRUE); UnfreezeStructFromCopy (&CPU, SnapCPU, COUNT (SnapCPU), local_cpu); UnfreezeStructFromCopy (&Registers, SnapRegisters, COUNT (SnapRegisters), local_registers); UnfreezeStructFromCopy (&PPU, SnapPPU, COUNT (SnapPPU), local_ppu); UnfreezeStructFromCopy (DMA, SnapDMA, COUNT (SnapDMA), local_dma); memcpy (Memory.VRAM, local_vram, 0x10000); memcpy (Memory.RAM, local_ram, 0x20000); memcpy (::SRAM, local_sram, 0x20000); memcpy (Memory.FillRAM, local_fillram, 0x8000); if(local_apu) { UnfreezeStructFromCopy (&APU, SnapAPU, COUNT (SnapAPU), local_apu); UnfreezeStructFromCopy (&APURegisters, SnapAPURegisters, COUNT (SnapAPURegisters), local_apu_registers); memcpy (IAPU.RAM, local_apu_ram, 0x10000); UnfreezeStructFromCopy (&SoundData, SnapSoundData, COUNT (SnapSoundData), local_apu_sounddata); } if(local_sa1) { UnfreezeStructFromCopy (&SA1, SnapSA1, COUNT (SnapSA1), local_sa1); UnfreezeStructFromCopy (&SA1Registers, SnapSA1Registers, COUNT (SnapSA1Registers), local_sa1_registers); } if(local_spc) { UnfreezeStructFromCopy (&s7r, SnapSPC7110, COUNT (SnapSPC7110), local_spc); } if(local_spc_rtc) { UnfreezeStructFromCopy (&rtc_f9, SnapS7RTC, COUNT (SnapS7RTC), local_spc_rtc); } Memory.FixROMSpeed (); CPU.Flags |= old_flags & (DEBUG_MODE_FLAG | TRACE_FLAG | SINGLE_STEP_FLAG | FRAME_ADVANCE_FLAG); IPPU.ColorsChanged = TRUE; IPPU.OBJChanged = TRUE; CPU.InDMA = FALSE; S9xFixColourBrightness (); IPPU.RenderThisFrame = FALSE; if (local_apu) { S9xSetSoundMute (FALSE); IAPU.PC = IAPU.RAM + APURegisters.PC; S9xAPUUnpackStatus (); if (APUCheckDirectPage ()) IAPU.DirectPage = IAPU.RAM + 0x100; else IAPU.DirectPage = IAPU.RAM; Settings.APUEnabled = TRUE; IAPU.APUExecuting = TRUE; } else { Settings.APUEnabled = FALSE; IAPU.APUExecuting = FALSE; S9xSetSoundMute (TRUE); } if (local_sa1) { S9xFixSA1AfterSnapshotLoad (); SA1.Flags |= sa1_old_flags & (TRACE_FLAG); } if (local_spc_rtc) { S9xUpdateRTC(); } S9xFixSoundAfterSnapshotLoad (); uint8 hdma_byte = Memory.FillRAM[0x420c]; S9xSetCPU(hdma_byte, 0x420c);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -