diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 06e02b76b..47f1b4e49 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -2829,17 +2829,18 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) UINT8 lightlevel = 0; extracolormap_t *colormap = NULL; UINT8 i; + SINT8 flip = P_MobjFlip(thing); INT32 light; fixed_t scalemul; UINT16 alpha; fixed_t floordiff; - fixed_t floorz; + fixed_t groundz; fixed_t slopez; - pslope_t *floorslope; + pslope_t *groundslope; - floorz = R_GetShadowZ(thing, &floorslope); - floordiff = abs(thingzpos - floorz); + groundz = R_GetShadowZ(thing, &groundslope); + floordiff = abs((flip < 0 ? thing->height : 0) + thingzpos - groundz); alpha = floordiff / (4*FRACUNIT) + 75; if (alpha >= 255) return; @@ -2860,7 +2861,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) HWR_GetPatch(gpatch); scalemul = FixedMul(FRACUNIT - floordiff/640, scale); - scalemul = FixedMul(scalemul, (thing->radius*2) / gpatch->height); + scalemul = FixedMul(scalemul, (thing->radius*2) / SHORT(gpatch->height)); fscale = FIXED_TO_FLOAT(scalemul); fx = FIXED_TO_FLOAT(thingxpos); @@ -2872,9 +2873,9 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) // 0--1 if (thing && fabsf(fscale - 1.0f) > 1.0E-36f) - offset = (gpatch->height/2) * fscale; + offset = (SHORT(gpatch->height)/2) * fscale; else - offset = (float)(gpatch->height/2); + offset = (float)(SHORT(gpatch->height)/2); shadowVerts[2].x = shadowVerts[3].x = fx + offset; shadowVerts[1].x = shadowVerts[0].x = fx - offset; @@ -2889,18 +2890,18 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) shadowVerts[i].z = fy + ((oldx - fx) * gr_viewsin) + ((oldy - fy) * gr_viewcos); } - if (floorslope) + if (groundslope) { for (i = 0; i < 4; i++) { - slopez = P_GetZAt(floorslope, FLOAT_TO_FIXED(shadowVerts[i].x), FLOAT_TO_FIXED(shadowVerts[i].z)); - shadowVerts[i].y = FIXED_TO_FLOAT(slopez) + 0.05f; + slopez = P_GetZAt(groundslope, FLOAT_TO_FIXED(shadowVerts[i].x), FLOAT_TO_FIXED(shadowVerts[i].z)); + shadowVerts[i].y = FIXED_TO_FLOAT(slopez) + flip * 0.05f; } } else { 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; } shadowVerts[0].s = shadowVerts[3].s = 0; @@ -2911,7 +2912,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) 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].extra_colormap) colormap = thing->subsector->sector->lightlist[light].extra_colormap; diff --git a/src/r_things.c b/src/r_things.c index 708e9e146..e999e55bc 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1157,25 +1157,34 @@ static void R_SplitSprite(vissprite_t *sprite) // fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) { - fixed_t z, floorz = INT32_MIN; - pslope_t *slope, *floorslope = NULL; + boolean isflipped = thing->eflags & MFE_VERTICALFLIP; + fixed_t z, groundz = isflipped ? INT32_MAX : INT32_MIN; + pslope_t *slope, *groundslope = NULL; msecnode_t *node; sector_t *sector; 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) { sector = node->m_sector; - slope = (sector->heightsec != -1) ? NULL : sector->f_slope; - z = slope ? P_GetZAt(slope, thing->x, thing->y) : ( - (sector->heightsec != -1) ? sectors[sector->heightsec].floorheight : sector->floorheight - ); + slope = sector->heightsec != -1 ? NULL : (isflipped ? sector->c_slope : sector->f_slope); - if (z < thing->z+thing->height/2 && z > floorz) + if (sector->heightsec != -1) + z = isflipped ? sectors[sector->heightsec].ceilingheight : sectors[sector->heightsec].floorheight; + else { - floorz = z; - floorslope = slope; + if (isflipped) + z = sector->c_slope ? P_GetZAt(sector->c_slope, thing->x, thing->y) : sector->ceilingheight; // P_GetSectorCeilingZAt + else + z = sector->f_slope ? P_GetZAt(sector->f_slope, thing->x, thing->y) : sector->floorheight; // P_GetSectorFloorZAt + } + + if CHECKZ + { + groundz = z; + groundslope = slope; } if (sector->ffloors) @@ -1184,24 +1193,30 @@ 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))) continue; - z = *rover->t_slope ? P_GetZAt(*rover->t_slope, thing->x, thing->y) : *rover->topheight; - if (z < thing->z+thing->height/2 && z > floorz) + if (isflipped) + z = *rover->b_slope ? P_GetZAt(*rover->b_slope, thing->x, thing->y) : *rover->bottomheight; // P_GetFFloorBottomZAt + else + z = *rover->t_slope ? P_GetZAt(*rover->t_slope, thing->x, thing->y) : *rover->topheight; // P_GetFFloorTopZAt + + if CHECKZ { - floorz = z; - floorslope = *rover->t_slope; + groundz = z; + 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; - floorslope = NULL; + groundz = isflipped ? thing->ceilingz : thing->floorz; + groundslope = NULL; } #if 0 // Unfortunately, this drops CEZ2 down to sub-17 FPS on my i7. //#ifdef POLYOBJECTS - // 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) { INT32 xl, xh, yl, yh, bx, by; @@ -1246,10 +1261,10 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) // We're inside it! Yess... 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; - floorslope = NULL; + groundz = z; + groundslope = NULL; } } plink = (polymaplink_t *)(plink->link.next); @@ -1259,9 +1274,9 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) #endif if (shadowslope != NULL) - *shadowslope = floorslope; + *shadowslope = groundslope; - return floorz; + return groundz; } static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, fixed_t tx, fixed_t tz) @@ -1272,14 +1287,15 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, INT32 light = 0; fixed_t scalemul; UINT8 trans; fixed_t floordiff; - fixed_t floorz; - pslope_t *floorslope; + fixed_t groundz; + 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; if (trans >= 9) return; @@ -1294,41 +1310,41 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, xscale = FixedDiv(projection, tz); yscale = FixedDiv(projectiony, tz); shadowxscale = FixedMul(thing->radius*2, scalemul); - shadowyscale = FixedMul(FixedMul(thing->radius*2, scalemul), FixedDiv(abs(floorz - viewz), tz)); - shadowyscale = min(shadowyscale, shadowxscale) / patch->height; - shadowxscale /= patch->width; + shadowyscale = FixedMul(FixedMul(thing->radius*2, scalemul), FixedDiv(abs(groundz - viewz), tz)); + shadowyscale = min(shadowyscale, shadowxscale) / SHORT(patch->height); + shadowxscale /= SHORT(patch->width); shadowskew = 0; - if (floorslope) + if (groundslope) { // haha let's try some dumb stuff 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); - zslope = FixedMul(FINECOSINE(sloperelang), floorslope->zdelta); + xslope = FixedMul(FINESINE(sloperelang), groundslope->zdelta); + zslope = FixedMul(FINECOSINE(sloperelang), groundslope->zdelta); //CONS_Printf("Shadow is sloped by %d %d\n", xslope, zslope); - if (viewz < floorz) - shadowyscale += FixedMul(FixedMul(thing->radius*2 / patch->height, scalemul), zslope); + if (viewz < groundz) + shadowyscale += FixedMul(FixedMul(thing->radius*2 / SHORT(patch->height), scalemul), zslope); else - shadowyscale -= FixedMul(FixedMul(thing->radius*2 / patch->height, scalemul), zslope); + shadowyscale -= FixedMul(FixedMul(thing->radius*2 / SHORT(patch->height), scalemul), zslope); shadowyscale = abs(shadowyscale); shadowskew = xslope; } - tx -= patch->width * shadowxscale/2; + tx -= SHORT(patch->width) * shadowxscale/2; x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; if (x1 >= viewwidth) return; - tx += patch->width * shadowxscale; + tx += SHORT(patch->width) * shadowxscale; x2 = ((centerxfrac + FixedMul(tx,xscale))>>FRACBITS); x2--; if (x2 < 0 || x2 <= x1) return; - if (shadowyscale < FRACUNIT/patch->height) return; // fix some crashes? + if (shadowyscale < FRACUNIT/SHORT(patch->height)) return; // fix some crashes? shadow = R_NewVisSprite(); @@ -1340,7 +1356,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, shadow->heightsec = vis->heightsec; shadow->thingheight = FRACUNIT; - shadow->pz = floorz; + shadow->pz = groundz + (isflipped ? -shadow->thingheight : 0); shadow->pzt = shadow->pz + shadow->thingheight; shadow->mobjflags = 0; @@ -1348,8 +1364,8 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, shadow->dispoffset = vis->dispoffset - 5; shadow->gx = thing->x; shadow->gy = thing->y; - shadow->gzt = shadow->pz + patch->height * shadowyscale / 2; - shadow->gz = shadow->gzt - patch->height * shadowyscale; + shadow->gzt = (isflipped ? shadow->pzt : shadow->pz) + SHORT(patch->height) * shadowyscale / 2; + shadow->gz = shadow->gzt - SHORT(patch->height) * shadowyscale; shadow->texturemid = FixedMul(thing->scale, FixedDiv(shadow->gzt - viewz, shadowyscale)); if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES) shadow->texturemid = FixedMul(shadow->texturemid, ((skin_t *)thing->skin)->highresscale); @@ -1379,7 +1395,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, shadow->startfrac = 0; //shadow->xiscale = 0x7ffffff0 / (shadow->xscale/2); - shadow->xiscale = (patch->width<xiscale = (SHORT(patch->width)<x1 > x1) shadow->startfrac += shadow->xiscale*(shadow->x1-x1);