Added weapon interpolation.

This commit is contained in:
Leonard 2015-08-19 15:59:54 +02:00
parent d786148ccf
commit 86e9504d04
8 changed files with 254 additions and 4 deletions

View file

@ -427,6 +427,7 @@ public:
short fixedcolormap; // can be set to REDCOLORMAP, etc.
short fixedlightlevel;
pspdef_t psprites[NUMPSPRITES]; // view sprites (gun, etc)
TObjPtr<DInterpolation> pspinterp[NUMPSPRITES]; // view sprite interpolations
int morphTics; // player is a chicken/pig if > 0
const PClass *MorphedPlayerClass; // [MH] (for SBARINFO) class # for this player instance when morphed
int MorphStyle; // which effects to apply for this player instance when morphed

View file

@ -1726,6 +1726,15 @@ void G_DoPlayerPop(int playernum)
players[playernum].mo = NULL;
players[playernum].camera = NULL;
}
// Now's the ideal time to remove his psprite interpolations.
for (int ii = 0; ii < NUMPSPRITES; ii++)
{
if (players[playernum].psprites[ii].interpolation != NULL)
{
players[playernum].psprites[ii].StopInterpolation();
players[playernum].pspinterp[ii] = NULL;
}
}
// [RH] Let the scripts know the player left
FBehavior::StaticStartTypedScripts(SCRIPT_Disconnect, NULL, true, playernum);
}

View file

@ -1104,11 +1104,32 @@ void P_MovePsprites (player_t *player)
P_CheckWeaponZoom (player);
}
}
psp = &player->psprites[0];
for (i = 0; i < NUMPSPRITES; i++, psp++)
{
if (psp->state == NULL)
{
if (psp->interpolation != NULL)
{
player->pspinterp[i] = NULL;
psp->StopInterpolation();
}
}
else if (psp->interpolation == NULL)
{
player->pspinterp[i] = psp->SetInterpolation(player - players, i);
}
}
}
FArchive &operator<< (FArchive &arc, pspdef_t &def)
{
arc << def.state << def.tics << def.sx << def.sy
<< def.sprite << def.frame;
if (SaveVersion >= 4525)
arc << def.interpolation;
return arc;
}

View file

@ -26,6 +26,7 @@
// Basic data types.
// Needs fixed point, and BAM angles.
#include "tables.h"
#include "r_data/r_interpolate.h"
#include "thingdef/thingdef.h"
#define WEAPONBOTTOM 128*FRACUNIT
@ -71,6 +72,11 @@ struct pspdef_t
int sprite;
int frame;
bool processPending; // true: waiting for periodic processing on this tick
TObjPtr<DInterpolation> interpolation;
DInterpolation *SetInterpolation(int player, int position);
void UpdateInterpolation(int player);
void StopInterpolation();
};
class FArchive;

View file

@ -297,6 +297,11 @@ static void CopyPlayer (player_t *dst, player_t *src, const char *name)
{
dst->mo->player = dst;
}
// Fix the psprite interpolation pointers too.
for (int i = 0; i < NUMPSPRITES; i++)
{
dst->psprites[i].UpdateInterpolation(dst - players);
}
// These 2 variables may not be overwritten.
dst->attackdown = attackdown;
dst->usedown = usedown;

View file

@ -316,6 +316,7 @@ player_t::player_t()
memset (&cmd, 0, sizeof(cmd));
memset (frags, 0, sizeof(frags));
memset (psprites, 0, sizeof(psprites));
memset (pspinterp, 0, sizeof(pspinterp));
}
player_t &player_t::operator=(const player_t &p)
@ -371,6 +372,7 @@ player_t &player_t::operator=(const player_t &p)
fixedcolormap = p.fixedcolormap;
fixedlightlevel = p.fixedlightlevel;
memcpy(psprites, &p.psprites, sizeof(psprites));
memcpy(pspinterp, &p.pspinterp, sizeof(pspinterp));
morphTics = p.morphTics;
MorphedPlayerClass = p.MorphedPlayerClass;
MorphStyle = p.MorphStyle;
@ -435,6 +437,10 @@ size_t player_t::FixPointers (const DObject *old, DObject *rep)
if (*&ConversationNPC == old) ConversationNPC = replacement, changed++;
if (*&ConversationPC == old) ConversationPC = replacement, changed++;
if (*&MUSINFOactor == old) MUSINFOactor = replacement, changed++;
for (int i = 0; i < NUMPSPRITES; i++)
if (*&pspinterp[i] == old) pspinterp[i] = static_cast<DInterpolation *>(rep), changed++;
return changed;
}
@ -454,6 +460,11 @@ size_t player_t::PropagateMark()
{
GC::Mark(PendingWeapon);
}
for (int i = 0; i < NUMPSPRITES; i++)
{
GC::Mark(pspinterp[i]);
}
return sizeof(*this);
}
@ -3049,7 +3060,11 @@ void player_t::Serialize (FArchive &arc)
for (i = 0; i < MAXPLAYERS; i++)
arc << frags[i];
for (i = 0; i < NUMPSPRITES; i++)
{
arc << psprites[i];
if (SaveVersion >= 4525)
arc << pspinterp[i];
}
arc << CurrentPlayerClass;

