From bea625a42c9aa0d854ae98e55a8a55945709730d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 23 Oct 2016 20:42:48 +0200 Subject: [PATCH 1/5] - added an ATTENUATE flag to dynamic lights, this is set by default for attached lights. For placed lights this is off, because it'd interfere with many existing maps that depend on unattenuated lights. --- src/gl/dynlights/gl_dynlight.cpp | 1 + src/gl/dynlights/gl_dynlight.h | 1 + src/gl/dynlights/gl_dynlight1.cpp | 2 +- wadsrc/static/shaders/glsl/main.fp | 17 ++++++++++------- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/gl/dynlights/gl_dynlight.cpp b/src/gl/dynlights/gl_dynlight.cpp index ae19ecf608..40008e3ad5 100644 --- a/src/gl/dynlights/gl_dynlight.cpp +++ b/src/gl/dynlights/gl_dynlight.cpp @@ -1082,6 +1082,7 @@ void gl_AttachLight(AActor *actor, unsigned int count, const FLightDefaults *lig light->target = actor; light->owned = true; light->ObjectFlags |= OF_Transient; + light->flags4 |= MF4_ATTENUATE; actor->dynamiclights.Push(light); } light->flags2&=~MF2_DORMANT; diff --git a/src/gl/dynlights/gl_dynlight.h b/src/gl/dynlights/gl_dynlight.h index 84965e3185..c51e0c79d8 100644 --- a/src/gl/dynlights/gl_dynlight.h +++ b/src/gl/dynlights/gl_dynlight.h @@ -50,6 +50,7 @@ enum #define MF4_SUBTRACTIVE MF4_MISSILEEVENMORE #define MF4_ADDITIVE MF4_MISSILEMORE #define MF4_DONTLIGHTSELF MF4_SEESDAGGERS +#define MF4_ATTENUATE MF4_INCOMBAT enum ELightType { diff --git a/src/gl/dynlights/gl_dynlight1.cpp b/src/gl/dynlights/gl_dynlight1.cpp index d20f5c01b1..2f8ef44edc 100644 --- a/src/gl/dynlights/gl_dynlight1.cpp +++ b/src/gl/dynlights/gl_dynlight1.cpp @@ -116,7 +116,7 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FD data[4] = r; data[5] = g; data[6] = b; - data[7] = 0; + data[7] = !!(light->flags4 & MF4_ATTENUATE); return true; } diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index fb1983fc73..36db31f681 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -142,16 +142,19 @@ float diffuseContribution(vec3 lightDirection, vec3 normal) // //=========================================================================== -float pointLightAttenuation(vec4 lightpos) +float pointLightAttenuation(vec4 lightpos, float attenuate) { float attenuation = max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w; - #if 0 + if (attenuate == 0.0) + { return attenuation; - #else + } + else + { vec3 lightDirection = normalize(lightpos.xyz - pixelpos.xyz); float diffuseAmount = diffuseContribution(lightDirection, normalize(vWorldNormal.xyz)); return attenuation * diffuseAmount; - #endif + } } //=========================================================================== @@ -229,7 +232,7 @@ vec4 getLightColor(float fogdist, float fogfactor) vec4 lightpos = lights[i]; vec4 lightcolor = lights[i+1]; - lightcolor.rgb *= pointLightAttenuation(lightpos); + lightcolor.rgb *= pointLightAttenuation(lightpos, lightcolor.a); dynlight.rgb += lightcolor.rgb; } // @@ -240,7 +243,7 @@ vec4 getLightColor(float fogdist, float fogfactor) vec4 lightpos = lights[i]; vec4 lightcolor = lights[i+1]; - lightcolor.rgb *= pointLightAttenuation(lightpos); + lightcolor.rgb *= pointLightAttenuation(lightpos, lightcolor.a); dynlight.rgb -= lightcolor.rgb; } } @@ -322,7 +325,7 @@ void main() vec4 lightpos = lights[i]; vec4 lightcolor = lights[i+1]; - lightcolor.rgb *= pointLightAttenuation(lightpos); + lightcolor.rgb *= pointLightAttenuation(lightpos, lightcolor.a); addlight.rgb += lightcolor.rgb; } frag.rgb = clamp(frag.rgb + desaturate(addlight).rgb, 0.0, 1.0); From 93ec6eb92e4e550ed8b126d6f53acbf933b4f7f3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 24 Oct 2016 22:22:47 +0200 Subject: [PATCH 2/5] - fixed DACSThinker did not save its LastScript member. This was probably responsible for some weird behavior recently, but with the addition of the OF_Transient flag this outright crashed because it left NULL pointers on reload in places where they weren't checked for. --- src/p_acs.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index fcbff904a8..f36aaaf69a 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -2907,7 +2907,8 @@ FSerializer &Serialize(FSerializer &arc, const char *key, SavingRunningscript &r void DACSThinker::Serialize(FSerializer &arc) { Super::Serialize(arc); - arc("scripts", Scripts); + arc("scripts", Scripts) + ("lastscript", LastScript); if (arc.isWriting()) { From 4e4fd97950c8b844a235c890f176c9233590bb18 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 24 Oct 2016 23:35:18 +0200 Subject: [PATCH 3/5] - fixed: Multipatch textures may not set up their patch references until all textures have been loaded. If done earlier they will not be able to detect overrides of sprites and graphics which are not part of the PATCHES lump. There was some fudging code to work around this problem but it was only partially working. Now these textures only collect the texture name and use type during setup and resolve them after all textures have been created. --- src/textures/multipatchtexture.cpp | 187 ++++++++++++++++------------- src/textures/texturemanager.cpp | 4 + src/textures/textures.h | 1 + 3 files changed, 110 insertions(+), 82 deletions(-) diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index b0db481a89..741f88a31c 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -48,6 +48,7 @@ #include "v_palette.h" #include "v_video.h" #include "v_text.h" +#include "cmdlib.h" #include "m_fixed.h" #include "textures/textures.h" #include "r_data/colormaps.h" @@ -138,7 +139,6 @@ struct strifemaptexture_t struct FPatchLookup { FString Name; - FTexture *Texture; }; @@ -166,6 +166,7 @@ public: int GetSourceLump() { return DefinitionLump; } FTexture *GetRedirect(bool wantwarped); FTexture *GetRawTexture(); + void ResolvePatches(); protected: BYTE *Pixels; @@ -185,8 +186,18 @@ protected: TexPart(); }; + struct TexInit + { + FString TexName; + int UseType = TEX_Null; + bool Silent = false; + bool HasLine = false; + FScriptPosition sc; + }; + int NumParts; TexPart *Parts; + TexInit *Inits; bool bRedirect:1; bool bTranslucentPatches:1; @@ -194,7 +205,7 @@ protected: private: void CheckForHacks (); - void ParsePatch(FScanner &sc, TexPart & part, bool silent, int usetype); + void ParsePatch(FScanner &sc, TexPart & part, TexInit &init); }; //========================================================================== @@ -204,7 +215,7 @@ private: //========================================================================== FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflumpnum) -: Pixels (0), Spans(0), Parts(0), bRedirect(false), bTranslucentPatches(false) +: Pixels (0), Spans(0), Parts(nullptr), Inits(nullptr), bRedirect(false), bTranslucentPatches(false) { union { @@ -240,7 +251,8 @@ FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchl } UseType = FTexture::TEX_Wall; - Parts = NumParts > 0 ? new TexPart[NumParts] : NULL; + Parts = NumParts > 0 ? new TexPart[NumParts] : nullptr; + Inits = NumParts > 0 ? new TexInit[NumParts] : nullptr; Width = SAFESHORT(mtexture.d->width); Height = SAFESHORT(mtexture.d->height); Name = (char *)mtexture.d->name; @@ -272,17 +284,9 @@ FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchl } Parts[i].OriginX = LittleShort(mpatch.d->originx); Parts[i].OriginY = LittleShort(mpatch.d->originy); - Parts[i].Texture = patchlookup[LittleShort(mpatch.d->patch)].Texture; - if (Parts[i].Texture == NULL) - { - Printf(TEXTCOLOR_RED "Unknown patch %s in texture %s\n", patchlookup[LittleShort(mpatch.d->patch)].Name.GetChars(), Name.GetChars()); - NumParts--; - i--; - } - else - { - Parts[i].Texture->bKeepAround = true; - } + Parts[i].Texture = nullptr; + Inits[i].TexName = patchlookup[LittleShort(mpatch.d->patch)].Name; + Inits[i].UseType = TEX_WallPatch; if (strife) mpatch.s++; else @@ -295,17 +299,6 @@ FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchl CheckForHacks (); - // If this texture is just a wrapper around a single patch, we can simply - // forward GetPixels() and GetColumn() calls to that patch. - if (NumParts == 1) - { - if (Parts->OriginX == 0 && Parts->OriginY == 0 && - Parts->Texture->GetWidth() == Width && - Parts->Texture->GetHeight() == Height) - { - bRedirect = true; - } - } DefinitionLump = deflumpnum; } @@ -327,6 +320,11 @@ FMultiPatchTexture::~FMultiPatchTexture () delete[] Parts; Parts = NULL; } + if (Inits != nullptr) + { + delete[] Inits; + Inits = nullptr; + } if (Spans != NULL) { FreeSpans (Spans); @@ -863,19 +861,6 @@ void FTextureManager::AddTexturesLump (const void *lumpdata, int lumpsize, int d pnames.Read(pname, 8); pname[8] = '\0'; patchlookup[i].Name = pname; - FTextureID j = CheckForTexture (patchlookup[i].Name, FTexture::TEX_WallPatch); - if (j.isValid()) - { - patchlookup[i].Texture = Textures[j.GetIndex()].Texture; - } - else - { - // Shareware Doom has the same PNAMES lump as the registered - // Doom, so printing warnings for patches that don't really - // exist isn't such a good idea. - //Printf ("Patch %s not found.\n", patchlookup[i].Name); - patchlookup[i].Texture = NULL; - } } } @@ -996,35 +981,13 @@ void FTextureManager::AddTexturesLumps (int lump1, int lump2, int patcheslump) // //========================================================================== -void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part, bool silent, int usetype) +void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part, TexInit &init) { FString patchname; + int Mirror = 0; sc.MustGetString(); - FTextureID texno = TexMan.CheckForTexture(sc.String, usetype); - int Mirror = 0; - - if (!texno.isValid()) - { - if (strlen(sc.String) <= 8 && !strpbrk(sc.String, "./")) - { - int lumpnum = Wads.CheckNumForName(sc.String, usetype == TEX_MiscPatch? ns_graphics : ns_patches); - if (lumpnum >= 0) - { - part.Texture = FTexture::CreateTexture(lumpnum, usetype); - TexMan.AddTexture(part.Texture); - } - } - } - else - { - part.Texture = TexMan[texno]; - bComplex |= part.Texture->bComplex; - } - if (part.Texture == NULL) - { - if (!silent) sc.ScriptMessage(TEXTCOLOR_RED "Unknown patch '%s' in texture '%s'\n", sc.String, Name.GetChars()); - } + init.TexName = sc.String; sc.MustGetStringName(","); sc.MustGetNumber(); part.OriginX = sc.Number; @@ -1207,6 +1170,7 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, int usetype) : Pixels (0), Spans(0), Parts(0), bRedirect(false), bTranslucentPatches(false) { TArray parts; + TArray inits; bool bSilent = false; bMultiPatch = true; @@ -1267,16 +1231,34 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, int usetype) else if (sc.Compare("Patch")) { TexPart part; - ParsePatch(sc, part, bSilent, TEX_WallPatch); - if (part.Texture != NULL) parts.Push(part); + TexInit init; + ParsePatch(sc, part, init); + if (init.TexName.IsNotEmpty()) + { + parts.Push(part); + init.UseType = TEX_WallPatch; + init.Silent = bSilent; + init.HasLine = true; + init.sc = sc; + inits.Push(init); + } part.Texture = NULL; part.Translation = NULL; } else if (sc.Compare("Graphic")) { TexPart part; - ParsePatch(sc, part, bSilent, TEX_MiscPatch); - if (part.Texture != NULL) parts.Push(part); + TexInit init; + ParsePatch(sc, part, init); + if (init.TexName.IsNotEmpty()) + { + parts.Push(part); + init.UseType = TEX_MiscPatch; + init.Silent = bSilent; + init.HasLine = true; + init.sc = sc; + inits.Push(init); + } part.Texture = NULL; part.Translation = NULL; } @@ -1297,21 +1279,10 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, int usetype) NumParts = parts.Size(); Parts = new TexPart[NumParts]; memcpy(Parts, &parts[0], NumParts * sizeof(*Parts)); - - //CalcBitSize (); - - // If this texture is just a wrapper around a single patch, we can simply - // forward GetPixels() and GetColumn() calls to that patch. - if (NumParts == 1) + Inits = new TexInit[NumParts]; + for (int i = 0; i < NumParts; i++) { - if (Parts->OriginX == 0 && Parts->OriginY == 0 && - Parts->Texture->GetWidth() == Width && - Parts->Texture->GetHeight() == Height && - Parts->Rotate == 0 && - !bComplex) - { - bRedirect = true; - } + Inits[i] = inits[i]; } } @@ -1328,6 +1299,58 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, int usetype) } +void FMultiPatchTexture::ResolvePatches() +{ + if (Inits != nullptr) + { + for (int i = 0; i < NumParts; i++) + { + FTextureID texno = TexMan.CheckForTexture(Inits[i].TexName, Inits[i].UseType); + + if (!texno.isValid()) + { + if (!Inits[i].Silent) + { + if (Inits[i].HasLine) Inits[i].sc.Message(MSG_WARNING, "Unknown patch '%s' in texture '%s'\n", Inits[i].TexName.GetChars(), Name.GetChars()); + else Printf(TEXTCOLOR_YELLOW "Unknown patch '%s' in texture '%s'\n", Inits[i].TexName.GetChars(), Name.GetChars()); + } + } + else + { + Parts[i].Texture = TexMan[texno]; + bComplex |= Parts[i].Texture->bComplex; + Parts[i].Texture->bKeepAround = true; + } + } + for (int i = 0; i < NumParts; i++) + { + if (Parts[i].Texture == nullptr) + { + memcpy(&Parts[i], &Parts[i + 1], NumParts - i - 1); + i--; + NumParts--; + } + } + } + delete[] Inits; + Inits = nullptr; + + // If this texture is just a wrapper around a single patch, we can simply + // forward GetPixels() and GetColumn() calls to that patch. + + if (NumParts == 1) + { + if (Parts->OriginX == 0 && Parts->OriginY == 0 && + Parts->Texture->GetWidth() == Width && + Parts->Texture->GetHeight() == Height && + Parts->Rotate == 0 && + !bComplex) + { + bRedirect = true; + } + } +} + void FTextureManager::ParseXTexture(FScanner &sc, int usetype) { diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 3fb01dc6cf..07ed71a3bb 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -981,6 +981,10 @@ void FTextureManager::Init() { AddTexturesForWad(i); } + for (unsigned i = 0; i < Textures.Size(); i++) + { + Textures[i].Texture->ResolvePatches(); + } // Add one marker so that the last WAD is easier to handle and treat // Build tiles as a completely separate block. diff --git a/src/textures/textures.h b/src/textures/textures.h index ad1d9ba8c2..407500f185 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -209,6 +209,7 @@ public: int GetScaledTopOffset () { int foo = int((TopOffset * 2) / Scale.Y); return (foo >> 1) + (foo & 1); } double GetScaledLeftOffsetDouble() { return LeftOffset / Scale.X; } double GetScaledTopOffsetDouble() { return TopOffset / Scale.Y; } + virtual void ResolvePatches() {} virtual void SetFrontSkyLayer(); From 8368272b4d5848d2f6596d5350164b3902194e94 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 24 Oct 2016 23:40:37 +0200 Subject: [PATCH 4/5] - just to be thorough, added a 'sprite' keyword to define a patch to give priority to the TEX_Sprite namespace. --- src/textures/multipatchtexture.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index 741f88a31c..340376a25b 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -1245,6 +1245,23 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, int usetype) part.Texture = NULL; part.Translation = NULL; } + else if (sc.Compare("Sprite")) + { + TexPart part; + TexInit init; + ParsePatch(sc, part, init); + if (init.TexName.IsNotEmpty()) + { + parts.Push(part); + init.UseType = TEX_Sprite; + init.Silent = bSilent; + init.HasLine = true; + init.sc = sc; + inits.Push(init); + } + part.Texture = NULL; + part.Translation = NULL; + } else if (sc.Compare("Graphic")) { TexPart part; From dad89b07830f649af1e26cba15990328e517ddf6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 25 Oct 2016 01:03:44 +0200 Subject: [PATCH 5/5] - fixed: Portals with disconnected parts were not grouped correctly. --- src/portal.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/portal.cpp b/src/portal.cpp index cef79820fe..f1454cdc6c 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -1024,7 +1024,8 @@ void P_CreateLinkedPortals() { if (sectors[i].GetPortalType(j) == PORTS_LINKEDPORTAL && sectors[i].PortalGroup == 0) { - CollectSectors(sectors[i].GetOppositePortalGroup(j), §ors[i]); + auto p = sectors[i].GetPortal(j); + CollectSectors(p->mOrigin->PortalGroup, §ors[i]); } } }