diff --git a/src/deh_soc.c b/src/deh_soc.c index adb44c61e..617857609 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -1566,6 +1566,23 @@ void readlevelheader(MYFILE *f, INT32 num) mapheaderinfo[num-1]->mobj_scale = get_number(word2); else if (fastcmp(word, "DEFAULTWAYPOINTRADIUS")) mapheaderinfo[num-1]->default_waypoint_radius = get_number(word2); + else if (fastcmp(word, "LIGHTCONTRAST")) + { + mapheaderinfo[num-1]->light_contrast = (UINT8)i; + } + else if (fastcmp(word, "LIGHTANGLE")) + { + if (fastcmp(word2, "EVEN")) + { + mapheaderinfo[num-1]->use_light_angle = false; + mapheaderinfo[num-1]->light_angle = 0; + } + else + { + mapheaderinfo[num-1]->use_light_angle = true; + mapheaderinfo[num-1]->light_angle = FixedAngle(FloatToFixed(atof(word2))); + } + } // Individual triggers for level flags, for ease of use (and 2.0 compatibility) else if (fastcmp(word, "SCRIPTISFILE")) { diff --git a/src/doomstat.h b/src/doomstat.h index 8c2671c96..4b3f75d13 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -386,6 +386,10 @@ typedef struct fixed_t mobj_scale; ///< Replacement for TOL_ERZ3 fixed_t default_waypoint_radius; ///< 0 is a special value for DEFAULT_WAYPOINT_RADIUS, but scaled with mobjscale + UINT8 light_contrast; ///< Range of wall lighting. 0 is no lighting. + boolean use_light_angle; ///< When false, wall lighting is evenly distributed. When true, wall lighting is directional. + angle_t light_angle; ///< Angle of directional wall lighting. + // Music stuff. UINT32 musinterfadeout; ///< Fade out level music on intermission screen in milliseconds char musintername[7]; ///< Intermission screen music. @@ -666,6 +670,13 @@ extern tic_t racecountdown, exitcountdown; extern fixed_t gravity; extern fixed_t mapobjectscale; +extern struct maplighting +{ + UINT8 contrast; + boolean directional; + angle_t angle; +} maplighting; + //for CTF balancing extern INT16 autobalance; extern INT16 teamscramble; diff --git a/src/g_game.c b/src/g_game.c index 6eae4df17..00d8fee42 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -288,6 +288,8 @@ tic_t racecountdown, exitcountdown; // for racing fixed_t gravity; fixed_t mapobjectscale; +struct maplighting maplighting; + INT16 autobalance; //for CTF team balance INT16 teamscramble; //for CTF team scramble INT16 scrambleplayers[MAXPLAYERS]; //for CTF team scramble diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index c47360f0f..bd0c874ad 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -285,84 +285,31 @@ UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if return surfcolor.s.alpha; } -static FUINT HWR_CalcWallLight(FUINT lightnum, fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y) +static FUINT HWR_CalcWallLight(FUINT lightnum, seg_t *seg) { INT16 finallight = lightnum; - if (cv_glfakecontrast.value != 0) + if (seg != NULL && P_ApplyLightOffsetFine(lightnum)) { - const UINT8 contrast = 8; - fixed_t extralight = 0; + finallight += seg->hwLightOffset; - if (cv_glfakecontrast.value == 2) // Smooth setting - { - extralight = (-(contrast<> FRACBITS; - } - else - { - if (v1y == v2y) - extralight = -contrast; - else if (v1x == v2x) - extralight = contrast; - } - - if (extralight != 0) - { - finallight += extralight; - - if (finallight < 0) - finallight = 0; - if (finallight > 255) - finallight = 255; - } + if (finallight > 255) finallight = 255; + if (finallight < 0) finallight = 0; } 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 && P_ApplyLightOffsetFine(lightnum)) { - const UINT8 contrast = 8; - fixed_t extralight = 0; + finallight += slope->hwLightOffset; - if (cv_glfakecontrast.value == 2) // Smooth setting - { - fixed_t dirmul = abs(FixedDiv(AngleFixed(dir) - (180<> FRACBITS; - } - 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; - } - - if (extralight != 0) - { - finallight += extralight; - - if (finallight < 0) - finallight = 0; - if (finallight > 255) - finallight = 255; - } + if (finallight > 255) finallight = 255; + if (finallight < 0) finallight = 0; } return (FUINT)finallight; @@ -573,9 +520,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)) @@ -894,7 +839,7 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, INT32 solid, i; lightlist_t * list = sector->lightlist; const UINT8 alpha = Surf->PolyColor.s.alpha; - FUINT lightnum = HWR_CalcWallLight(sector->lightlevel, v1x, v1y, v2x, v2y); + FUINT lightnum = sector->lightlevel; extracolormap_t *colormap = NULL; realtop = top = wallVerts[3].y; @@ -918,12 +863,12 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, { if (pfloor && (pfloor->flags & FF_FOG)) { - lightnum = HWR_CalcWallLight(pfloor->master->frontsector->lightlevel, v1x, v1y, v2x, v2y); + lightnum = pfloor->master->frontsector->lightlevel; colormap = pfloor->master->frontsector->extra_colormap; } else { - lightnum = HWR_CalcWallLight(*list[i].lightlevel, v1x, v1y, v2x, v2y); + lightnum = *list[i].lightlevel; colormap = *list[i].extra_colormap; } } @@ -1006,11 +951,11 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, wallVerts[1].y = endbot; if (polyflags & PF_Fog) - HWR_AddTransparentWall(wallVerts, Surf, texnum, polyflags, true, lightnum, colormap); + HWR_AddTransparentWall(wallVerts, Surf, texnum, polyflags, true, HWR_CalcWallLight(lightnum, gl_curline), colormap); else if (polyflags & (PF_Translucent|PF_Additive|PF_Subtractive|PF_Environment)) - HWR_AddTransparentWall(wallVerts, Surf, texnum, polyflags, false, lightnum, colormap); + HWR_AddTransparentWall(wallVerts, Surf, texnum, polyflags, false, HWR_CalcWallLight(lightnum, gl_curline), colormap); else - HWR_ProjectWall(wallVerts, Surf, polyflags, lightnum, colormap); + HWR_ProjectWall(wallVerts, Surf, polyflags, HWR_CalcWallLight(lightnum, gl_curline), colormap); top = bot; endtop = endbot; @@ -1035,11 +980,11 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, wallVerts[1].y = endbot; if (polyflags & PF_Fog) - HWR_AddTransparentWall(wallVerts, Surf, texnum, polyflags, true, lightnum, colormap); + HWR_AddTransparentWall(wallVerts, Surf, texnum, polyflags, true, HWR_CalcWallLight(lightnum, gl_curline), colormap); else if (polyflags & (PF_Translucent|PF_Additive|PF_Subtractive|PF_Environment)) - HWR_AddTransparentWall(wallVerts, Surf, texnum, polyflags, false, lightnum, colormap); + HWR_AddTransparentWall(wallVerts, Surf, texnum, polyflags, false, HWR_CalcWallLight(lightnum, gl_curline), colormap); else - HWR_ProjectWall(wallVerts, Surf, polyflags, lightnum, colormap); + HWR_ProjectWall(wallVerts, Surf, polyflags, HWR_CalcWallLight(lightnum, gl_curline), colormap); } // HWR_DrawSkyWall @@ -1083,7 +1028,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom fixed_t h, l; // 3D sides and 2s middle textures fixed_t hS, lS; - FUINT lightnum = 0; // shut up compiler + FUINT lightnum = 255; // shut up compiler extracolormap_t *colormap; FSurfaceInfo Surf; @@ -1126,7 +1071,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom cliphigh = (float)(texturehpeg + (gl_curline->flength*FRACUNIT)); } - lightnum = HWR_CalcWallLight(gl_frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y); + lightnum = HWR_CalcWallLight(gl_frontsector->lightlevel, gl_curline); colormap = gl_frontsector->extra_colormap; if (gl_frontsector) @@ -1801,7 +1746,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom blendmode = PF_Fog|PF_NoTexture; - lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y); + lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, gl_curline); colormap = rover->master->frontsector->extra_colormap; Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap); @@ -1927,7 +1872,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom blendmode = PF_Fog|PF_NoTexture; - lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y); + lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, gl_curline); colormap = rover->master->frontsector->extra_colormap; Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap); @@ -2384,9 +2329,9 @@ static void HWR_AddLine(seg_t * line) // PrBoom: use REAL clipping math YAYYYYYYY!!! if (!gld_clipper_SafeCheckRange(angle2, angle1)) - { + { return; - } + } checkforemptylines = true; #else @@ -2474,11 +2419,11 @@ static void HWR_AddLine(seg_t * line) #ifdef NEWCLIP if (!line->backsector) - { + { gld_clipper_SafeAddClipRange(angle2, angle1); - } - else - { + } + else + { boolean bothceilingssky = false, bothfloorssky = false; gl_backsector = R_FakeFlat(gl_backsector, &tempsec, NULL, NULL, true); @@ -2511,7 +2456,7 @@ static void HWR_AddLine(seg_t * line) // and no middle texture. if (checkforemptylines && R_IsEmptyLine(line, gl_frontsector, gl_backsector)) return; - } + } HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D return; @@ -6574,7 +6519,6 @@ static CV_PossibleValue_t glshaders_cons_t[] = {{HWD_SHADEROPTION_OFF, "Off"}, { #ifdef BAD_MODEL_OPTIONS static CV_PossibleValue_t glmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}}; #endif -static CV_PossibleValue_t glfakecontrast_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Smooth"}, {0, NULL}}; static CV_PossibleValue_t glshearing_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Third-person"}, {0, NULL}}; static void CV_glfiltermode_OnChange(void); @@ -6609,8 +6553,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_glfakecontrast = CVAR_INIT ("gr_fakecontrast", "Smooth", CV_SAVE, glfakecontrast_cons_t, 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); @@ -6652,7 +6594,6 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_glskydome); CV_RegisterVar(&cv_glspritebillboarding); - CV_RegisterVar(&cv_glfakecontrast); 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 33101edb2..de42152c6 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -113,8 +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_glfakecontrast; -extern consvar_t cv_glslopecontrast; extern consvar_t cv_glbatching; diff --git a/src/m_menu.c b/src/m_menu.c index a19504864..dc753db68 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1309,16 +1309,15 @@ static menuitem_t OP_VideoModeMenu[] = #ifdef HWRENDER static menuitem_t OP_OpenGLOptionsMenu[] = { - {IT_STRING | IT_CVAR, NULL, "3D Models", {.cvar = &cv_glmodels}, 10}, + {IT_STRING | IT_CVAR, NULL, "3D Models", {.cvar = &cv_glmodels}, 10}, {IT_STRING|IT_CVAR, NULL, "Shaders", {.cvar = &cv_glshaders}, 20}, {IT_STRING|IT_CVAR, NULL, "Texture Quality", {.cvar = &cv_scr_depth}, 40}, - {IT_STRING|IT_CVAR, NULL, "Texture Filter", {.cvar = &cv_glfiltermode}, 50}, + {IT_STRING|IT_CVAR, NULL, "Texture Filter", {.cvar = &cv_glfiltermode}, 50}, {IT_STRING|IT_CVAR, NULL, "Anisotropic", {.cvar = &cv_glanisotropicmode}, 60}, - {IT_STRING|IT_CVAR, NULL, "Wall Contrast Style", {.cvar = &cv_glfakecontrast}, 80}, - {IT_STRING|IT_CVAR, NULL, "Sprite Billboarding", {.cvar = &cv_glspritebillboarding}, 90}, - {IT_STRING|IT_CVAR, NULL, "Software Perspective", {.cvar = &cv_glshearing}, 100}, + {IT_STRING|IT_CVAR, NULL, "Sprite Billboarding", {.cvar = &cv_glspritebillboarding}, 80}, + {IT_STRING|IT_CVAR, NULL, "Software Perspective", {.cvar = &cv_glshearing}, 90}, }; #endif diff --git a/src/p_saveg.c b/src/p_saveg.c index 5d1a49835..b2e3d8ca0 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3137,6 +3137,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 2f23d6c1f..a47077ba5 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -413,6 +413,9 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) mapheaderinfo[num]->menuflags = 0; mapheaderinfo[num]->mobj_scale = FRACUNIT; mapheaderinfo[num]->default_waypoint_radius = 0; + mapheaderinfo[num]->light_contrast = 16; + mapheaderinfo[num]->use_light_angle = false; + mapheaderinfo[num]->light_angle = 0; #if 1 // equivalent to "FlickyList = DEMO" P_SetDemoFlickies(num); #else // equivalent to "FlickyList = NONE" @@ -2322,13 +2325,25 @@ static inline float P_SegLengthFloat(seg_t *seg) */ void P_UpdateSegLightOffset(seg_t *li) { - const UINT8 contrast = 16; + const UINT8 contrast = maplighting.contrast; + const fixed_t contrastFixed = ((fixed_t)contrast) * FRACUNIT; + fixed_t light = FRACUNIT; fixed_t extralight = 0; - extralight = -((fixed_t)contrast*FRACUNIT) + - FixedDiv(AngleFixed(R_PointToAngle2(0, 0, - abs(li->v1->x - li->v2->x), - abs(li->v1->y - li->v2->y))), 90*FRACUNIT) * ((fixed_t)contrast * 2); + if (maplighting.directional == true) + { + angle_t liAngle = R_PointToAngle2(0, 0, (li->v1->x - li->v2->x), (li->v1->y - li->v2->y)) - ANGLE_90; + + light = FixedMul(FINECOSINE(liAngle >> ANGLETOFINESHIFT), FINECOSINE(maplighting.angle >> ANGLETOFINESHIFT)) + + FixedMul(FINESINE(liAngle >> ANGLETOFINESHIFT), FINESINE(maplighting.angle >> ANGLETOFINESHIFT)); + light = (light + FRACUNIT) / 2; + } + else + { + light = FixedDiv(R_PointToAngle2(0, 0, abs(li->v1->x - li->v2->x), abs(li->v1->y - li->v2->y)), ANGLE_90); + } + + extralight = -contrastFixed + FixedMul(light, contrastFixed * 2); // Between -2 and 2 for software, -16 and 16 for hardware li->lightOffset = FixedFloor((extralight / 8) + (FRACUNIT / 2)) / FRACUNIT; @@ -2337,6 +2352,20 @@ void P_UpdateSegLightOffset(seg_t *li) #endif } +boolean P_ApplyLightOffset(UINT8 baselightnum) +{ + // Don't apply light offsets at full bright or full dark. + // Is in steps of light num . + return (baselightnum < LIGHTLEVELS-1 && baselightnum > 0); +} + +boolean P_ApplyLightOffsetFine(UINT8 baselightlevel) +{ + // Don't apply light offsets at full bright or full dark. + // Uses exact light levels for more smoothness. + return (baselightlevel < 255 && baselightlevel > 0); +} + static void P_InitializeSeg(seg_t *seg) { if (seg->linedef) diff --git a/src/p_setup.h b/src/p_setup.h index 548d9e7c0..7a8a8c18f 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -113,6 +113,8 @@ 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_ApplyLightOffset(UINT8 baselightnum); +boolean P_ApplyLightOffsetFine(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 f8846f531..20652a08a 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -31,11 +31,74 @@ UINT16 slopecount = 0; static void P_BuildSlopeAnchorList (void); static void P_SetupAnchoredSlopes (void); +// Calculate light +void P_UpdateSlopeLightOffset(pslope_t *slope) +{ + const UINT8 contrast = maplighting.contrast; + + fixed_t contrastFixed = ((fixed_t)contrast) * FRACUNIT; + fixed_t zMul = FRACUNIT; + fixed_t light = FRACUNIT; + fixed_t extralight = 0; + + if (slope->normal.z == 0) + { + slope->lightOffset = slope->hwLightOffset = 0; + return; + } + + if (maplighting.directional == true) + { + fixed_t nX = -slope->normal.x; + fixed_t nY = -slope->normal.y; + fixed_t nLen = FixedHypot(nX, nY); + + if (nLen == 0) + { + slope->lightOffset = slope->hwLightOffset = 0; + return; + } + + nX = FixedDiv(nX, nLen); + nY = FixedDiv(nY, nLen); + + /* + if (slope is ceiling) + { + // There is no good way to calculate this condition here. + // We reverse it in R_FindPlane now. + nX = -nX; + nY = -nY; + } + */ + + light = FixedMul(nX, FINECOSINE(maplighting.angle >> ANGLETOFINESHIFT)) + + FixedMul(nY, FINESINE(maplighting.angle >> ANGLETOFINESHIFT)); + light = (light + FRACUNIT) / 2; + } + else + { + light = FixedDiv(R_PointToAngle2(0, 0, abs(slope->d.x), abs(slope->d.y)), ANGLE_90); + } + + zMul = min(FRACUNIT, abs(slope->zdelta)*3/2); // *3/2, to make 60 degree slopes match walls. + contrastFixed = FixedMul(contrastFixed, zMul); + + extralight = -contrastFixed + FixedMul(light, contrastFixed * 2); + + // Between -2 and 2 for software, -16 and 16 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); } // Calculate slope's high & low z @@ -128,8 +191,10 @@ void P_ReconfigureViaVertexes (pslope_t *slope, const vector3_t v1, const vector // 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)); + slope->zangle = R_PointToAngle2(0, 0, FRACUNIT, -slope->zdelta); } + + P_UpdateSlopeLightOffset(slope); } /// Setup slope via constants. @@ -159,7 +224,9 @@ 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)); + slope->zangle = R_PointToAngle2(0, 0, FRACUNIT, -slope->zdelta); + + P_UpdateSlopeLightOffset(slope); } /// Recalculate dynamic slopes. @@ -544,6 +611,7 @@ static void line_SpawnViaMapthingVertexes(const int linenum, const boolean spawn UINT16 tag2 = line->args[2]; UINT16 tag3 = line->args[3]; UINT8 flags = 0; // Slope flags + if (line->args[4] & TMSL_NOPHYSICS) flags |= SL_NOPHYSICS; if (line->args[4] & TMSL_DYNAMIC) diff --git a/src/p_slopes.h b/src/p_slopes.h index 27f2ec27b..a72ca1776 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/p_spec.c b/src/p_spec.c index 56e7ae455..53d3b5370 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5884,6 +5884,11 @@ void P_InitSpecials(void) // Set the default gravity. Custom gravity overrides this setting. gravity = mapheaderinfo[gamemap-1]->gravity; + // Set map lighting settings. + maplighting.contrast = mapheaderinfo[gamemap-1]->light_contrast; + maplighting.directional = mapheaderinfo[gamemap-1]->use_light_angle; + maplighting.angle = mapheaderinfo[gamemap-1]->light_angle; + // Defaults in case levels don't have them set. sstimer = mapheaderinfo[gamemap-1]->sstimer*TICRATE + 6; ssspheres = mapheaderinfo[gamemap-1]->ssspheres; diff --git a/src/r_bsp.c b/src/r_bsp.c index 7c198af1f..7253fa930 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,16 +934,18 @@ 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)) { - floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel, - frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL, NULL, frontsector->f_slope, - R_NoEncore(frontsector, false), R_IsRipplePlane(frontsector, NULL, false)); + floorplane = R_FindPlane( + frontsector->floorheight, frontsector->floorpic, floorlightlevel, + frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, + floorcolormap, NULL, NULL, frontsector->f_slope, + R_NoEncore(frontsector, false), + R_IsRipplePlane(frontsector, NULL, false), + false + ); } else floorplane = NULL; @@ -986,10 +954,14 @@ static void R_Subsector(size_t num) || frontsector->ceilingpic == skyflatnum || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].floorpic == skyflatnum)) { - ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic, - ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle, + ceilingplane = R_FindPlane( + frontsector->ceilingheight, frontsector->ceilingpic, ceilinglightlevel, + frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle, ceilingcolormap, NULL, NULL, frontsector->c_slope, - R_NoEncore(frontsector, true), R_IsRipplePlane(frontsector, NULL, true)); + R_NoEncore(frontsector, true), + R_IsRipplePlane(frontsector, NULL, true), + true + ); } else ceilingplane = NULL; @@ -1027,19 +999,17 @@ 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, + ffloor[numffloors].plane = R_FindPlane( + *rover->bottomheight, *rover->bottompic, + *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)); + R_IsRipplePlane(rover->master->frontsector, rover, true), + true + ); ffloor[numffloors].slope = *rover->b_slope; @@ -1064,18 +1034,16 @@ 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, + 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, R_NoEncore(rover->master->frontsector, false), - R_IsRipplePlane(rover->master->frontsector, rover, false)); + R_IsRipplePlane(rover->master->frontsector, rover, false), + false + ); ffloor[numffloors].slope = *rover->t_slope; @@ -1114,19 +1082,18 @@ 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, + 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, (light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po, NULL, // will ffloors be slopable eventually? - R_NoEncore(polysec, false), false);/* TODO: wet polyobjects? */ + R_NoEncore(polysec, false), + false, /* TODO: wet polyobjects? */ + true + ); ffloor[numffloors].height = polysec->floorheight; ffloor[numffloors].polyobj = po; @@ -1145,18 +1112,17 @@ 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, + 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, NULL, // will ffloors be slopable eventually? - R_NoEncore(polysec, true), false);/* TODO: wet polyobjects? */ + R_NoEncore(polysec, true), + false, /* TODO: wet polyobjects? */ + false + ); ffloor[numffloors].polyobj = po; ffloor[numffloors].height = polysec->ceilingheight; diff --git a/src/r_defs.h b/src/r_defs.h index 93353a775..8be91fc9b 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -251,6 +251,12 @@ typedef struct pslope_s // SRB2Kart: For P_VeryTopOfFOF & P_VeryBottomOfFOF fixed_t lowz; fixed_t highz; + + // Light offsets (see seg_t) + SINT8 lightOffset; +#ifdef HWRENDER + INT16 hwLightOffset; +#endif } pslope_t; typedef enum diff --git a/src/r_plane.c b/src/r_plane.c index 0a4e8ef0d..4018ed49b 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -349,7 +349,7 @@ static visplane_t *new_visplane(unsigned hash) visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap, ffloor_t *pfloor, polyobj_t *polyobj, pslope_t *slope, boolean noencore, - boolean ripple) + boolean ripple, boolean reverseLight) { visplane_t *check; unsigned hash; @@ -386,6 +386,18 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, } } + if (slope != NULL && P_ApplyLightOffset(lightlevel >> LIGHTSEGSHIFT)) + { + if (reverseLight) + { + lightlevel -= slope->lightOffset * 8; + } + else + { + lightlevel += slope->lightOffset * 8; + } + } + // This appears to fix the Nimbus Ruins sky bug. if (picnum == skyflatnum && pfloor) { diff --git a/src/r_plane.h b/src/r_plane.h index 81757f515..61bac1968 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -84,7 +84,7 @@ void R_ClearFFloorClips (void); void R_DrawPlanes(void); visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap, ffloor_t *ffloor, polyobj_t *polyobj, pslope_t *slope, boolean noencore, - boolean ripple); + boolean ripple, boolean reverseLight); visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop); void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop); void R_PlaneBounds(visplane_t *plane); diff --git a/src/r_segs.c b/src/r_segs.c index 14310b368..d8d9adfd5 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 + 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 + 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 + 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 + 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 + else if (P_ApplyLightOffset(lightnum)) lightnum += curline->lightOffset; if (lightnum < 0) @@ -2436,7 +2436,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) // OPTIMIZE: get rid of LIGHTSEGSHIFT globally lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); - lightnum += curline->lightOffset; + if (P_ApplyLightOffset(lightnum)) + lightnum += curline->lightOffset; if (lightnum < 0) walllights = scalelight[0];