View file

@ -151,6 +151,35 @@ public:
};
//==========================================================================
//
//
//
//==========================================================================
class DPSpriteInterpolation : public DInterpolation
{
DECLARE_CLASS(DPSpriteInterpolation, DInterpolation)
pspdef_t *psp;
int player, position;
fixed_t oldx, oldy;
fixed_t bakx, baky;
fixed_t ofsx, ofsy;
fixed_t nfsx, nfsy;
public:
DPSpriteInterpolation() {}
DPSpriteInterpolation(pspdef_t *psp, int player, int position);
void UpdatePointer(int player);
void Destroy();
void UpdateInterpolation();
void Restore();
void Interpolate(fixed_t smoothratio);
void Serialize(FArchive &arc);
};
//==========================================================================
//
//
@ -162,6 +191,7 @@ IMPLEMENT_CLASS(DSectorPlaneInterpolation)
IMPLEMENT_CLASS(DSectorScrollInterpolation)
IMPLEMENT_CLASS(DWallScrollInterpolation)
IMPLEMENT_CLASS(DPolyobjInterpolation)
IMPLEMENT_CLASS(DPSpriteInterpolation)
//==========================================================================
//
@ -628,7 +658,6 @@ void DSectorScrollInterpolation::Serialize(FArchive &arc)
arc << sector << ceiling << oldx << oldy;
}
//==========================================================================
//
//
@ -824,6 +853,115 @@ void DPolyobjInterpolation::Serialize(FArchive &arc)
if (arc.IsLoading()) bakverts.Resize(oldverts.Size());
}
//==========================================================================
//
//
//
//==========================================================================
//==========================================================================
//
//
//
//==========================================================================
DPSpriteInterpolation::DPSpriteInterpolation(pspdef_t *_psp, int _player, int _position)
: nfsx(0), nfsy(0), ofsx(0), ofsy(0)
{
psp = _psp;
player = _player;
position = _position;
UpdateInterpolation ();
interpolator.AddInterpolation(this);
}
//==========================================================================
//
//
//
//==========================================================================
void DPSpriteInterpolation::UpdatePointer(int _player)
{
player = _player;
psp = &players[player].psprites[position];
}
//==========================================================================
//
//
//
//==========================================================================
void DPSpriteInterpolation::Destroy()
{
psp->interpolation = NULL;
Super::Destroy();
}
//==========================================================================
//
//
//
//==========================================================================
void DPSpriteInterpolation::UpdateInterpolation()
{
if ( position == ps_weapon )
P_BobWeapon( &players[player], psp, &ofsx, &ofsy );
oldx = psp->sx + ofsx;
oldy = psp->sy + ofsy;
}
//==========================================================================
//
//
//
//==========================================================================
void DPSpriteInterpolation::Restore()
{
psp->sx = bakx - nfsx;
psp->sy = baky - nfsy;
}
//==========================================================================
//
//
//
//==========================================================================
void DPSpriteInterpolation::Interpolate(fixed_t smoothratio)
{
if ( position == ps_weapon )
P_BobWeapon( &players[player], psp, &nfsx, &nfsy );
bakx = psp->sx + nfsx;
baky = psp->sy + nfsy;
psp->sx = oldx + FixedMul(bakx - oldx, smoothratio) - nfsx;
psp->sy = oldy + FixedMul(baky - oldy, smoothratio) - nfsy;
}
//==========================================================================
//
//
//
//==========================================================================
void DPSpriteInterpolation::Serialize(FArchive &arc)
{
Super::Serialize(arc);
arc << player << position << oldx << oldy << ofsx << ofsy;
UpdatePointer(player);
}
//==========================================================================
//
//
//
//==========================================================================
//==========================================================================
//
@ -944,6 +1082,63 @@ void FPolyObj::StopInterpolation()
}
}
//==========================================================================
//
//
//
//==========================================================================
DInterpolation *pspdef_t::SetInterpolation(int player, int position)
{
if (interpolation == NULL)
{
interpolation = new DPSpriteInterpolation(this, player, position);
}
interpolation->AddRef();
GC::WriteBarrier(interpolation);
return interpolation;
}
//==========================================================================
//
//
//
//==========================================================================
void pspdef_t::UpdateInterpolation(int player)
{
if (interpolation != NULL)
{
DInterpolation *pointer = interpolation;
static_cast<DPSpriteInterpolation *>(pointer)->UpdatePointer(player);
}
}
//==========================================================================
//
//
//
//==========================================================================
void pspdef_t::StopInterpolation()
{
if (interpolation != NULL)
{
interpolation->DelRef();
}
}
//==========================================================================
//
//
//
//==========================================================================
//==========================================================================
//
//
//
//==========================================================================
ADD_STAT (interpolations)
{
@ -951,5 +1146,3 @@ ADD_STAT (interpolations)
out.Format ("%d interpolations", interpolator.CountInterpolations ());
return out;
}

View file

@ -76,7 +76,7 @@ const char *GetVersionString();
// Use 4500 as the base git save version, since it's higher than the
// SVN revision ever got.
#define SAVEVER 4524
#define SAVEVER 4525
#define SAVEVERSTRINGIFY2(x) #x
#define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)