📄 snapshot.cpp
字号:
if(!Memory.FillRAM[0x4213]){ // most likely an old savestate Memory.FillRAM[0x4213]=Memory.FillRAM[0x4201]; if(!Memory.FillRAM[0x4213]) Memory.FillRAM[0x4213]=Memory.FillRAM[0x4201]=0xFF; } ICPU.ShiftedPB = Registers.PB << 16; ICPU.ShiftedDB = Registers.DB << 16; S9xSetPCBase (ICPU.ShiftedPB + Registers.PC); S9xUnpackStatus (); S9xFixCycles ();// S9xReschedule (); // <-- this causes desync when recording or playing movies#ifdef ZSNES_FX if (Settings.SuperFX) S9xSuperFXPostLoadState ();#endif S9xSRTCPostLoadState (); if (Settings.SDD1) S9xSDD1PostLoadState (); IAPU.NextAPUTimerPos = CPU.Cycles * 10000L; IAPU.APUTimerCounter = 0; } if (local_cpu) delete [] local_cpu; if (local_registers) delete [] local_registers; if (local_ppu) delete [] local_ppu; if (local_dma) delete [] local_dma; if (local_vram) delete [] local_vram; if (local_ram) delete [] local_ram; if (local_sram) delete [] local_sram; if (local_fillram) delete [] local_fillram; if (local_apu) delete [] local_apu; if (local_apu_registers) delete [] local_apu_registers; if (local_apu_ram) delete [] local_apu_ram; if (local_apu_sounddata) delete [] local_apu_sounddata; if (local_sa1) delete [] local_sa1; if (local_sa1_registers) delete [] local_sa1_registers; if (local_spc) delete [] local_spc; if (local_spc_rtc) delete [] local_spc_rtc; if (local_movie_data) delete [] local_movie_data; return (result);}int FreezeSize (int size, int type){ switch (type) { case uint16_ARRAY_V: return (size * 2); case uint32_ARRAY_V: return (size * 4); default: return (size); }}void FreezeStruct (STREAM stream, char *name, void *base, FreezeData *fields, int num_fields){ // Work out the size of the required block int len = 0; int i; int j; for (i = 0; i < num_fields; i++) { if (fields [i].offset + FreezeSize (fields [i].size, fields [i].type) > len) len = fields [i].offset + FreezeSize (fields [i].size, fields [i].type); } uint8 *block = new uint8 [len]; uint8 *ptr = block; uint16 word; uint32 dword; int64 qword; // Build the block ready to be streamed out for (i = 0; i < num_fields; i++) { switch (fields [i].type) { case INT_V: switch (fields [i].size) { case 1: *ptr++ = *((uint8 *) base + fields [i].offset); break; case 2: word = *((uint16 *) ((uint8 *) base + fields [i].offset)); *ptr++ = (uint8) (word >> 8); *ptr++ = (uint8) word; break; case 4: dword = *((uint32 *) ((uint8 *) base + fields [i].offset)); *ptr++ = (uint8) (dword >> 24); *ptr++ = (uint8) (dword >> 16); *ptr++ = (uint8) (dword >> 8); *ptr++ = (uint8) dword; break; case 8: qword = *((int64 *) ((uint8 *) base + fields [i].offset)); *ptr++ = (uint8) (qword >> 56); *ptr++ = (uint8) (qword >> 48); *ptr++ = (uint8) (qword >> 40); *ptr++ = (uint8) (qword >> 32); *ptr++ = (uint8) (qword >> 24); *ptr++ = (uint8) (qword >> 16); *ptr++ = (uint8) (qword >> 8); *ptr++ = (uint8) qword; break; } break; case uint8_ARRAY_V: memmove (ptr, (uint8 *) base + fields [i].offset, fields [i].size); ptr += fields [i].size; break; case uint16_ARRAY_V: for (j = 0; j < fields [i].size; j++) { word = *((uint16 *) ((uint8 *) base + fields [i].offset + j * 2)); *ptr++ = (uint8) (word >> 8); *ptr++ = (uint8) word; } break; case uint32_ARRAY_V: for (j = 0; j < fields [i].size; j++) { dword = *((uint32 *) ((uint8 *) base + fields [i].offset + j * 4)); *ptr++ = (uint8) (dword >> 24); *ptr++ = (uint8) (dword >> 16); *ptr++ = (uint8) (dword >> 8); *ptr++ = (uint8) dword; } break; } } FreezeBlock (stream, name, block, len); delete[] block;}void FreezeBlock (STREAM stream, char *name, uint8 *block, int size){ char buffer [512]; sprintf (buffer, "%s:%06d:", name, size); WRITE_STREAM (buffer, strlen (buffer), stream); WRITE_STREAM (block, size, stream); }int UnfreezeStruct (STREAM stream, char *name, void *base, FreezeData *fields, int num_fields){ // Work out the size of the required block int len = 0; int i; int j; for (i = 0; i < num_fields; i++) { if (fields [i].offset + FreezeSize (fields [i].size, fields [i].type) > len) len = fields [i].offset + FreezeSize (fields [i].size, fields [i].type); } uint8 *block = new uint8 [len]; uint8 *ptr = block; uint16 word; uint32 dword; int64 qword; int result; if ((result = UnfreezeBlock (stream, name, block, len)) != SUCCESS) { delete block; return (result); } // Unpack the block of data into a C structure for (i = 0; i < num_fields; i++) { switch (fields [i].type) { case INT_V: switch (fields [i].size) { case 1: *((uint8 *) base + fields [i].offset) = *ptr++; break; case 2: word = *ptr++ << 8; word |= *ptr++; *((uint16 *) ((uint8 *) base + fields [i].offset)) = word; break; case 4: dword = *ptr++ << 24; dword |= *ptr++ << 16; dword |= *ptr++ << 8; dword |= *ptr++; *((uint32 *) ((uint8 *) base + fields [i].offset)) = dword; break; case 8: qword = (int64) *ptr++ << 56; qword |= (int64) *ptr++ << 48; qword |= (int64) *ptr++ << 40; qword |= (int64) *ptr++ << 32; qword |= (int64) *ptr++ << 24; qword |= (int64) *ptr++ << 16; qword |= (int64) *ptr++ << 8; qword |= (int64) *ptr++; *((int64 *) ((uint8 *) base + fields [i].offset)) = qword; break; } break; case uint8_ARRAY_V: memmove ((uint8 *) base + fields [i].offset, ptr, fields [i].size); ptr += fields [i].size; break; case uint16_ARRAY_V: for (j = 0; j < fields [i].size; j++) { word = *ptr++ << 8; word |= *ptr++; *((uint16 *) ((uint8 *) base + fields [i].offset + j * 2)) = word; } break; case uint32_ARRAY_V: for (j = 0; j < fields [i].size; j++) { dword = *ptr++ << 24; dword |= *ptr++ << 16; dword |= *ptr++ << 8; dword |= *ptr++; *((uint32 *) ((uint8 *) base + fields [i].offset + j * 4)) = dword; } break; } } delete [] block; return (result);}int UnfreezeBlock (STREAM stream, char *name, uint8 *block, int size){ char buffer [20]; int len = 0; int rem = 0; int rew_len; if (READ_STREAM (buffer, 11, stream) != 11 || strncmp (buffer, name, 3) != 0 || buffer [3] != ':' || (len = atoi (&buffer [4])) == 0) { REVERT_STREAM(stream, FIND_STREAM(stream)-11, 0); return (WRONG_FORMAT); } if (len > size) { rem = len - size; len = size; } if ((rew_len=READ_STREAM (block, len, stream)) != len) { REVERT_STREAM(stream, FIND_STREAM(stream)-11-rew_len, 0); return (WRONG_FORMAT); } if (rem) { char *junk = new char [rem]; READ_STREAM (junk, rem, stream); delete [] junk; } return (SUCCESS);}int UnfreezeStructCopy (STREAM stream, char *name, uint8** block, FreezeData *fields, int num_fields){ // Work out the size of the required block int len = 0; int i; for (i = 0; i < num_fields; i++) { if (fields [i].offset + FreezeSize (fields [i].size, fields [i].type) > len) len = fields [i].offset + FreezeSize (fields [i].size, fields [i].type); } return (UnfreezeBlockCopy (stream, name, block, len));}void UnfreezeStructFromCopy (void *base, FreezeData *fields, int num_fields, uint8* block){ int i; int j; uint8 *ptr = block; uint16 word; uint32 dword; int64 qword; // Unpack the block of data into a C structure for (i = 0; i < num_fields; i++) { switch (fields [i].type) { case INT_V: switch (fields [i].size) { case 1: *((uint8 *) base + fields [i].offset) = *ptr++; break; case 2: word = *ptr++ << 8; word |= *ptr++; *((uint16 *) ((uint8 *) base + fields [i].offset)) = word; break; case 4: dword = *ptr++ << 24; dword |= *ptr++ << 16; dword |= *ptr++ << 8; dword |= *ptr++; *((uint32 *) ((uint8 *) base + fields [i].offset)) = dword; break; case 8: qword = (int64) *ptr++ << 56; qword |= (int64) *ptr++ << 48; qword |= (int64) *ptr++ << 40; qword |= (int64) *ptr++ << 32; qword |= (int64) *ptr++ << 24; qword |= (int64) *ptr++ << 16; qword |= (int64) *ptr++ << 8; qword |= (int64) *ptr++; *((int64 *) ((uint8 *) base + fields [i].offset)) = qword; break; } break; case uint8_ARRAY_V: memmove ((uint8 *) base + fields [i].offset, ptr, fields [i].size); ptr += fields [i].size; break; case uint16_ARRAY_V: for (j = 0; j < fields [i].size; j++) { word = *ptr++ << 8; word |= *ptr++; *((uint16 *) ((uint8 *) base + fields [i].offset + j * 2)) = word; } break; case uint32_ARRAY_V: for (j = 0; j < fields [i].size; j++) { dword = *ptr++ << 24; dword |= *ptr++ << 16; dword |= *ptr++ << 8; dword |= *ptr++; *((uint32 *) ((uint8 *) base + fields [i].offset + j * 4)) = dword; } break; } }}int UnfreezeBlockCopy (STREAM stream, char *name, uint8** block, int size){ *block = new uint8 [size]; int result; if ((result = UnfreezeBlock (stream, name, *block, size)) != SUCCESS) { delete [] (*block); *block = NULL; return (result); } return (result);}extern uint8 spc_dump_dsp[0x100];bool8 S9xSPCDump (const char *filename){ static uint8 header [] = { 'S', 'N', 'E', 'S', '-', 'S', 'P', 'C', '7', '0', '0', ' ', 'S', 'o', 'u', 'n', 'd', ' ', 'F', 'i', 'l', 'e', ' ', 'D', 'a', 't', 'a', ' ', 'v', '0', '.', '3', '0', 26, 26, 26 }; static uint8 version = { 0x1e }; FILE *fs; S9xSetSoundMute (TRUE); if (!(fs = fopen (filename, "wb"))) return (FALSE); // The SPC file format: // 0000: header: 'SNES-SPC700 Sound File Data v0.30',26,26,26 // 0036: version: $1e // 0037: SPC700 PC: // 0039: SPC700 A: // 0040: SPC700 X: // 0041: SPC700 Y: // 0042: SPC700 P: // 0043: SPC700 S: // 0044: Reserved: 0, 0, 0, 0 // 0048: Title of game: 32 bytes // 0000: Song name: 32 bytes // 0000: Name of dumper: 32 bytes // 0000: Comments: 32 bytes // 0000: Date of SPC dump: 4 bytes // 0000: Fade out time in milliseconds: 4 bytes // 0000: Fade out length in milliseconds: 2 bytes // 0000: Default channel enables: 1 bytes // 0000: Emulator used to dump .SPC files: 1 byte, 1 == ZSNES // 0000: Reserved: 36 bytes // 0256: SPC700 RAM: 64K // ----: DSP Registers: 256 bytes if (fwrite (header, sizeof (header), 1, fs) != 1 || fputc (version, fs) == EOF || fseek (fs, 37, SEEK_SET) == EOF || fputc (APURegisters.PC & 0xff, fs) == EOF || fputc (APURegisters.PC >> 8, fs) == EOF || fputc (APURegisters.YA.B.A, fs) == EOF || fputc (APURegisters.X, fs) == EOF || fputc (APURegisters.YA.B.Y, fs) == EOF || fputc (APURegisters.P, fs) == EOF || fputc (APURegisters.S, fs) == EOF || fseek (fs, 256, SEEK_SET) == EOF || fwrite (IAPU.RAM, 0x10000, 1, fs) != 1 || fwrite (spc_dump_dsp, 1, 256, fs) != 256 || fwrite (APU.ExtraRAM, 64, 1, fs) != 1 || fclose (fs) < 0) { S9xSetSoundMute (FALSE); return (FALSE); } S9xSetSoundMute (FALSE); return (TRUE);}bool8 S9xUnfreezeZSNES (const char *filename)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -