diff --git a/src/playsim/p_pspr.cpp b/src/playsim/p_pspr.cpp index d8e43042a..7e4e29c5b 100644 --- a/src/playsim/p_pspr.cpp +++ b/src/playsim/p_pspr.cpp @@ -134,6 +134,7 @@ DEFINE_FIELD(DPSprite, oldx) DEFINE_FIELD(DPSprite, oldy) DEFINE_FIELD(DPSprite, firstTic) DEFINE_FIELD(DPSprite, Tics) +DEFINE_FIELD(DPSprite, Translation) DEFINE_FIELD(DPSprite, alpha) DEFINE_FIELD_BIT(DPSprite, Flags, bAddWeapon, PSPF_ADDWEAPON) DEFINE_FIELD_BIT(DPSprite, Flags, bAddBob, PSPF_ADDBOB) @@ -154,6 +155,7 @@ DPSprite::DPSprite(player_t *owner, AActor *caller, int id) oldx(.0), oldy(.0), firstTic(true), Tics(0), + Translation(0), Flags(0), Caller(caller), Owner(owner), @@ -742,6 +744,30 @@ DEFINE_ACTION_FUNCTION(AActor, A_OverlayFlags) return 0; } +//--------------------------------------------------------------------------- +// +// PROC A_OverlayTranslation +// +//--------------------------------------------------------------------------- + +DEFINE_ACTION_FUNCTION(AActor, A_OverlayTranslation) +{ + PARAM_ACTION_PROLOGUE(AActor); + PARAM_INT(layer); + PARAM_UINT(trans); + + if (!ACTION_CALL_FROM_PSPRITE()) + return 0; + + DPSprite* pspr = self->player->FindPSprite(((layer != 0) ? layer : stateinfo->mPSPIndex)); + if (pspr != nullptr) + { + pspr->Translation = trans; + } + + return 0; +} + //--------------------------------------------------------------------------- // // PROC OverlayX/Y @@ -1017,6 +1043,7 @@ void DPSprite::Serialize(FSerializer &arc) ("flags", Flags) ("state", State) ("tics", Tics) + ("translation", Translation) .Sprite("sprite", Sprite, nullptr) ("frame", Frame) ("id", ID) diff --git a/src/playsim/p_pspr.h b/src/playsim/p_pspr.h index a4097a944..83a860e5d 100644 --- a/src/playsim/p_pspr.h +++ b/src/playsim/p_pspr.h @@ -83,15 +83,16 @@ public: static void NewTick(); void SetState(FState *newstate, bool pending = false); - int GetID() const { return ID; } - int GetSprite() const { return Sprite; } - int GetFrame() const { return Frame; } - int GetTics() const { return Tics; } - FState* GetState() const { return State; } - DPSprite* GetNext() { return Next; } - AActor* GetCaller() { return Caller; } - void SetCaller(AActor *newcaller) { Caller = newcaller; } - void ResetInterpolation() { oldx = x; oldy = y; } + int GetID() const { return ID; } + int GetSprite() const { return Sprite; } + int GetFrame() const { return Frame; } + int GetTics() const { return Tics; } + uint32_t GetTranslation() { return Translation; } + FState* GetState() const { return State; } + DPSprite* GetNext() { return Next; } + AActor* GetCaller() { return Caller; } + void SetCaller(AActor *newcaller) { Caller = newcaller; } + void ResetInterpolation() { oldx = x; oldy = y; } void OnDestroy() override; std::pair GetRenderStyle(FRenderStyle ownerstyle, double owneralpha); float GetYAdjust(bool fullscreen); @@ -100,6 +101,7 @@ public: double oldx, oldy; bool firstTic; int Tics; + uint32_t Translation; int Flags; FRenderStyle Renderstyle; diff --git a/src/r_data/models.cpp b/src/r_data/models.cpp index d98e55413..0b8a458b4 100644 --- a/src/r_data/models.cpp +++ b/src/r_data/models.cpp @@ -214,7 +214,9 @@ void RenderHUDModel(FModelRenderer *renderer, DPSprite *psp, float ofsX, float o float orientation = smf->xscale * smf->yscale * smf->zscale; renderer->BeginDrawHUDModel(playermo->RenderStyle, objectToWorldMatrix, orientation < 0); - RenderFrameModels(renderer, playermo->Level, smf, psp->GetState(), psp->GetTics(), playermo->player->ReadyWeapon->GetClass(), psp->Flags & PSPF_PLAYERTRANSLATED ? psp->Owner->mo->Translation : 0); + uint32_t trans = psp->GetTranslation() != 0 ? psp->GetTranslation() : 0; + if ((psp->Flags & PSPF_PLAYERTRANSLATED)) trans = psp->Owner->mo->Translation; + RenderFrameModels(renderer, playermo->Level, smf, psp->GetState(), psp->GetTics(), playermo->player->ReadyWeapon->GetClass(), trans); renderer->EndDrawHUDModel(playermo->RenderStyle); } diff --git a/src/rendering/hwrenderer/scene/hw_weapon.cpp b/src/rendering/hwrenderer/scene/hw_weapon.cpp index 99702923b..0fe4a1c16 100644 --- a/src/rendering/hwrenderer/scene/hw_weapon.cpp +++ b/src/rendering/hwrenderer/scene/hw_weapon.cpp @@ -96,7 +96,9 @@ void HWDrawInfo::DrawPSprite(HUDSprite *huds, FRenderState &state) { float thresh = (huds->texture->GetTranslucency() || huds->OverrideShader != -1) ? 0.f : gl_mask_sprite_threshold; state.AlphaFunc(Alpha_GEqual, thresh); - state.SetMaterial(huds->texture, UF_Sprite, CTF_Expand, CLAMP_XY_NOMIP, (huds->weapon->Flags & PSPF_PLAYERTRANSLATED) ? huds->owner->Translation : 0, huds->OverrideShader); + uint32_t trans = huds->weapon->GetTranslation() != 0 ? huds->weapon->GetTranslation() : 0; + if ((huds->weapon->Flags & PSPF_PLAYERTRANSLATED)) trans = huds->owner->Translation; + state.SetMaterial(huds->texture, UF_Sprite, CTF_Expand, CLAMP_XY_NOMIP, trans, huds->OverrideShader); state.Draw(DT_TriangleStrip, huds->mx, 4); } diff --git a/src/rendering/swrenderer/things/r_model.cpp b/src/rendering/swrenderer/things/r_model.cpp index b2dd3ed45..548dc7bab 100644 --- a/src/rendering/swrenderer/things/r_model.cpp +++ b/src/rendering/swrenderer/things/r_model.cpp @@ -141,7 +141,9 @@ namespace swrenderer ThingColor.a = 255; renderer.fillcolor = fullbrightSprite ? ThingColor : ThingColor.Modulate(playermo->Sector->SpecialColors[sector_t::sprites]); - renderer.Translation = 0xffffffff;// playermo->Translation; + uint32_t trans = psp->GetTranslation() != 0 ? psp->GetTranslation() : 0; + if ((psp->Flags & PSPF_PLAYERTRANSLATED)) trans = playermo->Translation; + renderer.Translation = trans; RenderHUDModel(&renderer, psp, ofsx, ofsy); PolyTriangleDrawer::SetModelVertexShader(thread->DrawQueue, -1, -1, 0.0f); diff --git a/src/rendering/swrenderer/things/r_playersprite.cpp b/src/rendering/swrenderer/things/r_playersprite.cpp index 3291de29c..f1fc735ab 100644 --- a/src/rendering/swrenderer/things/r_playersprite.cpp +++ b/src/rendering/swrenderer/things/r_playersprite.cpp @@ -313,6 +313,10 @@ namespace swrenderer vis.yscale = float(pspriteyscale / stex->GetScale().Y); vis.pic = stex; + uint32_t trans = pspr->GetTranslation() != 0 ? pspr->GetTranslation() : 0; + if ((pspr->Flags & PSPF_PLAYERTRANSLATED)) trans = owner->Translation; + vis.Translation = trans; + // If flip is used, provided that it's not already flipped (that would just invert itself) // (It's an XOR...) if (!(flip) != !(pspr->Flags & PSPF_FLIP)) @@ -434,6 +438,8 @@ namespace swrenderer accelSprite.x1 = x1; accelSprite.flip = vis.xiscale < 0; + accelSprite.Translation = trans; + if (vis.Light.BaseColormap >= &SpecialSWColormaps[0] && vis.Light.BaseColormap < &SpecialSWColormaps[SpecialColormaps.Size()]) { diff --git a/wadsrc/static/zscript/actors/actor.zs b/wadsrc/static/zscript/actors/actor.zs index 54cd2fc66..b1afa29a3 100644 --- a/wadsrc/static/zscript/actors/actor.zs +++ b/wadsrc/static/zscript/actors/actor.zs @@ -1185,6 +1185,7 @@ class Actor : Thinker native action native void A_OverlayFlags(int layer, int flags, bool set); action native void A_OverlayAlpha(int layer, double alph); action native void A_OverlayRenderStyle(int layer, int style); + action native void A_OverlayTranslation(int layer, int trans); native bool A_AttachLightDef(Name lightid, Name lightdef); native bool A_AttachLight(Name lightid, int type, Color lightcolor, int radius1, int radius2, int flags = 0, Vector3 ofs = (0,0,0), double param = 0, double spoti = 10, double spoto = 25, double spotp = 0); diff --git a/wadsrc/static/zscript/actors/player/player.zs b/wadsrc/static/zscript/actors/player/player.zs index fbdd3c8bd..e6252a5c7 100644 --- a/wadsrc/static/zscript/actors/player/player.zs +++ b/wadsrc/static/zscript/actors/player/player.zs @@ -2560,6 +2560,7 @@ class PSprite : Object native play native double alpha; native Bool firstTic; native int Tics; + native uint Translation; native bool bAddWeapon; native bool bAddBob; native bool bPowDouble;