Revert "- removed Interp_Sprite_Z."

Sadly, SW's sprite interpolation is too screwed up to do a better fix on short notice.
It's the same with interpolating sprites attached to SOP's, it is only needed because generally interpolating sprites in SW is problematic.
This commit is contained in:
Christoph Oelckers 2022-01-01 19:50:30 +01:00
parent 6807086f3c
commit 8c9b810b16
4 changed files with 55 additions and 9 deletions

View file

@ -32,11 +32,12 @@ struct Interpolation
double old, bak;
int index;
int type;
DCoreActor* actor;
};
static TArray<Interpolation> interpolations;
double Get(int index, int type)
double Get(int index, DCoreActor* actor, int type)
{
switch(type)
{
@ -54,11 +55,12 @@ double Get(int index, int type)
case Interp_Wall_PanX: return wall[index].xpan_;
case Interp_Wall_PanY: return wall[index].ypan_;
case Interp_Sprite_Z: return actor->spr.pos.Z;
default: return 0;
}
}
void Set(int index, int type, double val)
void Set(int index, DCoreActor* actor, int type, double val)
{
int old;
switch(type)
@ -76,6 +78,8 @@ void Set(int index, int type, double val)
case Interp_Wall_Y: old = wall[index].pos.Y; wall[index].pos.Y = xs_CRoundToInt(val); if (wall[index].pos.Y != old) wall[index].moved(); break;
case Interp_Wall_PanX: wall[index].xpan_ = float(val); break;
case Interp_Wall_PanY: wall[index].ypan_ = float(val); break;
case Interp_Sprite_Z: actor->spr.pos.Z = xs_CRoundToInt(val); break;
}
}
@ -89,8 +93,9 @@ void StartInterpolation(int index, int type)
int n = interpolations.Reserve(1);
interpolations[n].index = index;
interpolations[n].actor = nullptr;
interpolations[n].type = type;
interpolations[n].old = Get(index, type);
interpolations[n].old = Get(index, nullptr, type);
}
void StopInterpolation(int index, int type)
@ -106,11 +111,41 @@ void StopInterpolation(int index, int type)
}
}
void StartInterpolation(DCoreActor* actor, int type)
{
assert(type = Interp_Sprite_Z);
for (unsigned i = 0; i < interpolations.Size(); i++)
{
if (interpolations[i].actor == actor && interpolations[i].type == type)
return;
}
int n = interpolations.Reserve(1);
interpolations[n].index = -1;
interpolations[n].actor = actor;
interpolations[n].type = type;
interpolations[n].old = Get(-1, actor, type);
}
void StopInterpolation(DCoreActor* actor, int type)
{
assert(type = Interp_Sprite_Z);
for (unsigned i = 0; i < interpolations.Size(); i++)
{
if (interpolations[i].actor == actor && interpolations[i].type == type)
{
interpolations[i] = interpolations.Last();
interpolations.Pop();
return;
}
}
}
void UpdateInterpolations()
{
for (unsigned i = 0; i < interpolations.Size(); i++)
{
interpolations[i].old = Get(interpolations[i].index, interpolations[i].type);
interpolations[i].old = Get(interpolations[i].index, interpolations[i].actor, interpolations[i].type);
}
}
@ -120,11 +155,11 @@ void DoInterpolations(double smoothratio)
for (unsigned i = 0; i < interpolations.Size(); i++)
{
double bak;
interpolations[i].bak = bak = Get(interpolations[i].index, interpolations[i].type);
interpolations[i].bak = bak = Get(interpolations[i].index, interpolations[i].actor, interpolations[i].type);
double old = interpolations[i].old;
if (interpolations[i].type < Interp_Pan_First || fabs(bak-old) < 128.)
{
Set(interpolations[i].index, interpolations[i].type, old + (bak - old) * smoothratio);
Set(interpolations[i].index, interpolations[i].actor, interpolations[i].type, old + (bak - old) * smoothratio);
}
else
{
@ -133,7 +168,7 @@ void DoInterpolations(double smoothratio)
else old += 256;
double cur = old + (bak - old) * smoothratio;
if (cur >= 256.) cur -= 256.;
Set(interpolations[i].index, interpolations[i].type, cur);
Set(interpolations[i].index, interpolations[i].actor, interpolations[i].type, cur);
}
}
}
@ -143,7 +178,7 @@ void RestoreInterpolations()
if (!cl_interpolate) return;
for (unsigned i = 0; i < interpolations.Size(); i++)
{
Set(interpolations[i].index, interpolations[i].type, interpolations[i].bak);
Set(interpolations[i].index, interpolations[i].actor, interpolations[i].type, interpolations[i].bak);
}
}
@ -212,12 +247,13 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, Interpolation& w,
if (arc.BeginObject(keyname))
{
arc ("index", w.index)
("actor", w.actor)
("type", w.type)
.EndObject();
}
if (arc.isReading())
{
w.old = Get(w.index, w.type);
w.old = Get(w.index, w.actor, w.type);
}
return arc;
}

View file

@ -13,6 +13,8 @@ enum EInterpolationType
Interp_Wall_X,
Interp_Wall_Y,
Interp_Sprite_Z,
Interp_Pan_First,
// order of the following 4 flags must match the corresponding sector flags.
Interp_Sect_FloorPanX = Interp_Pan_First,
@ -25,6 +27,8 @@ enum EInterpolationType
void StartInterpolation(int index, int type);
void StopInterpolation(int index, int type);
void StartInterpolation(DCoreActor* actor, int type);
void StopInterpolation(DCoreActor* actor, int type);
void UpdateInterpolations();
void ClearInterpolations();
void ClearMovementInterpolations();

View file

@ -637,6 +637,7 @@ void KillActor(DSWActor* actor)
// any Anims attached
AnimDelete(ANIM_Userz, 0, actor);
AnimDelete(ANIM_Spritez, 0, actor);
StopInterpolation(actor, Interp_Sprite_Z);
// adjust sprites attached to sector objects
if (actor->user.Flags & (SPR_SO_ATTACHED))

View file

@ -254,6 +254,11 @@ void InterpSectorSprites(sectortype* sect, bool state)
if (actor->user.Flags & (SPR_SKIP2) && actor->spr.statnum <= STAT_SKIP2_INTERP_END)
continue;
}
if (state)
StartInterpolation(actor, Interp_Sprite_Z);
else
StopInterpolation(actor, Interp_Sprite_Z);
}
}