⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snapshot.cpp

📁 著名SFC模拟器Snes9x的源代码。
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    }    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 = Unfreeze (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;	    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);	}	S9xCloseSnapshotFile (snapshot);	return (TRUE);    }    return (FALSE);}static void Freeze (STREAM stream){    char buffer [1024];    int i;    S9xSetSoundMute (TRUE);#ifdef ZSNES_FX    if (Settings.SuperFX)	S9xSuperFXPreSaveState ();#endif    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));    }    S9xSetSoundMute (FALSE);#ifdef ZSNES_FX    if (Settings.SuperFX)	S9xSuperFXPostSaveState ();#endif}static int Unfreeze (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.");    }    uint32 old_flags = CPU.Flags;    uint32 sa1_old_flags = SA1.Flags;    S9xReset ();    S9xSetSoundMute (TRUE);    if ((result = UnfreezeStruct (stream, "CPU", &CPU, SnapCPU, 				  COUNT (SnapCPU))) != SUCCESS)	return (result);    Memory.FixROMSpeed ();    CPU.Flags |= old_flags & (DEBUG_MODE_FLAG | TRACE_FLAG |			      SINGLE_STEP_FLAG | FRAME_ADVANCE_FLAG);    if ((result = UnfreezeStruct (stream, "REG", &Registers, SnapRegisters, COUNT (SnapRegisters))) != SUCCESS)	return (result);    if ((result = UnfreezeStruct (stream, "PPU", &PPU, SnapPPU, COUNT (SnapPPU))) != SUCCESS)	return (result);    IPPU.ColorsChanged = TRUE;    IPPU.OBJChanged = TRUE;    CPU.InDMA = FALSE;    S9xFixColourBrightness ();    IPPU.RenderThisFrame = FALSE;    if ((result = UnfreezeStruct (stream, "DMA", DMA, SnapDMA, 				  COUNT (SnapDMA))) != SUCCESS)	return (result);    if ((result = UnfreezeBlock (stream, "VRA", Memory.VRAM, 0x10000)) != SUCCESS)	return (result);    if ((result = UnfreezeBlock (stream, "RAM", Memory.RAM, 0x20000)) != SUCCESS)	return (result);    if ((result = UnfreezeBlock (stream, "SRA", ::SRAM, 0x20000)) != SUCCESS)	return (result);    if ((result = UnfreezeBlock (stream, "FIL", Memory.FillRAM, 0x8000)) != SUCCESS)	return (result);    if (UnfreezeStruct (stream, "APU", &APU, SnapAPU, COUNT (SnapAPU)) == SUCCESS)    {	if ((result = UnfreezeStruct (stream, "ARE", &APURegisters, SnapAPURegisters,				      COUNT (SnapAPURegisters))) != SUCCESS)	    return (result);	if ((result = UnfreezeBlock (stream, "ARA", IAPU.RAM, 0x10000)) != SUCCESS)	    return (result);	if ((result = UnfreezeStruct (stream, "SOU", &SoundData, SnapSoundData,				      COUNT (SnapSoundData))) != SUCCESS)	    return (result);	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 ((result = UnfreezeStruct (stream, "SA1", &SA1, SnapSA1, 				  COUNT(SnapSA1))) == SUCCESS)    {	if ((result = UnfreezeStruct (stream, "SAR", &SA1Registers, 				      SnapSA1Registers, COUNT (SnapSA1Registers))) != SUCCESS)	    return (result);	S9xFixSA1AfterSnapshotLoad ();	SA1.Flags |= sa1_old_flags & (TRACE_FLAG);    }    S9xFixSoundAfterSnapshotLoad ();    ICPU.ShiftedPB = Registers.PB << 16;    ICPU.ShiftedDB = Registers.DB << 16;    S9xSetPCBase (ICPU.ShiftedPB + Registers.PC);    S9xUnpackStatus ();    S9xFixCycles ();    S9xReschedule ();#ifdef ZSNES_FX    if (Settings.SuperFX)	S9xSuperFXPostLoadState ();#endif    S9xSRTCPostLoadState ();    return (SUCCESS);}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;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -