diff --git a/source/exhumed/src/save.cpp b/source/exhumed/src/save.cpp index 6b8c6d555..e4b3b9349 100644 --- a/source/exhumed/src/save.cpp +++ b/source/exhumed/src/save.cpp @@ -29,6 +29,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_PS_NS +void SerializeSwitch(FSerializer& arc); +void SerializeView(FSerializer& arc); + void SerializeAnubis(FSerializer& arc); void SerializeFish(FSerializer& arc); void SerializeLavadude(FSerializer& arc); @@ -56,6 +59,9 @@ bool GameInterface::SaveGame() void GameInterface::SerializeGameState(FSerializer& arc) { + SerializeSwitch(arc); + SerializeView(arc); + SerializeAnubis(arc); SerializeFish(arc); SerializeLavadude(arc); diff --git a/source/exhumed/src/switch.cpp b/source/exhumed/src/switch.cpp index de52cc3f6..576629ebd 100644 --- a/source/exhumed/src/switch.cpp +++ b/source/exhumed/src/switch.cpp @@ -26,51 +26,71 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_PS_NS -short LinkCount = -1; -short SwitchCount = -1; +struct Link +{ + int8_t v[8]; +}; -int8_t LinkMap[kMaxLinks][8]; struct Switch { - short field_0; - short field_2; + short nWaitTimer; + short nWait; short nChannel; short nLink; - short field_8; + short nRunPtr; short nSector; - short field_C; + short nRun2; short nWall; - short field_10; - uint16_t field_12; - short field_14; - char pad[10]; + short nRun3; + uint16_t nKeyMask; }; -Switch SwitchData[kMaxSwitches]; +TArray LinkMap; +TArray SwitchData; -static SavegameHelper sghswitch("switch", - SV(LinkCount), - SV(SwitchCount), - SA(LinkMap), - SA(SwitchData), - nullptr); +FSerializer& Serialize(FSerializer& arc, const char* keyname, Link& w, Link* def) +{ + arc.Array(keyname, w.v, 8); + return arc; +} + +FSerializer& Serialize(FSerializer& arc, const char* keyname, Switch& w, Switch* def) +{ + if (arc.BeginObject(keyname)) + { + arc("waittimer", w.nWaitTimer) + ("wait", w.nWait) + ("channel", w.nChannel) + ("link", w.nLink) + ("runptr", w.nRunPtr) + ("sector", w.nSector) + ("run2", w.nRun2) + ("wall", w.nWall) + ("run3", w.nRun3) + ("keymask", w.nKeyMask) + .EndObject(); + } + return arc; +} + +void SerializeSwitch(FSerializer& arc) +{ + arc("switch", SwitchData) + ("linkmap", LinkMap); +} void InitLink() { - LinkCount = kMaxLinks; + LinkMap.Clear(); } int BuildLink(int nCount, ...) { - if (LinkCount <= 0) { - return -1; - } - va_list list; va_start(list, nCount); - LinkCount--; + unsigned LinkCount = LinkMap.Reserve(1); for (int i = 0; i < 8; i++) { @@ -85,7 +105,7 @@ int BuildLink(int nCount, ...) ebx = va_arg(list, int); } - LinkMap[LinkCount][i] = (int8_t)ebx; + LinkMap[LinkCount].v[i] = (int8_t)ebx; } va_end(list); @@ -94,28 +114,25 @@ int BuildLink(int nCount, ...) void InitSwitch() { - SwitchCount = kMaxSwitches; - memset(SwitchData, 0, sizeof(SwitchData)); + SwitchData.Clear(); } int BuildSwReady(int nChannel, short nLink) { - if (SwitchCount <= 0 || nLink < 0) { + if (nLink < 0) { I_Error("Too many switch readys!\n"); return -1; } - - SwitchCount--; + unsigned SwitchCount = SwitchData.Reserve(1); SwitchData[SwitchCount].nChannel = nChannel; SwitchData[SwitchCount].nLink = nLink; - return SwitchCount | 0x10000; } void FuncSwReady(int a, int, int nRun) { short nSwitch = RunData[nRun].nVal; - assert(nSwitch >= 0 && nSwitch < kMaxSwitches); + assert(nSwitch >= 0 && nSwitch < (int)SwitchData.Size()); int nMessage = a & 0x7F0000; @@ -130,7 +147,7 @@ void FuncSwReady(int a, int, int nRun) case 0x30000: { assert(sRunChannels[nChannel].c < 8); - int8_t nVal = LinkMap[nLink][sRunChannels[nChannel].c]; + int8_t nVal = LinkMap[nLink].v[sRunChannels[nChannel].c]; if (nVal >= 0) { runlist_ChangeChannel(nChannel, nVal); } @@ -145,24 +162,23 @@ void FuncSwReady(int a, int, int nRun) int BuildSwPause(int nChannel, int nLink, int ebx) { - for (int i = kMaxSwitches - 1; i >= SwitchCount; i--) + for (unsigned i = 0; i < SwitchData.Size(); i++) { - if (SwitchData[i].nChannel == nChannel && SwitchData[i].field_2 != 0) { + if (SwitchData[i].nChannel == nChannel && SwitchData[i].nWait != 0) { return i | 0x20000; } } - if (SwitchCount <= 0 || nLink < 0) { + if (nLink < 0) { I_Error("Too many switches!\n"); return -1; } - - SwitchCount--; + unsigned SwitchCount = SwitchData.Reserve(1); SwitchData[SwitchCount].nChannel = nChannel; SwitchData[SwitchCount].nLink = nLink; - SwitchData[SwitchCount].field_2 = ebx; - SwitchData[SwitchCount].field_8 = -1; + SwitchData[SwitchCount].nWait = ebx; + SwitchData[SwitchCount].nRunPtr = -1; return SwitchCount | 0x20000; } @@ -170,7 +186,7 @@ int BuildSwPause(int nChannel, int nLink, int ebx) void FuncSwPause(int a, int, int nRun) { short nSwitch = RunData[nRun].nVal; - assert(nSwitch >= 0 && nSwitch < kMaxSwitches); + assert(nSwitch >= 0 && nSwitch < (int)SwitchData.Size()); int nMessage = a & 0x7F0000; @@ -184,10 +200,10 @@ void FuncSwPause(int a, int, int nRun) case 0x10000: { - if (SwitchData[nSwitch].field_8 >= 0) + if (SwitchData[nSwitch].nRunPtr >= 0) { - runlist_SubRunRec(SwitchData[nSwitch].field_8); - SwitchData[nSwitch].field_8 = -1; + runlist_SubRunRec(SwitchData[nSwitch].nRunPtr); + SwitchData[nSwitch].nRunPtr = -1; } return; @@ -195,16 +211,16 @@ void FuncSwPause(int a, int, int nRun) case 0x20000: { - SwitchData[nSwitch].field_0--; - if (SwitchData[nSwitch].field_0 <= 0) + SwitchData[nSwitch].nWaitTimer--; + if (SwitchData[nSwitch].nWaitTimer <= 0) { - runlist_SubRunRec(SwitchData[nSwitch].field_8); - SwitchData[nSwitch].field_8 = -1; + runlist_SubRunRec(SwitchData[nSwitch].nRunPtr); + SwitchData[nSwitch].nRunPtr = -1; assert(sRunChannels[nChannel].c < 8); assert(nLink < 1024); - runlist_ChangeChannel(nChannel, LinkMap[nLink][sRunChannels[nChannel].c]); + runlist_ChangeChannel(nChannel, LinkMap[nLink].v[sRunChannels[nChannel].c]); } return; @@ -214,28 +230,28 @@ void FuncSwPause(int a, int, int nRun) { assert(sRunChannels[nChannel].c < 8); - if (LinkMap[nLink][sRunChannels[nChannel].c] < 0) { + if (LinkMap[nLink].v[sRunChannels[nChannel].c] < 0) { return; } - if (SwitchData[nSwitch].field_8 >= 0) { + if (SwitchData[nSwitch].nRunPtr >= 0) { return; } - SwitchData[nSwitch].field_8 = runlist_AddRunRec(NewRun, RunData[nRun].nMoves); + SwitchData[nSwitch].nRunPtr = runlist_AddRunRec(NewRun, RunData[nRun].nMoves); int eax; - if (SwitchData[nSwitch].field_2 <= 0) + if (SwitchData[nSwitch].nWait <= 0) { eax = 100; } else { - eax = SwitchData[nSwitch].field_2; + eax = SwitchData[nSwitch].nWait; } - SwitchData[nSwitch].field_0 = eax; + SwitchData[nSwitch].nWaitTimer = eax; return; } } @@ -243,15 +259,14 @@ void FuncSwPause(int a, int, int nRun) int BuildSwStepOn(int nChannel, int nLink, int nSector) { - if (SwitchCount <= 0 || nLink < 0 || nSector < 0) + if (nLink < 0 || nSector < 0) I_Error("Too many switches!\n"); - - int nSwitch = --SwitchCount; + unsigned nSwitch = SwitchData.Reserve(1); SwitchData[nSwitch].nChannel = nChannel; SwitchData[nSwitch].nLink = nLink; SwitchData[nSwitch].nSector = nSector; - SwitchData[nSwitch].field_C = -1; + SwitchData[nSwitch].nRun2 = -1; return nSwitch | 0x30000; } @@ -259,7 +274,7 @@ int BuildSwStepOn(int nChannel, int nLink, int nSector) void FuncSwStepOn(int a, int, int nRun) { short nSwitch = RunData[nRun].nVal; - assert(nSwitch >= 0 && nSwitch < kMaxSwitches); + assert(nSwitch >= 0 && nSwitch < (int)SwitchData.Size()); short nLink = SwitchData[nSwitch].nLink; short nChannel = SwitchData[nSwitch].nChannel; @@ -267,7 +282,7 @@ void FuncSwStepOn(int a, int, int nRun) assert(sRunChannels[nChannel].c < 8); - int8_t var_14 = LinkMap[nLink][sRunChannels[nChannel].c]; + int8_t var_14 = LinkMap[nLink].v[sRunChannels[nChannel].c]; int nMessage = a & 0x7F0000; @@ -278,15 +293,15 @@ void FuncSwStepOn(int a, int, int nRun) case 0x10000: { - if (SwitchData[nSwitch].field_C >= 0) + if (SwitchData[nSwitch].nRun2 >= 0) { - runlist_SubRunRec(SwitchData[nSwitch].field_C); - SwitchData[nSwitch].field_C = -1; + runlist_SubRunRec(SwitchData[nSwitch].nRun2); + SwitchData[nSwitch].nRun2 = -1; } if (var_14 >= 0) { - SwitchData[nSwitch].field_C = runlist_AddRunRec(sector[nSector].lotag - 1, RunData[nRun].nMoves); + SwitchData[nSwitch].nRun2 = runlist_AddRunRec(sector[nSector].lotag - 1, RunData[nRun].nMoves); } return; @@ -301,7 +316,7 @@ void FuncSwStepOn(int a, int, int nRun) assert(sRunChannels[nChannel].c < 8); - runlist_ChangeChannel(nChannel, LinkMap[nLink][sRunChannels[nChannel].c]); + runlist_ChangeChannel(nChannel, LinkMap[nLink].v[sRunChannels[nChannel].c]); } } @@ -312,17 +327,15 @@ void FuncSwStepOn(int a, int, int nRun) int BuildSwNotOnPause(int nChannel, int nLink, int nSector, int ecx) { - if (SwitchCount <= 0 || nLink < 0 || nSector < 0) + if (nLink < 0 || nSector < 0) I_Error("Too many switches!\n"); - - int nSwitch = --SwitchCount; - + unsigned nSwitch = SwitchData.Reserve(1); SwitchData[nSwitch].nChannel = nChannel; SwitchData[nSwitch].nLink = nLink; - SwitchData[nSwitch].field_2 = ecx; + SwitchData[nSwitch].nWait = ecx; SwitchData[nSwitch].nSector = nSector; - SwitchData[nSwitch].field_8 = -1; - SwitchData[nSwitch].field_C = -1; + SwitchData[nSwitch].nRunPtr = -1; + SwitchData[nSwitch].nRun2 = -1; return nSwitch | 0x40000; } @@ -330,7 +343,7 @@ int BuildSwNotOnPause(int nChannel, int nLink, int nSector, int ecx) void FuncSwNotOnPause(int a, int, int nRun) { short nSwitch = RunData[nRun].nVal; - assert(nSwitch >= 0 && nSwitch < kMaxSwitches); + assert(nSwitch >= 0 && nSwitch < (int)SwitchData.Size()); int nMessage = a & 0x7F0000; @@ -344,16 +357,16 @@ void FuncSwNotOnPause(int a, int, int nRun) case 0x10000: { - if (SwitchData[nSwitch].field_C >= 0) + if (SwitchData[nSwitch].nRun2 >= 0) { - runlist_SubRunRec(SwitchData[nSwitch].field_C); - SwitchData[nSwitch].field_C = -1; + runlist_SubRunRec(SwitchData[nSwitch].nRun2); + SwitchData[nSwitch].nRun2 = -1; } - if (SwitchData[nSwitch].field_8 >= 0) + if (SwitchData[nSwitch].nRunPtr >= 0) { - runlist_SubRunRec(SwitchData[nSwitch].field_8); - SwitchData[nSwitch].field_8 = -1; + runlist_SubRunRec(SwitchData[nSwitch].nRunPtr); + SwitchData[nSwitch].nRunPtr = -1; } return; @@ -361,12 +374,12 @@ void FuncSwNotOnPause(int a, int, int nRun) case 0x20000: { - SwitchData[nSwitch].field_0 -= 4; - if (SwitchData[nSwitch].field_0 <= 0) + SwitchData[nSwitch].nWaitTimer -= 4; + if (SwitchData[nSwitch].nWaitTimer <= 0) { assert(sRunChannels[nChannel].c < 8); - runlist_ChangeChannel(nChannel, LinkMap[nLink][sRunChannels[nChannel].c]); + runlist_ChangeChannel(nChannel, LinkMap[nLink].v[sRunChannels[nChannel].c]); } return; @@ -376,16 +389,16 @@ void FuncSwNotOnPause(int a, int, int nRun) { assert(sRunChannels[nChannel].c < 8); - if (LinkMap[nLink][sRunChannels[nChannel].c] >= 0) + if (LinkMap[nLink].v[sRunChannels[nChannel].c] >= 0) { - if (SwitchData[nSwitch].field_8 < 0) + if (SwitchData[nSwitch].nRunPtr < 0) { - SwitchData[nSwitch].field_8 = runlist_AddRunRec(NewRun, RunData[nRun].nMoves); + SwitchData[nSwitch].nRunPtr = runlist_AddRunRec(NewRun, RunData[nRun].nMoves); short nSector = SwitchData[nSwitch].nSector; - SwitchData[nSwitch].field_0 = SwitchData[nSwitch].field_2; - SwitchData[nSwitch].field_C = runlist_AddRunRec(sector[nSector].lotag - 1, RunData[nRun].nMoves); + SwitchData[nSwitch].nWaitTimer = SwitchData[nSwitch].nWait; + SwitchData[nSwitch].nRun2 = runlist_AddRunRec(sector[nSector].lotag - 1, RunData[nRun].nMoves); } } @@ -394,7 +407,7 @@ void FuncSwNotOnPause(int a, int, int nRun) case 0x50000: { - SwitchData[nSwitch].field_0 = SwitchData[nSwitch].field_2; + SwitchData[nSwitch].nWaitTimer = SwitchData[nSwitch].nWait; return; } } @@ -402,16 +415,14 @@ void FuncSwNotOnPause(int a, int, int nRun) int BuildSwPressSector(int nChannel, int nLink, int nSector, int keyMask) { - if (SwitchCount <= 0 || nLink < 0 || nSector < 0) + if (nLink < 0 || nSector < 0) I_Error("Too many switches!\n"); - - int nSwitch = --SwitchCount; - + unsigned nSwitch = SwitchData.Reserve(1); SwitchData[nSwitch].nChannel = nChannel; SwitchData[nSwitch].nLink = nLink; SwitchData[nSwitch].nSector = nSector; - SwitchData[nSwitch].field_12 = keyMask; - SwitchData[nSwitch].field_C = -1; + SwitchData[nSwitch].nKeyMask = keyMask; + SwitchData[nSwitch].nRun2 = -1; return nSwitch | 0x50000; } @@ -419,7 +430,7 @@ int BuildSwPressSector(int nChannel, int nLink, int nSector, int keyMask) void FuncSwPressSector(int a, int, int nRun) { short nSwitch = RunData[nRun].nVal; - assert(nSwitch >= 0 && nSwitch < kMaxSwitches); + assert(nSwitch >= 0 && nSwitch < (int)SwitchData.Size()); int nMessage = a & 0x7F0000; @@ -434,33 +445,33 @@ void FuncSwPressSector(int a, int, int nRun) case 0x10000: { - if (SwitchData[nSwitch].field_C >= 0) + if (SwitchData[nSwitch].nRun2 >= 0) { - runlist_SubRunRec(SwitchData[nSwitch].field_C); - SwitchData[nSwitch].field_C = -1; + runlist_SubRunRec(SwitchData[nSwitch].nRun2); + SwitchData[nSwitch].nRun2 = -1; } assert(sRunChannels[nChannel].c < 8); - if (LinkMap[nLink][sRunChannels[nChannel].c] < 0) { + if (LinkMap[nLink].v[sRunChannels[nChannel].c] < 0) { return; } short nSector = SwitchData[nSwitch].nSector; - SwitchData[nSwitch].field_C = runlist_AddRunRec(sector[nSector].lotag - 1, RunData[nRun].nMoves); + SwitchData[nSwitch].nRun2 = runlist_AddRunRec(sector[nSector].lotag - 1, RunData[nRun].nMoves); return; } case 0x40000: { - if ((PlayerList[nPlayer].keys & SwitchData[nSwitch].field_12) == SwitchData[nSwitch].field_12) + if ((PlayerList[nPlayer].keys & SwitchData[nSwitch].nKeyMask) == SwitchData[nSwitch].nKeyMask) { - runlist_ChangeChannel(nChannel, LinkMap[nLink][sRunChannels[nChannel].c]); + runlist_ChangeChannel(nChannel, LinkMap[nLink].v[sRunChannels[nChannel].c]); } else { - if (SwitchData[nSwitch].field_12) + if (SwitchData[nSwitch].nKeyMask) { short nSprite = PlayerList[nPlayer].nSprite; PlayFXAtXYZ(StaticSound[nSwitchSound], sprite[nSprite].x, sprite[nSprite].y, 0, sprite[nSprite].sectnum, CHANF_LISTENERZ); @@ -474,17 +485,14 @@ void FuncSwPressSector(int a, int, int nRun) int BuildSwPressWall(short nChannel, short nLink, short nWall) { - if (SwitchCount <= 0 || nLink < 0 || nWall < 0) { + if (nLink < 0 || nWall < 0) { I_Error("Too many switches!\n"); } - - SwitchCount--; - + unsigned SwitchCount = SwitchData.Reserve(1); SwitchData[SwitchCount].nChannel = nChannel; SwitchData[SwitchCount].nLink = nLink; SwitchData[SwitchCount].nWall = nWall; - SwitchData[SwitchCount].field_10 = -1; - SwitchData[SwitchCount].field_14 = 0; + SwitchData[SwitchCount].nRun3 = -1; return SwitchCount | 0x60000; } @@ -492,7 +500,7 @@ int BuildSwPressWall(short nChannel, short nLink, short nWall) void FuncSwPressWall(int a, int, int nRun) { short nSwitch = RunData[nRun].nVal; - assert(nSwitch >= 0 && nSwitch < kMaxSwitches); + assert(nSwitch >= 0 && nSwitch < (int)SwitchData.Size()); short nChannel = SwitchData[nSwitch].nChannel; short nLink = SwitchData[nSwitch].nLink; @@ -510,16 +518,16 @@ void FuncSwPressWall(int a, int, int nRun) case 0x30000: { - if (SwitchData[nSwitch].field_10 >= 0) + if (SwitchData[nSwitch].nRun3 >= 0) { - runlist_SubRunRec(SwitchData[nSwitch].field_10); - SwitchData[nSwitch].field_10 = -1; + runlist_SubRunRec(SwitchData[nSwitch].nRun3); + SwitchData[nSwitch].nRun3 = -1; } - if (LinkMap[nLink][sRunChannels[nChannel].c] >= 0) + if (LinkMap[nLink].v[sRunChannels[nChannel].c] >= 0) { short nWall = SwitchData[nSwitch].nWall; - SwitchData[nSwitch].field_10 = runlist_AddRunRec(wall[nWall].lotag - 1, RunData[nRun].nMoves); + SwitchData[nSwitch].nRun3 = runlist_AddRunRec(wall[nWall].lotag - 1, RunData[nRun].nMoves); } return; @@ -527,14 +535,14 @@ void FuncSwPressWall(int a, int, int nRun) case 0x40000: { - int8_t cx = LinkMap[nLink][sRunChannels[nChannel].c]; + int8_t cx = LinkMap[nLink].v[sRunChannels[nChannel].c]; - runlist_ChangeChannel(nChannel, LinkMap[nLink][sRunChannels[nChannel].c]); + runlist_ChangeChannel(nChannel, LinkMap[nLink].v[sRunChannels[nChannel].c]); - if (cx < 0 || LinkMap[nLink][cx] < 0) + if (cx < 0 || LinkMap[nLink].v[cx] < 0) { - runlist_SubRunRec(SwitchData[nSwitch].field_10); - SwitchData[nSwitch].field_10 = -1; + runlist_SubRunRec(SwitchData[nSwitch].nRun3); + SwitchData[nSwitch].nRun3 = -1; } short nWall = SwitchData[nSwitch].nWall; diff --git a/source/exhumed/src/view.cpp b/source/exhumed/src/view.cpp index 020162846..b729ccc48 100644 --- a/source/exhumed/src/view.cpp +++ b/source/exhumed/src/view.cpp @@ -467,21 +467,22 @@ void Clip() { } - -static SavegameHelper sghview("view", - SV(nCamerax), - SV(nCameray), - SV(nCameraz), - SV(bTouchFloor), - SV(nChunkTotal), - SV(nCameraa), - SV(nCamerapan), - SV(bCamera), - SV(viewz), - SV(enemy), - SV(nEnemyPal), - SA(dVertPan), - SA(nQuake), - nullptr); +void SerializeView(FSerializer& arc) +{ + arc("camerax", nCamerax) + ("cameray", nCameray) + ("cameraz", nCameraz) + ("touchfloor", bTouchFloor) + ("chunktotal", nChunkTotal) + ("cameraa", nCameraa) + ("camerapan", nCamerapan) + ("camera", bCamera) + ("viewz", viewz) + ("enemy", enemy) + ("enemypal", nEnemyPal) + .Array("vertpan", dVertPan, countof(dVertPan)) + .Array("quake", nQuake, countof(nQuake)) + .EndObject(); +} END_PS_NS