From 9d8f06612ffb48e83d1f8250333c437d81626fb7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 10 Sep 2022 10:32:39 +0200 Subject: [PATCH] - floatified MoveSector --- source/common/utility/m_fixed.h | 2 +- source/games/exhumed/src/aistuff.h | 7 +- source/games/exhumed/src/move.cpp | 144 ++++++++++++---------------- source/games/exhumed/src/object.cpp | 14 +-- source/games/exhumed/src/player.cpp | 5 +- 5 files changed, 77 insertions(+), 95 deletions(-) diff --git a/source/common/utility/m_fixed.h b/source/common/utility/m_fixed.h index 08f2d420f..adf9ac8ee 100644 --- a/source/common/utility/m_fixed.h +++ b/source/common/utility/m_fixed.h @@ -18,7 +18,7 @@ __forceinline constexpr int64_t DivScaleL(int64_t a, int64_t b, int shift) { ret template inline fixed_t FloatToFixed(double f) { - return xs_Fix::ToFix(f); + return int(f * (1 << b)); } template diff --git a/source/games/exhumed/src/aistuff.h b/source/games/exhumed/src/aistuff.h index 85c35534a..f0920c933 100644 --- a/source/games/exhumed/src/aistuff.h +++ b/source/games/exhumed/src/aistuff.h @@ -196,9 +196,8 @@ void FuncLion(int, int, int, int); struct BlockInfo { TObjPtr pActor; - int x; - int y; - int field_8; + DVector2 pos; + double mindist; }; extern BlockInfo sBlockInfo[]; @@ -231,7 +230,7 @@ int PlotCourseToSprite(DExhumedActor* nSprite1, DExhumedActor* nSprite2); void CheckSectorFloor(sectortype* pSector, double z, DVector2& xy); int GetAngleToSprite(DExhumedActor* nSprite1, DExhumedActor* nSprite2); int GetWallNormal(walltype* nWall); -void MoveSector(sectortype* pSector, int nAngle, int *nXVel, int *nYVel); +void MoveSector(sectortype* pSector, DAngle nAngle, int *nXVel, int *nYVel); Collision AngleChase(DExhumedActor* nSprite, DExhumedActor* nSprite2, int ebx, int ecx, int push1); void SetQuake(DExhumedActor* nSprite, int nVal); diff --git a/source/games/exhumed/src/move.cpp b/source/games/exhumed/src/move.cpp index afed61eb7..4b1d9c96e 100644 --- a/source/games/exhumed/src/move.cpp +++ b/source/games/exhumed/src/move.cpp @@ -66,10 +66,9 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, BlockInfo& w, Bloc { if (arc.BeginObject(keyname)) { - arc("at8", w.field_8) + arc("mindist", w.mindist) ("sprite", w.pActor) - ("x", w.x) - ("y", w.y) + ("pos", w.pos) .EndObject(); } return arc; @@ -651,163 +650,149 @@ int GrabPushBlock() void CreatePushBlock(sectortype* pSector) { int nBlock = GrabPushBlock(); - - double xSumm = 0; - double ySumm = 0; + DVector2 sum(0, 0); for (auto& wal : wallsofsector(pSector)) { - xSumm += wal.pos.X; - ySumm += wal.pos.Y; + sum += wal.pos; } - double xAvgg = xSumm / pSector->wallnum; - double yAvgg = ySumm / pSector->wallnum; + DVector2 avg = sum / pSector->wallnum; - sBlockInfo[nBlock].x = xAvgg * worldtoint; - sBlockInfo[nBlock].y = yAvgg * worldtoint; + sBlockInfo[nBlock].pos = avg; auto pActor = insertActor(pSector, 0); sBlockInfo[nBlock].pActor = pActor; - pActor->spr.pos = { xAvgg, yAvgg, pSector->floorz- 1 }; + pActor->spr.pos = { avg, pSector->floorz- 1 }; pActor->spr.cstat = CSTAT_SPRITE_INVISIBLE; double mindist = 0; for (auto& wal : wallsofsector(pSector)) { - double xDiff = abs(xAvgg - wal.pos.X); - double yDiff = abs(yAvgg - wal.pos.Y); + double length = (avg - wal.pos).Length(); - double nSqrt = g_sqrt(xDiff * xDiff + yDiff * yDiff); - - if (nSqrt > mindist) { - mindist = nSqrt; + if (length > mindist) { + mindist = length; } } - sBlockInfo[nBlock].field_8 = mindist * worldtoint; + sBlockInfo[nBlock].mindist = mindist; pActor->set_native_clipdist( (int(mindist * worldtoint) & 0xFF) << 2); pSector->extra = nBlock; } -void MoveSector(sectortype* pSector, int nAngle, int *nXVel, int *nYVel) + +void MoveSector(sectortype* pSector, DAngle nAngle, int *nXVel, int *nYVel) { if (pSector == nullptr) { return; } - int nXVect, nYVect; + DVector2 nVect; - if (nAngle < 0) + if (nAngle < nullAngle) { - nXVect = *nXVel; - nYVect = *nYVel; - nAngle = getangle(nXVect, nYVect); + nVect = { FixedToFloat<18>(*nXVel), FixedToFloat<18>(*nYVel) }; + nAngle = VecToAngle(nVect); } else { - nXVect = bcos(nAngle, 6); - nYVect = bsin(nAngle, 6); + nVect = nAngle.ToVector() * 4; } int nBlock = pSector->extra; int nSectFlag = pSector->Flag; - int nFloorZ = pSector->int_floorz(); + double nFloorZ = pSector->floorz; walltype *pStartWall = pSector->firstWall(); sectortype* pNextSector = pStartWall->nextSector(); BlockInfo *pBlockInfo = &sBlockInfo[nBlock]; - vec3_t pos; + DVector3 pos; - pos.X = sBlockInfo[nBlock].x; - int x_b = sBlockInfo[nBlock].x; + pos.XY() = sBlockInfo[nBlock].pos; + auto b_pos = pos.XY(); - pos.Y = sBlockInfo[nBlock].y; - int y_b = sBlockInfo[nBlock].y; - - - int nZVal; + double nZVal; int bUnderwater = nSectFlag & kSectUnderwater; if (nSectFlag & kSectUnderwater) { - nZVal = pSector->int_ceilingz(); - pos.Z = pNextSector->int_ceilingz() + 256; + nZVal = pSector->ceilingz; + pos.Z = pNextSector->ceilingz + 1; pSector->setceilingz(pNextSector->ceilingz); } else { - nZVal = pSector->int_floorz(); - pos.Z = pNextSector->int_floorz() - 256; + nZVal = pSector->floorz; + pos.Z = pNextSector->floorz - 1; pSector->setfloorz(pNextSector->floorz); } auto pSectorB = pSector; Collision scratch; - clipmove(pos, &pSectorB, nXVect, nYVect, pBlockInfo->field_8, 0, 0, CLIPMASK1, scratch); + clipmove(pos, &pSectorB, FloatToFixed<18>(nVect.X), FloatToFixed<18>(nVect.Y), pBlockInfo->mindist, 0, 0, CLIPMASK1, scratch); - int yvect = pos.Y - y_b; - int xvect = pos.X - x_b; + auto vect = pos.XY() - b_pos; if (pSectorB != pNextSector && pSectorB != pSector) { - yvect = 0; - xvect = 0; + vect.Zero(); } else { if (!bUnderwater) { - pos = { x_b, y_b, nZVal }; + pos.XY() = b_pos; + pos.Z = nZVal; - clipmove(pos, &pSectorB, nXVect, nYVect, pBlockInfo->field_8, 0, 0, CLIPMASK1, scratch); + clipmove(pos, &pSectorB, FloatToFixed<18>(nVect.X), FloatToFixed<18>(nVect.Y), pBlockInfo->mindist, 0, 0, CLIPMASK1, scratch); - int deltax = pos.X - x_b; - int deltay = pos.Y - y_b; + auto delta = pos.XY() - b_pos; - if (abs(xvect) > abs(deltax)) + if (abs(vect.X) > abs(delta.X)) { - xvect = deltax; + vect.X = delta.X; } - if (abs(yvect) > abs(deltay)) + if (abs(vect.Y) > abs(delta.Y)) { - yvect = deltay; + vect.Y = delta.Y; } } } // GREEN - if (yvect || xvect) + if (!vect.isZero()) { ExhumedSectIterator it(pSector); while (auto pActor = it.Next()) { if (pActor->spr.statnum < 99) { - pActor->add_int_pos({ xvect, yvect, 0 }); + pActor->spr.pos += vect; } else { - pos.Z = pActor->int_pos().Z; + pos.Z = pActor->spr.pos.Z; if ((nSectFlag & kSectUnderwater) || pos.Z != nZVal || pActor->spr.cstat & CSTAT_SPRITE_INVISIBLE) { - pos.X = pActor->int_pos().X; - pos.Y = pActor->int_pos().Y; + pos.XY() = pActor->spr.pos.XY(); pSectorB = pSector; - clipmove(pos, &pSectorB, -xvect, -yvect, 4 * pActor->native_clipdist(), 0, 0, CLIPMASK0, scratch); + // The vector that got passed in here originally was Q28.4, while clipmove expects Q14.18, effectively resulting in actual zero movement + // because the resulting offset would be far below the coordinate's precision. + clipmove(pos, &pSectorB, FloatToFixed<18>(-vect.X / 16384.), FloatToFixed<18>(-vect.Y / 16384), pActor->int_clipdist(), 0, 0, CLIPMASK0, scratch); if (pSectorB) { ChangeActorSect(pActor, pSectorB); @@ -820,18 +805,19 @@ void MoveSector(sectortype* pSector, int nAngle, int *nXVel, int *nYVel) { if (pActor->spr.statnum >= 99) { - pos = pActor->int_pos(); + pos = pActor->spr.pos; pSectorB = pNextSector; - clipmove(pos, &pSectorB, - -xvect - (bcos(nAngle) * (4 * pActor->native_clipdist())), - -yvect - (bsin(nAngle) * (4 * pActor->native_clipdist())), - 4 * pActor->native_clipdist(), 0, 0, CLIPMASK0, scratch); + // Original used 14 bits of scale from the sine table and 4 bits from clipdist. + // vect was added unscaled, essentially nullifying its effect entirely. + auto vect2 = -nAngle.ToVector() * pActor->fClipdist()/* - vect*/; + + clipmove(pos, &pSectorB, FloatToFixed<18>(vect2.X), FloatToFixed<18>(vect2.Y), pActor->int_clipdist(), 0, 0, CLIPMASK0, scratch); if (pSectorB != pNextSector && (pSectorB == pSector || pNextSector == pSector)) { - if (pSectorB != pSector || nFloorZ >= pActor->int_pos().Z) + if (pSectorB != pSector || nFloorZ >= pActor->spr.pos.Z) { if (pSectorB) { ChangeActorSect(pActor, pSectorB); @@ -839,10 +825,9 @@ void MoveSector(sectortype* pSector, int nAngle, int *nXVel, int *nYVel) } else { - movesprite(pActor, - (xvect << 14) + bcos(nAngle) * pActor->native_clipdist(), - (yvect << 14) + bsin(nAngle) * pActor->native_clipdist(), - 0, 0, 0, CLIPMASK0); + // Unlike the above, this one *did* scale vect + vect2 = nAngle.ToVector() * pActor->fClipdist() * 0.25 + vect; + movesprite(pActor, FloatToFixed<18>(vect2.X), FloatToFixed<18>(vect2.Y), 0, 0, 0, CLIPMASK0); } } } @@ -850,39 +835,36 @@ void MoveSector(sectortype* pSector, int nAngle, int *nXVel, int *nYVel) for(auto& wal : wallsofsector(pSector)) { - dragpoint(&wal, xvect + wal.wall_int_pos().X, yvect + wal.wall_int_pos().Y); + dragpoint(&wal, vect + wal.pos); } - pBlockInfo->x += xvect; - pBlockInfo->y += yvect; + pBlockInfo->pos += vect; } // loc_163DD - xvect <<= 14; - yvect <<= 14; if (!(nSectFlag & kSectUnderwater)) { ExhumedSectIterator it(pSector); while (auto pActor = it.Next()) { - if (pActor->spr.statnum >= 99 && nZVal == pActor->int_pos().Z && !(pActor->spr.cstat & CSTAT_SPRITE_INVISIBLE)) + if (pActor->spr.statnum >= 99 && nZVal == pActor->spr.pos.Z && !(pActor->spr.cstat & CSTAT_SPRITE_INVISIBLE)) { pSectorB = pSector; - clipmove(pActor->spr.pos, &pSectorB, xvect, yvect, 4 * pActor->native_clipdist(), 5120, -5120, CLIPMASK0, scratch); + clipmove(pActor->spr.pos, &pSectorB, FloatToFixed<18>(vect.X), FloatToFixed<18>(vect.Y), pActor->int_clipdist(), 5120, -5120, CLIPMASK0, scratch); } } } if (nSectFlag & kSectUnderwater) { - pSector->set_int_ceilingz(nZVal); + pSector->setceilingz(nZVal); } else { - pSector->set_int_floorz(nZVal); + pSector->setfloorz(nZVal); } - *nXVel = xvect; - *nYVel = yvect; + *nXVel = FloatToFixed<18>(vect.X); + *nYVel = FloatToFixed<18>(vect.Y); /* Update player position variables, in case the player sprite was moved by a sector, diff --git a/source/games/exhumed/src/object.cpp b/source/games/exhumed/src/object.cpp index f54feb860..6bf139997 100644 --- a/source/games/exhumed/src/object.cpp +++ b/source/games/exhumed/src/object.cpp @@ -2332,12 +2332,12 @@ void DoMovingSects() // TrailPoint *pTrail = &sTrailPoint[nTrail]; // loc_23872: - int nAngle = getangle(sTrailPoint[nTrail].x - pBlockInfo->x, sTrailPoint[nTrail].y - pBlockInfo->y); + int nAngle = getangle(sTrailPoint[nTrail].x - pBlockInfo->pos.X * worldtoint, sTrailPoint[nTrail].y - pBlockInfo->pos.Y * worldtoint); int nXVel = bcos(nAngle, 4) * sMoveSect[i].field_10; int nYVel = bsin(nAngle, 4) * sMoveSect[i].field_10; - int ebx = (sTrailPoint[nTrail].x - pBlockInfo->x) << 14; + int ebx = (sTrailPoint[nTrail].x - int(pBlockInfo->pos.X * worldtoint)) << 14; int eax = nXVel; if (eax < 0) { @@ -2347,7 +2347,7 @@ void DoMovingSects() int edx = eax; eax = ebx; - int ecx = (sTrailPoint[nTrail].y - pBlockInfo->y) << 14; + int ecx = (sTrailPoint[nTrail].y - int(pBlockInfo->pos.Y * worldtoint)) << 14; if (eax < 0) { eax = -eax; @@ -2403,18 +2403,18 @@ void DoMovingSects() // loc_2393A: if (sMoveSect[i].pCurSector != nullptr) { - MoveSector(sMoveSect[i].pCurSector, -1, &nXVel, &nYVel); + MoveSector(sMoveSect[i].pCurSector, -minAngle, &nXVel, &nYVel); } int var_2C = nXVel; int var_30 = nYVel; - MoveSector(pSector, -1, &nXVel, &nYVel); + MoveSector(pSector, -minAngle, &nXVel, &nYVel); if (nXVel != var_2C || nYVel != var_30) { - MoveSector(sMoveSect[i].pCurSector, -1, &var_2C, &var_30); - MoveSector(sMoveSect[i].pCurSector, -1, &nXVel, &nYVel); + MoveSector(sMoveSect[i].pCurSector, -minAngle, &var_2C, &var_30); + MoveSector(sMoveSect[i].pCurSector, -minAngle, &nXVel, &nYVel); } } } diff --git a/source/games/exhumed/src/player.cpp b/source/games/exhumed/src/player.cpp index 8b975e342..35c35e9f0 100644 --- a/source/games/exhumed/src/player.cpp +++ b/source/games/exhumed/src/player.cpp @@ -991,6 +991,7 @@ void AIPlayer::Tick(RunListEvent* ev) nNormal = GetWallNormal(nMove.hitWall); } + // moving blocks - move this to a separate function! if (sect != nullptr) { if ((sect->hitag == 45) && bTouchFloor) @@ -1007,10 +1008,10 @@ void AIPlayer::Tick(RunListEvent* ev) int xvel = sPlayerInput[nPlayer].xVel; int yvel = sPlayerInput[nPlayer].yVel; - int nMyAngle = getangle(xvel, yvel); + int nMyAngle = getangle(xvel, yvel) & 2047; // note: must be positive! setsectinterpolate(sect); - MoveSector(sect, nMyAngle, &xvel, &yvel); + MoveSector(sect, DAngle::fromBuild(nMyAngle), &xvel, &yvel); if (PlayerList[nPlayer].nPlayerPushSound <= -1) {