Commit b924fabe authored by Richard Gobeille's avatar Richard Gobeille
Browse files

engine: basic support for rotatesprite position interpolation

This is only really in the engine to avoid codedup across all supported games.
parent 8f635826
......@@ -45,6 +45,7 @@ extern int32_t startwin_idle(void *);
extern int32_t startwin_run(void);
// video
extern int32_t r_rotatespriteinterp;
extern int32_t r_usenewaspect, newaspect_enable;
extern int32_t r_fpgrouscan;
extern int32_t setaspect_new_use_dimen;
......
......@@ -237,17 +237,21 @@ enum {
RS_NOCLIP = 8,
RS_TOPLEFT = 16,
RS_TRANS2 = 32,
RS_TRANS_MASK = RS_TRANS1|RS_TRANS2,
RS_NOMASK = 64,
RS_PERM = 128,
RS_ALIGN_L = 256,
RS_ALIGN_R = 512,
RS_ALIGN_MASK = 768,
RS_ALIGN_MASK = RS_ALIGN_L|RS_ALIGN_R,
RS_STRETCH = 1024,
ROTATESPRITE_FULL16 = 2048,
RS_LERP = 4096,
RS_FORCELERP = 8192,
// ROTATESPRITE_MAX-1 is the mask of all externally available orientation bits
ROTATESPRITE_MAX = 4096,
ROTATESPRITE_MAX = 16384,
RS_CENTERORIGIN = (1<<30),
};
......@@ -802,7 +806,7 @@ EXTERN int32_t display_mirror;
// drawrooms() and is used for animateoffs().
EXTERN ClockTicks totalclock, totalclocklock;
static inline int32_t BGetTime(void) { return (int32_t) totalclock; }
EXTERN int32_t rotatespritesmoothratio;
EXTERN int32_t numframes, randomseed;
EXTERN int16_t sintable[2048];
......@@ -1249,6 +1253,15 @@ static FORCE_INLINE void rotatesprite_fs(int32_t sx, int32_t sy, int32_t z, int1
rotatesprite_(sx, sy, z, a, picnum, dashade, dapalnum, dastat, 0, 0, 0,0,xdim-1,ydim-1);
}
static FORCE_INLINE void rotatesprite_fs_id(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
int8_t dashade, char dapalnum, int32_t dastat, int16_t uniqid)
{
int restore = guniqhudid;
if (uniqid) guniqhudid = uniqid;
rotatesprite_(sx, sy, z, a, picnum, dashade, dapalnum, dastat, 0, 0, 0,0,xdim-1,ydim-1);
guniqhudid = restore;
}
static FORCE_INLINE void rotatesprite_fs_alpha(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
int8_t dashade, char dapalnum, int32_t dastat, uint8_t alpha)
{
......
......@@ -524,6 +524,7 @@ int32_t baselayer_init(void)
(void *) &r_screenxy, SCREENASPECT_CVAR_TYPE, 0, 9999 },
{ "r_fpgrouscan","use floating-point numbers for slope rendering",(void *) &r_fpgrouscan, CVAR_BOOL, 0, 1 },
{ "r_novoxmips","turn off/on the use of mipmaps when rendering 8-bit voxels",(void *) &novoxmips, CVAR_BOOL, 0, 1 },
{ "r_rotatespriteinterp", "interpolate repeated rotatesprite calls", (void *)&r_rotatespriteinterp, CVAR_INT, 0, 3 },
{ "r_voxels","enable/disable automatic sprite->voxel rendering",(void *) &usevoxels, CVAR_BOOL, 0, 1 },
{ "r_maxfps", "limit the frame rate", (void *)&r_maxfps, CVAR_INT | CVAR_FUNCPTR, -1, 1000 },
{ "r_maxfpsoffset", "menu-controlled offset for r_maxfps", (void *)&r_maxfpsoffset, CVAR_INT | CVAR_FUNCPTR, -10, 10 },
......
......@@ -125,6 +125,7 @@ static int32_t oxdimen = -1, oviewingrange = -1, oxyaspect = -1;
int32_t r_usenewaspect = 1, newaspect_enable=0;
uint32_t r_screenxy = 0;
int32_t r_rotatespriteinterp = 1;
int32_t r_fpgrouscan = 1;
int32_t r_displayindex = 0;
int32_t r_borderless = 2;
......@@ -7328,6 +7329,51 @@ static void dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t
dastat &= ~RS_ALIGN_MASK;
}
if (uniqid)
{
Bassert(uniqid < MAXUNIQHUDID);
// r_rotatespriteinterp 1: only interpolate when explicitly requested with RS_LERP
// r_rotatespriteinterp 2: interpolate if the picnum or size matches regardless of RS_LERP being set
// r_rotatespriteinterp 3: relax above picnum check to include the next tile, with potentially undesirable results
static struct sm
{
vec4_t lerp;
vec4_t goal;
int16_t picnum, flags;
} smooth[MAXUNIQHUDID];
auto &sm = smooth[uniqid];
vec4_t const goal = { sx, sy, z, a };
smooth[0] = { goal, goal, picnum, (int16_t)(dastat & ~RS_TRANS_MASK) };
auto lerpWouldLookDerp = [&](void)
{
return (!(dastat & RS_LERP) && r_rotatespriteinterp < 2) || sm.flags != (dastat & ~RS_TRANS_MASK)
|| (!(dastat & RS_FORCELERP) && tilesiz[picnum] != tilesiz[sm.picnum]
&& ((unsigned)(picnum - sm.picnum) > (int)(r_rotatespriteinterp == 3))) || klabs(a - sm.goal.a) == 1024;
};
if (!lerpWouldLookDerp())
{
smooth[0].lerp = { sm.lerp.x + mulscale16(smooth[0].goal.x - sm.lerp.x, rotatespritesmoothratio),
sm.lerp.y + mulscale16(smooth[0].goal.y - sm.lerp.y, rotatespritesmoothratio),
sm.lerp.z + mulscale16(smooth[0].goal.z - sm.lerp.z, rotatespritesmoothratio),
(sm.lerp.a + mulscale16(((smooth[0].goal.a + 1024 - sm.lerp.a) & 2047) - 1024, rotatespritesmoothratio)) & 2047 };
}
sm = smooth[0];
if (r_rotatespriteinterp)
{
sx = sm.lerp.x;
sy = sm.lerp.y;
z = sm.lerp.z;
a = sm.lerp.a;
}
}
//============================================================================= //POLYMOST BEGINS
#ifdef USE_OPENGL
if (videoGetRenderMode() >= REND_POLYMOST && in3dmode())
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment