mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-23 19:31:05 +00:00
Add sector plane level interpolations
This commit is contained in:
parent
ac2510f284
commit
9c8d0a3b6f
8 changed files with 238 additions and 0 deletions
|
@ -477,6 +477,7 @@ static void D_Display(void)
|
|||
|
||||
if (!automapactive && !dedicated && cv_renderview.value)
|
||||
{
|
||||
R_ApplyLevelInterpolators(cv_frameinterpolation.value == 1 ? rendertimefrac : FRACUNIT);
|
||||
PS_START_TIMING(ps_rendercalltime);
|
||||
if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD)
|
||||
{
|
||||
|
@ -525,6 +526,7 @@ static void D_Display(void)
|
|||
V_DoPostProcessor(1, postimgtype2, postimgparam2);
|
||||
}
|
||||
PS_STOP_TIMING(ps_rendercalltime);
|
||||
R_RestoreLevelInterpolators();
|
||||
}
|
||||
|
||||
if (lastdraw)
|
||||
|
|
|
@ -1830,6 +1830,7 @@ void G_DoLoadLevel(boolean resetplayer)
|
|||
}
|
||||
|
||||
// Setup the level.
|
||||
R_InitializeLevelInterpolators();
|
||||
if (!P_LoadLevel(false, false)) // this never returns false?
|
||||
{
|
||||
// fail so reset game stuff
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "doomdef.h"
|
||||
#include "p_local.h"
|
||||
#include "r_fps.h"
|
||||
#include "r_main.h"
|
||||
#include "s_sound.h"
|
||||
#include "z_zone.h"
|
||||
|
@ -602,6 +603,9 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type)
|
|||
ceiling->tag = tag;
|
||||
ceiling->type = type;
|
||||
firstone = 0;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&ceiling->thinker, sec, true);
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
@ -679,6 +683,10 @@ INT32 EV_DoCrush(line_t *line, ceiling_e type)
|
|||
|
||||
ceiling->tag = tag;
|
||||
ceiling->type = type;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&ceiling->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&ceiling->thinker, sec, true);
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "m_random.h"
|
||||
#include "p_local.h"
|
||||
#include "p_slopes.h"
|
||||
#include "r_fps.h"
|
||||
#include "r_state.h"
|
||||
#include "s_sound.h"
|
||||
#include "z_zone.h"
|
||||
|
@ -573,6 +574,8 @@ void T_ContinuousFalling(continuousfall_t *faller)
|
|||
{
|
||||
faller->sector->ceilingheight = faller->ceilingstartheight;
|
||||
faller->sector->floorheight = faller->floorstartheight;
|
||||
|
||||
R_ClearLevelInterpolatorState(&faller->thinker);
|
||||
}
|
||||
|
||||
P_CheckSector(faller->sector, false); // you might think this is irrelevant. you would be wrong
|
||||
|
@ -2010,6 +2013,9 @@ void EV_DoFloor(line_t *line, floor_e floortype)
|
|||
}
|
||||
|
||||
firstone = 0;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&dofloor->thinker, sec, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2140,6 +2146,10 @@ void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&elevator->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&elevator->thinker, sec, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2318,6 +2328,10 @@ void EV_DoContinuousFall(sector_t *sec, sector_t *backsector, fixed_t spd, boole
|
|||
|
||||
faller->destheight = backwards ? backsector->ceilingheight : backsector->floorheight;
|
||||
faller->direction = backwards ? 1 : -1;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&faller->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&faller->thinker, sec, true);
|
||||
}
|
||||
|
||||
// Some other 3dfloor special things Tails 03-11-2002 (Search p_mobj.c for description)
|
||||
|
|
16
src/p_spec.c
16
src/p_spec.c
|
@ -20,6 +20,7 @@
|
|||
#include "p_local.h"
|
||||
#include "p_setup.h" // levelflats for flat animation
|
||||
#include "r_data.h"
|
||||
#include "r_fps.h"
|
||||
#include "r_textures.h"
|
||||
#include "m_random.h"
|
||||
#include "p_mobj.h"
|
||||
|
@ -5695,6 +5696,9 @@ static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control,
|
|||
displace->speed = speed;
|
||||
displace->type = type;
|
||||
displace->reverse = reverse;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&displace->thinker, §ors[affectee], false);
|
||||
}
|
||||
|
||||
/** Adds a Mario block thinker, which changes the block's texture between blank
|
||||
|
@ -5754,6 +5758,10 @@ static void P_AddRaiseThinker(sector_t *sec, INT16 tag, fixed_t speed, fixed_t c
|
|||
raise->flags |= RF_REVERSE;
|
||||
if (spindash)
|
||||
raise->flags |= RF_SPINDASH;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&raise->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&raise->thinker, sec, true);
|
||||
}
|
||||
|
||||
static void P_AddAirbob(sector_t *sec, INT16 tag, fixed_t dist, boolean raise, boolean spindash, boolean dynamic)
|
||||
|
@ -5779,6 +5787,10 @@ static void P_AddAirbob(sector_t *sec, INT16 tag, fixed_t dist, boolean raise, b
|
|||
airbob->flags |= RF_SPINDASH;
|
||||
if (dynamic)
|
||||
airbob->flags |= RF_DYNAMIC;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&airbob->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&airbob->thinker, sec, true);
|
||||
}
|
||||
|
||||
/** Adds a thwomp thinker.
|
||||
|
@ -5819,6 +5831,10 @@ static inline void P_AddThwompThinker(sector_t *sec, line_t *sourceline, fixed_t
|
|||
sec->ceilingdata = thwomp;
|
||||
// Start with 'resting' texture
|
||||
sides[sourceline->sidenum[0]].midtexture = sides[sourceline->sidenum[0]].bottomtexture;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&thwomp->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&thwomp->thinker, sec, true);
|
||||
}
|
||||
|
||||
/** Adds a thinker which checks if any MF_ENEMY objects with health are in the defined area.
|
||||
|
|
|
@ -764,6 +764,11 @@ void P_Ticker(boolean run)
|
|||
LUA_HOOK(PostThinkFrame);
|
||||
}
|
||||
|
||||
if (run)
|
||||
{
|
||||
R_UpdateLevelInterpolators();
|
||||
}
|
||||
|
||||
P_MapEnd();
|
||||
|
||||
// Z_CheckMemCleanup();
|
||||
|
|
158
src/r_fps.c
158
src/r_fps.c
|
@ -20,6 +20,7 @@
|
|||
#include "r_plane.h"
|
||||
#include "p_spec.h"
|
||||
#include "r_state.h"
|
||||
#include "z_zone.h"
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h" // for cv_glshearing
|
||||
#endif
|
||||
|
@ -40,6 +41,11 @@ viewvars_t *newview = &p1view_new;
|
|||
|
||||
enum viewcontext_e viewcontext = VIEWCONTEXT_PLAYER1;
|
||||
|
||||
static levelinterpolator_t **levelinterpolators;
|
||||
static size_t levelinterpolators_len;
|
||||
static size_t levelinterpolators_size;
|
||||
|
||||
|
||||
static fixed_t R_LerpFixed(fixed_t from, fixed_t to, fixed_t frac)
|
||||
{
|
||||
return from + FixedMul(frac, to - from);
|
||||
|
@ -194,3 +200,155 @@ void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjst
|
|||
out->z = R_LerpFixed(mobj->old_z, mobj->z, frac);
|
||||
out->angle = mobj->angle;
|
||||
}
|
||||
|
||||
static void AddInterpolator(levelinterpolator_t* interpolator)
|
||||
{
|
||||
if (levelinterpolators_len >= levelinterpolators_size)
|
||||
{
|
||||
if (levelinterpolators_size == 0)
|
||||
{
|
||||
levelinterpolators_size = 128;
|
||||
}
|
||||
else
|
||||
{
|
||||
levelinterpolators_size *= 2;
|
||||
}
|
||||
|
||||
levelinterpolators = Z_ReallocAlign(
|
||||
(void*) levelinterpolators,
|
||||
sizeof(levelinterpolator_t*) * levelinterpolators_size,
|
||||
PU_LEVEL,
|
||||
NULL,
|
||||
sizeof(levelinterpolator_t*) * 8
|
||||
);
|
||||
}
|
||||
|
||||
levelinterpolators[levelinterpolators_len] = interpolator;
|
||||
levelinterpolators_len += 1;
|
||||
}
|
||||
|
||||
static levelinterpolator_t *CreateInterpolator(levelinterpolator_type_e type, thinker_t *thinker)
|
||||
{
|
||||
levelinterpolator_t *ret = (levelinterpolator_t*) Z_CallocAlign(
|
||||
sizeof(levelinterpolator_t),
|
||||
PU_LEVEL,
|
||||
NULL,
|
||||
sizeof(levelinterpolator_t) * 8
|
||||
);
|
||||
|
||||
ret->type = type;
|
||||
ret->thinker = thinker;
|
||||
|
||||
AddInterpolator(ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void R_CreateInterpolator_SectorPlane(thinker_t *thinker, sector_t *sector, boolean ceiling)
|
||||
{
|
||||
levelinterpolator_t *interp = CreateInterpolator(LVLINTERP_SectorPlane, thinker);
|
||||
interp->sectorplane.sector = sector;
|
||||
interp->sectorplane.ceiling = ceiling;
|
||||
if (ceiling)
|
||||
{
|
||||
interp->sectorplane.oldheight = interp->sectorplane.bakheight = sector->ceilingheight;
|
||||
}
|
||||
else
|
||||
{
|
||||
interp->sectorplane.oldheight = interp->sectorplane.bakheight = sector->floorheight;
|
||||
}
|
||||
}
|
||||
|
||||
void R_InitializeLevelInterpolators(void)
|
||||
{
|
||||
levelinterpolators_len = 0;
|
||||
levelinterpolators_size = 0;
|
||||
levelinterpolators = NULL;
|
||||
}
|
||||
|
||||
static void UpdateLevelInterpolatorState(levelinterpolator_t *interp)
|
||||
{
|
||||
switch (interp->type)
|
||||
{
|
||||
case LVLINTERP_SectorPlane:
|
||||
interp->sectorplane.oldheight = interp->sectorplane.bakheight;
|
||||
interp->sectorplane.bakheight = interp->sectorplane.ceiling ? interp->sectorplane.sector->ceilingheight : interp->sectorplane.sector->floorheight;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void R_UpdateLevelInterpolators(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < levelinterpolators_len; i++)
|
||||
{
|
||||
levelinterpolator_t *interp = levelinterpolators[i];
|
||||
|
||||
UpdateLevelInterpolatorState(interp);
|
||||
}
|
||||
}
|
||||
|
||||
void R_ClearLevelInterpolatorState(thinker_t *thinker)
|
||||
{
|
||||
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < levelinterpolators_len; i++)
|
||||
{
|
||||
levelinterpolator_t *interp = levelinterpolators[i];
|
||||
|
||||
if (interp->thinker == thinker)
|
||||
{
|
||||
// Do it twice to make the old state match the new
|
||||
UpdateLevelInterpolatorState(interp);
|
||||
UpdateLevelInterpolatorState(interp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void R_ApplyLevelInterpolators(fixed_t frac)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < levelinterpolators_len; i++)
|
||||
{
|
||||
levelinterpolator_t *interp = levelinterpolators[i];
|
||||
|
||||
switch (interp->type)
|
||||
{
|
||||
case LVLINTERP_SectorPlane:
|
||||
if (interp->sectorplane.ceiling)
|
||||
{
|
||||
interp->sectorplane.sector->ceilingheight = R_LerpFixed(interp->sectorplane.oldheight, interp->sectorplane.bakheight, frac);
|
||||
}
|
||||
else
|
||||
{
|
||||
interp->sectorplane.sector->floorheight = R_LerpFixed(interp->sectorplane.oldheight, interp->sectorplane.bakheight, frac);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void R_RestoreLevelInterpolators(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < levelinterpolators_len; i++)
|
||||
{
|
||||
levelinterpolator_t *interp = levelinterpolators[i];
|
||||
|
||||
switch (interp->type)
|
||||
{
|
||||
case LVLINTERP_SectorPlane:
|
||||
if (interp->sectorplane.ceiling)
|
||||
{
|
||||
interp->sectorplane.sector->ceilingheight = interp->sectorplane.bakheight;
|
||||
}
|
||||
else
|
||||
{
|
||||
interp->sectorplane.sector->floorheight = interp->sectorplane.bakheight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
34
src/r_fps.h
34
src/r_fps.h
|
@ -51,6 +51,27 @@ typedef struct {
|
|||
angle_t angle;
|
||||
} interpmobjstate_t;
|
||||
|
||||
// Level interpolators
|
||||
|
||||
// The union tag for levelinterpolator_t
|
||||
typedef enum {
|
||||
LVLINTERP_SectorPlane,
|
||||
} levelinterpolator_type_e;
|
||||
|
||||
// Tagged union of a level interpolator
|
||||
typedef struct levelinterpolator_s {
|
||||
levelinterpolator_type_e type;
|
||||
thinker_t *thinker;
|
||||
union {
|
||||
struct {
|
||||
sector_t *sector;
|
||||
fixed_t oldheight;
|
||||
fixed_t bakheight;
|
||||
boolean ceiling;
|
||||
} sectorplane;
|
||||
};
|
||||
} levelinterpolator_t;
|
||||
|
||||
// Interpolates the current view variables (r_state.h) against the selected view context in R_SetViewContext
|
||||
void R_InterpolateView(fixed_t frac);
|
||||
// Buffer the current new views into the old views. Call once after each real tic.
|
||||
|
@ -64,4 +85,17 @@ void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out);
|
|||
// Evaluate the interpolated mobj state for the given precipmobj
|
||||
void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjstate_t *out);
|
||||
|
||||
void R_CreateInterpolator_SectorPlane(thinker_t *thinker, sector_t *sector, boolean ceiling);
|
||||
|
||||
// Initialize level interpolators after a level change
|
||||
void R_InitializeLevelInterpolators(void);
|
||||
// Update level interpolators, storing the previous and current states.
|
||||
void R_UpdateLevelInterpolators(void);
|
||||
// Clear states for all level interpolators for the thinker
|
||||
void R_ClearLevelInterpolatorState(thinker_t *thinker);
|
||||
// Apply level interpolators to the actual game state
|
||||
void R_ApplyLevelInterpolators(fixed_t frac);
|
||||
// Restore level interpolators to the real game state
|
||||
void R_RestoreLevelInterpolators(void);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue