From b1e02467bfc009d1b08d83a12181fde87869bae0 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 7 Oct 2018 15:00:58 +0100 Subject: [PATCH] Weather is already run client-side. What if we ran it render-side, for major performance gains? This commit will answer all your questions - and more! --- src/hardware/hw_main.c | 22 ++++++++++++++++++---- src/p_mobj.c | 37 ++++++++++++++++++++----------------- src/p_mobj.h | 4 ++++ src/p_saveg.c | 6 ++---- src/p_spec.c | 34 ++++++++++------------------------ src/p_tick.c | 24 ++++++++++++------------ src/r_things.c | 23 +++++++++++++++++++---- 7 files changed, 85 insertions(+), 65 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index d7c73415..871a6a49 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5140,8 +5140,10 @@ static void HWR_AddSprites(sector_t *sec) approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y); - if (approx_dist <= limit_dist) - HWR_ProjectSprite(thing); + if (approx_dist > limit_dist) + continue; + + HWR_ProjectSprite(thing); } } else @@ -5163,8 +5165,10 @@ static void HWR_AddSprites(sector_t *sec) approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y); - if (approx_dist <= limit_dist) - HWR_ProjectPrecipitationSprite(precipthing); + if (approx_dist > limit_dist) + continue; + + HWR_ProjectPrecipitationSprite(precipthing); } } else @@ -5449,6 +5453,16 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) x1 = tr_x + x1 * rightcos; x2 = tr_x - x2 * rightcos; + // okay, we can't return now... this is a hack, but weather isn't networked, so it should be ok + if (!(thing->precipflags & PCF_THUNK)) + { + if (thing->precipflags & PCF_RAIN) + P_RainThinker(thing); + else + P_SnowThinker(thing); + thing->precipflags |= PCF_THUNK; + } + // // store information in a vissprite // diff --git a/src/p_mobj.c b/src/p_mobj.c index 5f85474c..bb9483d1 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3840,7 +3840,8 @@ void P_RecalcPrecipInSector(sector_t *sector) // void P_NullPrecipThinker(precipmobj_t *mobj) { - (void)mobj; + //(void)mobj; + mobj->precipflags &= ~PCF_THUNK; } void P_SnowThinker(precipmobj_t *mobj) @@ -3860,25 +3861,26 @@ void P_RainThinker(precipmobj_t *mobj) { // cycle through states, // calling action functions at transitions - if (mobj->tics > 0 && --mobj->tics == 0) - { - // you can cycle through multiple states in a tic - if (!P_SetPrecipMobjState(mobj, mobj->state->nextstate)) - return; // freed itself - } + if (mobj->tics <= 0) + return; + + if (--mobj->tics) + return; + + if (!P_SetPrecipMobjState(mobj, mobj->state->nextstate)) + return; + + if (mobj->state != &states[S_RAINRETURN]) + return; + + mobj->z = mobj->ceilingz; + P_SetPrecipMobjState(mobj, S_RAIN1); - if (mobj->state == &states[S_RAINRETURN]) - { - mobj->z = mobj->ceilingz; - P_SetPrecipMobjState(mobj, S_RAIN1); - } return; } // adjust height - mobj->z += mobj->momz; - - if (mobj->z <= mobj->floorz) + if ((mobj->z += mobj->momz) <= mobj->floorz) { // no splashes on sky or bottomless pits if (mobj->precipflags & PCF_PIT) @@ -7926,14 +7928,15 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype static inline precipmobj_t *P_SpawnRainMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) { precipmobj_t *mo = P_SpawnPrecipMobj(x,y,z,type); - mo->thinker.function.acp1 = (actionf_p1)P_RainThinker; + mo->precipflags |= PCF_RAIN; + //mo->thinker.function.acp1 = (actionf_p1)P_RainThinker; return mo; } static inline precipmobj_t *P_SpawnSnowMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) { precipmobj_t *mo = P_SpawnPrecipMobj(x,y,z,type); - mo->thinker.function.acp1 = (actionf_p1)P_SnowThinker; + //mo->thinker.function.acp1 = (actionf_p1)P_SnowThinker; return mo; } diff --git a/src/p_mobj.h b/src/p_mobj.h index 79cffae8..620028d8 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -252,6 +252,10 @@ typedef enum { PCF_FOF = 4, // Above MOVING FOF (this means we need to keep floorz up to date...) PCF_MOVINGFOF = 8, + // Is rain. + PCF_RAIN = 16, + // Ran the thinker this tic. + PCF_THUNK = 32, } precipflag_t; // Map Object definition. typedef struct mobj_s diff --git a/src/p_saveg.c b/src/p_saveg.c index d1ec8e5a..17d28302 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1661,8 +1661,7 @@ static void P_NetArchiveThinkers(void) for (th = thinkercap.next; th != &thinkercap; th = th->next) { if (!(th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed - || th->function.acp1 == (actionf_p1)P_RainThinker - || th->function.acp1 == (actionf_p1)P_SnowThinker)) + || th->function.acp1 == (actionf_p1)P_NullPrecipThinker)) numsaved++; if (th->function.acp1 == (actionf_p1)P_MobjThinker) @@ -1671,8 +1670,7 @@ static void P_NetArchiveThinkers(void) continue; } #ifdef PARANOIA - else if (th->function.acp1 == (actionf_p1)P_RainThinker - || th->function.acp1 == (actionf_p1)P_SnowThinker); + else if (th->function.acp1 == (actionf_p1)P_NullPrecipThinker); #endif else if (th->function.acp1 == (actionf_p1)T_MoveCeiling) { diff --git a/src/p_spec.c b/src/p_spec.c index c62c3b20..ff6691a9 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2039,8 +2039,7 @@ void P_SwitchWeather(INT32 weathernum) for (think = thinkercap.next; think != &thinkercap; think = think->next) { - if ((think->function.acp1 != (actionf_p1)P_SnowThinker) - && (think->function.acp1 != (actionf_p1)P_RainThinker)) + if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker) continue; // not a precipmobj thinker precipmobj = (precipmobj_t *)think; @@ -2056,14 +2055,12 @@ void P_SwitchWeather(INT32 weathernum) for (think = thinkercap.next; think != &thinkercap; think = think->next) { + if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker) + continue; // not a precipmobj thinker + precipmobj = (precipmobj_t *)think; + if (swap == PRECIP_RAIN) // Snow To Rain { - if (!(think->function.acp1 == (actionf_p1)P_SnowThinker - || think->function.acp1 == (actionf_p1)P_NullPrecipThinker)) - continue; // not a precipmobj thinker - - precipmobj = (precipmobj_t *)think; - precipmobj->flags = mobjinfo[MT_RAIN].flags; st = &states[mobjinfo[MT_RAIN].spawnstate]; precipmobj->state = st; @@ -2074,18 +2071,13 @@ void P_SwitchWeather(INT32 weathernum) precipmobj->precipflags &= ~PCF_INVISIBLE; - think->function.acp1 = (actionf_p1)P_RainThinker; + precipmobj->precipflags |= PCF_RAIN; + //think->function.acp1 = (actionf_p1)P_RainThinker; } else if (swap == PRECIP_SNOW) // Rain To Snow { INT32 z; - if (!(think->function.acp1 == (actionf_p1)P_RainThinker - || think->function.acp1 == (actionf_p1)P_NullPrecipThinker)) - continue; // not a precipmobj thinker - - precipmobj = (precipmobj_t *)think; - precipmobj->flags = mobjinfo[MT_SNOWFLAKE].flags; z = M_RandomByte(); @@ -2103,19 +2095,13 @@ void P_SwitchWeather(INT32 weathernum) precipmobj->frame = st->frame; precipmobj->momz = mobjinfo[MT_SNOWFLAKE].speed; - precipmobj->precipflags &= ~PCF_INVISIBLE; + precipmobj->precipflags &= ~(PCF_INVISIBLE|PCF_RAIN); - think->function.acp1 = (actionf_p1)P_SnowThinker; + //think->function.acp1 = (actionf_p1)P_SnowThinker; } else if (swap == PRECIP_BLANK || swap == PRECIP_STORM_NORAIN) // Remove precip, but keep it around for reuse. { - if (!(think->function.acp1 == (actionf_p1)P_RainThinker - || think->function.acp1 == (actionf_p1)P_SnowThinker)) - continue; - - precipmobj = (precipmobj_t *)think; - - think->function.acp1 = (actionf_p1)P_NullPrecipThinker; + //think->function.acp1 = (actionf_p1)P_NullPrecipThinker; precipmobj->precipflags |= PCF_INVISIBLE; } diff --git a/src/p_tick.c b/src/p_tick.c index f4bc5932..5ba74707 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -56,12 +56,12 @@ void Command_Numthinkers_f(void) CONS_Printf(M_GetText("numthinkers <#>: Count number of thinkers\n")); CONS_Printf( "\t1: P_MobjThinker\n" - "\t2: P_RainThinker\n" - "\t3: P_SnowThinker\n" - "\t4: P_NullPrecipThinker\n" - "\t5: T_Friction\n" - "\t6: T_Pusher\n" - "\t7: P_RemoveThinkerDelayed\n"); + /*"\t2: P_RainThinker\n" + "\t3: P_SnowThinker\n"*/ + "\t2: P_NullPrecipThinker\n" + "\t3: T_Friction\n" + "\t4: T_Pusher\n" + "\t5: P_RemoveThinkerDelayed\n"); return; } @@ -73,27 +73,27 @@ void Command_Numthinkers_f(void) action = (actionf_p1)P_MobjThinker; CONS_Printf(M_GetText("Number of %s: "), "P_MobjThinker"); break; - case 2: + /*case 2: action = (actionf_p1)P_RainThinker; CONS_Printf(M_GetText("Number of %s: "), "P_RainThinker"); break; case 3: action = (actionf_p1)P_SnowThinker; CONS_Printf(M_GetText("Number of %s: "), "P_SnowThinker"); - break; - case 4: + break;*/ + case 2: action = (actionf_p1)P_NullPrecipThinker; CONS_Printf(M_GetText("Number of %s: "), "P_NullPrecipThinker"); break; - case 5: + case 3: action = (actionf_p1)T_Friction; CONS_Printf(M_GetText("Number of %s: "), "T_Friction"); break; - case 6: + case 4: action = (actionf_p1)T_Pusher; CONS_Printf(M_GetText("Number of %s: "), "T_Pusher"); break; - case 7: + case 5: action = (actionf_p1)P_RemoveThinkerDelayed; CONS_Printf(M_GetText("Number of %s: "), "P_RemoveThinkerDelayed"); break; diff --git a/src/r_things.c b/src/r_things.c index 0b176416..910a52b3 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1451,6 +1451,17 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) return; } + // okay, we can't return now except for vertical clipping... this is a hack, but weather isn't networked, so it should be ok + if (!(thing->precipflags & PCF_THUNK)) + { + if (thing->precipflags & PCF_RAIN) + P_RainThinker(thing); + else + P_SnowThinker(thing); + thing->precipflags |= PCF_THUNK; + } + + //SoM: 3/17/2000: Disregard sprites that are out of view.. gzt = thing->z + spritecachedinfo[lump].topoffset; gz = gzt - spritecachedinfo[lump].height; @@ -1569,8 +1580,10 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y); - if (approx_dist <= limit_dist) - R_ProjectSprite(thing); + if (approx_dist > limit_dist) + continue; + + R_ProjectSprite(thing); } } else @@ -1591,8 +1604,10 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y); - if (approx_dist <= limit_dist) - R_ProjectPrecipitationSprite(precipthing); + if (approx_dist > limit_dist) + continue; + + R_ProjectPrecipitationSprite(precipthing); } } else