diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b4c0792d..48892e944 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -318,7 +318,7 @@ else() if( APPLE ) - set(CMAKE_OSX_DEPLOYMENT_TARGET "10.12") + set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13") if( CMAKE_CXX_COMPILER_ID STREQUAL "GNU" ) # If we're compiling with a custom GCC on the Mac (which we know since g++-4.2 doesn't support C++11) statically link libgcc. set( ALL_C_FLAGS "-static-libgcc" ) diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index 6057c328d..adcfd1239 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -233,6 +233,12 @@ Note: All fields default to false unless mentioned otherwise. lm_sampledist_top = ; // ZDRay customizable sampling distance for this sidedef's top part. Defines the map units each lightmap texel covers. Must be in powers of two. Default = 0 lm_sampledist_mid = ; // ZDRay customizable sampling distance for this sidedef's middle part. Defines the map units each lightmap texel covers. Must be in powers of two. Default = 0 lm_sampledist_bot = ; // ZDRay customizable sampling distance for this sidedef's bottom part. Defines the map units each lightmap texel covers. Must be in powers of two. Default = 0 + + skew_top = ; // enables skewing of wall textures, the skewing angle will be aligned to one of the 4 planes touching the floor. + skew_middle = ; // Vertical texture alignment defines the position at the leftmost point of the wall. + skew_bottom = ; // Possible values: 0 = no skewing, 1 = align to front floor, 2 = align to front ceiling, 3 = align to back floor, 4 = align to back ceiling. + // Front/Back are relative to the sidedef, not the owning linedef. Default = 0. + } sector @@ -542,6 +548,9 @@ Added/updated ZDRay/lightmap-related properties. 1.35 15.09.2023 fixed omissions: Blocklandmonsters and Blockfloaters line flags. +1.36 20.10.2023 +Sidedef skewing properties + =============================================================================== EOF =============================================================================== diff --git a/src/common/engine/serializer.cpp b/src/common/engine/serializer.cpp index 34fd6956b..7fbf7adc6 100644 --- a/src/common/engine/serializer.cpp +++ b/src/common/engine/serializer.cpp @@ -1,4 +1,5 @@ /* +/* ** serializer.cpp ** Savegame wrapper around RapidJSON ** diff --git a/src/common/models/modelrenderer.h b/src/common/models/modelrenderer.h index 18c49f641..d921e7100 100644 --- a/src/common/models/modelrenderer.h +++ b/src/common/models/modelrenderer.h @@ -17,8 +17,8 @@ public: virtual VSMatrix GetViewToWorldMatrix() = 0; - virtual void BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored) = 0; - virtual void EndDrawHUDModel(FRenderStyle style) = 0; + virtual void BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored, FSpriteModelFrame *smf) = 0; + virtual void EndDrawHUDModel(FRenderStyle style, FSpriteModelFrame *smf) = 0; virtual void SetInterpolation(double interpolation) = 0; virtual void SetMaterial(FGameTexture *skin, bool clampNoFilter, int translation) = 0; diff --git a/src/g_game.cpp b/src/g_game.cpp index 8a20b76a5..3f30a5788 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1892,9 +1892,9 @@ bool G_CheckSaveGameWads (FSerializer &arc, bool printwarn) bool printRequires = false; FString text; - arc("Game WAD", text); + text = arc.GetString("Game WAD"); CheckSingleWad (text.GetChars(), printRequires, printwarn); - arc("Map WAD", text); + text = arc.GetString("Map WAD"); CheckSingleWad (text.GetChars(), printRequires, printwarn); if (printRequires) diff --git a/src/gamedata/r_defs.h b/src/gamedata/r_defs.h index f164a92a4..0009c1662 100644 --- a/src/gamedata/r_defs.h +++ b/src/gamedata/r_defs.h @@ -1201,6 +1201,15 @@ struct side_t walltop = 0, wallbottom = 1, }; + enum ESkew + { + skew_none = 0, + skew_front_floor = 1, + skew_front_ceiling = 2, + skew_back_floor = 3, + skew_back_ceiling = 4 + }; + struct part { enum EPartFlags @@ -1216,7 +1225,8 @@ struct side_t double xScale; double yScale; TObjPtr interpolation; - int flags; + int16_t flags; + int8_t skew; FTextureID texture; TextureManipulation TextureFx; PalEntry SpecialColors[2]; diff --git a/src/gamedata/umapinfo.cpp b/src/gamedata/umapinfo.cpp index bb442f78d..08e16d9f8 100644 --- a/src/gamedata/umapinfo.cpp +++ b/src/gamedata/umapinfo.cpp @@ -443,11 +443,13 @@ void CommitUMapinfo(level_info_t *defaultinfo) if (map.partime > 0) levelinfo->partime = map.partime; if (map.enterpic[0]) levelinfo->EnterPic = map.enterpic; if (map.exitpic[0]) levelinfo->ExitPic = map.exitpic; + /* UMAPINFO's intermusic is for the text screen, not the summary. if (map.intermusic[0]) { levelinfo->InterMusic = map.intermusic; levelinfo->intermusicorder = 0; } + */ if (map.BossActions.Size() > 0 || map.BossCleared) { // Setting a boss action will deactivate the flag based monster actions. diff --git a/src/gamedata/xlat/xlat.h b/src/gamedata/xlat/xlat.h index f488704ff..516104af1 100644 --- a/src/gamedata/xlat/xlat.h +++ b/src/gamedata/xlat/xlat.h @@ -82,7 +82,7 @@ struct FBoomTranslator { uint16_t FirstLinetype = 0; uint16_t LastLinetype = 0; - uint8_t NewSpecial = 0; + uint16_t NewSpecial = 0; TArray Args; } ; diff --git a/src/maploader/udmf.cpp b/src/maploader/udmf.cpp index bb26f4dce..61416df38 100644 --- a/src/maploader/udmf.cpp +++ b/src/maploader/udmf.cpp @@ -104,6 +104,26 @@ static char HexenSectorSpecialOk[256]={ 1,1,1,1,1, }; +#if 0 +static const char* udmfsolidskewtypes[] = +{ + "none", + "front", + "back", + nullptr +}; + +static const char* udmfmaskedskewtypes[] = +{ + "none", + "front_floor", + "front_ceiling", + "back_floor", + "back_ceiling", + nullptr +}; +#endif + static inline bool P_IsThingSpecial(int specnum) { return (specnum >= Thing_Projectile && specnum <= Thing_SpawnNoFog) || @@ -282,6 +302,20 @@ const char *UDMFParserBase::CheckString(FName key) return parsedString.GetChars(); } +int UDMFParserBase::MatchString(FName key, const char* const* strings, int defval) +{ + const char* string = CheckString(key); + for (int i = 0; *strings != nullptr; i++, strings++) + { + if (!stricmp(string, *strings)) + { + return i; + } + } + sc.ScriptMessage("Unknown value %s for key '%s'", string, key.GetChars()); + return defval; +} + //=========================================================================== // // Storage of UDMF user properties @@ -1537,6 +1571,38 @@ public: sd->textures[side_t::bottom].LightmapSampleDistance = CheckInt(key); break; +#if 0 // specs are to rough and too vague - needs to be cleared first how this works. + case NAME_skew_top_type: + CHECK_N(Zd | Zdt) + sd->textures[side_t::top].skew = MatchString(key, udmfsolidskewtypes, 0); + break; + + case NAME_skew_middle_type: + CHECK_N(Zd | Zdt) + sd->textures[side_t::mid].skew = MatchString(key, udmfmaskedskewtypes, 0); + break; + + case NAME_skew_bottom_type: + CHECK_N(Zd | Zdt) + sd->textures[side_t::bottom].skew = MatchString(key, udmfsolidskewtypes, 0); + break; +#endif + + case NAME_skew_top: + CHECK_N(Zd | Zdt) + sd->textures[side_t::top].skew = CheckInt(key); + break; + + case NAME_skew_middle: + CHECK_N(Zd | Zdt) + sd->textures[side_t::mid].skew = CheckInt(key); + break; + + case NAME_skew_bottom: + CHECK_N(Zd | Zdt) + sd->textures[side_t::bottom].skew = CheckInt(key); + break; + default: if (strnicmp("user_", key.GetChars(), 5)) DPrintf(DMSG_WARNING, "Unknown UDMF sidedef key %s\n", key.GetChars()); @@ -2262,6 +2328,19 @@ public: sides[side].sector = &Level->sectors[intptr_t(sides[side].sector)]; lines[line].sidedef[sd] = &sides[side]; +#if 0 + if (sd == 1) + { + // fix flags for backside. The definition is linedef relative, not sidedef relative. + static const uint8_t swaps[] = { 0, side_t::skew_back, side_t::skew_front }; + static const uint8_t swapsm[] = {0, side_t::skew_back_floor, side_t::skew_back_ceiling, side_t::skew_front_floor, side_t::skew_front_ceiling}; + + sides[side].textures[side_t::top].skew = swaps[sides[side].textures[side_t::top].skew]; + sides[side].textures[side_t::bottom].skew = swaps[sides[side].textures[side_t::bottom].skew]; + sides[side].textures[side_t::mid].skew = swapsm[sides[side].textures[side_t::mid].skew]; + } +#endif + loader->ProcessSideTextures(!isExtended, &sides[side], sides[side].sector, &ParsedSideTextures[mapside], lines[line].special, lines[line].args[0], &tempalpha[sd], missingTex); diff --git a/src/maploader/udmf.h b/src/maploader/udmf.h index ed18345b5..38d904288 100644 --- a/src/maploader/udmf.h +++ b/src/maploader/udmf.h @@ -21,6 +21,7 @@ protected: DAngle CheckAngle(FName key); bool CheckBool(FName key); const char *CheckString(FName key); + int MatchString(FName key, const char* const* strings, int defval); template bool Flag(T &value, int mask, FName key) diff --git a/src/namedef_custom.h b/src/namedef_custom.h index 2cac59f5d..6f5e281a0 100644 --- a/src/namedef_custom.h +++ b/src/namedef_custom.h @@ -858,4 +858,11 @@ xx(lm_sampledist_ceiling) xx(lm_suncolor) xx(lm_dynamic) +xx(skew_bottom_type) +xx(skew_middle_type) +xx(skew_top_type) +xx(skew_bottom) +xx(skew_middle) +xx(skew_top) + xx(Corona) diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index f99a630fb..6088a8f52 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -140,6 +140,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, side_t::part &part, si ("texture", part.texture, def->texture) ("interpolation", part.interpolation) ("flags", part.flags, def->flags) + ("skew", part.skew, def->skew) ("color1", part.SpecialColors[0], def->SpecialColors[0]) ("color2", part.SpecialColors[1], def->SpecialColors[1]) ("addcolor", part.AdditiveColor, def->AdditiveColor) diff --git a/src/playsim/p_3dmidtex.cpp b/src/playsim/p_3dmidtex.cpp index 315ded0c9..0e2d7e10d 100644 --- a/src/playsim/p_3dmidtex.cpp +++ b/src/playsim/p_3dmidtex.cpp @@ -44,6 +44,7 @@ #include "g_levellocals.h" #include "actor.h" #include "texturemanager.h" +#include "vm.h" //============================================================================ @@ -258,6 +259,20 @@ bool P_GetMidTexturePosition(const line_t *line, int sideno, double *ptextop, do return true; } +DEFINE_ACTION_FUNCTION(_Line, GetMidTexturePosition) +{ + PARAM_SELF_STRUCT_PROLOGUE(line_t); + PARAM_INT(side); + double top = 0.0; + double bottom = 0.0; + + bool res = P_GetMidTexturePosition(self,side,&top,&bottom); + if (numret > 2) ret[2].SetFloat(bottom); + if (numret > 1) ret[1].SetFloat(top); + if (numret > 0) ret[0].SetInt(int(res)); + return numret; +} + //============================================================================ // // P_LineOpening_3dMidtex diff --git a/src/r_data/models.cpp b/src/r_data/models.cpp index ae409507e..60a3e50ce 100644 --- a/src/r_data/models.cpp +++ b/src/r_data/models.cpp @@ -261,11 +261,11 @@ void RenderHUDModel(FModelRenderer *renderer, DPSprite *psp, FVector3 translatio float orientation = smf->xscale * smf->yscale * smf->zscale; - renderer->BeginDrawHUDModel(playermo->RenderStyle, objectToWorldMatrix, orientation < 0); + renderer->BeginDrawHUDModel(playermo->RenderStyle, objectToWorldMatrix, orientation < 0, smf); uint32_t trans = psp->GetTranslation() != 0 ? psp->GetTranslation() : 0; if ((psp->Flags & PSPF_PLAYERTRANSLATED)) trans = psp->Owner->mo->Translation; RenderFrameModels(renderer, playermo->Level, smf, psp->GetState(), psp->GetTics(), psp->Caller->modelData != nullptr ? psp->Caller->modelData->modelDef != NAME_None ? PClass::FindActor(psp->Caller->modelData->modelDef) : psp->Caller->GetClass() : psp->Caller->GetClass(), trans, psp->Caller); - renderer->EndDrawHUDModel(playermo->RenderStyle); + renderer->EndDrawHUDModel(playermo->RenderStyle, smf); } void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpriteModelFrame *smf, const FState *curState, const int curTics, const PClass *ti, int translation, AActor* actor) diff --git a/src/rendering/hwrenderer/hw_models.cpp b/src/rendering/hwrenderer/hw_models.cpp index 4aec7c1ae..5b2f14d9b 100644 --- a/src/rendering/hwrenderer/hw_models.cpp +++ b/src/rendering/hwrenderer/hw_models.cpp @@ -88,7 +88,7 @@ void FHWModelRenderer::EndDrawModel(FRenderStyle style, FSpriteModelFrame *smf) state.SetCulling(Cull_None); } -void FHWModelRenderer::BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored) +void FHWModelRenderer::BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored, FSpriteModelFrame *smf) { state.SetDepthFunc(DF_LEqual); state.SetDepthClamp(true); @@ -104,7 +104,7 @@ void FHWModelRenderer::BeginDrawHUDModel(FRenderStyle style, const VSMatrix &obj // [BB] In case the model should be rendered translucent, do back face culling. // This solves a few of the problems caused by the lack of depth sorting. // TO-DO: Implement proper depth sorting. - if (!(style == DefaultRenderStyle())) + if (!(style == DefaultRenderStyle()) || (smf->flags & MDL_FORCECULLBACKFACES)) { state.SetCulling((mirrored ^ di->drawctx->portalState.isMirrored()) ? Cull_CW : Cull_CCW); } @@ -114,13 +114,13 @@ void FHWModelRenderer::BeginDrawHUDModel(FRenderStyle style, const VSMatrix &obj state.SetModelMatrix(objectToWorldMatrix, normalModelMatrix); } -void FHWModelRenderer::EndDrawHUDModel(FRenderStyle style) +void FHWModelRenderer::EndDrawHUDModel(FRenderStyle style, FSpriteModelFrame *smf) { state.SetBoneIndexBase(-1); state.SetModelMatrix(VSMatrix::identity(), VSMatrix::identity()); state.SetDepthFunc(DF_Less); - if (!(style == DefaultRenderStyle())) + if (!(style == DefaultRenderStyle()) || (smf->flags & MDL_FORCECULLBACKFACES)) state.SetCulling(Cull_None); } diff --git a/src/rendering/hwrenderer/hw_models.h b/src/rendering/hwrenderer/hw_models.h index 32248152b..80c9376af 100644 --- a/src/rendering/hwrenderer/hw_models.h +++ b/src/rendering/hwrenderer/hw_models.h @@ -50,8 +50,8 @@ public: void EndDrawModel(FRenderStyle style, FSpriteModelFrame *smf) override; IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) override; VSMatrix GetViewToWorldMatrix() override; - void BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored) override; - void EndDrawHUDModel(FRenderStyle style) override; + void BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored, FSpriteModelFrame *smf) override; + void EndDrawHUDModel(FRenderStyle style, FSpriteModelFrame *smf) override; void SetInterpolation(double interpolation) override; void SetMaterial(FGameTexture *skin, bool clampNoFilter, int translation) override; void DrawArrays(int start, int count) override; diff --git a/src/rendering/hwrenderer/scene/hw_decal.cpp b/src/rendering/hwrenderer/scene/hw_decal.cpp index 25d3749ed..e1c604c94 100644 --- a/src/rendering/hwrenderer/scene/hw_decal.cpp +++ b/src/rendering/hwrenderer/scene/hw_decal.cpp @@ -35,6 +35,7 @@ #include "hwrenderer/scene/hw_drawinfo.h" #include "hw_lighting.h" #include "hw_clock.h" +#include "hw_drawcontext.h" #include "flatvertices.h" #include "hw_renderstate.h" #include "texturemanager.h" @@ -70,7 +71,7 @@ void HWDecal::DrawDecal(HWDrawInfo *di, FRenderState &state) else state.AlphaFunc(Alpha_Greater, 0.f); - di->SetColor(state, lightlevel, rellight, di->isFullbrightScene(), Colormap, alpha); + SetColor(state, di->Level, di->lightmode, lightlevel, rellight, di->isFullbrightScene(), Colormap, alpha); // for additively drawn decals we must temporarily set the fog color to black. PalEntry fc = state.GetFogColor(); if (decal->RenderStyle.BlendOp == STYLEOP_Add && decal->RenderStyle.DestAlpha == STYLEALPHA_One) @@ -101,9 +102,9 @@ void HWDecal::DrawDecal(HWDrawInfo *di, FRenderState &state) FColormap thiscm; thiscm.FadeColor = Colormap.FadeColor; CopyFrom3DLight(thiscm, &lightlist[k]); - di->SetColor(state, thisll, rellight, di->isFullbrightScene(), thiscm, alpha); + SetColor(state, di->Level, di->lightmode, thisll, rellight, di->isFullbrightScene(), thiscm, alpha); if (di->Level->flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING) thiscm.Decolorize(); - di->SetFog(state, thisll, rellight, di->isFullbrightScene(), &thiscm, false); + SetFog(state, di->Level, di->lightmode, thisll, rellight, di->isFullbrightScene(), &thiscm, false, di->drawctx->portalState.inskybox); SetSplitPlanes(state, lightlist[k].plane, lowplane); state.Draw(DT_TriangleStrip, vertindex, 4); @@ -142,7 +143,7 @@ void HWDrawInfo::DrawDecals(FRenderState &state, TArray &decals) else { state.EnableSplit(false); - SetFog(state, gldecal->lightlevel, gldecal->rellight, isFullbrightScene(), &gldecal->Colormap, false); + SetFog(state, Level, lightmode, gldecal->lightlevel, gldecal->rellight, isFullbrightScene(), &gldecal->Colormap, false, drawctx->portalState.inskybox); } } gldecal->DrawDecal(this, state); @@ -164,7 +165,7 @@ void HWWall::DrawDecalsForMirror(HWDrawInfo *di, FRenderState &state, TArraySetFog(state, lightlevel, rellight + getExtraLight(), di->isFullbrightScene(), &Colormap, false); + SetFog(state, di->Level, di->lightmode, lightlevel, rellight + getExtraLight(), di->isFullbrightScene(), &Colormap, false, di->drawctx->portalState.inskybox); for (auto gldecal : decals) { if (gldecal->decal->Side == seg->sidedef) diff --git a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp index d88c7c757..093a4a2bd 100644 --- a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp +++ b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp @@ -599,7 +599,7 @@ void HWDrawInfo::DrawCorona(FRenderState& state, AActor* corona, float coronaFad alpha *= distFade; state.SetColorAlpha(0xffffff, alpha, 0); - if (isSoftwareLighting()) state.SetSoftLightLevel(255); + if (isSoftwareLighting(lightmode)) state.SetSoftLightLevel(255); else state.SetNoSoftLightLevel(); state.SetLightIndex(-1); diff --git a/src/rendering/hwrenderer/scene/hw_drawinfo.h b/src/rendering/hwrenderer/scene/hw_drawinfo.h index 1574d8c86..8ef0155e3 100644 --- a/src/rendering/hwrenderer/scene/hw_drawinfo.h +++ b/src/rendering/hwrenderer/scene/hw_drawinfo.h @@ -199,13 +199,6 @@ struct HWDrawInfo void RenderParticles(subsector_t *sub, sector_t *front); void DoSubsector(subsector_t * sub); void DrawPSprite(HUDSprite* huds, FRenderState& state); - void SetColor(FRenderState& state, int sectorlightlevel, int rellight, bool fullbright, const FColormap& cm, float alpha, bool weapon = false); - void SetFog(FRenderState& state, int lightlevel, int rellight, bool fullbright, const FColormap* cmap, bool isadditive); - void SetShaderLight(FRenderState& state, float level, float olight); - int CalcLightLevel(int lightlevel, int rellight, bool weapon, int blendfactor); - PalEntry CalcLightColor(int light, PalEntry pe, int blendfactor); - float GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity, int blendfactor); - bool CheckFog(sector_t* frontsector, sector_t* backsector); WeaponLighting GetWeaponLighting(sector_t* viewsector, const DVector3& pos, int cm, area_t in_area, const DVector3& playerpos); void PreparePlayerSprites2D(sector_t* viewsector, area_t in_area, FRenderState& state); @@ -334,26 +327,6 @@ public: HWDecal *AddDecal(bool onmirror); - bool isSoftwareLighting() const - { - return lightmode == ELightMode::ZDoomSoftware || lightmode == ELightMode::DoomSoftware || lightmode == ELightMode::Build; - } - - bool isBuildSoftwareLighting() const - { - return lightmode == ELightMode::Build; - } - - bool isDoomSoftwareLighting() const - { - return lightmode == ELightMode::ZDoomSoftware || lightmode == ELightMode::DoomSoftware; - } - - bool isDarkLightMode() const - { - return lightmode == ELightMode::Doom || lightmode == ELightMode::DoomDark; - } - void SetFallbackLightMode() { lightmode = ELightMode::Doom; @@ -384,3 +357,30 @@ void WriteSavePic(player_t* player, FileWriter* file, int width, int height); sector_t* RenderView(player_t* player); +inline bool isSoftwareLighting(ELightMode lightmode) +{ + return lightmode == ELightMode::ZDoomSoftware || lightmode == ELightMode::DoomSoftware || lightmode == ELightMode::Build; +} + +inline bool isBuildSoftwareLighting(ELightMode lightmode) +{ + return lightmode == ELightMode::Build; +} + +inline bool isDoomSoftwareLighting(ELightMode lightmode) +{ + return lightmode == ELightMode::ZDoomSoftware || lightmode == ELightMode::DoomSoftware; +} + +inline bool isDarkLightMode(ELightMode lightmode) +{ + return lightmode == ELightMode::Doom || lightmode == ELightMode::DoomDark; +} + +int CalcLightLevel(ELightMode lightmode, int lightlevel, int rellight, bool weapon, int blendfactor); +PalEntry CalcLightColor(ELightMode lightmode, int light, PalEntry pe, int blendfactor); +float GetFogDensity(FLevelLocals* Level, ELightMode lightmode, int lightlevel, PalEntry fogcolor, int sectorfogdensity, int blendfactor); +bool CheckFog(FLevelLocals* Level, sector_t* frontsector, sector_t* backsector, ELightMode lightmode); +void SetColor(FRenderState& state, FLevelLocals* Level, ELightMode lightmode, int sectorlightlevel, int rellight, bool fullbright, const FColormap& cm, float alpha, bool weapon = false); +void SetShaderLight(FRenderState& state, FLevelLocals* Level, float level, float olight); +void SetFog(FRenderState& state, FLevelLocals* Level, ELightMode lightmode, int lightlevel, int rellight, bool fullbright, const FColormap* cmap, bool isadditive, bool inskybox); diff --git a/src/rendering/hwrenderer/scene/hw_drawlist.cpp b/src/rendering/hwrenderer/scene/hw_drawlist.cpp index f27d4d81f..8b598a2ff 100644 --- a/src/rendering/hwrenderer/scene/hw_drawlist.cpp +++ b/src/rendering/hwrenderer/scene/hw_drawlist.cpp @@ -38,6 +38,7 @@ #include "hw_drawinfo.h" #include "hw_fakeflat.h" #include "hw_drawcontext.h" +#include "hw_walldispatcher.h" //========================================================================== // @@ -373,8 +374,8 @@ void HWDrawList::SortWallIntoWall(HWDrawInfo *di, FRenderState& state, SortNode w->zbottom[0]=ws->zbottom[1]=izb; w->tcs[HWWall::LOLFT].u = w->tcs[HWWall::UPLFT].u = ws->tcs[HWWall::LORGT].u = ws->tcs[HWWall::UPRGT].u = iu; w->lightuv[HWWall::LOLFT].u = w->lightuv[HWWall::UPLFT].u = ws->lightuv[HWWall::LORGT].u = ws->lightuv[HWWall::UPRGT].u = iu; - ws->MakeVertices(di, state, false); - w->MakeVertices(di, state, false); + ws->MakeVertices(state, false); + w->MakeVertices(state, false); SortNode * sort2=drawctx->SortNodes.GetNew(); memset(sort2,0,sizeof(SortNode)); @@ -722,8 +723,9 @@ void HWDrawList::DoDraw(HWDrawInfo *di, FRenderState &state, bool translucent, i case DrawType_WALL: { HWWall * w= walls[drawitems[i].index]; + HWWallDispatcher dis(di); RenderWall.Clock(); - w->DrawWall(di, state, translucent); + w->DrawWall(&dis, state, translucent); RenderWall.Unclock(); } break; @@ -759,10 +761,11 @@ void HWDrawList::Draw(HWDrawInfo *di, FRenderState &state, bool translucent) //========================================================================== void HWDrawList::DrawWalls(HWDrawInfo *di, FRenderState &state, bool translucent) { + HWWallDispatcher dis(di); RenderWall.Clock(); for (auto &item : drawitems) { - walls[item.index]->DrawWall(di, state, translucent); + walls[item.index]->DrawWall(&dis, state, translucent); } RenderWall.Unclock(); } diff --git a/src/rendering/hwrenderer/scene/hw_drawlistadd.cpp b/src/rendering/hwrenderer/scene/hw_drawlistadd.cpp index cf59688c9..a44bc4e35 100644 --- a/src/rendering/hwrenderer/scene/hw_drawlistadd.cpp +++ b/src/rendering/hwrenderer/scene/hw_drawlistadd.cpp @@ -80,7 +80,7 @@ void HWDrawInfo::AddMirrorSurface(HWWall *w, FRenderState& state) auto tcs = newwall->tcs; tcs[HWWall::LOLFT].u = tcs[HWWall::LORGT].u = tcs[HWWall::UPLFT].u = tcs[HWWall::UPRGT].u = v.X; tcs[HWWall::LOLFT].v = tcs[HWWall::LORGT].v = tcs[HWWall::UPLFT].v = tcs[HWWall::UPRGT].v = v.Z; - newwall->MakeVertices(this, state, false); + newwall->MakeVertices(state, false); bool hasDecals = newwall->seg->sidedef && newwall->seg->sidedef->AttachedDecals; if (hasDecals && Level->HasDynamicLights && !isFullbrightScene()) diff --git a/src/rendering/hwrenderer/scene/hw_drawstructs.h b/src/rendering/hwrenderer/scene/hw_drawstructs.h index 374477c8c..0152679cd 100644 --- a/src/rendering/hwrenderer/scene/hw_drawstructs.h +++ b/src/rendering/hwrenderer/scene/hw_drawstructs.h @@ -226,7 +226,7 @@ public: void SetupLights(HWDrawInfo* di, FRenderState& state, FDynLightData& lightdata); - void MakeVertices(HWDrawInfo* di, FRenderState& state, bool nosplit); + void MakeVertices(FRenderState& state, bool nosplit); void SkyPlane(HWWallDispatcher* di, FRenderState& state, sector_t* sector, int plane, bool allowmirror); void SkyLine(HWWallDispatcher* di, FRenderState& state, sector_t* sec, line_t* line); @@ -237,19 +237,19 @@ public: bool DoHorizon(HWWallDispatcher* di, FRenderState& state, seg_t* seg, sector_t* fs, vertex_t* v1, vertex_t* v2); bool SetWallCoordinates(seg_t* seg, FTexCoordInfo* tci, float ceilingrefheight, - float topleft, float topright, float bottomleft, float bottomright, float t_ofs); + float topleft, float topright, float bottomleft, float bottomright, float t_ofs, float skew); void DoTexture(HWWallDispatcher* di, FRenderState& state, int type, seg_t* seg, int peg, float ceilingrefheight, float floorrefheight, float CeilingHeightstart, float CeilingHeightend, float FloorHeightstart, float FloorHeightend, - float v_offset); + float v_offset, float skew); void DoMidTexture(HWWallDispatcher* di, FRenderState& state, seg_t* seg, bool drawfogboundary, sector_t* front, sector_t* back, sector_t* realfront, sector_t* realback, float fch1, float fch2, float ffh1, float ffh2, - float bch1, float bch2, float bfh1, float bfh2, float zalign); + float bch1, float bch2, float bfh1, float bfh2, float zalign, float skew); void GetPlanePos(F3DFloor::planeref* planeref, float& left, float& right); @@ -280,11 +280,11 @@ public: int CountVertices(); - void RenderWall(HWDrawInfo* di, FRenderState& state, int textured); - void RenderFogBoundary(HWDrawInfo* di, FRenderState& state); - void RenderMirrorSurface(HWDrawInfo* di, FRenderState& state); - void RenderTexturedWall(HWDrawInfo* di, FRenderState& state, int rflags); - void RenderTranslucentWall(HWDrawInfo* di, FRenderState& state); + void RenderWall(FRenderState& state, int textured); + void RenderFogBoundary(HWWallDispatcher* di, FRenderState& state); + void RenderMirrorSurface(HWWallDispatcher* di, FRenderState& state); + void RenderTexturedWall(HWWallDispatcher* di, FRenderState& state, int rflags); + void RenderTranslucentWall(HWWallDispatcher* di, FRenderState& state); void DrawDecalsForMirror(HWDrawInfo* di, FRenderState& state, TArray& decals); public: @@ -296,7 +296,7 @@ public: return -((y - glseg.y1) * (glseg.x2 - glseg.x1) - (x - glseg.x1) * (glseg.y2 - glseg.y1)); } - void DrawWall(HWDrawInfo* di, FRenderState& state, bool translucent); + void DrawWall(HWWallDispatcher* di, FRenderState& state, bool translucent); }; diff --git a/src/rendering/hwrenderer/scene/hw_flats.cpp b/src/rendering/hwrenderer/scene/hw_flats.cpp index 902464d16..8e34de67c 100644 --- a/src/rendering/hwrenderer/scene/hw_flats.cpp +++ b/src/rendering/hwrenderer/scene/hw_flats.cpp @@ -41,6 +41,7 @@ #include "hw_clock.h" #include "hw_lighting.h" #include "hw_material.h" +#include "hw_drawcontext.h" #include "hwrenderer/scene/hw_drawinfo.h" #include "flatvertices.h" #include "hw_drawstructs.h" @@ -321,8 +322,8 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent) state.SetNormal(plane.plane.Normal().X, plane.plane.Normal().Z, plane.plane.Normal().Y); - di->SetColor(state, lightlevel, rel, di->isFullbrightScene(), Colormap, alpha); - di->SetFog(state, lightlevel, rel, di->isFullbrightScene(), &Colormap, false); + SetColor(state, di->Level, di->lightmode, lightlevel, rel, di->isFullbrightScene(), Colormap, alpha); + SetFog(state, di->Level, di->lightmode, lightlevel, rel, di->isFullbrightScene(), &Colormap, false, di->drawctx->portalState.inskybox); state.SetObjectColor(FlatColor | 0xff000000); state.SetAddColor(AddColor | 0xff000000); state.ApplyTextureManipulation(TextureFx); diff --git a/src/rendering/hwrenderer/scene/hw_lighting.cpp b/src/rendering/hwrenderer/scene/hw_lighting.cpp index e22a359bf..bfcaf5f74 100644 --- a/src/rendering/hwrenderer/scene/hw_lighting.cpp +++ b/src/rendering/hwrenderer/scene/hw_lighting.cpp @@ -76,13 +76,13 @@ CUSTOM_CVAR(Int, gl_distfog, 70, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // //========================================================================== -int HWDrawInfo::CalcLightLevel(int lightlevel, int rellight, bool weapon, int blendfactor) +int CalcLightLevel(ELightMode lightmode, int lightlevel, int rellight, bool weapon, int blendfactor) { int light; if (lightlevel <= 0) return 0; - bool darklightmode = (isDarkLightMode()) || (isSoftwareLighting() && blendfactor > 0); + bool darklightmode = (isDarkLightMode(lightmode)) || (isSoftwareLighting(lightmode) && blendfactor > 0); if (darklightmode && lightlevel < 192 && !weapon) { @@ -119,13 +119,13 @@ int HWDrawInfo::CalcLightLevel(int lightlevel, int rellight, bool weapon, int bl // //========================================================================== -PalEntry HWDrawInfo::CalcLightColor(int light, PalEntry pe, int blendfactor) +PalEntry CalcLightColor(ELightMode lightmode, int light, PalEntry pe, int blendfactor) { int r,g,b; if (blendfactor == 0) { - if (isSoftwareLighting()) + if (isSoftwareLighting(lightmode)) { return pe; } @@ -165,12 +165,12 @@ PalEntry HWDrawInfo::CalcLightColor(int light, PalEntry pe, int blendfactor) // //========================================================================== -float HWDrawInfo::GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity, int blendfactor) +float GetFogDensity(FLevelLocals* Level, ELightMode lightmode, int lightlevel, PalEntry fogcolor, int sectorfogdensity, int blendfactor) { float density; auto oldlightmode = lightmode; - if (isSoftwareLighting() && blendfactor > 0) lightmode = ELightMode::Doom; // The blendfactor feature does not work with software-style lighting. + if (isSoftwareLighting(lightmode) && blendfactor > 0) lightmode = ELightMode::Doom; // The blendfactor feature does not work with software-style lighting. if (lightmode == ELightMode::DoomLegacy) { @@ -185,7 +185,7 @@ float HWDrawInfo::GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfog else if ((fogcolor.d & 0xffffff) == 0) { // case 2: black fog - if ((!isDoomSoftwareLighting() || blendfactor > 0) && !(Level->flags3 & LEVEL3_NOLIGHTFADE)) + if ((!isDoomSoftwareLighting(lightmode) || blendfactor > 0) && !(Level->flags3 & LEVEL3_NOLIGHTFADE)) { density = distfogtable[lightmode != ELightMode::LinearStandard][hw_ClampLight(lightlevel)]; } diff --git a/src/rendering/hwrenderer/scene/hw_portal.cpp b/src/rendering/hwrenderer/scene/hw_portal.cpp index 29dabd443..cfaf2a6f7 100644 --- a/src/rendering/hwrenderer/scene/hw_portal.cpp +++ b/src/rendering/hwrenderer/scene/hw_portal.cpp @@ -36,6 +36,7 @@ #include "flatvertices.h" #include "hw_clock.h" #include "hw_lighting.h" +#include "hw_drawcontext.h" #include "texturemanager.h" EXTERN_CVAR(Int, r_mirror_recursions) @@ -969,14 +970,14 @@ void HWHorizonPortal::DrawContents(HWDrawInfo *di, FRenderState &state) if (texture->isFullbright()) { // glowing textures are always drawn full bright without color - di->SetColor(state, 255, 0, false, origin->colormap, 1.f); - di->SetFog(state, 255, 0, false, &origin->colormap, false); + SetColor(state, di->Level, di->lightmode, 255, 0, false, origin->colormap, 1.f); + SetFog(state, di->Level, di->lightmode, 255, 0, false, &origin->colormap, false, di->drawctx->portalState.inskybox); } else { int rel = getExtraLight(); - di->SetColor(state, origin->lightlevel, rel, di->isFullbrightScene(), origin->colormap, 1.0f); - di->SetFog(state, origin->lightlevel, rel, di->isFullbrightScene(), &origin->colormap, false); + SetColor(state, di->Level, di->lightmode, origin->lightlevel, rel, di->isFullbrightScene(), origin->colormap, 1.0f); + SetFog(state, di->Level, di->lightmode, origin->lightlevel, rel, di->isFullbrightScene(), &origin->colormap, false, di->drawctx->portalState.inskybox); } diff --git a/src/rendering/hwrenderer/scene/hw_setcolor.cpp b/src/rendering/hwrenderer/scene/hw_setcolor.cpp index 946be1c68..f8b150f67 100644 --- a/src/rendering/hwrenderer/scene/hw_setcolor.cpp +++ b/src/rendering/hwrenderer/scene/hw_setcolor.cpp @@ -38,20 +38,20 @@ // set current light color // //========================================================================== -void HWDrawInfo::SetColor(FRenderState &state, int sectorlightlevel, int rellight, bool fullbright, const FColormap &cm, float alpha, bool weapon) +void SetColor(FRenderState &state, FLevelLocals* Level, ELightMode lightmode, int sectorlightlevel, int rellight, bool fullbright, const FColormap &cm, float alpha, bool weapon) { if (fullbright) { state.SetColorAlpha(0xffffff, alpha, 0); - if (isSoftwareLighting()) state.SetSoftLightLevel(255); + if (isSoftwareLighting(lightmode)) state.SetSoftLightLevel(255); else state.SetNoSoftLightLevel(); } else { - int hwlightlevel = CalcLightLevel(sectorlightlevel, rellight, weapon, cm.BlendFactor); - PalEntry pe = CalcLightColor(hwlightlevel, cm.LightColor, cm.BlendFactor); + int hwlightlevel = CalcLightLevel(lightmode, sectorlightlevel, rellight, weapon, cm.BlendFactor); + PalEntry pe = CalcLightColor(lightmode, hwlightlevel, cm.LightColor, cm.BlendFactor); state.SetColorAlpha(pe, alpha, cm.Desaturation); - if (isSoftwareLighting()) state.SetSoftLightLevel(hw_ClampLight(sectorlightlevel + rellight), cm.BlendFactor); + if (isSoftwareLighting(lightmode)) state.SetSoftLightLevel(hw_ClampLight(sectorlightlevel + rellight), cm.BlendFactor); else state.SetNoSoftLightLevel(); } } @@ -62,7 +62,7 @@ void HWDrawInfo::SetColor(FRenderState &state, int sectorlightlevel, int relligh // //========================================================================== -void HWDrawInfo::SetShaderLight(FRenderState &state, float level, float olight) +void SetShaderLight(FRenderState &state, FLevelLocals* Level, float level, float olight) { const float MAXDIST = 256.f; const float THRESHOLD = 96.f; @@ -96,7 +96,7 @@ void HWDrawInfo::SetShaderLight(FRenderState &state, float level, float olight) // //========================================================================== -void HWDrawInfo::SetFog(FRenderState &state, int lightlevel, int rellight, bool fullbright, const FColormap *cmap, bool isadditive) +void SetFog(FRenderState &state, FLevelLocals* Level, ELightMode lightmode, int lightlevel, int rellight, bool fullbright, const FColormap *cmap, bool isadditive, bool inskybox) { PalEntry fogcolor; float fogdensity; @@ -109,7 +109,7 @@ void HWDrawInfo::SetFog(FRenderState &state, int lightlevel, int rellight, bool else if (cmap != nullptr && !fullbright) { fogcolor = cmap->FadeColor; - fogdensity = GetFogDensity(lightlevel, fogcolor, cmap->FogDensity, cmap->BlendFactor); + fogdensity = GetFogDensity(Level, lightmode, lightlevel, fogcolor, cmap->FogDensity, cmap->BlendFactor); fogcolor.a = 0; } else @@ -119,7 +119,7 @@ void HWDrawInfo::SetFog(FRenderState &state, int lightlevel, int rellight, bool } // Make fog a little denser when inside a skybox - if (drawctx->portalState.inskybox) fogdensity += fogdensity / 2; + if (inskybox) fogdensity += fogdensity / 2; // no fog in enhanced vision modes! @@ -130,10 +130,10 @@ void HWDrawInfo::SetFog(FRenderState &state, int lightlevel, int rellight, bool } else { - if ((lightmode == ELightMode::Doom || (isSoftwareLighting() && cmap && cmap->BlendFactor > 0)) && fogcolor == 0) + if ((lightmode == ELightMode::Doom || (isSoftwareLighting(lightmode) && cmap && cmap->BlendFactor > 0)) && fogcolor == 0) { - float light = (float)CalcLightLevel(lightlevel, rellight, false, cmap->BlendFactor); - SetShaderLight(state, light, lightlevel); + float light = (float)CalcLightLevel(lightmode, lightlevel, rellight, false, cmap->BlendFactor); + SetShaderLight(state, Level, light, lightlevel); } else if (lightmode == ELightMode::Build) { @@ -155,7 +155,7 @@ void HWDrawInfo::SetFog(FRenderState &state, int lightlevel, int rellight, bool state.SetFog(fogcolor, fogdensity); // Korshun: fullbright fog like in software renderer. - if (isSoftwareLighting() && cmap && cmap->BlendFactor == 0 && Level->brightfog && fogdensity != 0 && fogcolor != 0) + if (isSoftwareLighting(lightmode) && cmap && cmap->BlendFactor == 0 && Level->brightfog && fogdensity != 0 && fogcolor != 0) { state.SetSoftLightLevel(255); } diff --git a/src/rendering/hwrenderer/scene/hw_skyportal.cpp b/src/rendering/hwrenderer/scene/hw_skyportal.cpp index 386b8fc1f..89f83e130 100644 --- a/src/rendering/hwrenderer/scene/hw_skyportal.cpp +++ b/src/rendering/hwrenderer/scene/hw_skyportal.cpp @@ -43,7 +43,7 @@ void HWSkyPortal::DrawContents(HWDrawInfo *di, FRenderState &state) // We have no use for Doom lighting special handling here, so disable it for this function. auto oldlightmode = di->lightmode; - if (di->isSoftwareLighting()) + if (isSoftwareLighting(oldlightmode)) { di->SetFallbackLightMode(); state.SetNoSoftLightLevel(); diff --git a/src/rendering/hwrenderer/scene/hw_sprites.cpp b/src/rendering/hwrenderer/scene/hw_sprites.cpp index 70baef14b..0ad807a3e 100644 --- a/src/rendering/hwrenderer/scene/hw_sprites.cpp +++ b/src/rendering/hwrenderer/scene/hw_sprites.cpp @@ -56,6 +56,7 @@ #include "hw_material.h" #include "hw_dynlightdata.h" #include "hw_renderstate.h" +#include "hw_drawcontext.h" extern TArray sprites; extern TArray SpriteFrames; @@ -144,7 +145,7 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent) if (!Colormap.FadeColor.isBlack()) { float dist = Dist2(vp.Pos.X, vp.Pos.Y, x, y); - int fogd = di->GetFogDensity(lightlevel, Colormap.FadeColor, Colormap.FogDensity, Colormap.BlendFactor); + int fogd = GetFogDensity(di->Level, di->lightmode, lightlevel, Colormap.FadeColor, Colormap.FogDensity, Colormap.BlendFactor); // this value was determined by trial and error and is scale dependent! float factor = 0.05f + exp(-fogd * dist / 62500.f); @@ -189,7 +190,7 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent) state.SetObjectColor(finalcol); state.SetAddColor(cursec->AdditiveColors[sector_t::sprites] | 0xff000000); } - di->SetColor(state, lightlevel, rel, di->isFullbrightScene(), Colormap, trans); + SetColor(state, di->Level, di->lightmode, lightlevel, rel, di->isFullbrightScene(), Colormap, trans); } @@ -216,7 +217,7 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent) else RenderStyle.BlendOp = STYLEOP_Fuzz; // subtractive with models is not going to work. } - if (!foglayer) di->SetFog(state, foglevel, rel, di->isFullbrightScene(), &Colormap, additivefog); + if (!foglayer) SetFog(state, di->Level, di->lightmode, foglevel, rel, di->isFullbrightScene(), &Colormap, additivefog, di->drawctx->portalState.inskybox); else { state.EnableFog(false); @@ -257,10 +258,10 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent) thiscm.Decolorize(); } - di->SetColor(state, thisll, rel, di->isFullbrightScene(), thiscm, trans); + SetColor(state, di->Level, di->lightmode, thisll, rel, di->isFullbrightScene(), thiscm, trans); if (!foglayer) { - di->SetFog(state, thislight, rel, di->isFullbrightScene(), &thiscm, additivefog); + SetFog(state, di->Level, di->lightmode, thislight, rel, di->isFullbrightScene(), &thiscm, additivefog, di->drawctx->portalState.inskybox); } SetSplitPlanes(state, *topplane, *lowplane); } @@ -285,7 +286,7 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent) if (foglayer) { // If we get here we know that we have colored fog and no fixed colormap. - di->SetFog(state, foglevel, rel, false, &Colormap, additivefog); + SetFog(state, di->Level, di->lightmode, foglevel, rel, false, &Colormap, additivefog, di->drawctx->portalState.inskybox); state.SetTextureMode(TM_FOGLAYER); state.SetRenderStyle(STYLE_Translucent); state.Draw(DT_TriangleStrip, vertexindex, 4); @@ -347,8 +348,8 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent) state.SetDynLight(0, 0, 0); state.SetRenderStyle(STYLE_Normal); state.SetTextureMode(TM_NORMAL); - di->SetFog(state, 0, 0, false, &Colormap, true); - di->SetColor(state, 255, 0, true, Colormap, true); + SetFog(state, di->Level, di->lightmode, 0, 0, false, &Colormap, true, di->drawctx->portalState.inskybox); + SetColor(state, di->Level, di->lightmode, 255, 0, true, Colormap, true); state.EnableTexture(false); int scales[12][6] = diff --git a/src/rendering/hwrenderer/scene/hw_walls.cpp b/src/rendering/hwrenderer/scene/hw_walls.cpp index 0b9fe91c9..ffc7cf1b2 100644 --- a/src/rendering/hwrenderer/scene/hw_walls.cpp +++ b/src/rendering/hwrenderer/scene/hw_walls.cpp @@ -82,7 +82,7 @@ void SetSplitPlanes(FRenderState& state, const secplane_t& top, const secplane_t // //========================================================================== -void HWWall::RenderWall(HWDrawInfo*di, FRenderState &state, int textured) +void HWWall::RenderWall(FRenderState &state, int textured) { assert(vertcount > 0); state.SetLightIndex(dynlightindex); @@ -96,17 +96,17 @@ void HWWall::RenderWall(HWDrawInfo*di, FRenderState &state, int textured) // //========================================================================== -void HWWall::RenderFogBoundary(HWDrawInfo*di, FRenderState &state) +void HWWall::RenderFogBoundary(HWWallDispatcher*di, FRenderState &state) { if (gl_fogmode && !di->isFullbrightScene()) { int rel = rellight + getExtraLight(); state.EnableDrawBufferAttachments(false); - di->SetFog(state, lightlevel, rel, false, &Colormap, false); + SetFog(state, di->Level, di->lightmode, lightlevel, rel, false, &Colormap, false, di->di ? di->di->drawctx->portalState.inskybox : false); state.SetEffect(EFF_FOGBOUNDARY); state.AlphaFunc(Alpha_GEqual, 0.f); state.SetDepthBias(-1, -128); - RenderWall(di, state, HWWall::RWF_BLANK); + RenderWall(state, HWWall::RWF_BLANK); state.ClearDepthBias(); state.SetEffect(EFF_NONE); state.EnableDrawBufferAttachments(true); @@ -119,7 +119,7 @@ void HWWall::RenderFogBoundary(HWDrawInfo*di, FRenderState &state) // // //========================================================================== -void HWWall::RenderMirrorSurface(HWDrawInfo*di, FRenderState &state) +void HWWall::RenderMirrorSurface(HWWallDispatcher*di, FRenderState &state) { if (!TexMan.mirrorTexture.isValid()) return; @@ -127,8 +127,8 @@ void HWWall::RenderMirrorSurface(HWDrawInfo*di, FRenderState &state) // Use sphere mapping for this state.SetEffect(EFF_SPHEREMAP); - di->SetColor(state, lightlevel, 0, di->isFullbrightScene(), Colormap, 0.1f); - di->SetFog(state, lightlevel, 0, di->isFullbrightScene(), &Colormap, true); + SetColor(state, di->Level, di->lightmode, lightlevel, 0, di->isFullbrightScene(), Colormap, 0.1f); + SetFog(state, di->Level, di->lightmode, lightlevel, 0, di->isFullbrightScene(), &Colormap, true, di->di ? di->di->drawctx->portalState.inskybox : false); state.SetRenderStyle(STYLE_Add); state.AlphaFunc(Alpha_Greater, 0); @@ -136,7 +136,7 @@ void HWWall::RenderMirrorSurface(HWDrawInfo*di, FRenderState &state) state.SetMaterial(tex, UF_None, 0, CLAMP_NONE, 0, -1); // do not upscale the mirror texture. flags &= ~HWWall::HWF_GLOW; - RenderWall(di, state, HWWall::RWF_BLANK); + RenderWall(state, HWWall::RWF_BLANK); state.SetTextureMatrix(VSMatrix::identity()); state.SetEffect(EFF_NONE); @@ -147,9 +147,9 @@ void HWWall::RenderMirrorSurface(HWDrawInfo*di, FRenderState &state) // This is drawn in the translucent pass which is done after the decal pass // As a result the decals have to be drawn here, right after the wall they are on, // because the depth buffer won't get set by translucent items. - if (seg->sidedef->AttachedDecals) + if (di->di && seg->sidedef->AttachedDecals) { - DrawDecalsForMirror(di, state, di->Decals[1]); + DrawDecalsForMirror(di->di, state, di->di->Decals[1]); } state.SetRenderStyle(STYLE_Translucent); } @@ -178,7 +178,7 @@ static const uint8_t renderwalltotier[] = CVAR(Bool, hw_npottest, false, 0) #endif -void HWWall::RenderTexturedWall(HWDrawInfo*di, FRenderState &state, int rflags) +void HWWall::RenderTexturedWall(HWWallDispatcher*di, FRenderState &state, int rflags) { int tmode = state.GetTextureMode(); int rel = rellight + getExtraLight(); @@ -214,7 +214,7 @@ void HWWall::RenderTexturedWall(HWDrawInfo*di, FRenderState &state, int rflags) if (type == RENDERWALL_M2SNF) { - di->SetFog(state, 255, 0, di->isFullbrightScene(), nullptr, false); + SetFog(state, di->Level, di->lightmode, 255, 0, di->isFullbrightScene(), nullptr, false, di->di ? di->di->drawctx->portalState.inskybox : false); } if (type != RENDERWALL_COLOR && seg->sidedef != nullptr) { @@ -262,9 +262,9 @@ void HWWall::RenderTexturedWall(HWDrawInfo*di, FRenderState &state, int rflags) float absalpha = fabsf(alpha); if (lightlist == nullptr) { - if (type != RENDERWALL_M2SNF) di->SetFog(state, lightlevel, rel, di->isFullbrightScene(), &Colormap, RenderStyle == STYLE_Add); - di->SetColor(state, lightlevel, rel, di->isFullbrightScene(), Colormap, absalpha); - RenderWall(di, state, rflags); + if (type != RENDERWALL_M2SNF) SetFog(state, di->Level, di->lightmode, lightlevel, rel, di->isFullbrightScene(), &Colormap, RenderStyle == STYLE_Add, di->di ? di->di->drawctx->portalState.inskybox : false); + SetColor(state, di->Level, di->lightmode, lightlevel, rel, di->isFullbrightScene(), Colormap, absalpha); + RenderWall(state, rflags); } else { @@ -284,10 +284,10 @@ void HWWall::RenderTexturedWall(HWDrawInfo*di, FRenderState &state, int rflags) thiscm.FadeColor = Colormap.FadeColor; thiscm.FogDensity = Colormap.FogDensity; CopyFrom3DLight(thiscm, &(*lightlist)[i]); - di->SetColor(state, thisll, rel, false, thiscm, absalpha); - if (type != RENDERWALL_M2SNF) di->SetFog(state, thisll, rel, false, &thiscm, RenderStyle == STYLE_Add); + SetColor(state, di->Level, di->lightmode, thisll, rel, false, thiscm, absalpha); + if (type != RENDERWALL_M2SNF) SetFog(state, di->Level, di->lightmode, thisll, rel, false, &thiscm, RenderStyle == STYLE_Add, di->di ? di->di->drawctx->portalState.inskybox : false); SetSplitPlanes(state, (*lightlist)[i].plane, lowplane); - RenderWall(di, state, rflags); + RenderWall(state, rflags); } if (low1 <= zbottom[0] && low2 <= zbottom[1]) break; } @@ -311,7 +311,7 @@ void HWWall::RenderTexturedWall(HWDrawInfo*di, FRenderState &state, int rflags) // //========================================================================== -void HWWall::RenderTranslucentWall(HWDrawInfo*di, FRenderState &state) +void HWWall::RenderTranslucentWall(HWWallDispatcher*di, FRenderState &state) { state.SetRenderStyle(RenderStyle); if (texture) @@ -323,10 +323,10 @@ void HWWall::RenderTranslucentWall(HWDrawInfo*di, FRenderState &state) else { state.AlphaFunc(Alpha_GEqual, 0.f); - di->SetColor(state, lightlevel, 0, false, Colormap, fabsf(alpha)); - di->SetFog(state, lightlevel, 0, false, &Colormap, RenderStyle == STYLE_Add); + SetColor(state, di->Level, di->lightmode, lightlevel, 0, false, Colormap, fabsf(alpha)); + SetFog(state, di->Level, di->lightmode, lightlevel, 0, false, &Colormap, RenderStyle == STYLE_Add, di->di ? di->di->drawctx->portalState.inskybox : false); state.EnableTexture(false); - RenderWall(di, state, HWWall::RWF_NOSPLIT); + RenderWall(state, HWWall::RWF_NOSPLIT); state.EnableTexture(true); } state.SetRenderStyle(STYLE_Translucent); @@ -337,13 +337,13 @@ void HWWall::RenderTranslucentWall(HWDrawInfo*di, FRenderState &state) // // //========================================================================== -void HWWall::DrawWall(HWDrawInfo*di, FRenderState &state, bool translucent) +void HWWall::DrawWall(HWWallDispatcher*di, FRenderState &state, bool translucent) { - if (di->Level->HasDynamicLights && !di->isFullbrightScene() && texture != nullptr) + if (di->di && di->Level->HasDynamicLights && !di->isFullbrightScene() && texture != nullptr) { - SetupLights(di, state, lightdata); + SetupLights(di->di, state, lightdata); } - MakeVertices(di, state, !!(flags & HWWall::HWF_TRANSLUCENT)); + MakeVertices(state, !!(flags & HWWall::HWF_TRANSLUCENT)); state.SetNormal(glseg.Normal()); if (!translucent) @@ -567,7 +567,7 @@ void HWWall::PutPortal(HWWallDispatcher *di, FRenderState& state, int ptype, int auto ddi = di->di; if (ddi) { - MakeVertices(ddi, state, false); + MakeVertices(state, false); switch (ptype) { // portals don't go into the draw list. @@ -893,7 +893,7 @@ static float ZeroLightmapUVs[8] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0. // //========================================================================== bool HWWall::SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float texturetop, - float topleft, float topright, float bottomleft, float bottomright, float t_ofs) + float topleft, float topright, float bottomleft, float bottomright, float t_ofs, float skew) { // // @@ -986,8 +986,8 @@ bool HWWall::SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float textureto if (tci) { - tcs[UPRGT].v = tci->FloatToTexV(-ztop[1] + texturetop); - tcs[LORGT].v = tci->FloatToTexV(-zbottom[1] + texturetop); + tcs[UPRGT].v = tci->FloatToTexV(-ztop[1] + texturetop + skew); + tcs[LORGT].v = tci->FloatToTexV(-zbottom[1] + texturetop + skew); } lightuv[UPRGT].v = srclightuv[UPRGT].v; @@ -1009,7 +1009,7 @@ bool HWWall::SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float textureto zbottom[1] = ztop[1] = inter_y; if (tci) { - tcs[LORGT].v = tcs[UPRGT].v = tci->FloatToTexV(-ztop[1] + texturetop); + tcs[LORGT].v = tcs[UPRGT].v = tci->FloatToTexV(-ztop[1] + texturetop + skew); } lightuv[UPRGT].v = srclightuv[UPRGT].v + inter_x * (srclightuv[UPRGT].v - srclightuv[UPLFT].v); @@ -1135,7 +1135,7 @@ void HWWall::DoTexture(HWWallDispatcher *di, FRenderState& state, int _type,seg_ float ceilingrefheight,float floorrefheight, float topleft,float topright, float bottomleft,float bottomright, - float v_offset) + float v_offset, float skew) { if (topleft<=bottomleft && topright<=bottomright) return; @@ -1181,7 +1181,7 @@ void HWWall::DoTexture(HWWallDispatcher *di, FRenderState& state, int _type,seg_ if (peg) floatceilingref += tci.mRenderHeight - flh - v_offset; if (!SetWallCoordinates(seg, &tci, floatceilingref, topleft, topright, bottomleft, bottomright, - seg->sidedef->GetTextureXOffset(texpos))) return; + seg->sidedef->GetTextureXOffset(texpos), skew)) return; if (seg->linedef->special == Line_Mirror && _type == RENDERWALL_M1S && gl_mirrors && !(di->Level->ib_compatflags & BCOMPATF_NOMIRRORS)) { @@ -1213,7 +1213,7 @@ void HWWall::DoMidTexture(HWWallDispatcher *di, FRenderState& state, seg_t * seg sector_t * front, sector_t * back, sector_t * realfront, sector_t * realback, float fch1, float fch2, float ffh1, float ffh2, - float bch1, float bch2, float bfh1, float bfh2, float zalign) + float bch1, float bch2, float bfh1, float bfh2, float zalign, float skew) { FTexCoordInfo tci; @@ -1339,10 +1339,10 @@ void HWWall::DoMidTexture(HWWallDispatcher *di, FRenderState& state, seg_t * seg // if we don't need a fog sheet let's clip away some unnecessary parts of the polygon // // - if (!drawfogboundary && !wrap) + if (!drawfogboundary && !wrap && skew == 0) { - if (texturetopbottomleft && texturebottom>bottomright) bottomleft=bottomright=texturebottom; + if (texturetop < topleft && texturetop < topright) topleft = topright = texturetop; + if (texturebottom > bottomleft && texturebottom > bottomright) bottomleft = bottomright = texturebottom; } } else @@ -1355,8 +1355,10 @@ void HWWall::DoMidTexture(HWWallDispatcher *di, FRenderState& state, seg_t * seg // unwanted side effects. // // - topleft=topright=texturetop; - bottomleft=bottomright=texturebottom; + topleft = texturetop; + topright = texturetop + skew; + bottomleft = texturebottom; + bottomright = texturebottom + skew; } // nothing visible - skip the rest @@ -1419,7 +1421,7 @@ void HWWall::DoMidTexture(HWWallDispatcher *di, FRenderState& state, seg_t * seg // mid textures on portal lines need the same offsetting as mid textures on sky lines flags |= HWF_SKYHACK; } - SetWallCoordinates(seg, &tci, texturetop, topleft, topright, bottomleft, bottomright, t_ofs); + SetWallCoordinates(seg, &tci, texturetop, topleft, topright, bottomleft, bottomright, t_ofs, skew); // // @@ -1478,7 +1480,7 @@ void HWWall::DoMidTexture(HWWallDispatcher *di, FRenderState& state, seg_t * seg FloatRect *splitrect; int v = texture->GetAreas(&splitrect); if (seg->frontsector == seg->backsector) flags |= HWF_NOSPLIT; // we don't need to do vertex splits if a line has both sides in the same sector - if (v>0 && !drawfogboundary && !(seg->linedef->flags&ML_WRAP_MIDTEX) && !(flags & HWF_NOSLICE)) + if (v>0 && !drawfogboundary && !(seg->linedef->flags&ML_WRAP_MIDTEX) && !(flags & HWF_NOSLICE) && skew == 0) { // split the poly! int i,t=0; @@ -1934,6 +1936,10 @@ inline int CalcRelLight(int lightlevel, int orglightlevel, int rel) } } +CVAR(Int, topskew, 0, 0) +CVAR(Int, midskew, 0, 0) +CVAR(Int, bottomskew, 0, 0) + //========================================================================== // // @@ -2090,9 +2096,14 @@ void HWWall::Process(HWWallDispatcher *di, FRenderState& state, seg_t *seg, sect texture = TexMan.GetGameTexture(seg->sidedef->GetTexture(side_t::mid), true); if (texture && texture->isValid()) { + int skewflag = seg->sidedef->textures[side_t::mid].skew; + if (skewflag == 0) skewflag = midskew; + float skew = + skewflag == side_t::skew_front_ceiling ? fch2 - fch1 : + skewflag == side_t::skew_front_floor ? ffh2 - ffh1 : 0.; DoTexture(di, state, RENDERWALL_M1S, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0, crefz, frefz, // must come from the original! - fch1, fch2, ffh1, ffh2, 0); + fch1, fch2, ffh1, ffh2, 0, skew); } } } @@ -2160,9 +2171,31 @@ void HWWall::Process(HWWallDispatcher *di, FRenderState& state, seg_t *seg, sect texture = TexMan.GetGameTexture(seg->sidedef->GetTexture(side_t::top), true); if (texture && texture->isValid()) { + int skewflag = seg->sidedef->textures[side_t::top].skew; + float skew; + if (skewflag == 0) skewflag = topskew; + + switch (skewflag) + { + default: + skew = 0; + break; + case side_t::skew_front_ceiling: + skew = fch2 - fch1; + break; + case side_t::skew_back_ceiling: + skew = bch2 - bch1; + break; + case side_t::skew_front_floor: + skew = bfh2 - bfh1; + break; + case side_t::skew_back_floor: + skew = ffh2 - ffh1; + break; + } DoTexture(di, state, RENDERWALL_TOP, seg, (seg->linedef->flags & (ML_DONTPEGTOP)) == 0, crefz, realback->GetPlaneTexZ(sector_t::ceiling), - fch1, fch2, bch1a, bch2a, 0); + fch1, fch2, bch1a, bch2a, 0, skew); } else if (!(seg->sidedef->Flags & WALLF_POLYOBJ)) { @@ -2175,7 +2208,7 @@ void HWWall::Process(HWWallDispatcher *di, FRenderState& state, seg_t *seg, sect { DoTexture(di, state, RENDERWALL_TOP, seg, (seg->linedef->flags & (ML_DONTPEGTOP)) == 0, crefz, realback->GetPlaneTexZ(sector_t::ceiling), - fch1, fch2, bch1a, bch2a, 0); + fch1, fch2, bch1a, bch2a, 0, 0); } } else @@ -2210,6 +2243,28 @@ void HWWall::Process(HWWallDispatcher *di, FRenderState& state, seg_t *seg, sect lightlevel = hw_ClampLight(seg->sidedef->GetLightLevel(foggy, orglightlevel, side_t::mid, false, &rel)); rellight = CalcRelLight(lightlevel, orglightlevel, rel); + float skew; + int skewflag = seg->sidedef->textures[side_t::mid].skew; + if (skewflag == 0) skewflag = midskew; + switch (skewflag) + { + default: + skew = 0; + break; + case side_t::skew_front_ceiling: + skew = fch2 - fch1; + break; + case side_t::skew_back_ceiling: + skew = bch2 - bch1; + break; + case side_t::skew_front_floor: + skew = bfh2 - bfh1; + break; + case side_t::skew_back_floor: + skew = ffh2 - ffh1; + break; + } + if (isportal) { lineportal = seg->linedef->getPortal()->mGroup; @@ -2222,7 +2277,7 @@ void HWWall::Process(HWWallDispatcher *di, FRenderState& state, seg_t *seg, sect if (texture && seg->backsector != nullptr) { DoMidTexture(di, state, seg, drawfogboundary, frontsector, backsector, realfront, realback, - fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2, zalign); + fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2, zalign, skew); } } else @@ -2231,7 +2286,7 @@ void HWWall::Process(HWWallDispatcher *di, FRenderState& state, seg_t *seg, sect if (texture || drawfogboundary) { DoMidTexture(di, state, seg, drawfogboundary, frontsector, backsector, realfront, realback, - fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2, zalign); + fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2, zalign, skew); } if (backsector->e->XFloor.ffloors.Size() || frontsector->e->XFloor.ffloors.Size()) @@ -2244,6 +2299,7 @@ void HWWall::Process(HWWallDispatcher *di, FRenderState& state, seg_t *seg, sect /* bottom texture */ // the back sector's ceiling obstructs part of this wall (specially important for sky sectors) + float bfh1a = bch1, bfh2a = bch2; if (fch1 < bfh1 && fch2 < bfh2 && (seg->linedef->flags & ML_DRAWFULLHEIGHT) == 0) { bfh1 = fch1; @@ -2257,12 +2313,34 @@ void HWWall::Process(HWWallDispatcher *di, FRenderState& state, seg_t *seg, sect texture = TexMan.GetGameTexture(seg->sidedef->GetTexture(side_t::bottom), true); if (texture && texture->isValid()) { + int skewflag = seg->sidedef->textures[side_t::bottom].skew; + if (skewflag == 0) skewflag = bottomskew; + float skew; + switch (skewflag) + { + default: + skew = 0; + break; + case side_t::skew_front_ceiling: + skew = fch2 - fch1; + break; + case side_t::skew_back_ceiling: + skew = bch2 - bch1; + break; + case side_t::skew_front_floor: + skew = bfh2a - bfh1a; + break; + case side_t::skew_back_floor: + skew = ffh2 - ffh1; + break; + } + DoTexture(di, state, RENDERWALL_BOTTOM, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0, realback->GetPlaneTexZ(sector_t::floor), frefz, bfh1, bfh2, ffh1, ffh2, frontsector->GetTexture(sector_t::ceiling) == skyflatnum && backsector->GetTexture(sector_t::ceiling) == skyflatnum ? frefz - realback->GetPlaneTexZ(sector_t::ceiling) : - frefz - crefz); + frefz - crefz, skew); } else if (!(seg->sidedef->Flags & WALLF_POLYOBJ)) { @@ -2278,7 +2356,7 @@ void HWWall::Process(HWWallDispatcher *di, FRenderState& state, seg_t *seg, sect { DoTexture(di, state, RENDERWALL_BOTTOM, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0, realback->GetPlaneTexZ(sector_t::floor), frefz, - bfh1, bfh2, ffh1, ffh2, frefz - crefz); + bfh1, bfh2, ffh1, ffh2, frefz - crefz, 0); } } else if (backsector->GetTexture(sector_t::floor) != skyflatnum) @@ -2350,7 +2428,7 @@ void HWWall::ProcessLowerMiniseg(HWWallDispatcher *di, FRenderState& state, seg_ FTexCoordInfo tci; type = RENDERWALL_BOTTOM; tci.GetFromTexture(texture, 1, 1, false); - SetWallCoordinates(seg, &tci, bfh, bfh, bfh, ffh, ffh, 0); + SetWallCoordinates(seg, &tci, bfh, bfh, bfh, ffh, ffh, 0, 0); PutWall(di, state, false); } } diff --git a/src/rendering/hwrenderer/scene/hw_walls_vertex.cpp b/src/rendering/hwrenderer/scene/hw_walls_vertex.cpp index c66e11105..a92cd7087 100644 --- a/src/rendering/hwrenderer/scene/hw_walls_vertex.cpp +++ b/src/rendering/hwrenderer/scene/hw_walls_vertex.cpp @@ -283,7 +283,7 @@ int HWWall::CountVertices() // //========================================================================== -void HWWall::MakeVertices(HWDrawInfo *di, FRenderState& state, bool nosplit) +void HWWall::MakeVertices(FRenderState& state, bool nosplit) { if (vertcount == 0) { diff --git a/src/rendering/hwrenderer/scene/hw_weapon.cpp b/src/rendering/hwrenderer/scene/hw_weapon.cpp index f9f510bde..d4e3f4f06 100644 --- a/src/rendering/hwrenderer/scene/hw_weapon.cpp +++ b/src/rendering/hwrenderer/scene/hw_weapon.cpp @@ -68,7 +68,7 @@ void HWDrawInfo::DrawPSprite(HUDSprite *huds, FRenderState &state) } else { - SetColor(state, huds->lightlevel, 0, isFullbrightScene(), huds->cm, huds->alpha, true); + SetColor(state, Level, lightmode, huds->lightlevel, 0, isFullbrightScene(), huds->cm, huds->alpha, true); } state.SetLightIndex(-1); state.SetRenderStyle(huds->RenderStyle); @@ -120,7 +120,7 @@ void HWDrawInfo::DrawPSprite(HUDSprite *huds, FRenderState &state) void HWDrawInfo::DrawPlayerSprites(bool hudModelStep, FRenderState &state) { auto oldlightmode = lightmode; - if (!hudModelStep && isSoftwareLighting()) SetFallbackLightMode(); // Software lighting cannot handle 2D content. + if (!hudModelStep && isSoftwareLighting(oldlightmode)) SetFallbackLightMode(); // Software lighting cannot handle 2D content. for (auto &hudsprite : hudsprites) { if ((!!hudsprite.mframe) == hudModelStep) @@ -352,9 +352,9 @@ WeaponLighting HWDrawInfo::GetWeaponLighting(sector_t *viewsector, const DVector if (Level->flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING) l.cm.ClearColor(); } - l.lightlevel = CalcLightLevel(l.lightlevel, getExtraLight(), true, 0); + l.lightlevel = CalcLightLevel(lightmode, l.lightlevel, getExtraLight(), true, 0); - if (isSoftwareLighting() || l.lightlevel < 92) + if (isSoftwareLighting(lightmode) || 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 @@ -702,7 +702,7 @@ void HWDrawInfo::PreparePlayerSprites2D(sector_t * viewsector, area_t in_area, F // hack alert! Rather than changing everything in the underlying lighting code let's just temporarily change // light mode here to draw the weapon sprite. auto oldlightmode = lightmode; - if (isSoftwareLighting()) SetFallbackLightMode(); + if (isSoftwareLighting(oldlightmode)) SetFallbackLightMode(); for (DPSprite *psp = player->psprites; psp != nullptr && psp->GetID() < PSP_TARGETCENTER; psp = psp->GetNext()) { @@ -788,7 +788,7 @@ void HWDrawInfo::PreparePlayerSprites3D(sector_t * viewsector, area_t in_area, F // hack alert! Rather than changing everything in the underlying lighting code let's just temporarily change // light mode here to draw the weapon sprite. auto oldlightmode = lightmode; - if (isSoftwareLighting()) SetFallbackLightMode(); + if (isSoftwareLighting(oldlightmode)) SetFallbackLightMode(); for (DPSprite *psp = player->psprites; psp != nullptr && psp->GetID() < PSP_TARGETCENTER; psp = psp->GetNext()) { diff --git a/wadsrc/static/zscript/mapdata.zs b/wadsrc/static/zscript/mapdata.zs index dfe4a7016..8abfe8f1b 100644 --- a/wadsrc/static/zscript/mapdata.zs +++ b/wadsrc/static/zscript/mapdata.zs @@ -238,6 +238,7 @@ struct Line native play native clearscope int Index() const; native bool Activate(Actor activator, int side, int type); native bool RemoteActivate(Actor activator, int side, int type, Vector3 pos); + native bool, double, double GetMidTexturePosition (int side); clearscope int GetUDMFInt(Name nm) const {