From dc890caef3d525d4b1d8ab37f612dec5fc0c8242 Mon Sep 17 00:00:00 2001 From: Sally Coolatta <tehrealsalt@gmail.com> Date: Tue, 24 May 2022 22:23:04 -0400 Subject: [PATCH] Add slope lighting Makes slopes at a great enough steepness able to match the contrast of walls. COMING SOON: Directional lighting & contrast modifier, as options for map header. --- src/hardware/hw_main.c | 29 ++++----------------- src/hardware/hw_main.h | 1 - src/p_saveg.c | 2 ++ src/p_setup.c | 3 ++- src/p_setup.h | 2 +- src/p_slopes.c | 36 ++++++++++++++++++++++++++ src/p_slopes.h | 1 + src/r_bsp.c | 59 +----------------------------------------- src/r_defs.h | 3 +++ src/r_plane.c | 6 +++++ src/r_segs.c | 12 ++++----- 11 files changed, 63 insertions(+), 91 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index e65233d8e6..8e5c46e39b 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -289,7 +289,7 @@ static FUINT HWR_CalcWallLight(FUINT lightnum, seg_t *seg) { INT16 finallight = lightnum; - if (seg != NULL && P_ApplySegLightOffset(lightnum)) + if (seg != NULL && P_ApplyLightOffset(lightnum)) { finallight += seg->hwLightOffset; } @@ -297,28 +297,13 @@ static FUINT HWR_CalcWallLight(FUINT lightnum, seg_t *seg) 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_glslopecontrast.value != 0) + if (slope != NULL && P_ApplyLightOffset(lightnum)) { - const UINT8 contrast = 8; - fixed_t extralight = 0; - fixed_t dirmul = abs(FixedDiv(AngleFixed(dir) - (180<<FRACBITS), 180<<FRACBITS)); - - extralight = -(contrast<<FRACBITS) + (dirmul * (contrast * 2)); - extralight = FixedMul(extralight, delta*4) >> FRACBITS; - - if (extralight != 0) - { - finallight += extralight; - - if (finallight < 0) - finallight = 0; - if (finallight > 255) - finallight = 255; - } + finallight += slope->lightOffset; } return (FUINT)finallight; @@ -529,9 +514,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool for (i = 0, v3d = planeVerts; i < nrPlaneVerts; i++,v3d++,pv++) 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); if (PolyFlags & (PF_Translucent|PF_Additive|PF_Subtractive|PF_Fog)) @@ -6564,7 +6547,6 @@ consvar_t cv_glmodellighting = CVAR_INIT ("gr_modellighting", "Off", CV_SAVE, CV consvar_t cv_glshearing = CVAR_INIT ("gr_shearing", "Off", CV_SAVE, glshearing_cons_t, NULL); consvar_t cv_glspritebillboarding = CVAR_INIT ("gr_spritebillboarding", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_glskydome = CVAR_INIT ("gr_skydome", "On", CV_SAVE, CV_OnOff, NULL); -consvar_t cv_glslopecontrast = CVAR_INIT ("gr_slopecontrast", "Off", CV_SAVE, CV_OnOff, NULL); consvar_t cv_glfiltermode = CVAR_INIT ("gr_filtermode", "Nearest", CV_SAVE|CV_CALL, glfiltermode_cons_t, CV_glfiltermode_OnChange); consvar_t cv_glanisotropicmode = CVAR_INIT ("gr_anisotropicmode", "1", CV_CALL, glanisotropicmode_cons_t, CV_glanisotropic_OnChange); @@ -6606,7 +6588,6 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_glskydome); CV_RegisterVar(&cv_glspritebillboarding); - CV_RegisterVar(&cv_glslopecontrast); CV_RegisterVar(&cv_glshearing); CV_RegisterVar(&cv_glshaders); CV_RegisterVar(&cv_glallowshaders); diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 2ed91cfb2b..de42152c62 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -113,7 +113,6 @@ extern consvar_t cv_glsolvetjoin; extern consvar_t cv_glshearing; extern consvar_t cv_glspritebillboarding; extern consvar_t cv_glskydome; -extern consvar_t cv_glslopecontrast; extern consvar_t cv_glbatching; diff --git a/src/p_saveg.c b/src/p_saveg.c index e92458710a..69f8fa4e61 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3127,6 +3127,8 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) slope->normal.x = READFIXED(save_p); slope->normal.y = READFIXED(save_p); slope->normal.z = READFIXED(save_p); + + P_UpdateSlopeLightOffset(slope); } if (diff2 & MD2_HITLAG) { diff --git a/src/p_setup.c b/src/p_setup.c index c659e090da..632602a683 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2337,8 +2337,9 @@ void P_UpdateSegLightOffset(seg_t *li) #endif } -boolean P_ApplySegLightOffset(UINT8 baselightlevel) +boolean P_ApplyLightOffset(UINT8 baselightlevel) { + // Don't apply light offsets at full bright or full dark. return (baselightlevel < 255 && baselightlevel > 0); } diff --git a/src/p_setup.h b/src/p_setup.h index b6994054ad..128ddd8dc4 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -113,7 +113,7 @@ void P_LoadSoundsRange(UINT16 wadnum, UINT16 first, UINT16 num); void P_LoadMusicsRange(UINT16 wadnum, UINT16 first, UINT16 num); void P_WriteThings(void); void P_UpdateSegLightOffset(seg_t *li); -boolean P_ApplySegLightOffset(UINT8 baselightlevel); +boolean P_ApplyLightOffset(UINT8 baselightlevel); size_t P_PrecacheLevelFlats(void); void P_AllocMapHeader(INT16 i); diff --git a/src/p_slopes.c b/src/p_slopes.c index f8846f5318..2f4d64be7a 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -31,11 +31,43 @@ UINT16 slopecount = 0; static void P_BuildSlopeAnchorList (void); static void P_SetupAnchoredSlopes (void); +// Calculate light +void P_UpdateSlopeLightOffset(pslope_t *slope) +{ + const boolean ceiling = (slope->normal.z < 0); + const UINT8 contrast = 16; + + fixed_t contrastFixed = (contrast * FRACUNIT); + fixed_t zMul = FRACUNIT; + angle_t slopeDir = ANGLE_MAX; + fixed_t extralight = 0; + + if (slope->normal.z == 0) + { + slope->lightOffset = 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)); + + // -16 and 16 for both software & hardware + slope->lightOffset = FixedFloor(extralight + (FRACUNIT / 2)) / FRACUNIT; +} + // 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); } // Calculate slope's high & low z @@ -130,6 +162,8 @@ void P_ReconfigureViaVertexes (pslope_t *slope, const vector3_t v1, const vector slope->xydirection = R_PointToAngle2(0, 0, slope->d.x, slope->d.y)+ANGLE_180; slope->zangle = InvAngle(R_PointToAngle2(0, 0, FRACUNIT, slope->zdelta)); } + + P_UpdateSlopeLightOffset(slope); } /// Setup slope via constants. @@ -160,6 +194,8 @@ static void ReconfigureViaConstants (pslope_t *slope, const fixed_t a, const fix // Get angles slope->xydirection = R_PointToAngle2(0, 0, slope->d.x, slope->d.y)+ANGLE_180; slope->zangle = InvAngle(R_PointToAngle2(0, 0, FRACUNIT, slope->zdelta)); + + P_UpdateSlopeLightOffset(slope); } /// Recalculate dynamic slopes. diff --git a/src/p_slopes.h b/src/p_slopes.h index 27f2ec27b2..a72ca17767 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -49,6 +49,7 @@ typedef enum void P_LinkSlopeThinkers (void); +void P_UpdateSlopeLightOffset(pslope_t *slope); void P_CalculateSlopeNormal(pslope_t *slope); void P_ReconfigureViaVertexes(pslope_t *slope, const vector3_t v1, const vector3_t v2, const vector3_t v3); void P_InitSlopes(void); diff --git a/src/r_bsp.c b/src/r_bsp.c index 7c198af1fa..a8236be615 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -67,40 +67,6 @@ boolean R_IsRipplePlane(sector_t *sector, ffloor_t *rover, int ceiling) sector->flags & (SF_RIPPLE_FLOOR << ceiling); } -static void R_PlaneLightOverride(sector_t *sector, boolean ceiling, INT32 *lightlevel) -{ - terrain_t *t = NULL; - - if (ceiling == true) - { - t = K_GetTerrainForFlatNum(sector->ceilingpic); - } - else - { - t = K_GetTerrainForFlatNum(sector->floorpic); - } - - if (t != NULL) - { - if (t->flags & TRF_SNEAKERPANEL) - { - *lightlevel = 255; - } - } - else - { - // Sector effect sneaker panels (DEPRECATED) - if (GETSECSPECIAL(sector->special, 4) == 6) - { - if ((ceiling && (sector->flags & SF_FLIPSPECIAL_CEILING)) - || (!ceiling && (sector->flags & SF_FLIPSPECIAL_FLOOR))) - { - *lightlevel = 255; - } - } - } -} - // // R_ClearDrawSegs // @@ -968,9 +934,6 @@ static void R_Subsector(size_t num) sub->sector->extra_colormap = frontsector->extra_colormap; - R_PlaneLightOverride(frontsector, false, &floorlightlevel); - R_PlaneLightOverride(frontsector, true, &ceilinglightlevel); - if (P_GetSectorFloorZAt(frontsector, viewx, viewy) < viewz || frontsector->floorpic == skyflatnum || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum)) @@ -1027,16 +990,11 @@ static void R_Subsector(size_t num) && ((viewz < heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || (viewz > heightcheck && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) { - INT32 newlightlevel; - light = R_GetPlaneLight(frontsector, planecenterz, viewz < heightcheck); - newlightlevel = *frontsector->lightlist[light].lightlevel; - R_PlaneLightOverride(rover->master->frontsector, true, &newlightlevel); - ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic, - newlightlevel, *rover->bottomxoffs, + *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, *rover->bottomyoffs, *rover->bottomangle, *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->b_slope, R_NoEncore(rover->master->frontsector, true), R_IsRipplePlane(rover->master->frontsector, rover, true)); @@ -1064,13 +1022,8 @@ static void R_Subsector(size_t num) && ((viewz > heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || (viewz < heightcheck && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) { - INT32 newlightlevel; - light = R_GetPlaneLight(frontsector, planecenterz, viewz < heightcheck); - newlightlevel = *frontsector->lightlist[light].lightlevel; - R_PlaneLightOverride(rover->master->frontsector, false, &newlightlevel); - ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic, *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle, *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->t_slope, @@ -1114,13 +1067,8 @@ static void R_Subsector(size_t num) && polysec->floorheight >= floorcenterz && (viewz < polysec->floorheight)) { - INT32 newlightlevel; - light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight); - newlightlevel = (light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel); - R_PlaneLightOverride(polysec, false, &newlightlevel); - ffloor[numffloors].plane = R_FindPlane(polysec->floorheight, polysec->floorpic, (light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->floor_xoffs, polysec->floor_yoffs, polysec->floorpic_angle-po->angle, @@ -1145,13 +1093,8 @@ static void R_Subsector(size_t num) && polysec->ceilingheight <= ceilingcenterz && (viewz > polysec->ceilingheight)) { - INT32 newlightlevel; - light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight); - newlightlevel = (light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel); - R_PlaneLightOverride(polysec, true, &newlightlevel); - ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic, (light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->ceiling_xoffs, polysec->ceiling_yoffs, polysec->ceilingpic_angle-po->angle, (light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po, diff --git a/src/r_defs.h b/src/r_defs.h index 93353a7758..c749c3252c 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -251,6 +251,9 @@ typedef struct pslope_s // SRB2Kart: For P_VeryTopOfFOF & P_VeryBottomOfFOF fixed_t lowz; fixed_t highz; + + // Light offsets (see seg_t) + INT16 lightOffset; } pslope_t; typedef enum diff --git a/src/r_plane.c b/src/r_plane.c index 0a4e8ef0d3..7f58a373f0 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -386,6 +386,12 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, } } + if (slope != NULL && P_ApplyLightOffset(lightlevel)) + { + // for software: crunchitize the light level offset, otherwise it's too bright. + lightlevel += (slope->lightOffset / 8) * 8; + } + // This appears to fix the Nimbus Ruins sky bug. if (picnum == skyflatnum && pfloor) { diff --git a/src/r_segs.c b/src/r_segs.c index 2f3099c12a..d8d9adfd59 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -286,7 +286,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) if (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG)) ; - else if (P_ApplySegLightOffset(lightnum)) + else if (P_ApplyLightOffset(lightnum)) lightnum += curline->lightOffset; rlight->lightnum = lightnum; @@ -303,7 +303,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) if ((R_CheckColumnFunc(COLDRAWFUNC_FOG) == true) || (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG))) ; - else if (P_ApplySegLightOffset(lightnum)) + else if (P_ApplyLightOffset(lightnum)) lightnum += curline->lightOffset; if (lightnum < 0) @@ -770,7 +770,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (pfloor->flags & FF_FOG || rlight->flags & FF_FOG || (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG))) ; - else if (P_ApplySegLightOffset(rlight->lightnum)) + else if (P_ApplyLightOffset(rlight->lightnum)) rlight->lightnum += curline->lightOffset; p++; @@ -793,7 +793,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (pfloor->flags & FF_FOG || (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG))) ; - else if (P_ApplySegLightOffset(lightnum)) + else if (P_ApplyLightOffset(lightnum)) lightnum += curline->lightOffset; if (lightnum < 0) @@ -1383,7 +1383,7 @@ static void R_RenderSegLoop (void) if (dc_lightlist[i].extra_colormap) ; - else if (P_ApplySegLightOffset(lightnum)) + else if (P_ApplyLightOffset(lightnum)) lightnum += curline->lightOffset; if (lightnum < 0) @@ -2436,7 +2436,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) // OPTIMIZE: get rid of LIGHTSEGSHIFT globally lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); - if (P_ApplySegLightOffset(lightnum)) + if (P_ApplyLightOffset(lightnum)) lightnum += curline->lightOffset; if (lightnum < 0) -- GitLab