diff --git a/src/g_level.cpp b/src/g_level.cpp index a5dc609ec..191d2d7a3 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -127,7 +127,7 @@ CUSTOM_CVAR(Int, gl_lightmode, 3, CVAR_ARCHIVE | CVAR_NOINITCALL) else if (newself > 4) newself = 8; else if (newself < 0) newself = 0; if (self != newself) self = newself; - else if ((level.info == nullptr || level.info->lightmode == -1)) level.lightmode = self; + else if ((level.info == nullptr || level.info->lightmode == ELightMode::NotSet)) level.lightmode = (ELightMode)*self; } @@ -1523,7 +1523,7 @@ void G_InitLevelLocals () level.DefaultEnvironment = info->DefaultEnvironment; - level.lightmode = info->lightmode < 0? gl_lightmode : info->lightmode; + level.lightmode = info->lightmode == ELightMode::NotSet? (ELightMode)*gl_lightmode : info->lightmode; level.brightfog = info->brightfog < 0? gl_brightfog : !!info->brightfog; level.lightadditivesurfaces = info->lightadditivesurfaces < 0 ? gl_lightadditivesurfaces : !!info->lightadditivesurfaces; level.notexturefill = info->notexturefill < 0 ? gl_notexturefill : !!info->notexturefill; diff --git a/src/g_level.h b/src/g_level.h index a98a8d415..f512287d3 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -314,6 +314,19 @@ struct FExitText } }; +enum class ELightMode : int8_t +{ + NotSet = -1, + LinearStandard = 0, + DoomBright = 1, + Doom = 2, + DoomDark = 3, + DoomLegacy = 4, + ZDoomSoftware = 8, + DoomSoftware = 16 +}; + + struct level_info_t { int levelnum; @@ -395,7 +408,7 @@ struct level_info_t TArray EventHandlers; - int8_t lightmode; + ELightMode lightmode; int8_t brightfog; int8_t lightadditivesurfaces; int8_t notexturefill; diff --git a/src/g_levellocals.h b/src/g_levellocals.h index c39da9250..3eb3e48df 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -47,9 +47,9 @@ struct FLevelLocals { - void Tick (); + void Tick(); void Mark(); - void AddScroller (int secnum); + void AddScroller(int secnum); void SetInterMusic(const char *nextmap); void SetMusicVolume(float v); @@ -87,7 +87,7 @@ struct FLevelLocals TArray gamenodes; node_t *headgamenode; TArray rejectmatrix; - + static const int BODYQUESIZE = 32; TObjPtr bodyque[BODYQUESIZE]; int bodyqueslot; @@ -100,7 +100,7 @@ struct FLevelLocals FDisplacementTable Displacements; FPortalBlockmap PortalBlockmap; TArray linkedPortals; // only the linked portals, this is used to speed up looking for them in P_CollectConnectedGroups. - TArray portalGroups; + TArray portalGroups; TArray linePortalSpans; FSectionContainer sections; @@ -181,7 +181,7 @@ struct FLevelLocals float MusicVolume; // Hardware render stuff that can either be set via CVAR or MAPINFO - int lightmode; + ELightMode lightmode; bool brightfog; bool lightadditivesurfaces; bool notexturefill; @@ -192,7 +192,7 @@ struct FLevelLocals node_t *HeadNode() const { - return nodes.Size() == 0? nullptr : &nodes[nodes.Size() - 1]; + return nodes.Size() == 0 ? nullptr : &nodes[nodes.Size() - 1]; } node_t *HeadGamenode() const { @@ -202,9 +202,24 @@ struct FLevelLocals // Returns true if level is loaded from saved game or is being revisited as a part of a hub bool IsReentering() const { - return savegamerestore + return savegamerestore || (info != nullptr && info->Snapshot.mBuffer != nullptr && info->isValid()); } + + bool isSoftwareLighting() const + { + return lightmode >= ELightMode::ZDoomSoftware; + } + + bool isDarkLightMode() const + { + return !!((int)lightmode & (int)ELightMode::Doom); + } + + void SetFallbackLightMode() + { + lightmode = ELightMode::Doom; + } }; extern FLevelLocals level; diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index d621b231c..e79abf0c8 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -284,7 +284,7 @@ void level_info_t::Reset() PrecacheSounds.Clear(); brightfog = -1; - lightmode = -1; + lightmode = ELightMode::NotSet; notexturefill = -1; lightadditivesurfaces = -1; skyrotatevector = FVector3(0, 0, 1); @@ -1381,9 +1381,9 @@ DEFINE_MAP_OPTION(lightmode, false) parse.ParseAssign(); parse.sc.MustGetNumber(); - if ((parse.sc.Number >= 0 && parse.sc.Number <= 4) || parse.sc.Number == 8) + if ((parse.sc.Number >= 0 && parse.sc.Number <= 4) || parse.sc.Number == 8 || parse.sc.Number == 16) { - info->lightmode = uint8_t(parse.sc.Number); + info->lightmode = ELightMode(parse.sc.Number); } else { diff --git a/src/hwrenderer/scene/hw_renderstate.cpp b/src/hwrenderer/scene/hw_renderstate.cpp index 3ead6232d..721b87fd5 100644 --- a/src/hwrenderer/scene/hw_renderstate.cpp +++ b/src/hwrenderer/scene/hw_renderstate.cpp @@ -127,7 +127,7 @@ void FRenderState::SetFog(int lightlevel, int rellight, bool fullbright, const F } else { - if ((level.lightmode == 2 || (level.lightmode >= 8 && cmap->BlendFactor > 0)) && fogcolor == 0) + if ((level.lightmode == ELightMode::Doom || (level.isSoftwareLighting() && cmap->BlendFactor > 0)) && fogcolor == 0) { float light = (float)hw_CalcLightLevel(lightlevel, rellight, false, cmap->BlendFactor); SetShaderLight(light, lightlevel); @@ -148,7 +148,7 @@ void FRenderState::SetFog(int lightlevel, int rellight, bool fullbright, const F SetFog(fogcolor, fogdensity); // Korshun: fullbright fog like in software renderer. - if (level.lightmode >= 8 && cmap->BlendFactor == 0 && level.brightfog && fogdensity != 0 && fogcolor != 0) + if (level.isSoftwareLighting() && cmap->BlendFactor == 0 && level.brightfog && fogdensity != 0 && fogcolor != 0) { SetSoftLightLevel(255); } diff --git a/src/hwrenderer/scene/hw_renderstate.h b/src/hwrenderer/scene/hw_renderstate.h index e39d25b26..d820c07ec 100644 --- a/src/hwrenderer/scene/hw_renderstate.h +++ b/src/hwrenderer/scene/hw_renderstate.h @@ -326,7 +326,7 @@ public: void SetSoftLightLevel(int llevel, int blendfactor = 0) { - if (level.lightmode >= 8 && blendfactor == 0) mLightParms[3] = llevel / 255.f; + if (level.isSoftwareLighting() && blendfactor == 0) mLightParms[3] = llevel / 255.f; else mLightParms[3] = -1.f; } diff --git a/src/hwrenderer/scene/hw_skyportal.cpp b/src/hwrenderer/scene/hw_skyportal.cpp index 83bd7de57..74edb1266 100644 --- a/src/hwrenderer/scene/hw_skyportal.cpp +++ b/src/hwrenderer/scene/hw_skyportal.cpp @@ -164,10 +164,10 @@ void HWSkyPortal::DrawContents(HWDrawInfo *di, FRenderState &state) auto &vp = di->Viewpoint; // We have no use for Doom lighting special handling here, so disable it for this function. - int oldlightmode = ::level.lightmode; - if (::level.lightmode >= 8) + auto oldlightmode = ::level.lightmode; + if (::level.isSoftwareLighting()) { - ::level.lightmode = 2; + ::level.SetFallbackLightMode(); state.SetSoftLightLevel(-1); } diff --git a/src/hwrenderer/scene/hw_weapon.cpp b/src/hwrenderer/scene/hw_weapon.cpp index 7d0a1f3d1..dec31cc6f 100644 --- a/src/hwrenderer/scene/hw_weapon.cpp +++ b/src/hwrenderer/scene/hw_weapon.cpp @@ -106,8 +106,8 @@ void HWDrawInfo::DrawPSprite(HUDSprite *huds, FRenderState &state) void HWDrawInfo::DrawPlayerSprites(bool hudModelStep, FRenderState &state) { - int oldlightmode = level.lightmode; - if (!hudModelStep && level.lightmode >= 8) level.lightmode = 2; // Software lighting cannot handle 2D content so revert to lightmode 2 for that. + auto oldlightmode = level.lightmode; + if (!hudModelStep && level.isSoftwareLighting()) level.SetFallbackLightMode(); // Software lighting cannot handle 2D content. for (auto &hudsprite : hudsprites) { if ((!!hudsprite.mframe) == hudModelStep) @@ -260,7 +260,7 @@ static WeaponLighting GetWeaponLighting(sector_t *viewsector, const DVector3 &po l.lightlevel = hw_CalcLightLevel(l.lightlevel, getExtraLight(), true, 0); - if (level.lightmode >= 8 || l.lightlevel < 92) + if (level.isSoftwareLighting() || l.lightlevel < 92) { // Korshun: the way based on max possible light level for sector like in software renderer. double min_L = 36.0 / 31.0 - ((l.lightlevel / 255.0) * (63.0 / 31.0)); // Lightlevel in range 0-63 @@ -498,8 +498,8 @@ void HWDrawInfo::PreparePlayerSprites(sector_t * viewsector, area_t in_area) // hack alert! Rather than changing everything in the underlying lighting code let's just temporarily change // light mode here to draw the weapon sprite. - int oldlightmode = level.lightmode; - if (level.lightmode >= 8) level.lightmode = 2; + auto oldlightmode = level.lightmode; + if (level.isSoftwareLighting()) level.SetFallbackLightMode(); for (DPSprite *psp = player->psprites; psp != nullptr && psp->GetID() < PSP_TARGETCENTER; psp = psp->GetNext()) { diff --git a/src/hwrenderer/utility/hw_lighting.cpp b/src/hwrenderer/utility/hw_lighting.cpp index cee925b68..8d7298b9f 100644 --- a/src/hwrenderer/utility/hw_lighting.cpp +++ b/src/hwrenderer/utility/hw_lighting.cpp @@ -88,7 +88,7 @@ int hw_CalcLightLevel(int lightlevel, int rellight, bool weapon, int blendfactor if (lightlevel == 0) return 0; - bool darklightmode = (level.lightmode & 2) || (level.lightmode >= 8 && blendfactor > 0); + bool darklightmode = (level.isDarkLightMode()) || (level.isSoftwareLighting() && blendfactor > 0); if (darklightmode && lightlevel < 192 && !weapon) { @@ -130,7 +130,7 @@ PalEntry hw_CalcLightColor(int light, PalEntry pe, int blendfactor) if (blendfactor == 0) { - if (level.lightmode >= 8) + if (level.isSoftwareLighting()) { return pe; } @@ -174,10 +174,10 @@ float hw_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity, { float density; - int lightmode = level.lightmode; - if (lightmode >= 8 && blendfactor > 0) lightmode = 2; // The blendfactor feature does not work with software-style lighting. + auto lightmode = level.lightmode; + if (level.isSoftwareLighting() && blendfactor > 0) lightmode = ELightMode::Doom; // The blendfactor feature does not work with software-style lighting. - if (lightmode & 4) + if (lightmode == ELightMode::DoomLegacy) { // uses approximations of Legacy's default settings. density = level.fogdensity ? (float)level.fogdensity : 18; @@ -190,9 +190,9 @@ float hw_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity, else if ((fogcolor.d & 0xffffff) == 0) { // case 2: black fog - if ((lightmode < 8 || blendfactor > 0) && !(level.flags3 & LEVEL3_NOLIGHTFADE)) + if ((!level.isSoftwareLighting() || blendfactor > 0) && !(level.flags3 & LEVEL3_NOLIGHTFADE)) { - density = distfogtable[level.lightmode != 0][hw_ClampLight(lightlevel)]; + density = distfogtable[level.lightmode != ELightMode::LinearStandard][hw_ClampLight(lightlevel)]; } else { @@ -250,7 +250,7 @@ bool hw_CheckFog(sector_t *frontsector, sector_t *backsector) else if (level.outsidefogdensity != 0 && APART(level.info->outsidefog) != 0xff && (fogcolor.d & 0xffffff) == (level.info->outsidefog & 0xffffff)) { } - else if (level.fogdensity!=0 || (level.lightmode & 4)) + else if (level.fogdensity!=0 || level.lightmode == ELightMode::DoomLegacy) { // case 3: level has fog density set } @@ -269,7 +269,7 @@ bool hw_CheckFog(sector_t *frontsector, sector_t *backsector) { return false; } - else if (level.fogdensity!=0 || (level.lightmode & 4)) + else if (level.fogdensity!=0 || level.lightmode == ELightMode::DoomLegacy) { // case 3: level has fog density set return false; diff --git a/src/v_2ddrawer.cpp b/src/v_2ddrawer.cpp index 6b4305de9..ed76dbff2 100644 --- a/src/v_2ddrawer.cpp +++ b/src/v_2ddrawer.cpp @@ -430,7 +430,7 @@ void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints, double fadelevel; // The hardware renderer's light modes 0, 1 and 4 use a linear light scale which must be used here as well. Otherwise the automap gets too dark. - if (vid_rendermode != 4 || (level.lightmode >= 2 && level.lightmode != 4)) + if (vid_rendermode != 4 || level.isDarkLightMode() || level.isSoftwareLighting()) { double map = (NUMCOLORMAPS * 2.) - ((lightlevel + 12) * (NUMCOLORMAPS / 128.)); fadelevel = clamp((map - 12) / NUMCOLORMAPS, 0.0, 1.0);