diff --git a/src/playsim/p_pspr.cpp b/src/playsim/p_pspr.cpp index 5256d20712..4b7ded01b1 100644 --- a/src/playsim/p_pspr.cpp +++ b/src/playsim/p_pspr.cpp @@ -132,10 +132,8 @@ DEFINE_FIELD(DPSprite, x) DEFINE_FIELD(DPSprite, y) DEFINE_FIELD(DPSprite, oldx) DEFINE_FIELD(DPSprite, oldy) -DEFINE_FIELD(DPSprite, px) -DEFINE_FIELD(DPSprite, py) -DEFINE_FIELD(DPSprite, scalex) -DEFINE_FIELD(DPSprite, scaley) +DEFINE_FIELD(DPSprite, pivot) +DEFINE_FIELD(DPSprite, scale) DEFINE_FIELD(DPSprite, rotation) DEFINE_FIELD_NAMED(DPSprite, Coord[0], Coord0) DEFINE_FIELD_NAMED(DPSprite, Coord[1], Coord1) @@ -178,13 +176,13 @@ DPSprite::DPSprite(player_t *owner, AActor *caller, int id) Frame(0), ID(id), processPending(true), - scalex(1.0), scaley(1.0), - px(.0), py(.0), - rotation(.0), HAlign(0), VAlign(0), InterpolateTic(false) { + rotation = 0.; + scale = {1.0, 1.0}; + pivot = {0.0, 0.0}; for (int i = 0; i < 4; i++) { Coord[i] = DVector2(0, 0); @@ -675,6 +673,17 @@ enum WOFFlags WOF_ZEROY = 1 << 5, }; +void HandleOverlayRelative(DPSprite *psp, double *x, double *y) +{ + double wx = *x; + double wy = *y; + + double c = psp->rotation.Cos(), s = psp->rotation.Sin(); + double nx = wx * c + wy * s; + double ny = wx * s - wy * c; + *x = nx; *y = ny; +} + //--------------------------------------------------------------------------- // // PROC A_OverlayVertexOffset @@ -701,7 +710,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_OverlayVertexOffset) if (!(flags & WOF_KEEPX)) pspr->Coord[index].X = (flags & WOF_ADD) ? pspr->Coord[index].X + x : x; if (!(flags & WOF_KEEPY)) pspr->Coord[index].Y = (flags & WOF_ADD) ? pspr->Coord[index].Y + y : y; - if (flags & WOF_INTERPOLATE) pspr->InterpolateTic = true; + if (flags & (WOF_ADD | WOF_INTERPOLATE)) pspr->InterpolateTic = true; return 0; } @@ -731,10 +740,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_OverlayScale) if (!(flags & WOF_ZEROY) && wy == 0.0) wy = wx; - if (!(flags & WOF_KEEPX)) pspr->scalex = (flags & WOF_ADD) ? pspr->scalex + wx : wx; - if (!(flags & WOF_KEEPY)) pspr->scaley = (flags & WOF_ADD) ? pspr->scaley + wy : wy; + if (!(flags & WOF_KEEPX)) pspr->scale.X = (flags & WOF_ADD) ? pspr->scale.X + wx : wx; + if (!(flags & WOF_KEEPY)) pspr->scale.Y = (flags & WOF_ADD) ? pspr->scale.Y + wy : wy; - if (flags & WOF_INTERPOLATE) pspr->InterpolateTic = true; + if (flags & (WOF_ADD | WOF_INTERPOLATE)) pspr->InterpolateTic = true; return 0; } @@ -749,7 +758,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_OverlayRotate) { PARAM_ACTION_PROLOGUE(AActor); PARAM_INT(layer) - PARAM_FLOAT(degrees) + PARAM_ANGLE(degrees) PARAM_INT(flags) if (!ACTION_CALL_FROM_PSPRITE()) @@ -760,7 +769,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_OverlayRotate) if (pspr != nullptr) { pspr->rotation = (flags & WOF_ADD) ? pspr->rotation + degrees : degrees; - if (flags & WOF_INTERPOLATE) pspr->InterpolateTic = true; + if (flags & (WOF_ADD | WOF_INTERPOLATE)) pspr->InterpolateTic = true; } return 0; @@ -790,17 +799,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_OverlayPivot) if (flags & WOF_RELATIVE) { - DAngle rot = pspr->rotation; - double c = rot.Cos(), s = rot.Sin(); - double nx = wx * c + wy * s; - double ny = wx * s - wy * c; - wx = nx; wy = ny; + HandleOverlayRelative(pspr, &wx, &wy); } - if (!(flags & WOF_KEEPX)) pspr->px = (flags & WOF_ADD) ? pspr->px + wx : wx; - if (!(flags & WOF_KEEPY)) pspr->py = (flags & WOF_ADD) ? pspr->py + wy : wy; + if (!(flags & WOF_KEEPX)) pspr->pivot.X = (flags & WOF_ADD) ? pspr->pivot.X + wx : wx; + if (!(flags & WOF_KEEPY)) pspr->pivot.Y = (flags & WOF_ADD) ? pspr->pivot.Y + wy : wy; - if (flags & WOF_INTERPOLATE) pspr->InterpolateTic = true; + if (flags & (WOF_ADD | WOF_INTERPOLATE)) pspr->InterpolateTic = true; return 0; } @@ -830,17 +835,13 @@ void A_OverlayOffset(AActor *self, int layer, double wx, double wy, int flags) if (flags & WOF_RELATIVE) { - DAngle rot = psp->rotation; - double c = rot.Cos(), s = rot.Sin(); - double nx = wx * c + wy * s; - double ny = wx * s - wy * c; - wx = nx; wy = ny; + HandleOverlayRelative(psp, &wx, &wy); } if (!(flags & WOF_KEEPX)) psp->x = (flags & WOF_ADD) ? psp->x + wx : wx; if (!(flags & WOF_KEEPY)) psp->y = (flags & WOF_ADD) ? psp->y + wy : wy; - if (flags & WOF_INTERPOLATE) psp->InterpolateTic = true; + if (flags & (WOF_ADD | WOF_INTERPOLATE)) psp->InterpolateTic = true; /* if (!(flags & (WOF_INTERPOLATE|WOF_ADD))) { @@ -1251,10 +1252,8 @@ void DPSprite::Serialize(FSerializer &arc) ("oldx", oldx) ("oldy", oldy) ("alpha", alpha) - ("px", px) - ("py", py) - ("scalex", scalex) - ("scaley", scaley) + ("pivot", pivot) + ("scale", scale) ("rotation", rotation) ("halign", HAlign) ("valign", VAlign) diff --git a/src/playsim/p_pspr.h b/src/playsim/p_pspr.h index 36ffb0136a..df5b45f540 100644 --- a/src/playsim/p_pspr.h +++ b/src/playsim/p_pspr.h @@ -114,15 +114,15 @@ public: float GetYAdjust(bool fullscreen); int HAlign, VAlign; // Horizontal and vertical alignment - double px, py; // pivot points - double rotation; // How much rotation to apply. - double scalex, scaley; // Scale + DAngle rotation; // How much rotation to apply. + DVector2 pivot; // pivot points + DVector2 scale; // Scale double x, y, alpha; double oldx, oldy; - bool InterpolateTic; - DVector2 Coord[4]; // Offsets - WeaponInterp Prev; // Interpolation - WeaponInterp Vert; // Current Position + bool InterpolateTic; // One tic interpolation (WOF_INTERPOLATE) + DVector2 Coord[4]; // Offsets + WeaponInterp Prev; // Interpolation + WeaponInterp Vert; // Current Position bool firstTic; int Tics; uint32_t Translation; diff --git a/src/rendering/hwrenderer/scene/hw_weapon.cpp b/src/rendering/hwrenderer/scene/hw_weapon.cpp index b298d7e24b..43a002504f 100644 --- a/src/rendering/hwrenderer/scene/hw_weapon.cpp +++ b/src/rendering/hwrenderer/scene/hw_weapon.cpp @@ -481,7 +481,7 @@ bool HUDSprite::GetWeaponRect(HWDrawInfo *di, DPSprite *psp, float sx, float sy, const float cx = (flip) ? -psp->Coord[i].X : psp->Coord[i].X; Vert.v[i] += FVector2(cx * scalex, psp->Coord[i].Y * scale); } - if (psp->rotation != 0.0 || psp->scalex != 1.0 || psp->scaley != 1.0) + if (psp->rotation != 0.0 || !psp->scale.isZero()) { // [MC] Sets up the alignment for starting the pivot at, in a corner. float anchorx, anchory; @@ -503,16 +503,15 @@ bool HUDSprite::GetWeaponRect(HWDrawInfo *di, DPSprite *psp, float sx, float sy, // Handle PSPF_FLIP. if (flip) anchorx = 1.0 - anchorx; - FAngle rot = float((flip) ? -psp->rotation : psp->rotation); - rot.Normalized360(); + FAngle rot = float((flip) ? -psp->rotation.Degrees : psp->rotation.Degrees); const float cosang = rot.Cos(); const float sinang = rot.Sin(); float xcenter, ycenter; const float width = x2 - x1; const float height = y2 - y1; - const float px = float((flip) ? -psp->px : psp->px); - const float py = float(psp->py); + const float px = float((flip) ? -psp->pivot.X : psp->pivot.X); + const float py = float(psp->pivot.Y); // Set up the center and offset accordingly. PivotPercent changes it to be a range [0.0, 1.0] // instead of pixels and is enabled by default. @@ -531,14 +530,14 @@ bool HUDSprite::GetWeaponRect(HWDrawInfo *di, DPSprite *psp, float sx, float sy, for (int i = 0; i < 4; i++) { Vert.v[i] -= {xcenter, ycenter}; - const float xx = xcenter + psp->scalex * (Vert.v[i].X * cosang + Vert.v[i].Y * sinang); - const float yy = ycenter - psp->scaley * (Vert.v[i].X * sinang - Vert.v[i].Y * cosang); + const float xx = xcenter + psp->scale.X * (Vert.v[i].X * cosang + Vert.v[i].Y * sinang); + const float yy = ycenter - psp->scale.Y * (Vert.v[i].X * sinang - Vert.v[i].Y * cosang); Vert.v[i] = {xx, yy}; } } psp->Vert = Vert; - if (psp->scalex == 0.0 || psp->scaley == 0.0) + if (psp->scale.X == 0.0 || psp->scale.Y == 0.0) return false; bool vertsOnScreen = false; diff --git a/wadsrc/static/zscript/actors/inventory/weapons.zs b/wadsrc/static/zscript/actors/inventory/weapons.zs index 15d95d979e..3968d9722f 100644 --- a/wadsrc/static/zscript/actors/inventory/weapons.zs +++ b/wadsrc/static/zscript/actors/inventory/weapons.zs @@ -217,8 +217,10 @@ class Weapon : StateProvider { if (!psp) return; psp.rotation = 0; - psp.scalex = 1.0; - psp.scaley = 1.0; + psp.scale.x = 1; + psp.scale.y = 1; + psp.pivot.x = 0; + psp.pivot.y = 0; psp.valign = 0; psp.halign = 0; psp.Coord0 = (0,0); diff --git a/wadsrc/static/zscript/actors/player/player.zs b/wadsrc/static/zscript/actors/player/player.zs index f569f70efb..4fb6d19f68 100644 --- a/wadsrc/static/zscript/actors/player/player.zs +++ b/wadsrc/static/zscript/actors/player/player.zs @@ -2561,10 +2561,8 @@ class PSprite : Object native play native double y; native double oldx; native double oldy; - native double px; - native double py; - native double scalex; - native double scaley; + native Vector2 pivot; + native Vector2 scale; native double rotation; native int HAlign, VAlign; native Vector2 Coord0; // [MC] Not the actual coordinates. Just the offsets by A_OverlayVertexOffset.