mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-27 20:20:40 +00:00
- made the new interpolation system work in Blood.
The panning interpolations need wraparuound handling due to their small value range.
This commit is contained in:
parent
2cd3927613
commit
82a0e95485
10 changed files with 109 additions and 133 deletions
|
@ -468,7 +468,7 @@ void viewProcessSprites(int32_t cX, int32_t cY, int32_t cZ, int32_t cA, int32_t
|
|||
}
|
||||
|
||||
int nSprite = pTSprite->owner;
|
||||
if (cl_interpolate && TestBitString(gInterpolateSprite, nSprite) && !(pTSprite->flags&512))
|
||||
if (cl_interpolate && gInterpolateSprite[nSprite] && !(pTSprite->flags&512))
|
||||
{
|
||||
LOCATION *pPrevLoc = &gPrevSpriteLoc[nSprite];
|
||||
int iInterpolate = (int)gInterpolate;
|
||||
|
|
|
@ -290,7 +290,9 @@ void GameInterface::Ticker()
|
|||
if (newweap > 0 && newweap < WeaponSel_MaxBlood) gPlayer[i].newWeapon = newweap;
|
||||
}
|
||||
|
||||
viewClearInterpolations();
|
||||
gInterpolateSprite.Zero();
|
||||
ClearMovementInterpolations();
|
||||
UpdateInterpolations();
|
||||
|
||||
if (!(paused || (gGameOptions.nGameType == 0 && M_Active())))
|
||||
{
|
||||
|
|
|
@ -2269,6 +2269,16 @@ void useSectorWindGen(XSPRITE* pXSource, sectortype* pSector) {
|
|||
pXSector->panCeiling = true;
|
||||
break;
|
||||
}
|
||||
if (pXSector->panCeiling)
|
||||
{
|
||||
StartInterpolation(pXSector->reference, Interp_Sect_CeilingPanX);
|
||||
StartInterpolation(pXSector->reference, Interp_Sect_CeilingPanY);
|
||||
}
|
||||
if (pXSector->panFloor)
|
||||
{
|
||||
StartInterpolation(pXSector->reference, Interp_Sect_FloorPanX);
|
||||
StartInterpolation(pXSector->reference, Interp_Sect_FloorPanY);
|
||||
}
|
||||
|
||||
short oldPan = pXSector->panVel;
|
||||
pXSector->panAngle = pXSector->windAng;
|
||||
|
@ -2284,7 +2294,9 @@ void useSectorWindGen(XSPRITE* pXSource, sectortype* pSector) {
|
|||
}
|
||||
|
||||
if (i == panCount)
|
||||
{
|
||||
panList[panCount++] = nXSector;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "gameutil.h"
|
||||
#include "globals.h"
|
||||
#include "sectorfx.h"
|
||||
#include "interpolate.h"
|
||||
|
||||
BEGIN_BLD_NS
|
||||
|
||||
|
@ -342,7 +343,21 @@ void InitSectorFX(void)
|
|||
if (pXSector->amplitude)
|
||||
shadeList[shadeCount++] = nXSector;
|
||||
if (pXSector->panVel)
|
||||
{
|
||||
panList[panCount++] = nXSector;
|
||||
|
||||
if (pXSector->panCeiling)
|
||||
{
|
||||
StartInterpolation(i, Interp_Sect_CeilingPanX);
|
||||
StartInterpolation(i, Interp_Sect_CeilingPanY);
|
||||
}
|
||||
if (pXSector->panFloor)
|
||||
{
|
||||
StartInterpolation(i, Interp_Sect_FloorPanX);
|
||||
StartInterpolation(i, Interp_Sect_FloorPanY);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < numwalls; i++)
|
||||
|
@ -352,7 +367,11 @@ void InitSectorFX(void)
|
|||
{
|
||||
XWALL *pXWall = &xwall[nXWall];
|
||||
if (pXWall->panXVel || pXWall->panYVel)
|
||||
{
|
||||
wallPanList[wallPanCount++] = nXWall;
|
||||
if (pXWall->panXVel) StartInterpolation(i, Interp_Wall_PanX);
|
||||
if (pXWall->panXVel) StartInterpolation(i, Interp_Wall_PanY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1497,7 +1497,7 @@ void OperateTeleport(unsigned int nSector, XSECTOR *pXSector)
|
|||
ChangeSpriteSect(nSprite, pDest->sectnum);
|
||||
sfxPlay3DSound(pDest, 201, -1, 0);
|
||||
xvel[nSprite] = yvel[nSprite] = zvel[nSprite] = 0;
|
||||
ClearBitString(gInterpolateSprite, nSprite);
|
||||
gInterpolateSprite.Clear(nSprite);
|
||||
viewBackupSpriteLoc(nSprite, pSprite);
|
||||
if (pPlayer)
|
||||
{
|
||||
|
|
|
@ -50,27 +50,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
|
||||
BEGIN_BLD_NS
|
||||
|
||||
|
||||
FixedBitArray<kMaxSprites> gInterpolateSprite;
|
||||
VIEW gPrevView[kMaxPlayers];
|
||||
VIEWPOS gViewPos;
|
||||
int gViewIndex;
|
||||
|
||||
struct INTERPOLATE {
|
||||
void *pointer;
|
||||
int value;
|
||||
int value2;
|
||||
INTERPOLATE_TYPE type;
|
||||
};
|
||||
|
||||
double gInterpolate;
|
||||
int nInterpolations;
|
||||
char gInterpolateSprite[(kMaxSprites+7)>>3];
|
||||
char gInterpolateWall[(kMaxWalls+7)>>3];
|
||||
char gInterpolateSector[(kMaxSectors+7)>>3];
|
||||
|
||||
enum { kMaxInterpolations = 16384 };
|
||||
|
||||
INTERPOLATE gInterpolation[kMaxInterpolations];
|
||||
|
||||
int gScreenTilt;
|
||||
|
||||
|
@ -131,76 +116,6 @@ void viewCorrectViewOffsets(int nPlayer, vec3_t const *oldpos)
|
|||
pView->at38 += pPlayer->pSprite->z-oldpos->z;
|
||||
}
|
||||
|
||||
void viewClearInterpolations(void)
|
||||
{
|
||||
nInterpolations = 0;
|
||||
memset(gInterpolateSprite, 0, sizeof(gInterpolateSprite));
|
||||
memset(gInterpolateWall, 0, sizeof(gInterpolateWall));
|
||||
memset(gInterpolateSector, 0, sizeof(gInterpolateSector));
|
||||
}
|
||||
|
||||
void viewAddInterpolation(void *data, INTERPOLATE_TYPE type)
|
||||
{
|
||||
if (nInterpolations == kMaxInterpolations)
|
||||
I_Error("Too many interpolations");
|
||||
INTERPOLATE *pInterpolate = &gInterpolation[nInterpolations++];
|
||||
pInterpolate->pointer = data;
|
||||
pInterpolate->type = type;
|
||||
switch (type)
|
||||
{
|
||||
case INTERPOLATE_TYPE_INT:
|
||||
pInterpolate->value = *((int*)data);
|
||||
break;
|
||||
case INTERPOLATE_TYPE_SHORT:
|
||||
pInterpolate->value = *((short*)data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CalcInterpolations(void)
|
||||
{
|
||||
int i;
|
||||
INTERPOLATE *pInterpolate = gInterpolation;
|
||||
for (i = 0; i < nInterpolations; i++, pInterpolate++)
|
||||
{
|
||||
switch (pInterpolate->type)
|
||||
{
|
||||
case INTERPOLATE_TYPE_INT:
|
||||
{
|
||||
pInterpolate->value2 = *((int*)pInterpolate->pointer);
|
||||
int newValue = interpolate(pInterpolate->value, *((int*)pInterpolate->pointer), gInterpolate);
|
||||
*((int*)pInterpolate->pointer) = newValue;
|
||||
break;
|
||||
}
|
||||
case INTERPOLATE_TYPE_SHORT:
|
||||
{
|
||||
pInterpolate->value2 = *((short*)pInterpolate->pointer);
|
||||
int newValue = interpolate(pInterpolate->value, *((short*)pInterpolate->pointer), gInterpolate);
|
||||
*((short*)pInterpolate->pointer) = newValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RestoreInterpolations(void)
|
||||
{
|
||||
int i;
|
||||
INTERPOLATE *pInterpolate = gInterpolation;
|
||||
for (i = 0; i < nInterpolations; i++, pInterpolate++)
|
||||
{
|
||||
switch (pInterpolate->type)
|
||||
{
|
||||
case INTERPOLATE_TYPE_INT:
|
||||
*((int*)pInterpolate->pointer) = pInterpolate->value2;
|
||||
break;
|
||||
case INTERPOLATE_TYPE_SHORT:
|
||||
*((short*)pInterpolate->pointer) = pInterpolate->value2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void viewDrawText(int nFont, const char *pString, int x, int y, int nShade, int nPalette, int position, char shadow, unsigned int nStat, uint8_t alpha)
|
||||
{
|
||||
if (nFont < 0 || nFont >= kFontNum || !pString) return;
|
||||
|
@ -603,7 +518,7 @@ void viewDrawScreen(bool sceneonly)
|
|||
|
||||
if (cl_interpolate)
|
||||
{
|
||||
CalcInterpolations();
|
||||
DoInterpolations(gInterpolate / MaxSmoothRatio);
|
||||
}
|
||||
|
||||
if (automapMode != am_full)
|
||||
|
|
|
@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "common_game.h"
|
||||
#include "messages.h"
|
||||
#include "player.h"
|
||||
#include "interpolate.h"
|
||||
|
||||
BEGIN_BLD_NS
|
||||
|
||||
|
@ -101,11 +102,6 @@ enum VIEWPOS {
|
|||
VIEWPOS_1
|
||||
};
|
||||
|
||||
enum INTERPOLATE_TYPE {
|
||||
INTERPOLATE_TYPE_INT = 0,
|
||||
INTERPOLATE_TYPE_SHORT,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kBackTile = 253,
|
||||
|
@ -134,9 +130,7 @@ extern int gScreenTilt;
|
|||
extern int deliriumTilt, deliriumTurn, deliriumPitch;
|
||||
extern int gScreenTiltO, deliriumTurnO, deliriumPitchO;
|
||||
extern int gShowFrameRate;
|
||||
extern char gInterpolateSprite[];
|
||||
extern char gInterpolateWall[];
|
||||
extern char gInterpolateSector[];
|
||||
extern FixedBitArray<kMaxSprites> gInterpolateSprite;
|
||||
extern LOCATION gPrevSpriteLoc[kMaxSprites];
|
||||
extern int gLastPal;
|
||||
extern double gInterpolate;
|
||||
|
@ -147,10 +141,6 @@ void viewUpdatePrediction(InputPacket *pInput);
|
|||
void viewCorrectPrediction(void);
|
||||
void viewBackupView(int nPlayer);
|
||||
void viewCorrectViewOffsets(int nPlayer, vec3_t const *oldpos);
|
||||
void viewClearInterpolations(void);
|
||||
void viewAddInterpolation(void *data, INTERPOLATE_TYPE type);
|
||||
void CalcInterpolations(void);
|
||||
void RestoreInterpolations(void);
|
||||
void viewDrawText(int nFont, const char *pString, int x, int y, int nShade, int nPalette, int position, char shadow, unsigned int nStat = 0, uint8_t alpha = 255);
|
||||
void InitStatusBar(void);
|
||||
void UpdateStatusBar();
|
||||
|
@ -169,35 +159,27 @@ void viewSetSystemMessage(const char* pMessage, ...);
|
|||
|
||||
inline void viewInterpolateSector(int nSector, sectortype *pSector)
|
||||
{
|
||||
if (!TestBitString(gInterpolateSector, nSector))
|
||||
{
|
||||
viewAddInterpolation(&pSector->floorz, INTERPOLATE_TYPE_INT);
|
||||
viewAddInterpolation(&pSector->ceilingz, INTERPOLATE_TYPE_INT);
|
||||
viewAddInterpolation(&pSector->floorheinum, INTERPOLATE_TYPE_SHORT);
|
||||
SetBitString(gInterpolateSector, nSector);
|
||||
}
|
||||
StartInterpolation(nSector, Interp_Sect_Floorz);
|
||||
StartInterpolation(nSector, Interp_Sect_Ceilingz);
|
||||
StartInterpolation(nSector, Interp_Sect_Floorheinum);
|
||||
}
|
||||
|
||||
inline void viewInterpolateWall(int nWall, walltype *pWall)
|
||||
{
|
||||
if (!TestBitString(gInterpolateWall, nWall))
|
||||
{
|
||||
viewAddInterpolation(&pWall->x, INTERPOLATE_TYPE_INT);
|
||||
viewAddInterpolation(&pWall->y, INTERPOLATE_TYPE_INT);
|
||||
SetBitString(gInterpolateWall, nWall);
|
||||
}
|
||||
StartInterpolation(nWall, Interp_Wall_X);
|
||||
StartInterpolation(nWall, Interp_Wall_Y);
|
||||
}
|
||||
|
||||
inline void viewBackupSpriteLoc(int nSprite, spritetype *pSprite)
|
||||
{
|
||||
if (!TestBitString(gInterpolateSprite, nSprite))
|
||||
if (!gInterpolateSprite[nSprite])
|
||||
{
|
||||
LOCATION *pPrevLoc = &gPrevSpriteLoc[nSprite];
|
||||
pPrevLoc->x = pSprite->x;
|
||||
pPrevLoc->y = pSprite->y;
|
||||
pPrevLoc->z = pSprite->z;
|
||||
pPrevLoc->ang = pSprite->ang;
|
||||
SetBitString(gInterpolateSprite, nSprite);
|
||||
gInterpolateSprite.Set(nSprite);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -208,7 +208,7 @@ int CheckLink(spritetype *pSprite)
|
|||
else
|
||||
z2 = getceilzofslope(pSprite->sectnum, pSprite->x, pSprite->y);
|
||||
pSprite->z += z2-z;
|
||||
ClearBitString(gInterpolateSprite, pSprite->index);
|
||||
gInterpolateSprite.Clear(pSprite->index);
|
||||
return pUpper->type;
|
||||
}
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ int CheckLink(spritetype *pSprite)
|
|||
else
|
||||
z2 = getflorzofslope(pSprite->sectnum, pSprite->x, pSprite->y);
|
||||
pSprite->z += z2-z;
|
||||
ClearBitString(gInterpolateSprite, pSprite->index);
|
||||
gInterpolateSprite.Clear(pSprite->index);
|
||||
return pLower->type;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "interpolate.h"
|
||||
#include "xs_Float.h"
|
||||
#include "serializer.h"
|
||||
#include "gamecvars.h"
|
||||
|
||||
|
||||
struct Interpolation
|
||||
|
@ -50,8 +51,8 @@ double Get(int index, int type)
|
|||
|
||||
case Interp_Wall_X: return wall[index].x;
|
||||
case Interp_Wall_Y: return wall[index].y;
|
||||
case Interp_Wall_PanX: return 0/*wall[index].panx_*/; // later
|
||||
case Interp_Wall_PanY: return 0/*wall[index].pany_*/; // later
|
||||
case Interp_Wall_PanX: return wall[index].xpan_;
|
||||
case Interp_Wall_PanY: return wall[index].ypan_;
|
||||
|
||||
case Interp_Sprite_Z: return sprite[index].z;
|
||||
default: return 0;
|
||||
|
@ -73,14 +74,14 @@ void Set(int index, int type, double val)
|
|||
|
||||
case Interp_Wall_X: wall[index].x = xs_CRoundToInt(val); break;
|
||||
case Interp_Wall_Y: wall[index].y = xs_CRoundToInt(val); break;
|
||||
case Interp_Wall_PanX: break;
|
||||
case Interp_Wall_PanY: 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: sprite[index].z = xs_CRoundToInt(val); break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetInterpolation(int index, int type)
|
||||
void StartInterpolation(int index, int type)
|
||||
{
|
||||
for (unsigned i = 0; i < interpolations.Size(); i++)
|
||||
{
|
||||
|
@ -115,25 +116,67 @@ void UpdateInterpolations()
|
|||
}
|
||||
}
|
||||
|
||||
void Dointerpolations(float smoothratio)
|
||||
void DoInterpolations(double smoothratio)
|
||||
{
|
||||
if (!cl_interpolate) return;
|
||||
for (unsigned i = 0; i < interpolations.Size(); i++)
|
||||
{
|
||||
double bak;
|
||||
interpolations[i].bak = bak = Get(interpolations[i].index, interpolations[i].type);
|
||||
double old = interpolations[i].old;
|
||||
Set(interpolations[i].index, interpolations[i].type, old + (bak - old) * smoothratio);
|
||||
if (interpolations[i].type < Interp_Pan_First || fabs(bak-old) < 128.)
|
||||
{
|
||||
Set(interpolations[i].index, interpolations[i].type, old + (bak - old) * smoothratio);
|
||||
}
|
||||
else
|
||||
{
|
||||
// with the panning types we need to check for potential wraparound.
|
||||
if (bak < old) bak += 256.;
|
||||
else old += 256;
|
||||
double cur = old + (bak - old) * smoothratio;
|
||||
if (cur >= 256.) cur -= 256.;
|
||||
Set(interpolations[i].index, interpolations[i].type, cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RestoreInterpolations()
|
||||
{
|
||||
for (unsigned i = 0; i < interpolations.Size(); i++)
|
||||
if (!cl_interpolate) return;
|
||||
for (unsigned i = 0; i < interpolations.Size(); i++)
|
||||
{
|
||||
Set(interpolations[i].index, interpolations[i].type, interpolations[i].bak);
|
||||
}
|
||||
}
|
||||
|
||||
void ClearInterpolations()
|
||||
{
|
||||
interpolations.Clear();
|
||||
}
|
||||
|
||||
void ClearMovementInterpolations()
|
||||
{
|
||||
// This clears all movement interpolations. Needed for Blood which destroys its interpolations each frame.
|
||||
for (unsigned i = 0; i < interpolations.Size();)
|
||||
{
|
||||
switch (interpolations[i].type)
|
||||
{
|
||||
case Interp_Sect_Floorz:
|
||||
case Interp_Sect_Ceilingz:
|
||||
case Interp_Sect_Floorheinum:
|
||||
case Interp_Sect_Ceilingheinum:
|
||||
case Interp_Wall_X:
|
||||
case Interp_Wall_Y:
|
||||
interpolations[i] = interpolations.Last();
|
||||
interpolations.Pop();
|
||||
break;
|
||||
default:
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, Interpolation& w, Interpolation* def)
|
||||
{
|
||||
if (arc.BeginObject(keyname))
|
||||
|
|
|
@ -7,23 +7,26 @@ enum EInterpolationType
|
|||
Interp_Sect_Ceilingz,
|
||||
Interp_Sect_Floorheinum,
|
||||
Interp_Sect_Ceilingheinum,
|
||||
Interp_Sect_FloorPanX,
|
||||
Interp_Sect_FloorPanY,
|
||||
Interp_Sect_CeilingPanX,
|
||||
Interp_Sect_CeilingPanY,
|
||||
|
||||
Interp_Wall_X,
|
||||
Interp_Wall_Y,
|
||||
Interp_Wall_PanX,
|
||||
Interp_Wall_PanY,
|
||||
|
||||
Interp_Sprite_Z,
|
||||
|
||||
Interp_Pan_First,
|
||||
Interp_Sect_FloorPanX = Interp_Pan_First,
|
||||
Interp_Sect_FloorPanY,
|
||||
Interp_Sect_CeilingPanX,
|
||||
Interp_Sect_CeilingPanY,
|
||||
Interp_Wall_PanX,
|
||||
Interp_Wall_PanY,
|
||||
};
|
||||
|
||||
void StartInterpolation(int index, int type);
|
||||
void StopInterpolation(int index, int type);
|
||||
void UpdateInterpolations();
|
||||
void ClearInterpolations();
|
||||
void ClearMovementInterpolations();
|
||||
void DoInterpolations(double smoothratio);
|
||||
void RestoreInterpolations();
|
||||
void SerializeInterpolations(FSerializer& arc);
|
||||
|
|
Loading…
Reference in a new issue