From c365a79f81b97c85de536ea42c2cf459de18508a Mon Sep 17 00:00:00 2001 From: sirlemonhead Date: Thu, 14 Nov 2019 20:36:54 +0000 Subject: [PATCH] Fix asserts firing for some sector tags. This code now handles cases where the effects aren't set up correctly in the .map file - a floor/ceiling is not in the expected starting position. The nextsectorneighborz() function would end up returning -1 but the game would use this value to index the sector array. It seems the developers were lucky and this resulted in the correct value being returned regardless. --- source/exhumed/src/runlist.cpp | 75 +++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 15 deletions(-) diff --git a/source/exhumed/src/runlist.cpp b/source/exhumed/src/runlist.cpp index 4d17303c1..83582bb66 100644 --- a/source/exhumed/src/runlist.cpp +++ b/source/exhumed/src/runlist.cpp @@ -767,10 +767,19 @@ void runlist_ProcessSectorTag(int nSector, int lotag, int hitag) case 13: // Sector raise / lower case 37: // Sector raise / lower { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, -1); - assert(nextSector > -1); + /* + fix for original behaviour - nextSector could be -1 the and game would do an invalid memory read + when getting the floorz for nextSector. Here, we assume 0 and only set the correct value if nextSector + is valid. + */ + int zVal = 0; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), var_18 * 100, var_18 * 100, 2, sector[nSector].floorz, sector[nextSector].floorz); + short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, -1); + if (nextSector >= 0) { + zVal = sector[nextSector].floorz; + } + + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), var_18 * 100, var_18 * 100, 2, sector[nSector].floorz, zVal); runlist_AddRunRec(sRunChannels[nChannel].a, nElev); return; @@ -778,10 +787,19 @@ void runlist_ProcessSectorTag(int nSector, int lotag, int hitag) case 11: // Switch activated lift up { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, -1); - assert(nextSector > -1); + /* + fix for original behaviour - nextSector could be -1 the and game would do an invalid memory read + when getting the floorz for nextSector. Here, we assume 0 and only set the correct value if nextSector + is valid. + */ + int zVal = 0; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), var_18 * 100, var_18 * 100, 2, sector[nSector].floorz, sector[nextSector].floorz); + short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, -1); + if (nextSector >= 0) { + zVal = sector[nextSector].floorz; + } + + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), var_18 * 100, var_18 * 100, 2, sector[nSector].floorz, zVal); runlist_AddRunRec(sRunChannels[nChannel].a, nElev); @@ -793,10 +811,19 @@ void runlist_ProcessSectorTag(int nSector, int lotag, int hitag) case 12: // Bobbing floor { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, 1); - assert(nextSector > -1); + /* + fix for original behaviour - nextSector could be -1 the and game would do an invalid memory read + when getting the floorz for nextSector. Here, we assume 0 and only set the correct value if nextSector + is valid. + */ + int zVal = 0; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), var_18 * 100, var_18 * 100, 2, sector[nSector].floorz, sector[nextSector].floorz); + short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, 1); + if (nextSector >= 0) { + zVal = sector[nextSector].floorz; + } + + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), var_18 * 100, var_18 * 100, 2, sector[nSector].floorz, zVal); runlist_AddRunRec(sRunChannels[nChannel].a, nElev); @@ -875,10 +902,19 @@ void runlist_ProcessSectorTag(int nSector, int lotag, int hitag) case 22: // Floor raise, Sychronize { - short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, 1); - assert(nextSector > -1); + /* + fix for original behaviour - nextSector could be -1 the and game would do an invalid memory read + when getting the floorz for nextSector. Here, we assume 0 and only set the correct value if nextSector + is valid. + */ + int zVal = 0; - int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), 32767, 200, 2, sector[nSector].floorz, sector[nextSector].floorz); + short nextSector = nextsectorneighborz(nSector, sector[nSector].floorz, 1, 1); + if (nextSector >= 0) { + zVal = sector[nextSector].floorz; + } + + int nElev = BuildElevF(nChannel, nSector, FindWallSprites(nSector), 32767, 200, 2, sector[nSector].floorz, zVal); runlist_AddRunRec(sRunChannels[nChannel].a, nElev); @@ -1093,10 +1129,19 @@ void runlist_ProcessSectorTag(int nSector, int lotag, int hitag) case 47: // Ceiling lower { - short nextSector = nextsectorneighborz(nSector, sector[nSector].ceilingz, -1, 1); - assert(nextSector > -1); + /* + fix for original behaviour - nextSector could be -1 the and game would do an invalid memory read + when getting the floorz for nextSector. Here, we assume 0 and only set the correct value if nextSector + is valid. + */ + int zVal = 0; - int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), 200, var_18 * 100, 2, sector[nSector].ceilingz, sector[nextSector].ceilingz); + short nextSector = nextsectorneighborz(nSector, sector[nSector].ceilingz, -1, 1); + if (nextSector >= 0) { + zVal = sector[nextSector].ceilingz; + } + + int nElev = BuildElevC(0, nChannel, nSector, FindWallSprites(nSector), 200, var_18 * 100, 2, sector[nSector].ceilingz, zVal); runlist_AddRunRec(sRunChannels[nChannel].a, nElev); return;