Merge branch 'gravflip-shadows' into 'next'

Move drop shadows to the ceiling for objects in reverse gravity

See merge request STJr/SRB2!973
This commit is contained in:
MascaraSnake 2020-06-01 07:23:29 -04:00
commit b13f29852f
2 changed files with 51 additions and 44 deletions

View File

@ -3862,20 +3862,21 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale
UINT8 lightlevel = 255; UINT8 lightlevel = 255;
extracolormap_t *colormap = NULL; extracolormap_t *colormap = NULL;
UINT8 i; UINT8 i;
SINT8 flip = P_MobjFlip(thing);
INT32 light; INT32 light;
fixed_t scalemul; fixed_t scalemul;
UINT16 alpha; UINT16 alpha;
fixed_t floordiff; fixed_t floordiff;
fixed_t floorz; fixed_t groundz;
fixed_t slopez; fixed_t slopez;
pslope_t *floorslope; pslope_t *groundslope;
floorz = R_GetShadowZ(thing, &floorslope); groundz = R_GetShadowZ(thing, &groundslope);
//if (abs(floorz - gr_viewz) / tz > 4) return; // Prevent stretchy shadows and possible crashes //if (abs(groundz - gr_viewz) / tz > 4) return; // Prevent stretchy shadows and possible crashes
floordiff = abs(thing->z - floorz); floordiff = abs((flip < 0 ? thing->height : 0) + thing->z - groundz);
alpha = floordiff / (4*FRACUNIT) + 75; alpha = floordiff / (4*FRACUNIT) + 75;
if (alpha >= 255) return; if (alpha >= 255) return;
@ -3907,18 +3908,18 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale
shadowVerts[0].z = shadowVerts[1].z = fy - offset; shadowVerts[0].z = shadowVerts[1].z = fy - offset;
shadowVerts[3].z = shadowVerts[2].z = fy + offset; shadowVerts[3].z = shadowVerts[2].z = fy + offset;
if (floorslope) if (groundslope)
{ {
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
slopez = P_GetSlopeZAt(floorslope, FLOAT_TO_FIXED(shadowVerts[i].x), FLOAT_TO_FIXED(shadowVerts[i].z)); slopez = P_GetSlopeZAt(groundslope, FLOAT_TO_FIXED(shadowVerts[i].x), FLOAT_TO_FIXED(shadowVerts[i].z));
shadowVerts[i].y = FIXED_TO_FLOAT(slopez) + 0.05f; shadowVerts[i].y = FIXED_TO_FLOAT(slopez) + flip * 0.05f;
} }
} }
else else
{ {
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
shadowVerts[i].y = FIXED_TO_FLOAT(floorz) + 0.05f; shadowVerts[i].y = FIXED_TO_FLOAT(groundz) + flip * 0.05f;
} }
if (spr->flip) if (spr->flip)
@ -3946,7 +3947,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale
if (thing->subsector->sector->numlights) if (thing->subsector->sector->numlights)
{ {
light = R_GetPlaneLight(thing->subsector->sector, floorz, false); // Always use the light at the top instead of whatever I was doing before light = R_GetPlaneLight(thing->subsector->sector, groundz, false); // Always use the light at the top instead of whatever I was doing before
if (*thing->subsector->sector->lightlist[light].lightlevel > 255) if (*thing->subsector->sector->lightlist[light].lightlevel > 255)
lightlevel = 255; lightlevel = 255;

View File

@ -1096,27 +1096,29 @@ static void R_SplitSprite(vissprite_t *sprite)
// //
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
{ {
fixed_t z, floorz = INT32_MIN; boolean isflipped = thing->eflags & MFE_VERTICALFLIP;
pslope_t *slope, *floorslope = NULL; fixed_t z, groundz = isflipped ? INT32_MAX : INT32_MIN;
pslope_t *slope, *groundslope = NULL;
msecnode_t *node; msecnode_t *node;
sector_t *sector; sector_t *sector;
ffloor_t *rover; ffloor_t *rover;
#define CHECKZ (isflipped ? z > thing->z+thing->height/2 && z < groundz : z < thing->z+thing->height/2 && z > groundz)
for (node = thing->touching_sectorlist; node; node = node->m_sectorlist_next) for (node = thing->touching_sectorlist; node; node = node->m_sectorlist_next)
{ {
sector = node->m_sector; sector = node->m_sector;
slope = sector->heightsec != -1 ? NULL : sector->f_slope; slope = sector->heightsec != -1 ? NULL : (isflipped ? sector->c_slope : sector->f_slope);
if (sector->heightsec != -1) if (sector->heightsec != -1)
z = sectors[sector->heightsec].floorheight; z = isflipped ? sectors[sector->heightsec].ceilingheight : sectors[sector->heightsec].floorheight;
else else
z = P_GetSectorFloorZAt(sector, thing->x, thing->y); z = isflipped ? P_GetSectorCeilingZAt(sector, thing->x, thing->y) : P_GetSectorFloorZAt(sector, thing->x, thing->y);
if (z < thing->z+thing->height/2 && z > floorz) if CHECKZ
{ {
floorz = z; groundz = z;
floorslope = slope; groundslope = slope;
} }
if (sector->ffloors) if (sector->ffloors)
@ -1125,23 +1127,25 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES) || (rover->alpha < 90 && !(rover->flags & FF_SWIMMABLE))) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES) || (rover->alpha < 90 && !(rover->flags & FF_SWIMMABLE)))
continue; continue;
z = P_GetFFloorTopZAt(rover, thing->x, thing->y); z = isflipped ? P_GetFFloorBottomZAt(rover, thing->x, thing->y) : P_GetFFloorTopZAt(rover, thing->x, thing->y);
if (z < thing->z+thing->height/2 && z > floorz) if CHECKZ
{ {
floorz = z; groundz = z;
floorslope = *rover->t_slope; groundslope = isflipped ? *rover->b_slope : *rover->t_slope;
} }
} }
} }
if (thing->floorz > floorz + (!floorslope ? 0 : FixedMul(abs(floorslope->zdelta), thing->radius*3/2))) if (isflipped ? (thing->ceilingz < groundz - (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2)))
: (thing->floorz > groundz + (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2))))
{ {
floorz = thing->floorz; groundz = isflipped ? thing->ceilingz : thing->floorz;
floorslope = NULL; groundslope = NULL;
} }
#if 0 // Unfortunately, this drops CEZ2 down to sub-17 FPS on my i7. #if 0 // Unfortunately, this drops CEZ2 down to sub-17 FPS on my i7.
// Check polyobjects and see if floorz needs to be altered, for rings only because they don't update floorz // 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) if (thing->type == MT_RING)
{ {
INT32 xl, xh, yl, yh, bx, by; INT32 xl, xh, yl, yh, bx, by;
@ -1186,10 +1190,10 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
// We're inside it! Yess... // We're inside it! Yess...
z = po->lines[0]->backsector->ceilingheight; z = po->lines[0]->backsector->ceilingheight;
if (z < thing->z+thing->height/2 && z > floorz) if (z < thing->z+thing->height/2 && z > groundz)
{ {
floorz = z; groundz = z;
floorslope = NULL; groundslope = NULL;
} }
} }
plink = (polymaplink_t *)(plink->link.next); plink = (polymaplink_t *)(plink->link.next);
@ -1199,9 +1203,10 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
#endif #endif
if (shadowslope != NULL) if (shadowslope != NULL)
*shadowslope = floorslope; *shadowslope = groundslope;
return floorz; return groundz;
#undef CHECKZ
} }
static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, fixed_t tx, fixed_t tz) static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, fixed_t tx, fixed_t tz)
@ -1212,14 +1217,15 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
INT32 light = 0; INT32 light = 0;
fixed_t scalemul; UINT8 trans; fixed_t scalemul; UINT8 trans;
fixed_t floordiff; fixed_t floordiff;
fixed_t floorz; fixed_t groundz;
pslope_t *floorslope; pslope_t *groundslope;
boolean isflipped = thing->eflags & MFE_VERTICALFLIP;
floorz = R_GetShadowZ(thing, &floorslope); groundz = R_GetShadowZ(thing, &groundslope);
if (abs(floorz-viewz)/tz > 4) return; // Prevent stretchy shadows and possible crashes if (abs(groundz-viewz)/tz > 4) return; // Prevent stretchy shadows and possible crashes
floordiff = abs(thing->z - floorz); floordiff = abs((isflipped ? thing->height : 0) + thing->z - groundz);
trans = floordiff / (100*FRACUNIT) + 3; trans = floordiff / (100*FRACUNIT) + 3;
if (trans >= 9) return; if (trans >= 9) return;
@ -1230,23 +1236,23 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
xscale = FixedDiv(projection, tz); xscale = FixedDiv(projection, tz);
yscale = FixedDiv(projectiony, tz); yscale = FixedDiv(projectiony, tz);
shadowxscale = FixedMul(thing->radius*2, scalemul); shadowxscale = FixedMul(thing->radius*2, scalemul);
shadowyscale = FixedMul(FixedMul(thing->radius*2, scalemul), FixedDiv(abs(floorz - viewz), tz)); shadowyscale = FixedMul(FixedMul(thing->radius*2, scalemul), FixedDiv(abs(groundz - viewz), tz));
shadowyscale = min(shadowyscale, shadowxscale) / SHORT(patch->height); shadowyscale = min(shadowyscale, shadowxscale) / SHORT(patch->height);
shadowxscale /= SHORT(patch->width); shadowxscale /= SHORT(patch->width);
shadowskew = 0; shadowskew = 0;
if (floorslope) if (groundslope)
{ {
// haha let's try some dumb stuff // haha let's try some dumb stuff
fixed_t xslope, zslope; fixed_t xslope, zslope;
angle_t sloperelang = (R_PointToAngle(thing->x, thing->y) - floorslope->xydirection) >> ANGLETOFINESHIFT; angle_t sloperelang = (R_PointToAngle(thing->x, thing->y) - groundslope->xydirection) >> ANGLETOFINESHIFT;
xslope = FixedMul(FINESINE(sloperelang), floorslope->zdelta); xslope = FixedMul(FINESINE(sloperelang), groundslope->zdelta);
zslope = FixedMul(FINECOSINE(sloperelang), floorslope->zdelta); zslope = FixedMul(FINECOSINE(sloperelang), groundslope->zdelta);
//CONS_Printf("Shadow is sloped by %d %d\n", xslope, zslope); //CONS_Printf("Shadow is sloped by %d %d\n", xslope, zslope);
if (viewz < floorz) if (viewz < groundz)
shadowyscale += FixedMul(FixedMul(thing->radius*2 / SHORT(patch->height), scalemul), zslope); shadowyscale += FixedMul(FixedMul(thing->radius*2 / SHORT(patch->height), scalemul), zslope);
else else
shadowyscale -= FixedMul(FixedMul(thing->radius*2 / SHORT(patch->height), scalemul), zslope); shadowyscale -= FixedMul(FixedMul(thing->radius*2 / SHORT(patch->height), scalemul), zslope);
@ -1271,7 +1277,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
shadow->heightsec = vis->heightsec; shadow->heightsec = vis->heightsec;
shadow->thingheight = FRACUNIT; shadow->thingheight = FRACUNIT;
shadow->pz = floorz; shadow->pz = groundz + (isflipped ? -shadow->thingheight : 0);
shadow->pzt = shadow->pz + shadow->thingheight; shadow->pzt = shadow->pz + shadow->thingheight;
shadow->mobjflags = 0; shadow->mobjflags = 0;
@ -1279,7 +1285,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
shadow->dispoffset = vis->dispoffset - 5; shadow->dispoffset = vis->dispoffset - 5;
shadow->gx = thing->x; shadow->gx = thing->x;
shadow->gy = thing->y; shadow->gy = thing->y;
shadow->gzt = shadow->pz + SHORT(patch->height) * shadowyscale / 2; shadow->gzt = (isflipped ? shadow->pzt : shadow->pz) + SHORT(patch->height) * shadowyscale / 2;
shadow->gz = shadow->gzt - SHORT(patch->height) * shadowyscale; shadow->gz = shadow->gzt - SHORT(patch->height) * shadowyscale;
shadow->texturemid = FixedMul(thing->scale, FixedDiv(shadow->gzt - viewz, shadowyscale)); shadow->texturemid = FixedMul(thing->scale, FixedDiv(shadow->gzt - viewz, shadowyscale));
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES) if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)