From de212b07cd23acd1c90f20d6be6f587c3e7e9df0 Mon Sep 17 00:00:00 2001 From: Sally Coolatta <tehrealsalt@gmail.com> Date: Mon, 25 Apr 2022 20:14:53 -0400 Subject: [PATCH] Bring back shadows on polyobjects Also optimizes the method used so rings can show their shadows too. Using just the subsector is a tad bit imprecise admittedly but any more precise methods get really laggy. --- src/r_fps.c | 5 +++ src/r_fps.h | 1 + src/r_things.c | 87 ++++++++++++++++---------------------------------- 3 files changed, 33 insertions(+), 60 deletions(-) diff --git a/src/r_fps.c b/src/r_fps.c index cc518cc35..c4f69415c 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -256,6 +256,8 @@ void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out) out->y = R_LerpFixed(mobj->old_y, mobj->y, frac); out->z = R_LerpFixed(mobj->old_z, mobj->z, frac); + out->subsector = R_PointInSubsector(out->x, out->y); + if (mobj->player) { out->angle = R_LerpAngle(mobj->player->old_drawangle, mobj->player->drawangle, frac); @@ -271,6 +273,9 @@ void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjst out->x = R_LerpFixed(mobj->old_x, mobj->x, frac); out->y = R_LerpFixed(mobj->old_y, mobj->y, frac); out->z = R_LerpFixed(mobj->old_z, mobj->z, frac); + + out->subsector = R_PointInSubsector(out->x, out->y); + out->angle = R_LerpAngle(mobj->old_angle, mobj->angle, frac); } diff --git a/src/r_fps.h b/src/r_fps.h index 59d3df747..32c9131fe 100644 --- a/src/r_fps.h +++ b/src/r_fps.h @@ -53,6 +53,7 @@ typedef struct { fixed_t x; fixed_t y; fixed_t z; + subsector_t *subsector; angle_t angle; } interpmobjstate_t; diff --git a/src/r_things.c b/src/r_things.c index 0af691b38..5e10d8fa3 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1158,8 +1158,8 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) } halfHeight = interp.z + (thing->height >> 1); - floorz = P_GetFloorZ(thing, thing->subsector->sector, interp.x, interp.y, NULL); - ceilingz = P_GetCeilingZ(thing, thing->subsector->sector, interp.x, interp.y, NULL); + floorz = P_GetFloorZ(thing, interp.subsector->sector, interp.x, interp.y, NULL); + ceilingz = P_GetCeilingZ(thing, interp.subsector->sector, interp.x, interp.y, NULL); #define CHECKZ (isflipped ? z > halfHeight && z < groundz : z < halfHeight && z > groundz) @@ -1195,71 +1195,38 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) } } - if (isflipped ? (ceilingz < groundz - (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2))) - : (floorz > groundz + (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2)))) - { - groundz = isflipped ? ceilingz : floorz; - groundslope = NULL; - } - -#if 0 // Unfortunately, this drops CEZ2 down to sub-17 FPS on my i7. - // NOTE: this section was not updated to reflect reverse gravity support - // Check polyobjects and see if groundz needs to be altered, for rings only because they don't update floorz - if (thing->type == MT_RING) + // Check polyobjects and see if groundz needs to be altered { - INT32 xl, xh, yl, yh, bx, by; - - xl = (unsigned)(interp.x - thing->radius - bmaporgx)>>MAPBLOCKSHIFT; - xh = (unsigned)(interp.x + thing->radius - bmaporgx)>>MAPBLOCKSHIFT; - yl = (unsigned)(interp.y - thing->radius - bmaporgy)>>MAPBLOCKSHIFT; - yh = (unsigned)(interp.y + thing->radius - bmaporgy)>>MAPBLOCKSHIFT; - - BMBOUNDFIX(xl, xh, yl, yh); - - validcount++; + // This isn't very precise, but the precise method was far too slow. + // (Polies are just naturally pretty flickery anyway :P) + polyobj_t *po = interp.subsector->polyList; - for (by = yl; by <= yh; by++) - for (bx = xl; bx <= xh; bx++) + while (po) + { + if (!(po->flags & POF_RENDERPLANES) || !P_MobjInsidePolyobj(po, thing)) { - INT32 offset; - polymaplink_t *plink; // haleyjd 02/22/06 - - if (bx < 0 || by < 0 || bx >= bmapwidth || by >= bmapheight) - continue; - - offset = by*bmapwidth + bx; - - // haleyjd 02/22/06: consider polyobject lines - plink = polyblocklinks[offset]; - - while (plink) - { - polyobj_t *po = plink->po; - - if (po->validcount != validcount) // if polyobj hasn't been checked - { - po->validcount = validcount; + po = (polyobj_t *)(po->link.next); + continue; + } - if (!P_MobjInsidePolyobj(po, thing) || !(po->flags & POF_RENDERPLANES)) - { - plink = (polymaplink_t *)(plink->link.next); - continue; - } + // We're inside it! Yess... + z = isflipped ? po->lines[0]->backsector->floorheight : po->lines[0]->backsector->ceilingheight; + if CHECKZ + { + groundz = z; + groundslope = NULL; + } - // We're inside it! Yess... - z = po->lines[0]->backsector->ceilingheight; + po = (polyobj_t *)(po->link.next); + } + } - if (z < halfHeight && z > groundz) - { - groundz = z; - groundslope = NULL; - } - } - plink = (polymaplink_t *)(plink->link.next); - } - } + if (isflipped ? (ceilingz < groundz - (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2))) + : (floorz > groundz + (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2)))) + { + groundz = isflipped ? ceilingz : floorz; + groundslope = NULL; } -#endif if (shadowslope != NULL) *shadowslope = groundslope; -- GitLab