From 940e53af6fed5ed9f50f5495eac9d1fda42a6065 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 3 Apr 2025 08:38:16 +0200 Subject: [PATCH] avoid type punning in TVector XY() and XYZ() methods. --- source/common/utility/vectors.h | 34 ++++++++---------------------- source/core/coreactor.h | 7 +++--- source/core/gamefuncs.h | 7 +++--- source/games/duke/src/player.cpp | 4 ++-- source/games/duke/src/player_d.cpp | 4 ++-- source/games/duke/src/player_r.cpp | 10 ++++----- source/games/sw/src/player.cpp | 20 +++++++++--------- 7 files changed, 36 insertions(+), 50 deletions(-) diff --git a/source/common/utility/vectors.h b/source/common/utility/vectors.h index 47eb59793..299a08985 100644 --- a/source/common/utility/vectors.h +++ b/source/common/utility/vectors.h @@ -539,15 +539,9 @@ struct TVector3 return *this; } - // returns the XY fields as a 2D-vector. - constexpr const Vector2& XY() const + constexpr Vector2 XY() const { - return *reinterpret_cast(this); - } - - constexpr Vector2& XY() - { - return *reinterpret_cast(this); + return Vector2(X, Y); } // Add a 3D vector and a 2D vector. @@ -785,28 +779,16 @@ struct TVector4 } // returns the XY fields as a 2D-vector. - constexpr const Vector2& XY() const + constexpr Vector2 XY() const { - return *reinterpret_cast(this); + return Vector2(X, Y); } - constexpr Vector2& XY() + constexpr Vector3 XYZ() const { - return *reinterpret_cast(this); + return Vector3(X, Y, Z); } - // returns the XY fields as a 2D-vector. - constexpr const Vector3& XYZ() const - { - return *reinterpret_cast(this); - } - - constexpr Vector3& XYZ() - { - return *reinterpret_cast(this); - } - - // Test for approximate equality bool ApproximatelyEquals(const TVector4 &other) const { @@ -1789,7 +1771,9 @@ struct TRotator template inline TVector3::TVector3 (const TRotator &rot) { - XY() = rot.Pitch.Cos() * rot.Yaw.ToVector(); + auto XY = rot.Pitch.Cos() * rot.Yaw.ToVector(); + X = XY.X; + Y = XY.Y; Z = rot.Pitch.Sin(); } diff --git a/source/core/coreactor.h b/source/core/coreactor.h index 92ecbc5b2..cab007cfd 100644 --- a/source/core/coreactor.h +++ b/source/core/coreactor.h @@ -490,12 +490,13 @@ inline int clipmove(DVector3& pos, sectortype** const sect, const DVector2& mvec return result.type; } -inline int clipmove(DVector2& pos, double z, sectortype** const sect, const DVector2& mvec, +inline int clipmove(DVector3& pos, double z, sectortype** const sect, const DVector2& mvec, double const walldist, double const ceildist, double const flordist, unsigned const cliptype, CollisionBase& result, int clipmoveboxtracenum = 3) { - auto vect = DVector3(pos, z); + auto vect = DVector3(pos.XY(), z); auto res = clipmove(vect, sect, mvec, walldist, ceildist, flordist, cliptype, result); - pos = vect.XY(); + pos.X = vect.X; + pos.Y = vect.Y; return res; } diff --git a/source/core/gamefuncs.h b/source/core/gamefuncs.h index 7451dbcf8..861f2bd22 100644 --- a/source/core/gamefuncs.h +++ b/source/core/gamefuncs.h @@ -227,11 +227,12 @@ bool checkOpening(const DVector2& inpos, double z, const sectortype* sec, const int pushmove(DVector3& pos, sectortype** pSect, double walldist, double ceildist, double flordist, unsigned cliptype); tspritetype* renderAddTsprite(tspriteArray& tsprites, DCoreActor* actor); -inline int pushmove(DVector2& pos, double z, sectortype** pSect, double walldist, double ceildist, double flordist, unsigned cliptype) +inline int pushmove(DVector3& pos, double z, sectortype** pSect, double walldist, double ceildist, double flordist, unsigned cliptype) { - auto vect = DVector3(pos, z); + auto vect = DVector3(pos.XY(), z); auto result = pushmove(vect, pSect, walldist, ceildist, flordist, cliptype); - pos = vect.XY(); + pos.X = vect.X; + pos.Y = vect.Y; return result; } diff --git a/source/games/duke/src/player.cpp b/source/games/duke/src/player.cpp index 840e1dbe6..36d9e4327 100644 --- a/source/games/duke/src/player.cpp +++ b/source/games/duke/src/player.cpp @@ -590,7 +590,7 @@ void playerisdead(DDukePlayer* const p, int psectlotag, double floorz, double ce } Collision coll; - clipmove(actor->spr.pos.XY(), actor->getOffsetZ(), &p->cursector, DVector2( 0, 0), 10.25, 4., 4., CLIPMASK0, coll); + clipmove(actor->spr.pos, actor->getOffsetZ(), &p->cursector, DVector2( 0, 0), 10.25, 4., 4., CLIPMASK0, coll); } actor->backuploc(); @@ -599,7 +599,7 @@ void playerisdead(DDukePlayer* const p, int psectlotag, double floorz, double ce updatesector(actor->getPosWithOffsetZ(), &p->cursector); - pushmove(actor->spr.pos.XY(), actor->getOffsetZ(), &p->cursector, 8, 4, 20, CLIPMASK0); + pushmove(actor->spr.pos, actor->getOffsetZ(), &p->cursector, 8, 4, 20, CLIPMASK0); if (floorz > ceilingz + 16 && actor->spr.pal != 1) p->ViewAngles.Roll = DAngle::fromBuild(-(p->dead_flag + ((floorz + actor->getOffsetZ()) * 2))); diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index fc4cb6216..3ab014d87 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -1828,7 +1828,7 @@ HORIZONLY: ChangeActorSect(pact, p->cursector); } else - clipmove(pact->spr.pos.XY(), pact->getOffsetZ(), &p->cursector, p->vel.XY(), 10.25, 4., iif, CLIPMASK0, clip); + clipmove(pact->spr.pos, pact->getOffsetZ(), &p->cursector, p->vel.XY(), 10.25, 4., iif, CLIPMASK0, clip); if (p->jetpack_on == 0 && psectlotag != 2 && psectlotag != 1 && shrunk) pact->spr.pos.Z += 32; @@ -1881,7 +1881,7 @@ HORIZONLY: while (ud.clipping == 0) { int blocked; - blocked = (pushmove(pact->spr.pos.XY(), pact->getOffsetZ(), &p->cursector, 10.25, 4, 4, CLIPMASK0) < 0 && furthestangle(pact, 8) < DAngle90); + blocked = (pushmove(pact->spr.pos, pact->getOffsetZ(), &p->cursector, 10.25, 4, 4, CLIPMASK0) < 0 && furthestangle(pact, 8) < DAngle90); if (fabs(pact->floorz - pact->ceilingz) < 48 || blocked) { diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index 93ffe79d0..24174f9fd 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -2720,7 +2720,7 @@ HORIZONLY: ChangeActorSect(pact, p->cursector); } else - clipmove(pact->spr.pos.XY(), pact->getOffsetZ(), &p->cursector, p->vel.XY(), 10.25, 4., iif, CLIPMASK0, clip); + clipmove(pact->spr.pos, pact->getOffsetZ(), &p->cursector, p->vel.XY(), 10.25, 4., iif, CLIPMASK0, clip); if (p->jetpack_on == 0 && psectlotag != 2 && psectlotag != 1 && shrunk) pact->spr.pos.Z += 32; @@ -2749,10 +2749,10 @@ HORIZONLY: if (wal->lotag < 44) { dofurniture(p, clip.hitWall); - pushmove(pact->spr.pos.XY(), pact->getOffsetZ(), &p->cursector, 10.75, 4, 4, CLIPMASK0); + pushmove(pact->spr.pos, pact->getOffsetZ(), &p->cursector, 10.75, 4, 4, CLIPMASK0); } else - pushmove(pact->spr.pos.XY(), pact->getOffsetZ(), &p->cursector, 10.75, 4, 4, CLIPMASK0); + pushmove(pact->spr.pos, pact->getOffsetZ(), &p->cursector, 10.75, 4, 4, CLIPMASK0); } } } @@ -2833,9 +2833,9 @@ HORIZONLY: { int blocked; if (pact->clipdist == 16) - blocked = (pushmove(pact->spr.pos.XY(), pact->getOffsetZ(), &p->cursector, 8, 4, 4, CLIPMASK0) < 0 && furthestangle(pact, 8) < DAngle90); + blocked = (pushmove(pact->spr.pos, pact->getOffsetZ(), &p->cursector, 8, 4, 4, CLIPMASK0) < 0 && furthestangle(pact, 8) < DAngle90); else - blocked = (pushmove(pact->spr.pos.XY(), pact->getOffsetZ(), &p->cursector, 1, 4, 4, CLIPMASK0) < 0 && furthestangle(pact, 8) < DAngle90); + blocked = (pushmove(pact->spr.pos, pact->getOffsetZ(), &p->cursector, 1, 4, 4, CLIPMASK0) < 0 && furthestangle(pact, 8) < DAngle90); if (fabs(pact->floorz - pact->ceilingz) < 48 || blocked) { diff --git a/source/games/sw/src/player.cpp b/source/games/sw/src/player.cpp index 3f7cd8437..020576fe1 100644 --- a/source/games/sw/src/player.cpp +++ b/source/games/sw/src/player.cpp @@ -1842,7 +1842,7 @@ void DoPlayerSlide(DSWPlayer* pp) if (abs(pp->slide_vect.X) < 0.05 && abs(pp->slide_vect.Y) < 0.05) pp->slide_vect.Zero(); - push_ret = pushmove(pp->GetActor()->spr.pos.XY(), pp->GetActor()->getOffsetZ(), &pp->cursector, actor->clipdist, pp->p_ceiling_dist, pp->p_floor_dist, CLIPMASK_PLAYER); + push_ret = pushmove(pp->GetActor()->spr.pos, pp->GetActor()->getOffsetZ(), &pp->cursector, actor->clipdist, pp->p_ceiling_dist, pp->p_floor_dist, CLIPMASK_PLAYER); if (push_ret < 0) { if (!(pp->Flags & PF_DEAD)) @@ -1856,10 +1856,10 @@ void DoPlayerSlide(DSWPlayer* pp) return; } Collision coll; - clipmove(pp->GetActor()->spr.pos.XY(), pp->GetActor()->getOffsetZ(), &pp->cursector, pp->slide_vect, actor->clipdist, pp->p_ceiling_dist, pp->p_floor_dist, CLIPMASK_PLAYER, coll); + clipmove(pp->GetActor()->spr.pos, pp->GetActor()->getOffsetZ(), &pp->cursector, pp->slide_vect, actor->clipdist, pp->p_ceiling_dist, pp->p_floor_dist, CLIPMASK_PLAYER, coll); PlayerCheckValidMove(pp); - push_ret = pushmove(pp->GetActor()->spr.pos.XY(), pp->GetActor()->getOffsetZ(), &pp->cursector, actor->clipdist, pp->p_ceiling_dist, pp->p_floor_dist, CLIPMASK_PLAYER); + push_ret = pushmove(pp->GetActor()->spr.pos, pp->GetActor()->getOffsetZ(), &pp->cursector, actor->clipdist, pp->p_ceiling_dist, pp->p_floor_dist, CLIPMASK_PLAYER); if (push_ret < 0) { if (!(pp->Flags & PF_DEAD)) @@ -2008,7 +2008,7 @@ void DoPlayerMove(DSWPlayer* pp) } else { - push_ret = pushmove(pp->GetActor()->spr.pos.XY(), pp->GetActor()->getOffsetZ(), &pp->cursector, actor->clipdist, pp->p_ceiling_dist, pp->p_floor_dist - 16., CLIPMASK_PLAYER); + push_ret = pushmove(pp->GetActor()->spr.pos, pp->GetActor()->getOffsetZ(), &pp->cursector, actor->clipdist, pp->p_ceiling_dist, pp->p_floor_dist - 16., CLIPMASK_PLAYER); if (push_ret < 0) { @@ -2031,12 +2031,12 @@ void DoPlayerMove(DSWPlayer* pp) actor->spr.cstat &= ~(CSTAT_SPRITE_BLOCK); Collision coll; updatesector(pp->GetActor()->getPosWithOffsetZ(), &pp->cursector); - clipmove(pp->GetActor()->spr.pos.XY(), pp->GetActor()->getOffsetZ(), &pp->cursector, pp->vect, actor->clipdist, pp->p_ceiling_dist, pp->p_floor_dist, CLIPMASK_PLAYER, coll); + clipmove(pp->GetActor()->spr.pos, pp->GetActor()->getOffsetZ(), &pp->cursector, pp->vect, actor->clipdist, pp->p_ceiling_dist, pp->p_floor_dist, CLIPMASK_PLAYER, coll); actor->spr.cstat = save_cstat; PlayerCheckValidMove(pp); - push_ret = pushmove(pp->GetActor()->spr.pos.XY(), pp->GetActor()->getOffsetZ(), &pp->cursector, actor->clipdist, pp->p_ceiling_dist, pp->p_floor_dist - 16., CLIPMASK_PLAYER); + push_ret = pushmove(pp->GetActor()->spr.pos, pp->GetActor()->getOffsetZ(), &pp->cursector, actor->clipdist, pp->p_ceiling_dist, pp->p_floor_dist - 16., CLIPMASK_PLAYER); if (push_ret < 0) { @@ -2626,7 +2626,7 @@ void DoPlayerMoveVehicle(DSWPlayer* pp) if (pp->sop->clipdist) { Collision coll; - clipmove(plActor->spr.pos.XY(), zz, &pp->cursector, pp->vect, pp->sop->clipdist, 4., floordist, CLIPMASK_PLAYER, actor->user.coll); + clipmove(plActor->spr.pos, zz, &pp->cursector, pp->vect, pp->sop->clipdist, 4., floordist, CLIPMASK_PLAYER, actor->user.coll); } else { @@ -4612,7 +4612,7 @@ void DoPlayerCurrent(DSWPlayer* pp) auto vect = sectu->angle.ToVector() / 256. * sectu->speed * synctics; // 16384 >> 4 - Beware of clipmove's odd format for vect! - push_ret = pushmove(pp->GetActor()->spr.pos.XY(), pp->GetActor()->getOffsetZ(), &pp->cursector, pp->GetActor()->clipdist, pp->p_ceiling_dist, pp->p_floor_dist, CLIPMASK_PLAYER); + push_ret = pushmove(pp->GetActor()->spr.pos, pp->GetActor()->getOffsetZ(), &pp->cursector, pp->GetActor()->clipdist, pp->p_ceiling_dist, pp->p_floor_dist, CLIPMASK_PLAYER); if (push_ret < 0) { if (!(pp->Flags & PF_DEAD)) @@ -4628,10 +4628,10 @@ void DoPlayerCurrent(DSWPlayer* pp) return; } Collision coll; - clipmove(pp->GetActor()->spr.pos.XY(), pp->GetActor()->getOffsetZ(), &pp->cursector, vect, pp->GetActor()->clipdist, pp->p_ceiling_dist, pp->p_floor_dist, CLIPMASK_PLAYER, coll); + clipmove(pp->GetActor()->spr.pos, pp->GetActor()->getOffsetZ(), &pp->cursector, vect, pp->GetActor()->clipdist, pp->p_ceiling_dist, pp->p_floor_dist, CLIPMASK_PLAYER, coll); PlayerCheckValidMove(pp); - pushmove(pp->GetActor()->spr.pos.XY(), pp->GetActor()->getOffsetZ(), &pp->cursector, pp->GetActor()->clipdist, pp->p_ceiling_dist, pp->p_floor_dist, CLIPMASK_PLAYER); + pushmove(pp->GetActor()->spr.pos, pp->GetActor()->getOffsetZ(), &pp->cursector, pp->GetActor()->clipdist, pp->p_ceiling_dist, pp->p_floor_dist, CLIPMASK_PLAYER); if (push_ret < 0) { if (!(pp->Flags & PF_DEAD))