diff --git a/src/playsim/p_pspr.cpp b/src/playsim/p_pspr.cpp index e49e652578..d858c0598a 100644 --- a/src/playsim/p_pspr.cpp +++ b/src/playsim/p_pspr.cpp @@ -142,8 +142,6 @@ DEFINE_FIELD(DPSprite, oldscalex) DEFINE_FIELD(DPSprite, oldscaley) DEFINE_FIELD(DPSprite, rotation) DEFINE_FIELD(DPSprite, oldrotation) -DEFINE_FIELD(DPSprite, PivotPercent) -DEFINE_FIELD(DPSprite, PivotScreen) DEFINE_FIELD(DPSprite, firstTic) DEFINE_FIELD(DPSprite, Tics) DEFINE_FIELD(DPSprite, Translation) @@ -157,6 +155,7 @@ DEFINE_FIELD_BIT(DPSprite, Flags, bMirror, PSPF_MIRROR) DEFINE_FIELD_BIT(DPSprite, Flags, bPlayerTranslated, PSPF_PLAYERTRANSLATED) DEFINE_FIELD_BIT(DPSprite, Flags, bPivotPercent, PSPF_PIVOTPERCENT) DEFINE_FIELD_BIT(DPSprite, Flags, bPivotScreen, PSPF_PIVOTSCREEN) +DEFINE_FIELD_BIT(DPSprite, Flags, bPivotOffsetRel, PSPF_PIVOTOFFSETREL) //------------------------------------------------------------------------ // @@ -185,7 +184,8 @@ DPSprite::DPSprite(player_t *owner, AActor *caller, int id) oldpx(.0), oldpy(.0), oldrotation(.0), PivotPercent(true), - PivotScreen(false) + PivotScreen(false), + PivotOffsetRel(false) { alpha = 1; Renderstyle = STYLE_Normal; diff --git a/src/playsim/p_pspr.h b/src/playsim/p_pspr.h index e5d7ad10bb..27afacb5cc 100644 --- a/src/playsim/p_pspr.h +++ b/src/playsim/p_pspr.h @@ -73,6 +73,7 @@ enum PSPFlags PSPF_PLAYERTRANSLATED = 1 << 10, PSPF_PIVOTPERCENT = 1 << 11, PSPF_PIVOTSCREEN = 1 << 12, + PSPF_PIVOTOFFSETREL = 1 << 13, }; class DPSprite : public DObject @@ -101,6 +102,7 @@ public: bool PivotScreen; // If true, the pivot is based on the entire screen width/height instead of the image's dimensions/position. bool PivotPercent; // If true, the pivot goes between [0.0, 1.0]. Otherwise, it's a pixel position offset from the image size. + bool PivotOffsetRel; // If true, x & y are relative to rotation. Otherwise, x is left/right and y is up/down. double px, py; // pivot points double oldpx, oldpy; double rotation; // How much rotation to apply. diff --git a/src/rendering/hwrenderer/scene/hw_weapon.cpp b/src/rendering/hwrenderer/scene/hw_weapon.cpp index cbe4015c36..452b33f862 100644 --- a/src/rendering/hwrenderer/scene/hw_weapon.cpp +++ b/src/rendering/hwrenderer/scene/hw_weapon.cpp @@ -485,29 +485,67 @@ bool HUDSprite::GetWeaponRect(HWDrawInfo *di, DPSprite *psp, float sx, float sy, auto verts = screen->mVertexData->AllocVertices(4); mx = verts.second; - + // [MC] Code copied from DTA_Rotate + // Big thanks to IvanDobrovski who helped me modify this. if (psp->rotation != 0.0 || psp->scalex != 1.0 || psp->scaley != 1.0) { - double radang = psp->rotation * (pi::pi() / 180.); - double cosang = cos(radang); - double sinang = sin(radang); + float radang = psp->rotation * (pi::pi() / 180.); + float cosang = -cos(radang); + float sinang = -sin(radang); - double xcenter = psp->x; - double ycenter = psp->y; + float xcenter, ycenter; + float px = float(psp->px); + float py = float(psp->py); - double xx1 = xcenter + psp->scalex * (x1 * cosang + y1 * sinang); - double yy1 = ycenter + psp->scaley * (x1 * sinang - y1 * cosang); + if (psp->Flags & PSPF_PIVOTSCREEN) + { + if (psp->Flags & PSPF_PIVOTPERCENT) + { + xcenter = vw * psp->px + viewwindowx + psp->x; + ycenter = vh * psp->py + viewwindowy + psp->y; + } + else + { + xcenter = vw * 0.5 + viewwindowx + psp->x + psp->px; + ycenter = vh * 0.5 + viewwindowy + psp->y + psp->py; + } + } + else + { + if (psp->Flags & PSPF_PIVOTPERCENT) + { + xcenter = (x1 + x2) * psp->px + psp->x; + ycenter = (y1 + y2) * psp->py + psp->y; + } + else + { + xcenter = ((x1 + x2) * 0.5 + psp->x) + psp->px; + ycenter = ((x1 + x2) * 0.5 + psp->y) + psp->py; + } + } - double xx2 = xcenter + psp->scalex * (x1 * cosang + y2 * sinang); - double yy2 = ycenter + psp->scaley * (x1 * sinang - y2 * cosang); + x1 -= xcenter; + y1 -= ycenter; - double xx3 = xcenter + psp->scalex * (x2 * cosang + y1 * sinang); - double yy3 = ycenter + psp->scaley * (x2 * sinang - y1 * cosang); + x2 -= xcenter; + y2 -= ycenter; + + float ssx = (float)psp->scalex; + float ssy = (float)psp->scaley; + + float xx1 = xcenter + ssx * (x1 * cosang + y1 * sinang); + float yy1 = ycenter + ssy * (x1 * sinang - y1 * cosang); + + float xx2 = xcenter + ssx * (x1 * cosang + y2 * sinang); + float yy2 = ycenter + ssy * (x1 * sinang - y2 * cosang); + + float xx3 = xcenter + ssx * (x2 * cosang + y1 * sinang); + float yy3 = ycenter + ssy * (x2 * sinang - y1 * cosang); + + float xx4 = xcenter + ssx * (x2 * cosang + y2 * sinang); + float yy4 = ycenter + ssy * (x2 * sinang - y2 * cosang); - double xx4 = xcenter + psp->scalex * (x2 * cosang + y2 * sinang); - double yy4 = ycenter + psp->scaley * (x2 * sinang - y2 * cosang); - verts.first[0].Set(xx1, yy1, 0, u1, v1); verts.first[1].Set(xx2, yy2, 0, u1, v2); verts.first[2].Set(xx3, yy3, 0, u2, v1); @@ -515,7 +553,6 @@ bool HUDSprite::GetWeaponRect(HWDrawInfo *di, DPSprite *psp, float sx, float sy, } else { - verts.first[0].Set(x1, y1, 0, u1, v1); verts.first[1].Set(x1, y2, 0, u1, v2); verts.first[2].Set(x2, y1, 0, u2, v1); diff --git a/wadsrc/static/zscript/actors/player/player.zs b/wadsrc/static/zscript/actors/player/player.zs index f076e680a4..d0f5ccf258 100644 --- a/wadsrc/static/zscript/actors/player/player.zs +++ b/wadsrc/static/zscript/actors/player/player.zs @@ -2580,6 +2580,7 @@ class PSprite : Object native play native bool bPlayerTranslated; native bool bPivotPercent; native bool bPivotScreen; + native bool bPivotOffsetRel; native void SetState(State newstate, bool pending = false);