diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index ffe5196d14abc083ed1c184241a077fe88a4929b..f6c5eb77404bbcbf7d5ca80fafea474525e782c0 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -265,44 +265,23 @@ static FUINT HWR_CalcWallLight(FUINT lightnum, fixed_t v1x, fixed_t v1y, fixed_t return (FUINT)finallight; } -static FUINT HWR_CalcSlopeLight(FUINT lightnum, angle_t dir, fixed_t delta) +static FUINT HWR_CalcSlopeLight(FUINT lightnum, pslope_t *slope) { INT16 finallight = lightnum; - if (cv_glfakecontrast.value != 0 && cv_glslopecontrast.value != 0) + if (slope != NULL && cv_glfakecontrast.value != 0 && cv_glslopecontrast.value != 0) { - const UINT8 contrast = 8; fixed_t extralight = 0; if (cv_glfakecontrast.value == 2) // Smooth setting - { - fixed_t dirmul = abs(FixedDiv(AngleFixed(dir) - (180<<FRACBITS), 180<<FRACBITS)); - - extralight = -(contrast<<FRACBITS) + (dirmul * (contrast * 2)); - - extralight = FixedMul(extralight, delta*4) >> FRACBITS; - } + extralight += slope->hwLightOffset; else - { - dir = ((dir + ANGLE_45) / ANGLE_90) * ANGLE_90; - - if (dir == ANGLE_180) - extralight = -contrast; - else if (dir == 0) - extralight = contrast; - - if (delta >= FRACUNIT/2) - extralight *= 2; - } + extralight += slope->lightOffset * 8; if (extralight != 0) { finallight += extralight; - - if (finallight < 0) - finallight = 0; - if (finallight > 255) - finallight = 255; + finallight = min(max(finallight, 0) , 255); } } @@ -499,7 +478,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool SETUP3DVERT(v3d, pv->x, pv->y); if (slope) - lightlevel = HWR_CalcSlopeLight(lightlevel, R_PointToAngle2(0, 0, slope->normal.x, slope->normal.y), abs(slope->zdelta)); + lightlevel = HWR_CalcSlopeLight(lightlevel, slope); HWR_Lighting(&Surf, lightlevel, planecolormap); diff --git a/src/p_slopes.c b/src/p_slopes.c index a78d5c46f75c2eb39323b91da42a666511b242d4..65df1a010ec05070f7d6bd8ab642ecd18cd2b3cb 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -30,12 +30,48 @@ UINT16 slopecount = 0; static void P_UpdateMidtextureSlopesForSector(sector_t *sector); +// Calculate light +static void P_UpdateSlopeLightOffset(pslope_t *slope) +{ + const boolean ceiling = (slope->normal.z < 0); + const UINT8 contrast = 8; + + fixed_t contrastFixed = ((fixed_t)contrast) * FRACUNIT; + fixed_t zMul = FRACUNIT; + angle_t slopeDir = ANGLE_MAX; + fixed_t extralight = 0; + + if (slope->normal.z == 0) + { + slope->lightOffset = slope->hwLightOffset = 0; + return; + } + + slopeDir = R_PointToAngle2(0, 0, abs(slope->normal.y), abs(slope->normal.x)); + if (ceiling == true) + { + slopeDir ^= ANGLE_180; + } + + zMul = min(FRACUNIT, abs(slope->zdelta)*3/2); // *3/2, to make 60 degree slopes match walls. + contrastFixed = FixedMul(contrastFixed, zMul); + extralight = -contrastFixed + FixedMul(FixedDiv(AngleFixed(slopeDir), 90*FRACUNIT), (contrastFixed * 2)); + + // Between -2 and 2 for software, -8 and 8 for hardware + slope->lightOffset = FixedFloor((extralight / 8) + (FRACUNIT / 2)) / FRACUNIT; +#ifdef HWRENDER + slope->hwLightOffset = FixedFloor(extralight + (FRACUNIT / 2)) / FRACUNIT; +#endif +} + // Calculate line normal void P_CalculateSlopeNormal(pslope_t *slope) { slope->normal.z = FINECOSINE(slope->zangle>>ANGLETOFINESHIFT); slope->normal.x = FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.x); slope->normal.y = FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.y); + + P_UpdateSlopeLightOffset(slope); } static void CalculateNormalDir(pslope_t *slope, dvector3_t *dnormal) @@ -121,6 +157,8 @@ static void ReconfigureViaVertexes (pslope_t *slope, const vector3_t v1, const v slope->zangle = InvAngle(R_PointToAngle2(0, 0, FRACUNIT, slope->zdelta)); } + P_UpdateSlopeLightOffset(slope); + P_CalculateSlopeVectors(slope); } diff --git a/src/r_defs.h b/src/r_defs.h index ac479b78d95968827c42354a3807f5889003b73b..73e9e5d382cdca692093e2cc9fbb3984dd3c9caa 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -354,6 +354,11 @@ typedef struct pslope_s boolean moved; UINT8 flags; // Slope options + + SINT8 lightOffset; +#ifdef HWRENDER + INT16 hwLightOffset; +#endif } pslope_t; typedef enum diff --git a/src/r_plane.c b/src/r_plane.c index bfc7614006f91256eb5b026f0a5d163f798b10a7..daa752af589db4e1f78abc1c7e27080aeb097588 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -473,6 +473,12 @@ visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 li offset_x = ((INT64)offset_x * xscale) / FRACUNIT; offset_y = ((INT64)offset_y * yscale) / FRACUNIT; + + if (slope != NULL) + { + lightlevel += (slope->lightOffset / 8); + } + // This appears to fix the Nimbus Ruins sky bug. if (picnum == skyflatnum && pfloor) {