📄 sv_save.c
字号:
static void ArchiveThinkers(void){ thinker_t *thinker; thinkInfo_t *info; byte buffer[MAX_THINKER_SIZE]; StreamOutLong(ASEG_THINKERS); for(thinker = thinkercap.next; thinker != &thinkercap; thinker = thinker->next) { for(info = ThinkerInfo; info->tClass != TC_NULL; info++) { if(thinker->function == info->thinkerFunc) { StreamOutByte(info->tClass); memcpy(buffer, thinker, info->size); if(info->mangleFunc) { info->mangleFunc(buffer); } StreamOutBuffer(buffer, info->size); break; } } } // Add a termination marker StreamOutByte(TC_NULL);}//==========================================================================//// UnarchiveThinkers////==========================================================================static void UnarchiveThinkers(void){ int tClass; thinker_t *thinker; thinkInfo_t *info; AssertSegment(ASEG_THINKERS); while((tClass = GET_BYTE) != TC_NULL) { for(info = ThinkerInfo; info->tClass != TC_NULL; info++) { if(tClass == info->tClass) { thinker = Z_Malloc(info->size, PU_LEVEL, NULL); memcpy(thinker, SavePtr.b, info->size); SavePtr.b += info->size; thinker->function = info->thinkerFunc; if(info->restoreFunc) { info->restoreFunc(thinker); } P_AddThinker(thinker); break; } } if(info->tClass == TC_NULL) { I_Error("UnarchiveThinkers: Unknown tClass %d in " "savegame", tClass); } }}//==========================================================================//// MangleSSThinker////==========================================================================static void MangleSSThinker(ssthinker_t *sst){ sst->sector = (sector_t *)(sst->sector-sectors);}//==========================================================================//// RestoreSSThinker////==========================================================================static void RestoreSSThinker(ssthinker_t *sst){ sst->sector = §ors[(int)sst->sector]; sst->sector->specialdata = sst->thinker.function;}//==========================================================================//// RestoreSSThinkerNoSD////==========================================================================static void RestoreSSThinkerNoSD(ssthinker_t *sst){ sst->sector = §ors[(int)sst->sector];}//==========================================================================//// MangleScript////==========================================================================static void MangleScript(acs_t *script){ script->ip = (int *)((int)(script->ip)-(int)ActionCodeBase); script->line = script->line ? (line_t *)(script->line-lines) : (line_t *)-1; script->activator = (mobj_t *)GetMobjNum(script->activator);}//==========================================================================//// RestoreScript////==========================================================================static void RestoreScript(acs_t *script){ script->ip = (int *)(ActionCodeBase+(int)script->ip); if((int)script->line == -1) { script->line = NULL; } else { script->line = &lines[(int)script->line]; } SetMobjPtr((int *)&script->activator);}//==========================================================================//// RestorePlatRaise////==========================================================================static void RestorePlatRaise(plat_t *plat){ plat->sector = §ors[(int)plat->sector]; plat->sector->specialdata = T_PlatRaise; P_AddActivePlat(plat);}//==========================================================================//// RestoreMoveCeiling////==========================================================================static void RestoreMoveCeiling(ceiling_t *ceiling){ ceiling->sector = §ors[(int)ceiling->sector]; ceiling->sector->specialdata = T_MoveCeiling; P_AddActiveCeiling(ceiling);}//==========================================================================//// ArchiveScripts////==========================================================================static void ArchiveScripts(void){ int i; StreamOutLong(ASEG_SCRIPTS); for(i = 0; i < ACScriptCount; i++) { StreamOutWord(ACSInfo[i].state); StreamOutWord(ACSInfo[i].waitValue); } StreamOutBuffer(MapVars, sizeof(MapVars));}//==========================================================================//// UnarchiveScripts////==========================================================================static void UnarchiveScripts(void){ int i; AssertSegment(ASEG_SCRIPTS); for(i = 0; i < ACScriptCount; i++) { ACSInfo[i].state = GET_WORD; ACSInfo[i].waitValue = GET_WORD; } memcpy(MapVars, SavePtr.b, sizeof(MapVars)); SavePtr.b += sizeof(MapVars);}//==========================================================================//// ArchiveMisc////==========================================================================static void ArchiveMisc(void){ int ix; StreamOutLong(ASEG_MISC); for (ix=0; ix<MAXPLAYERS; ix++) { StreamOutLong(localQuakeHappening[ix]); }}//==========================================================================//// UnarchiveMisc////==========================================================================static void UnarchiveMisc(void){ int ix; AssertSegment(ASEG_MISC); for (ix=0; ix<MAXPLAYERS; ix++) { localQuakeHappening[ix] = GET_LONG; }}//==========================================================================//// RemoveAllThinkers////==========================================================================static void RemoveAllThinkers(void){ thinker_t *thinker; thinker_t *nextThinker; thinker = thinkercap.next; while(thinker != &thinkercap) { nextThinker = thinker->next; if(thinker->function == P_MobjThinker) { P_RemoveMobj((mobj_t *)thinker); } else { Z_Free(thinker); } thinker = nextThinker; } P_InitThinkers();}//==========================================================================//// ArchiveSounds////==========================================================================static void ArchiveSounds(void){ seqnode_t *node; sector_t *sec; int difference; int i; StreamOutLong(ASEG_SOUNDS); // Save the sound sequences StreamOutLong(ActiveSequences); for(node = SequenceListHead; node; node = node->next) { StreamOutLong(node->sequence); StreamOutLong(node->delayTics); StreamOutLong(node->volume); StreamOutLong(SN_GetSequenceOffset(node->sequence, node->sequencePtr)); StreamOutLong(node->currentSoundID); for(i = 0; i < po_NumPolyobjs; i++) { if(node->mobj == (mobj_t *)&polyobjs[i].startSpot) { break; } } if(i == po_NumPolyobjs) { // Sound is attached to a sector, not a polyobj sec = R_PointInSubsector(node->mobj->x, node->mobj->y)->sector; difference = (int)((byte *)sec -(byte *)§ors[0])/sizeof(sector_t); StreamOutLong(0); // 0 -- sector sound origin } else { StreamOutLong(1); // 1 -- polyobj sound origin difference = i; } StreamOutLong(difference); }}//==========================================================================//// UnarchiveSounds////==========================================================================static void UnarchiveSounds(void){ int i; int numSequences; int sequence; int delayTics; int volume; int seqOffset; int soundID; int polySnd; int secNum; mobj_t *sndMobj; AssertSegment(ASEG_SOUNDS); // Reload and restart all sound sequences numSequences = GET_LONG; i = 0; while(i < numSequences) { sequence = GET_LONG; delayTics = GET_LONG; volume = GET_LONG; seqOffset = GET_LONG; soundID = GET_LONG; polySnd = GET_LONG; secNum = GET_LONG; if(!polySnd) { sndMobj = (mobj_t *)§ors[secNum].soundorg; } else { sndMobj = (mobj_t *)&polyobjs[secNum].startSpot; } SN_StartSequence(sndMobj, sequence); SN_ChangeNodeData(i, seqOffset, delayTics, volume, soundID); i++; }}//==========================================================================//// ArchivePolyobjs////==========================================================================static void ArchivePolyobjs(void){ int i; StreamOutLong(ASEG_POLYOBJS); StreamOutLong(po_NumPolyobjs); for(i = 0; i < po_NumPolyobjs; i++) { StreamOutLong(polyobjs[i].tag); StreamOutLong(polyobjs[i].angle); StreamOutLong(polyobjs[i].startSpot.x); StreamOutLong(polyobjs[i].startSpot.y); }}//==========================================================================//// UnarchivePolyobjs////==========================================================================static void UnarchivePolyobjs(void){ int i; fixed_t deltaX; fixed_t deltaY; AssertSegment(ASEG_POLYOBJS); if(GET_LONG != po_NumPolyobjs) { I_Error("UnarchivePolyobjs: Bad polyobj count"); } for(i = 0; i < po_NumPolyobjs; i++) { if(GET_LONG != polyobjs[i].tag) { I_Error("UnarchivePolyobjs: Invalid polyobj tag"); } PO_RotatePolyobj(polyobjs[i].tag, (angle_t)GET_LONG); deltaX = GET_LONG-polyobjs[i].startSpot.x; deltaY = GET_LONG-polyobjs[i].startSpot.y; PO_MovePolyobj(polyobjs[i].tag, deltaX, deltaY); }}//==========================================================================//// AssertSegment////==========================================================================static void AssertSegment(gameArchiveSegment_t segType){ if(GET_LONG != segType) { I_Error("Corrupt save game: Segment [%d] failed alignment check", segType); }}//==========================================================================//// ClearSaveSlot//// Deletes all save game files associated with a slot number.////==========================================================================static void ClearSaveSlot(int slot){ int i; char fileName[100]; for(i = 0; i < MAX_MAPS; i++) { sprintf(fileName, "%shex%d%02d.hxs", SavePath, slot, i); remove(fileName); } sprintf(fileName, "%shex%d.hxs", SavePath, slot); remove(fileName);}//==========================================================================//// CopySaveSlot//// Copies all the save game files from one slot to another.////==========================================================================static void CopySaveSlot(int sourceSlot, int destSlot){ int i; char sourceName[100]; char destName[100]; for(i = 0; i < MAX_MAPS; i++) { sprintf(sourceName, "%shex%d%02d.hxs", SavePath, sourceSlot, i); if(ExistingFile(sourceName)) { sprintf(destName, "%shex%d%02d.hxs", SavePath, destSlot, i); CopyFile(sourceName, destName); } } sprintf(sourceName, "%shex%d.hxs", SavePath, sourceSlot); if(ExistingFile(sourceName)) { sprintf(destName, "%shex%d.hxs", SavePath, destSlot); CopyFile(sourceName, destName); }}//==========================================================================//// CopyFile////==========================================================================static void CopyFile(char *sourceName, char *destName){ int length; byte *buffer; length = M_ReadFile(sourceName, &buffer); M_WriteFile(destName, buffer, length); Z_Free(buffer);}//==========================================================================//// ExistingFile////==========================================================================static boolean ExistingFile(char *name){ FILE *fp; if((fp = fopen(name, "rb")) != NULL) { fclose(fp); return true; } else { return false; }}//==========================================================================//// OpenStreamOut////==========================================================================static void OpenStreamOut(char *fileName){ SavingFP = fopen(fileName, "wb");}//==========================================================================//// CloseStreamOut////==========================================================================static void CloseStreamOut(void){ if(SavingFP) { fclose(SavingFP); }}//==========================================================================//// StreamOutBuffer////==========================================================================static void StreamOutBuffer(void *buffer, int size){ fwrite(buffer, size, 1, SavingFP);}//==========================================================================//// StreamOutByte////==========================================================================static void StreamOutByte(byte val){ fwrite(&val, sizeof(byte), 1, SavingFP);}//==========================================================================//// StreamOutWord////==========================================================================static void StreamOutWord(unsigned short val){ fwrite(&val, sizeof(unsigned short), 1, SavingFP);}//==========================================================================//// StreamOutLong////==========================================================================static void StreamOutLong(unsigned int val){ fwrite(&val, sizeof(int), 1, SavingFP);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -