Skip to content

Commit

Permalink
Finished implementing PSprite interpolation for vertices.
Browse files Browse the repository at this point in the history
- Setting WOF_INTERPOLATE on any of the functions with flags (except A_OverlayFlags) will enable one tic for interpolating.
- Setting PSPF_INTERPOLATE with A_OverlayFlags will permanently enable it for that layer, but requires manual calling.
  • Loading branch information
MajorCooke authored and coelckers committed Oct 25, 2020
1 parent c41733e commit a6bbddf
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 109 deletions.
96 changes: 40 additions & 56 deletions src/playsim/p_pspr.cpp
Expand Up @@ -136,10 +136,7 @@ DEFINE_FIELD(DPSprite, px)
DEFINE_FIELD(DPSprite, py)
DEFINE_FIELD(DPSprite, scalex)
DEFINE_FIELD(DPSprite, scaley)
DEFINE_FIELD(DPSprite, oldscalex)
DEFINE_FIELD(DPSprite, oldscaley)
DEFINE_FIELD(DPSprite, rotation)
DEFINE_FIELD(DPSprite, oldrotation)
DEFINE_FIELD_NAMED(DPSprite, Coord[0], Coord0)
DEFINE_FIELD_NAMED(DPSprite, Coord[1], Coord1)
DEFINE_FIELD_NAMED(DPSprite, Coord[2], Coord2)
Expand All @@ -150,6 +147,7 @@ DEFINE_FIELD(DPSprite, Translation)
DEFINE_FIELD(DPSprite, HAlign)
DEFINE_FIELD(DPSprite, VAlign)
DEFINE_FIELD(DPSprite, alpha)
DEFINE_FIELD(DPSprite, InterpolateTic)
DEFINE_FIELD_BIT(DPSprite, Flags, bAddWeapon, PSPF_ADDWEAPON)
DEFINE_FIELD_BIT(DPSprite, Flags, bAddBob, PSPF_ADDBOB)
DEFINE_FIELD_BIT(DPSprite, Flags, bPowDouble, PSPF_POWDOUBLE)
Expand All @@ -158,6 +156,7 @@ DEFINE_FIELD_BIT(DPSprite, Flags, bFlip, PSPF_FLIP)
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, bInterpolate, PSPF_INTERPOLATE)

//------------------------------------------------------------------------
//
Expand All @@ -182,15 +181,16 @@ DPSprite::DPSprite(player_t *owner, AActor *caller, int id)
scalex(1.0), scaley(1.0),
px(.0), py(.0),
rotation(.0),
oldscalex(.0), oldscaley(.0),
oldrotation(.0),
PivotPercent(true),
HAlign(0),
VAlign(0)
VAlign(0),
InterpolateTic(false)
{
for (int i = 0; i < 4; i++)
Coord[i] = DVector2(0,0);

{
Coord[i] = DVector2(0, 0);
Prev.v[i] = Vert.v[i] = FVector2(0,0);
}

alpha = 1;
Renderstyle = STYLE_Normal;

Expand Down Expand Up @@ -698,8 +698,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_OverlayVertexOffset)
if (pspr == nullptr)
return 0;

if (!(flags & WOF_KEEPX)) pspr->Coord[index].X = x;
if (!(flags & WOF_KEEPY)) pspr->Coord[index].Y = y;
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;

return 0;
}
Expand Down Expand Up @@ -729,16 +731,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->scalex = (flags & WOF_ADD) ? pspr->scalex + wx : wx;
if (!(flags & WOF_KEEPY)) pspr->scaley = (flags & WOF_ADD) ? pspr->scaley + wy : wy;

if (!(flags & WOF_INTERPOLATE))
{
pspr->oldscalex = pspr->scalex;
pspr->oldscaley = pspr->scaley;
}
if (flags & WOF_INTERPOLATE) pspr->InterpolateTic = true;

return 0;
}
Expand All @@ -761,13 +757,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_OverlayRotate)

DPSprite *pspr = self->player->FindPSprite(((layer != 0) ? layer : stateinfo->mPSPIndex));

if (pspr == nullptr)
return 0;

pspr->rotation = (flags & WOF_ADD) ? pspr->rotation + degrees : degrees;

if (!(flags & WOF_INTERPOLATE))
pspr->oldrotation = degrees;
if (pspr != nullptr)
{
pspr->rotation = (flags & WOF_ADD) ? pspr->rotation + degrees : degrees;
if (flags & WOF_INTERPOLATE) pspr->InterpolateTic = true;
}

return 0;
}
Expand Down Expand Up @@ -803,10 +797,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_OverlayPivot)
wx = nx; wy = ny;
}

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->px = (flags & WOF_ADD) ? pspr->px + wx : wx;
if (!(flags & WOF_KEEPY)) pspr->py = (flags & WOF_ADD) ? pspr->py + wy : wy;

if (flags & WOF_INTERPOLATE) pspr->InterpolateTic = true;

return 0;
}
Expand Down Expand Up @@ -843,30 +837,17 @@ void A_OverlayOffset(AActor *self, int layer, double wx, double wy, int flags)
wx = nx; wy = ny;
}

if (!(flags & WOF_KEEPX))
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_INTERPOLATE|WOF_ADD)))
{
if (flags & WOF_ADD)
{
psp->x += wx;
}
else
{
psp->x = wx;
if (!(flags & WOF_INTERPOLATE)) psp->oldx = psp->x;
}
}
if (!(flags & WOF_KEEPY))
{
if (flags & WOF_ADD)
{
psp->y += wy;
}
else
{
psp->y = wy;
if (!(flags & WOF_INTERPOLATE)) psp->oldy = psp->y;
}
psp->oldx = psp->x;
psp->oldy = psp->y;
}
*/
}
}

Expand Down Expand Up @@ -915,8 +896,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_OverlayFlags)
if (set)
pspr->Flags |= flags;
else
{
pspr->Flags &= ~flags;

// This is the only way to shut off the temporary interpolation tic
// in the event another mod is causing potential interference
if (flags & PSPF_INTERPOLATE)
pspr->ResetInterpolation();
}
return 0;
}

Expand Down Expand Up @@ -1268,10 +1255,7 @@ void DPSprite::Serialize(FSerializer &arc)
("py", py)
("scalex", scalex)
("scaley", scaley)
("oldscalex", oldscalex)
("oldscaley", oldscaley)
("rotation", rotation)
("oldrotation", oldrotation)
("halign", HAlign)
("valign", VAlign)
("renderstyle_", Renderstyle); // The underscore is intentional to avoid problems with old savegames which had this as an ERenderStyle (which is not future proof.)
Expand Down
16 changes: 11 additions & 5 deletions src/playsim/p_pspr.h
Expand Up @@ -72,6 +72,7 @@ enum PSPFlags
PSPF_MIRROR = 1 << 9,
PSPF_PLAYERTRANSLATED = 1 << 10,
PSPF_PIVOTPERCENT = 1 << 11,
PSPF_INTERPOLATE = 1 << 12,
};

enum PSPAlign
Expand All @@ -83,6 +84,11 @@ enum PSPAlign
PSPA_RIGHT = 2
};

struct WeaponInterp
{
FVector2 v[4];
};

class DPSprite : public DObject
{
DECLARE_CLASS (DPSprite, DObject)
Expand All @@ -102,21 +108,21 @@ class DPSprite : public DObject
DPSprite* GetNext() { return Next; }
AActor* GetCaller() { return Caller; }
void SetCaller(AActor *newcaller) { Caller = newcaller; }
void ResetInterpolation() { oldx = x; oldy = y; }
void ResetInterpolation() { oldx = x; oldy = y; Prev = Vert; InterpolateTic = false; }
void OnDestroy() override;
std::pair<FRenderStyle, float> GetRenderStyle(FRenderStyle ownerstyle, double owneralpha);
float GetYAdjust(bool fullscreen);

int HAlign, VAlign; // Horizontal and vertical alignment
bool PivotPercent; // If true, the pivot goes between [0.0, 1.0]. Otherwise, it's a pixel position offset from the image size.
double px, py; // pivot points
double rotation; // How much rotation to apply.
double oldrotation;
double scalex, scaley; // Scale
double oldscalex, oldscaley;
double x, y, alpha;
double oldx, oldy;
DVector2 Coord[4];
bool InterpolateTic;
DVector2 Coord[4]; // Offsets
WeaponInterp Prev; // Interpolation
WeaponInterp Vert; // Current Position
bool firstTic;
int Tics;
uint32_t Translation;
Expand Down
2 changes: 1 addition & 1 deletion src/rendering/hwrenderer/scene/hw_drawinfo.h
Expand Up @@ -291,7 +291,7 @@ struct HWDrawInfo
void GetDynSpriteLight(AActor *thing, particle_t *particle, float *out);

void PreparePlayerSprites(sector_t * viewsector, area_t in_area);
void PrepareTargeterSprites(WeaponPosition *weap);
void PrepareTargeterSprites(double ticfrac);

void UpdateCurrentMapSection();
void SetViewMatrix(const FRotator &angles, float vx, float vy, float vz, bool mirror, bool planemirror);
Expand Down

0 comments on commit a6bbddf

Please sign in to comment.