mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-12-28 18:52:31 +00:00
Merge branch 'optimize-precip-think' into 'master'
Optimize precipitation by eliminating the thinker entirely See merge request KartKrew/Kart!1157
This commit is contained in:
commit
d6d8cf548a
8 changed files with 84 additions and 52 deletions
|
|
@ -5082,6 +5082,12 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
// uncapped/interpolation
|
||||
interpmobjstate_t interp = {0};
|
||||
|
||||
// okay... this is a hack, but weather isn't networked, so it should be ok
|
||||
if (!P_PrecipThinker(thing))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// do interpolation
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
{
|
||||
|
|
@ -5181,13 +5187,6 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
|
||||
vis->precip = true;
|
||||
vis->bbox = false;
|
||||
|
||||
// okay... this is a hack, but weather isn't networked, so it should be ok
|
||||
if (!(thing->precipflags & PCF_THUNK))
|
||||
{
|
||||
P_PrecipThinker(thing);
|
||||
thing->precipflags |= PCF_THUNK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ precise_t ps_playerthink_time = 0;
|
|||
precise_t ps_botticcmd_time = 0;
|
||||
precise_t ps_thinkertime = 0;
|
||||
|
||||
precise_t ps_thlist_times[NUM_THINKERLISTS];
|
||||
precise_t ps_thlist_times[NUM_ACTIVETHINKERLISTS];
|
||||
precise_t ps_acs_time = 0;
|
||||
|
||||
int ps_checkposition_calls = 0;
|
||||
|
|
@ -367,7 +367,6 @@ static void M_DrawTickStats(void)
|
|||
{"main ", "Main: ", &ps_thlist_times[THINK_MAIN]},
|
||||
{"mobjs ", "Mobjs: ", &ps_thlist_times[THINK_MOBJ]},
|
||||
{"dynslop", "Dynamic slopes: ", &ps_thlist_times[THINK_DYNSLOPE]},
|
||||
{"precip ", "Precipitation: ", &ps_thlist_times[THINK_PRECIP]},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -72,7 +72,13 @@ typedef enum
|
|||
THINK_MAIN,
|
||||
THINK_MOBJ,
|
||||
THINK_DYNSLOPE,
|
||||
THINK_PRECIP,
|
||||
|
||||
// Lists after this may exist but they do not call an
|
||||
// action in P_RunThinkers
|
||||
NUM_ACTIVETHINKERLISTS,
|
||||
|
||||
THINK_PRECIP = NUM_ACTIVETHINKERLISTS,
|
||||
|
||||
NUM_THINKERLISTS
|
||||
} thinklistnum_t; /**< Thinker lists. */
|
||||
extern thinker_t thlist[];
|
||||
|
|
@ -80,6 +86,7 @@ extern thinker_t thlist[];
|
|||
void P_InitThinkers(void);
|
||||
void P_AddThinker(const thinklistnum_t n, thinker_t *thinker);
|
||||
void P_RemoveThinker(thinker_t *thinker);
|
||||
void P_UnlinkThinker(thinker_t *thinker);
|
||||
|
||||
//
|
||||
// P_USER
|
||||
|
|
|
|||
52
src/p_mobj.c
52
src/p_mobj.c
|
|
@ -546,7 +546,7 @@ static boolean P_SetPrecipMobjState(precipmobj_t *mobj, statenum_t state)
|
|||
|
||||
if (state == S_NULL)
|
||||
{ // Remove mobj
|
||||
P_RemovePrecipMobj(mobj);
|
||||
P_FreePrecipMobj(mobj);
|
||||
return false;
|
||||
}
|
||||
st = &states[state];
|
||||
|
|
@ -4174,25 +4174,33 @@ void P_RecalcPrecipInSector(sector_t *sector)
|
|||
//
|
||||
// P_NullPrecipThinker
|
||||
//
|
||||
// For "Blank" precipitation
|
||||
// Just the identification of a precip thinker. The thinker
|
||||
// should never actually be called!
|
||||
//
|
||||
void P_NullPrecipThinker(precipmobj_t *mobj)
|
||||
{
|
||||
//(void)mobj;
|
||||
mobj->precipflags &= ~PCF_THUNK;
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
(void)mobj;
|
||||
I_Assert("P_NullPrecipThinker should not be called" == 0);
|
||||
}
|
||||
|
||||
void P_PrecipThinker(precipmobj_t *mobj)
|
||||
boolean P_PrecipThinker(precipmobj_t *mobj)
|
||||
{
|
||||
boolean flip = (mobj->precipflags & PCF_FLIP);
|
||||
|
||||
if (mobj->lastThink == leveltime)
|
||||
return true; // already thinked this tick
|
||||
|
||||
mobj->lastThink = leveltime;
|
||||
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
P_CycleStateAnimation((mobj_t *)mobj);
|
||||
|
||||
if (mobj->state == &states[S_RAINRETURN])
|
||||
{
|
||||
// Reset to ceiling!
|
||||
P_SetPrecipMobjState(mobj, mobj->info->spawnstate);
|
||||
if (!P_SetPrecipMobjState(mobj, mobj->info->spawnstate))
|
||||
return false;
|
||||
|
||||
mobj->z = (flip) ? (mobj->floorz) : (mobj->ceilingz);
|
||||
mobj->momz = FixedMul(-mobj->info->speed, mapobjectscale);
|
||||
mobj->precipflags &= ~PCF_SPLASH;
|
||||
|
|
@ -4213,20 +4221,23 @@ void P_PrecipThinker(precipmobj_t *mobj)
|
|||
// HACK: sprite changes are 1 tic late, so you would see splashes on the ceiling if not for this state.
|
||||
// We need to use the settings from the previous state, since some of those are NOT 1 tic late.
|
||||
INT32 frame = (mobj->frame & ~FF_FRAMEMASK);
|
||||
P_SetPrecipMobjState(mobj, S_RAINRETURN);
|
||||
|
||||
if (!P_SetPrecipMobjState(mobj, S_RAINRETURN))
|
||||
return false;
|
||||
|
||||
mobj->frame = frame;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!P_SetPrecipMobjState(mobj, mobj->state->nextstate))
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mobj->precipflags & PCF_SPLASH)
|
||||
return;
|
||||
return true;
|
||||
|
||||
mobj->z += mobj->momz;
|
||||
|
||||
|
|
@ -4240,12 +4251,16 @@ void P_PrecipThinker(precipmobj_t *mobj)
|
|||
}
|
||||
else
|
||||
{
|
||||
P_SetPrecipMobjState(mobj, mobj->info->deathstate);
|
||||
if (!P_SetPrecipMobjState(mobj, mobj->info->deathstate))
|
||||
return false;
|
||||
|
||||
mobj->z = (flip) ? (mobj->ceilingz) : (mobj->floorz);
|
||||
mobj->precipflags |= PCF_SPLASH;
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void P_RingThinker(mobj_t *mobj)
|
||||
|
|
@ -11253,7 +11268,7 @@ boolean P_MobjWasRemoved(mobj_t *mobj)
|
|||
return true;
|
||||
}
|
||||
|
||||
void P_RemovePrecipMobj(precipmobj_t *mobj)
|
||||
void P_FreePrecipMobj(precipmobj_t *mobj)
|
||||
{
|
||||
// unlink from sector and block lists
|
||||
P_UnsetPrecipThingPosition(mobj);
|
||||
|
|
@ -11265,7 +11280,9 @@ void P_RemovePrecipMobj(precipmobj_t *mobj)
|
|||
}
|
||||
|
||||
// free block
|
||||
P_RemoveThinker((thinker_t *)mobj);
|
||||
// Precipmobjs don't actually think using their thinker,
|
||||
// so the free cannot be delayed.
|
||||
P_UnlinkThinker((thinker_t*)mobj);
|
||||
}
|
||||
|
||||
// Clearing out stuff for savegames
|
||||
|
|
@ -11301,12 +11318,7 @@ void P_RemoveSavegameMobj(mobj_t *mobj)
|
|||
|
||||
// free block
|
||||
// Here we use the same code as R_RemoveThinkerDelayed, but without reference counting (we're removing everything so it shouldn't matter) and without touching currentthinker since we aren't in P_RunThinkers
|
||||
{
|
||||
thinker_t *thinker = (thinker_t *)mobj;
|
||||
thinker_t *next = thinker->next;
|
||||
(next->prev = thinker->prev)->next = next;
|
||||
Z_Free(thinker);
|
||||
}
|
||||
P_UnlinkThinker((thinker_t*)mobj);
|
||||
}
|
||||
|
||||
static CV_PossibleValue_t respawnitemtime_cons_t[] = {{1, "MIN"}, {300, "MAX"}, {0, NULL}};
|
||||
|
|
|
|||
|
|
@ -493,6 +493,8 @@ struct precipmobj_t
|
|||
INT32 tics; // state tic counter
|
||||
state_t *state;
|
||||
UINT32 flags; // flags from mobjinfo tables
|
||||
|
||||
tic_t lastThink;
|
||||
};
|
||||
|
||||
struct actioncache_t
|
||||
|
|
@ -540,9 +542,9 @@ void P_RemoveFloorSpriteSlope(mobj_t *mobj);
|
|||
boolean P_BossTargetPlayer(mobj_t *actor, boolean closest);
|
||||
boolean P_SupermanLook4Players(mobj_t *actor);
|
||||
void P_DestroyRobots(void);
|
||||
void P_PrecipThinker(precipmobj_t *mobj);
|
||||
boolean P_PrecipThinker(precipmobj_t *mobj);
|
||||
void P_NullPrecipThinker(precipmobj_t *mobj);
|
||||
void P_RemovePrecipMobj(precipmobj_t *mobj);
|
||||
void P_FreePrecipMobj(precipmobj_t *mobj);
|
||||
void P_SetScale(mobj_t *mobj, fixed_t newscale);
|
||||
void P_XYMovement(mobj_t *mo);
|
||||
void P_RingXYMovement(mobj_t *mo);
|
||||
|
|
|
|||
|
|
@ -1833,16 +1833,18 @@ void P_SwitchWeather(preciptype_t newWeather)
|
|||
if (purge == true)
|
||||
{
|
||||
thinker_t *think;
|
||||
thinker_t *next;
|
||||
precipmobj_t *precipmobj;
|
||||
|
||||
for (think = thlist[THINK_PRECIP].next; think != &thlist[THINK_PRECIP]; think = think->next)
|
||||
for (think = thlist[THINK_PRECIP].next; think != &thlist[THINK_PRECIP]; think = next)
|
||||
{
|
||||
next = think->next;
|
||||
|
||||
if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker)
|
||||
continue; // not a precipmobj thinker
|
||||
|
||||
precipmobj = (precipmobj_t *)think;
|
||||
|
||||
P_RemovePrecipMobj(precipmobj);
|
||||
P_FreePrecipMobj(precipmobj);
|
||||
}
|
||||
}
|
||||
else if (swap != MT_NULL) // Rather than respawn all that crap, reuse it!
|
||||
|
|
|
|||
27
src/p_tick.c
27
src/p_tick.c
|
|
@ -295,8 +295,6 @@ static thinker_t *currentthinker;
|
|||
//
|
||||
void P_RemoveThinkerDelayed(thinker_t *thinker)
|
||||
{
|
||||
thinker_t *next;
|
||||
|
||||
if (thinker->references != 0)
|
||||
{
|
||||
#ifdef PARANOIA
|
||||
|
|
@ -327,15 +325,30 @@ void P_RemoveThinkerDelayed(thinker_t *thinker)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Remove from main thinker list */
|
||||
next = thinker->next;
|
||||
R_DestroyLevelInterpolators(thinker);
|
||||
|
||||
/* Note that currentthinker is guaranteed to point to us,
|
||||
* and since we're freeing our memory, we had better change that. So
|
||||
* point it to thinker->prev, so the iterator will correctly move on to
|
||||
* thinker->prev->next = thinker->next */
|
||||
(next->prev = currentthinker = thinker->prev)->next = next;
|
||||
currentthinker = thinker->prev;
|
||||
|
||||
R_DestroyLevelInterpolators(thinker);
|
||||
/* Remove from main thinker list */
|
||||
P_UnlinkThinker(thinker);
|
||||
}
|
||||
|
||||
//
|
||||
// P_UnlinkThinker()
|
||||
//
|
||||
// Actually removes thinker from the list and frees its memory.
|
||||
//
|
||||
void P_UnlinkThinker(thinker_t *thinker)
|
||||
{
|
||||
thinker_t *next = thinker->next;
|
||||
|
||||
I_Assert(thinker->references == 0);
|
||||
|
||||
(next->prev = thinker->prev)->next = next;
|
||||
Z_Free(thinker);
|
||||
}
|
||||
|
||||
|
|
@ -437,7 +450,7 @@ static void P_RunThinkers(void)
|
|||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < NUM_THINKERLISTS; i++)
|
||||
for (i = 0; i < NUM_ACTIVETHINKERLISTS; i++)
|
||||
{
|
||||
ps_thlist_times[i] = I_GetPreciseTime();
|
||||
for (currentthinker = thlist[i].next; currentthinker != &thlist[i]; currentthinker = currentthinker->next)
|
||||
|
|
|
|||
|
|
@ -2465,6 +2465,12 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
// uncapped/interpolation
|
||||
interpmobjstate_t interp = {0};
|
||||
|
||||
// okay... this is a hack, but weather isn't networked, so it should be ok
|
||||
if (!P_PrecipThinker(thing))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// do interpolation
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
{
|
||||
|
|
@ -2554,7 +2560,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
if (thing->subsector->sector->cullheight)
|
||||
{
|
||||
if (R_DoCulling(thing->subsector->sector->cullheight, viewsector->cullheight, viewz, gz, gzt))
|
||||
goto weatherthink;
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine the blendmode and translucency value
|
||||
|
|
@ -2565,7 +2571,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
|
||||
trans = (thing->frame & FF_TRANSMASK) >> FF_TRANSSHIFT;
|
||||
if (trans >= NUMTRANSMAPS)
|
||||
goto weatherthink; // cap
|
||||
return; // cap
|
||||
}
|
||||
|
||||
// store information in a vissprite
|
||||
|
|
@ -2623,14 +2629,6 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
|
||||
// Fullbright
|
||||
vis->colormap = colormaps;
|
||||
|
||||
weatherthink:
|
||||
// okay... this is a hack, but weather isn't networked, so it should be ok
|
||||
if (!(thing->precipflags & PCF_THUNK))
|
||||
{
|
||||
P_PrecipThinker(thing);
|
||||
thing->precipflags |= PCF_THUNK;
|
||||
}
|
||||
}
|
||||
|
||||
// R_AddSprites
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue