From dc9c7afa246f1e318e2b03cd17e6d9e39b3b2694 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 16:05:48 +0100 Subject: [PATCH 01/17] - reimplemented the GetRawTexture redirect. --- src/textures/formats/multipatchtexture.h | 2 ++ src/textures/texture.cpp | 16 +++++++++++++++- src/textures/textures.h | 5 +++-- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/textures/formats/multipatchtexture.h b/src/textures/formats/multipatchtexture.h index f1284e0a90..3d78008328 100644 --- a/src/textures/formats/multipatchtexture.h +++ b/src/textures/formats/multipatchtexture.h @@ -1,4 +1,5 @@ #pragma once +#include "sc_man.h" //========================================================================== // @@ -28,6 +29,7 @@ struct TexPart class FMultiPatchTexture : public FImageSource { + friend class FTexture; public: FMultiPatchTexture(int w, int h, const TArray &parts, bool complex, bool textual); diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index ec09c38980..6f01f0e4fc 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -50,6 +50,7 @@ #include "swrenderer/textures/r_swtexture.h" #include "imagehelpers.h" #include "image.h" +#include "formats/multipatchtexture.h" FTexture *CreateBrightmapTexture(FImageSource*); @@ -221,7 +222,20 @@ FBitmap FTexture::GetBgraBitmap(PalEntry *remap, int *ptrans) FTexture *FTexture::GetRawTexture() { - return this; + if (OffsetLess) return OffsetLess; + // Reject anything that cannot have been a single-patch multipatch texture in vanilla. + auto image = static_cast(GetImage()); + if (bMultiPatch != 1 || UseType != ETextureType::Wall || Scale.X != 1 || Scale.Y != 1 || bWorldPanning || image == nullptr || image->NumParts != 1) + { + OffsetLess = this; + return this; + } + // Set up a new texture that directly references the underlying patch. + // From here we cannot retrieve the original texture made for it, so just create a new one. + FImageSource *source = image->Parts[0].Image; + OffsetLess = new FImageTexture(source, ""); + TexMan.AddTexture(OffsetLess); + return OffsetLess; } void FTexture::SetScaledSize(int fitwidth, int fitheight) diff --git a/src/textures/textures.h b/src/textures/textures.h index d250266347..e40b9fc0a2 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -338,7 +338,7 @@ public: int GetSkyOffset() const { return SkyOffset; } FTextureID GetID() const { return id; } PalEntry GetSkyCapColor(bool bottom); - virtual FTexture *GetRawTexture(); // for FMultiPatchTexture to override + FTexture *GetRawTexture(); virtual int GetSourceLump() { return SourceLump; } // needed by the scripted GetName method. void GetGlowColor(float *data); bool isGlowing() const { return bGlowing; } @@ -371,11 +371,12 @@ protected: public: FHardwareTextureContainer SystemTextures; protected: - //IHardwareTexture *SystemTexture[2] = { nullptr, nullptr }; FSoftwareTexture *SoftwareTexture = nullptr; // None of the following pointers are owned by this texture, they are all controlled by the texture manager. + // Offset-less version for COMPATF_MASKEDMIDTEX + FTexture *OffsetLess = nullptr; // Paletted variant FTexture *PalVersion = nullptr; // External hires texture From 74ea9143ee2f7b79eb399bb4571be2d36c3830dc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 16:29:37 +0100 Subject: [PATCH 02/17] - added a 'forceworldpanning' map flag. Since unfortunately this cannot be set as a general default, let's at least make it as easy as possible to disable that panning+scaling madness without having to edit the texture data. --- src/g_level.h | 1 + src/g_mapinfo.cpp | 1 + src/swrenderer/textures/r_swtexture.h | 3 ++- src/textures/texture.cpp | 3 ++- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/g_level.h b/src/g_level.h index f512287d36..46ffbf795b 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -247,6 +247,7 @@ enum ELevelFlags : unsigned int LEVEL3_NOCOLOREDSPRITELIGHTING = 0x00000010, // draw sprites only with color-less light LEVEL3_EXITNORMALUSED = 0x00000020, LEVEL3_EXITSECRETUSED = 0x00000040, + LEVEL3_FORCEWORLDPANNING = 0x00000080, // Forces the world panning flag for all textures, even those without it explicitly set. }; diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index e79abf0c84..4595afff00 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -1553,6 +1553,7 @@ MapFlagHandlers[] = { "forcefakecontrast", MITYPE_SETFLAG3, LEVEL3_FORCEFAKECONTRAST, 0 }, { "nolightfade", MITYPE_SETFLAG3, LEVEL3_NOLIGHTFADE, 0 }, { "nocoloredspritelighting", MITYPE_SETFLAG3, LEVEL3_NOCOLOREDSPRITELIGHTING, 0 }, + { "forceworldpanning", MITYPE_SETFLAG3, LEVEL3_FORCEWORLDPANNING, 0 }, { "nobotnodes", MITYPE_IGNORE, 0, 0 }, // Skulltag option: nobotnodes { "compat_shorttex", MITYPE_COMPATFLAG, COMPATF_SHORTTEX, 0 }, { "compat_stairs", MITYPE_COMPATFLAG, COMPATF_STAIRINDEX, 0 }, diff --git a/src/swrenderer/textures/r_swtexture.h b/src/swrenderer/textures/r_swtexture.h index 14810b0719..f03f8c86a6 100644 --- a/src/swrenderer/textures/r_swtexture.h +++ b/src/swrenderer/textures/r_swtexture.h @@ -1,6 +1,7 @@ #pragma once #include "textures/textures.h" #include "v_video.h" +#include "g_levellocals.h" struct FSoftwareTextureSpan @@ -48,7 +49,7 @@ public: // The feature from hell... :( bool useWorldPanning() const { - return mTexture->bWorldPanning; + return mTexture->bWorldPanning || (level.flags3 & LEVEL3_FORCEWORLDPANNING); } bool isMasked() diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 6f01f0e4fc..44203413aa 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -51,6 +51,7 @@ #include "imagehelpers.h" #include "image.h" #include "formats/multipatchtexture.h" +#include "g_levellocals.h" FTexture *CreateBrightmapTexture(FImageSource*); @@ -903,7 +904,7 @@ void FTexCoordInfo::GetFromTexture(FTexture *tex, float x, float y) mScale.Y = -mScale.Y; mRenderHeight = -mRenderHeight; } - mWorldPanning = tex->bWorldPanning; + mWorldPanning = tex->bWorldPanning || (level.flags3 & LEVEL3_FORCEWORLDPANNING); mWidth = tex->GetWidth(); } From c105a1f670d1a9e90b4e6614296b8e9493bafd38 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 16:57:20 +0100 Subject: [PATCH 03/17] - fixed two broken ScriptUtil calls in FraggleScript. --- src/fragglescript/t_func.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 87858f91f0..fe15599916 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -2453,7 +2453,7 @@ void FParser::SF_PlayerKeys(void) else { givetake = intvalue(t_argv[2]); - ScriptUtil::Exec(givetake?NAME_GiveInventory : NAME_TakeInventory, players[playernum].mo, keyname.GetIndex(), 1); + ScriptUtil::Exec(givetake?NAME_GiveInventory : NAME_TakeInventory, ScriptUtil::Pointer, players[playernum].mo, ScriptUtil::Int, keyname.GetIndex(), ScriptUtil::Int, 1, ScriptUtil::End); t_return.type = svt_int; t_return.value.i = 0; } @@ -2648,7 +2648,7 @@ void FParser::SF_GiveInventory(void) if(t_argc == 2) count=1; else count=intvalue(t_argv[2]); - ScriptUtil::Exec(NAME_GiveInventory, ScriptUtil::Pointer, players[playernum].mo, FName(stringvalue(t_argv[1])).GetIndex(), count); + ScriptUtil::Exec(NAME_GiveInventory, ScriptUtil::Pointer, players[playernum].mo, ScriptUtil::Int, FName(stringvalue(t_argv[1])).GetIndex(), ScriptUtil::Int, count, ScriptUtil::End); t_return.type = svt_int; t_return.value.i = 0; } @@ -2671,7 +2671,7 @@ void FParser::SF_TakeInventory(void) if(t_argc == 2) count=32767; else count=intvalue(t_argv[2]); - ScriptUtil::Exec(NAME_TakeInventory, ScriptUtil::Pointer, players[playernum].mo, FName(stringvalue(t_argv[1])).GetIndex(), count); + ScriptUtil::Exec(NAME_TakeInventory, ScriptUtil::Pointer, players[playernum].mo, ScriptUtil::Int, FName(stringvalue(t_argv[1])).GetIndex(), ScriptUtil::Int, count, ScriptUtil::End); t_return.type = svt_int; t_return.value.i = 0; } From d1ca2a91f38a6d93c275da148f0c6f6c8bab9493 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 17:49:12 +0100 Subject: [PATCH 04/17] - fixed: ThePatchRemap table was only initialized in one of FFont's constructors. --- src/d_dehacked.cpp | 1 - src/v_font.cpp | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 2562d8e636..ad7a3f8918 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -2694,7 +2694,6 @@ static bool LoadDehSupp () return false; } bool gotnames = false; - int i; if (++DehUseCount > 1) diff --git a/src/v_font.cpp b/src/v_font.cpp index e1e5998ba2..ccbe56c41c 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -899,6 +899,8 @@ FFont::FFont (int lump) FontName = NAME_None; Cursor = '_'; noTranslate = false; + uint8_t pp = 0; + for (auto &p : PatchRemap) p = pp++; } //========================================================================== From e6e4f0f305e17cbd4da9b50d29b91560d1392bd7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 19:15:05 +0100 Subject: [PATCH 05/17] - disabled redirection to the original patch for FSpecialFont. Using the same code as for the standard font does not work as intended, the reason still needs to be investigated. --- src/v_font.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v_font.cpp b/src/v_font.cpp index ccbe56c41c..b42de72d30 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -1552,13 +1552,13 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l if (charlumps[i] != nullptr) { - Chars[i].OriginalPic = charlumps[i]; if (!noTranslate) { Chars[i].TranslatedPic = new FImageTexture(new FFontChar1 (charlumps[i]->GetImage()), ""); TexMan.AddTexture(Chars[i].TranslatedPic); } else Chars[i].TranslatedPic = charlumps[i]; + Chars[i].OriginalPic = Chars[i].TranslatedPic; Chars[i].XMove = Chars[i].OriginalPic->GetDisplayWidth(); } else From 8e24a50b36d8301240e6bb118e78748da246c104 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 20:07:21 +0100 Subject: [PATCH 06/17] - let FxNop have a value type, even if it's just TypeError. --- src/scripting/backend/codegen.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/scripting/backend/codegen.h b/src/scripting/backend/codegen.h index 3876f96261..4140b9d9bf 100644 --- a/src/scripting/backend/codegen.h +++ b/src/scripting/backend/codegen.h @@ -2104,6 +2104,7 @@ public: : FxExpression(EFX_Nop, p) { isresolved = true; + ValueType = TypeError; } ExpEmit Emit(VMFunctionBuilder *build) { From 091f73b833d41c5d5dfa597b713df9bbe058cc33 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 20:22:42 +0100 Subject: [PATCH 07/17] - fixed: no sprites were drawn in a sector if it only had ones in its sectorportal_thinglist. --- src/hwrenderer/scene/hw_bsp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hwrenderer/scene/hw_bsp.cpp b/src/hwrenderer/scene/hw_bsp.cpp index 39d4145f37..4daadd63f2 100644 --- a/src/hwrenderer/scene/hw_bsp.cpp +++ b/src/hwrenderer/scene/hw_bsp.cpp @@ -646,7 +646,7 @@ void HWDrawInfo::DoSubsector(subsector_t * sub) sector->validcount = validcount; sector->MoreFlags |= SECMF_DRAWN; - if (gl_render_things && sector->touching_renderthings) + if (gl_render_things && (sector->touching_renderthings || sector->sectorportal_thinglist)) { if (multithread) { From 39f6489ac50d17159745bb51ceb08f729784ed26 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 20:40:17 +0100 Subject: [PATCH 08/17] - two more places where explicit allocations could be replaced. --- src/p_things.cpp | 7 +++---- src/p_user.cpp | 8 ++------ 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/p_things.cpp b/src/p_things.cpp index f6d5139f68..0eb7ef5ebd 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -572,23 +572,22 @@ static int SpawnableSort(const void *a, const void *b) static void DumpClassMap(FClassMap &themap) { FClassMap::Iterator it(themap); - FClassMap::Pair *pair, **allpairs; + FClassMap::Pair *pair; + TArray allpairs(themap.CountUsed(), true); int i = 0; // Sort into numerical order, since their arrangement in the map can // be in an unspecified order. - allpairs = new FClassMap::Pair *[themap.CountUsed()]; while (it.NextPair(pair)) { allpairs[i++] = pair; } - qsort(allpairs, i, sizeof(*allpairs), SpawnableSort); + qsort(allpairs.Data, i, sizeof(allpairs[0]), SpawnableSort); for (int j = 0; j < i; ++j) { pair = allpairs[j]; Printf ("%d %s\n", pair->Key, pair->Value->TypeName.GetChars()); } - delete[] allpairs; } CCMD(dumpspawnables) diff --git a/src/p_user.cpp b/src/p_user.cpp index 4bae6ee5e0..6077d597c0 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -429,12 +429,8 @@ void player_t::SetLogNumber (int num) } else { - int length=Wads.LumpLength(lumpnum); - char *data= new char[length+1]; - Wads.ReadLump (lumpnum, data); - data[length]=0; - SetLogText (data); - delete[] data; + auto lump = Wads.ReadLump(lumpnum); + SetLogText (lump.GetString()); } } From c92e6b03ac461ac16c13412ae414332145e60081 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 21:39:00 +0100 Subject: [PATCH 09/17] - why wasn't this saved? --- src/p_things.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_things.cpp b/src/p_things.cpp index 0eb7ef5ebd..9728c691ea 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -582,7 +582,7 @@ static void DumpClassMap(FClassMap &themap) { allpairs[i++] = pair; } - qsort(allpairs.Data, i, sizeof(allpairs[0]), SpawnableSort); + qsort(allpairs.Data(), i, sizeof(allpairs[0]), SpawnableSort); for (int j = 0; j < i; ++j) { pair = allpairs[j]; From 87b0567cd75ad5d1ed7086359bda4d9fd3790312 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 23:32:49 +0100 Subject: [PATCH 10/17] - the font character substitution logic needed more fixes. The ZScript DrawChar function was incomplete and FFont::GetChar did not always return the proper texture. To make things clearer the OriginalPic is now only used in the few cases where substitution takes place and nothing else. --- src/v_font.cpp | 59 ++++++++++++++++++++------------------------------ src/v_font.h | 6 ++--- src/v_text.cpp | 5 +++-- 3 files changed, 30 insertions(+), 40 deletions(-) diff --git a/src/v_font.cpp b/src/v_font.cpp index b42de72d30..aaf4507252 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -381,20 +381,19 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, if (charLumps[i] != nullptr) { - Chars[i].OriginalPic = charLumps[i]; - if (!noTranslate) { + Chars[i].OriginalPic = charLumps[i]; Chars[i].TranslatedPic = new FImageTexture(new FFontChar1 (charLumps[i]->GetImage()), ""); TexMan.AddTexture(Chars[i].TranslatedPic); } else Chars[i].TranslatedPic = charLumps[i]; - Chars[i].XMove = Chars[i].OriginalPic->GetDisplayWidth(); + Chars[i].XMove = Chars[i].TranslatedPic->GetDisplayWidth(); } else { - Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr; + Chars[i].TranslatedPic = nullptr; Chars[i].XMove = INT_MIN; } } @@ -403,7 +402,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, { SpaceWidth = spacewidth; } - else if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].OriginalPic != nullptr) + else if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].TranslatedPic != nullptr) { SpaceWidth = (Chars['N' - first].XMove + 1) / 2; } @@ -706,7 +705,7 @@ int FFont::GetCharCode(int code, bool needpic) const // regular chars turn negative when the 8th bit is set. code &= 255; } - if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].OriginalPic != nullptr)) + if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].TranslatedPic != nullptr)) { return code; } @@ -714,7 +713,7 @@ int FFont::GetCharCode(int code, bool needpic) const if (myislower(code)) { code -= 32; - if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].OriginalPic != nullptr)) + if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].TranslatedPic != nullptr)) { return code; } @@ -724,7 +723,7 @@ int FFont::GetCharCode(int code, bool needpic) const if (newcode != code) { code = newcode; - if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].OriginalPic != nullptr)) + if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].TranslatedPic != nullptr)) { return code; } @@ -747,7 +746,7 @@ FTexture *FFont::GetChar (int code, int translation, int *const width, bool *red { code -= FirstChar; xmove = Chars[code].XMove; - if (Chars[code].OriginalPic == nullptr) + if (Chars[code].TranslatedPic == nullptr) { code = GetCharCode(code + FirstChar, true); if (code >= 0) @@ -766,9 +765,10 @@ FTexture *FFont::GetChar (int code, int translation, int *const width, bool *red if (translation == CR_UNTRANSLATED) { - if (redirected) - *redirected = Chars[code].OriginalPic != Chars[code].TranslatedPic; - return Chars[code].OriginalPic; + bool redirect = Chars[code].OriginalPic && Chars[code].OriginalPic != Chars[code].TranslatedPic; + if (redirected) *redirected = redirect; + if (redirect) + return Chars[code].OriginalPic; } if (redirected) *redirected = false; return Chars[code].TranslatedPic; @@ -963,7 +963,7 @@ void FSingleLumpFont::CreateFontFromPic (FTextureID picnum) FirstChar = LastChar = 'A'; Chars.Resize(1); - Chars[0].TranslatedPic = Chars[0].OriginalPic = pic; + Chars[0].TranslatedPic = pic; // Only one color range. Don't bother with the others. ActiveColors = 0; @@ -1040,10 +1040,6 @@ void FSingleLumpFont::LoadFON1 (int lump, const uint8_t *data) LastChar = 255; GlobalKerning = 0; translateUntranslated = true; - - for(unsigned int i = 0;i < 256;++i) - Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr; - LoadTranslations(); } @@ -1128,12 +1124,12 @@ void FSingleLumpFont::LoadFON2 (int lump, const uint8_t *data) Chars[i].XMove = widths2[i]; if (destSize <= 0) { - Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr; + Chars[i].TranslatedPic = nullptr; } else { - Chars[i].TranslatedPic = Chars[i].OriginalPic = new FImageTexture(new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight)); - TexMan.AddTexture(Chars[i].OriginalPic); + Chars[i].TranslatedPic = new FImageTexture(new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight)); + TexMan.AddTexture(Chars[i].TranslatedPic); do { int8_t code = *data_p++; @@ -1216,12 +1212,6 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data) } count = LastChar - FirstChar + 1; Chars.Resize(count); - for (i = 0; i < count; ++i) - { - Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr; - Chars[i].XMove = INT_MIN; - } - // BMF palettes are only six bits per component. Fix that. for (i = 0; i < ActiveColors*3; ++i) { @@ -1273,7 +1263,7 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data) -(int8_t)chardata[chari+3], // x offset -(int8_t)chardata[chari+4] // y offset )); - Chars[chardata[chari] - FirstChar].TranslatedPic = Chars[chardata[chari] - FirstChar].OriginalPic = tex; + Chars[chardata[chari] - FirstChar].TranslatedPic = tex; TexMan.AddTexture(tex); } @@ -1337,13 +1327,12 @@ void FSingleLumpFont::CheckFON1Chars (double *luminosity) { int destSize = SpaceWidth * FontHeight; - if(!Chars[i].OriginalPic) + if(!Chars[i].TranslatedPic) { - Chars[i].OriginalPic = new FImageTexture(new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight)); + Chars[i].TranslatedPic = new FImageTexture(new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight)); Chars[i].XMove = SpaceWidth; - TexMan.AddTexture(Chars[i].OriginalPic); + TexMan.AddTexture(Chars[i].TranslatedPic); } - Chars[i].TranslatedPic = Chars[i].OriginalPic; // Advance to next char's data and count the used colors. do @@ -1552,24 +1541,24 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l if (charlumps[i] != nullptr) { + Chars[i].OriginalPic = charlumps[i]; if (!noTranslate) { Chars[i].TranslatedPic = new FImageTexture(new FFontChar1 (charlumps[i]->GetImage()), ""); TexMan.AddTexture(Chars[i].TranslatedPic); } else Chars[i].TranslatedPic = charlumps[i]; - Chars[i].OriginalPic = Chars[i].TranslatedPic; - Chars[i].XMove = Chars[i].OriginalPic->GetDisplayWidth(); + Chars[i].XMove = Chars[i].TranslatedPic->GetDisplayWidth(); } else { - Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr; + Chars[i].TranslatedPic = nullptr; Chars[i].XMove = INT_MIN; } } // Special fonts normally don't have all characters so be careful here! - if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].OriginalPic != nullptr) + if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].TranslatedPic != nullptr) { SpaceWidth = (Chars['N' - first].XMove + 1) / 2; } diff --git a/src/v_font.h b/src/v_font.h index b15790844a..96283947ad 100644 --- a/src/v_font.h +++ b/src/v_font.h @@ -123,9 +123,9 @@ protected: bool translateUntranslated; struct CharData { - FTexture *TranslatedPic; // Texture for use with font translations. - FTexture *OriginalPic; // Texture for use with CR_UNTRANSLATED or font colorization. - int XMove; + FTexture *TranslatedPic = nullptr; // Texture for use with font translations. + FTexture *OriginalPic = nullptr; // Texture for use with CR_UNTRANSLATED or font colorization. + int XMove = INT_MIN; }; TArray Chars; int ActiveColors; diff --git a/src/v_text.cpp b/src/v_text.cpp index ea977168fc..a6d57399b9 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -169,15 +169,16 @@ void DFrameBuffer::DrawChar(FFont *font, int normalcolor, double x, double y, in FTexture *pic; int dummy; + bool redirected; - if (NULL != (pic = font->GetChar(character, normalcolor, &dummy))) + if (NULL != (pic = font->GetChar(character, normalcolor, &dummy, &redirected))) { DrawParms parms; uint32_t tag = ListGetInt(args); bool res = ParseDrawTextureTags(pic, x, y, tag, args, &parms, false); if (!res) return; PalEntry color = 0xffffffff; - parms.remap = font->GetColorTranslation((EColorRange)normalcolor, &color); + parms.remap = redirected ? nullptr : font->GetColorTranslation((EColorRange)normalcolor, &color); parms.color = PalEntry((color.a * parms.color.a) / 255, (color.r * parms.color.r) / 255, (color.g * parms.color.g) / 255, (color.b * parms.color.b) / 255); DrawTextureParms(pic, parms); } From 51f03c8215c35116eca4bc1ef9060724512a1e87 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 16 Dec 2018 00:37:34 +0100 Subject: [PATCH 11/17] - a few more fixes. --- src/textures/skyboxtexture.cpp | 1 + src/v_font.cpp | 5 +++-- src/v_font.h | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/textures/skyboxtexture.cpp b/src/textures/skyboxtexture.cpp index 6b5346ac28..45e79bf74d 100644 --- a/src/textures/skyboxtexture.cpp +++ b/src/textures/skyboxtexture.cpp @@ -38,6 +38,7 @@ FSkyBox::FSkyBox(const char *name) : FTexture(name) { FTextureID texid = TexMan.CheckForTexture(name, ETextureType::Wall); + previous = nullptr; if (texid.isValid()) { previous = TexMan.GetTexture(texid); diff --git a/src/v_font.cpp b/src/v_font.cpp index aaf4507252..da33352365 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -149,7 +149,7 @@ public: FSinglePicFont(const char *picname); // FFont interface - FTexture *GetChar (int code, int *const width) const; + FTexture *GetChar(int code, int translation, int *const width, bool *redirected = nullptr) const override; int GetCharWidth (int code) const; protected: @@ -1465,9 +1465,10 @@ FSinglePicFont::FSinglePicFont(const char *picname) : // //========================================================================== -FTexture *FSinglePicFont::GetChar (int code, int *const width) const +FTexture *FSinglePicFont::GetChar (int code, int translation, int *const width, bool *redirected) const { *width = SpaceWidth; + if (redirected) *redirected = false; if (code == 'a' || code == 'A') { return TexMan.GetPalettedTexture(PicNum, true); diff --git a/src/v_font.h b/src/v_font.h index 96283947ad..7e83735320 100644 --- a/src/v_font.h +++ b/src/v_font.h @@ -82,7 +82,7 @@ public: FFont (const char *fontname, const char *nametemplate, int first, int count, int base, int fdlump, int spacewidth=-1, bool notranslate = false); virtual ~FFont (); - FTexture *GetChar (int code, int translation, int *const width, bool *redirected = nullptr) const; + virtual FTexture *GetChar (int code, int translation, int *const width, bool *redirected = nullptr) const; virtual int GetCharWidth (int code) const; FRemapTable *GetColorTranslation (EColorRange range, PalEntry *color = nullptr) const; int GetLump() const { return Lump; } From d0ce0218052f44840b1662ff039727a245645a72 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 16 Dec 2018 09:05:02 +0100 Subject: [PATCH 12/17] - fixed: Both main and worker thread were modifying the portal state. The parts in the main thread have been offloaded to a new worker job to avoid having to use a mutex to protect the portal state. --- src/hwrenderer/scene/hw_bsp.cpp | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/hwrenderer/scene/hw_bsp.cpp b/src/hwrenderer/scene/hw_bsp.cpp index 4daadd63f2..732af5641f 100644 --- a/src/hwrenderer/scene/hw_bsp.cpp +++ b/src/hwrenderer/scene/hw_bsp.cpp @@ -56,6 +56,7 @@ struct RenderJob WallJob, SpriteJob, ParticleJob, + PortalJob, TerminateJob // inserted when all work is done so that the worker can return. }; @@ -177,7 +178,12 @@ void HWDrawInfo::WorkerThread() RenderParticles(job->sub, front); SetupSprite.Unclock(); break; + + case RenderJob::PortalJob: + AddSubsectorToPortal((FSectorPortalGroup *)job->seg, job->sub); + break; } + } } @@ -706,16 +712,35 @@ void HWDrawInfo::DoSubsector(subsector_t * sub) // This is for portal coverage. FSectorPortalGroup *portal; + // AddSubsectorToPortal cannot be called here when using multithreaded processing, + // because the wall processing code in the worker can also modify the portal state. + // To avoid costly synchronization for every access to the portal list, + // the call to AddSubsectorToPortal will be deferred to the worker. + // (GetPortalGruop only accesses static sector data so this check can be done here, restricting the new job to the minimum possible extent.) portal = fakesector->GetPortalGroup(sector_t::ceiling); if (portal != nullptr) { - AddSubsectorToPortal(portal, sub); + if (multithread) + { + jobQueue.AddJob(RenderJob::PortalJob, sub, (seg_t *)portal); + } + else + { + AddSubsectorToPortal(portal, sub); + } } portal = fakesector->GetPortalGroup(sector_t::floor); if (portal != nullptr) { - AddSubsectorToPortal(portal, sub); + if (multithread) + { + jobQueue.AddJob(RenderJob::PortalJob, sub, (seg_t *)portal); + } + else + { + AddSubsectorToPortal(portal, sub); + } } } } From a96b86b13b97148a762f653808c805730d2b0cd0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 16 Dec 2018 09:38:22 +0100 Subject: [PATCH 13/17] - fixed: sidedef-less GLWalls may not apply per-sidedef render properties. These always come from open-sector render hacks where the renderer tries to fill in some gaps --- src/hwrenderer/scene/hw_walls.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hwrenderer/scene/hw_walls.cpp b/src/hwrenderer/scene/hw_walls.cpp index 70ca0f6335..f50ffbe450 100644 --- a/src/hwrenderer/scene/hw_walls.cpp +++ b/src/hwrenderer/scene/hw_walls.cpp @@ -165,7 +165,7 @@ void GLWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags) } state.SetFog(255, 0, di->isFullbrightScene(), nullptr, false); } - if (type != RENDERWALL_COLOR) + if (type != RENDERWALL_COLOR && seg->sidedef != nullptr) { auto side = seg->sidedef; auto tierndx = renderwalltotier[type]; From a38e75db00c701123251567648d37f7b1f0f89ba Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 16 Dec 2018 09:56:53 +0100 Subject: [PATCH 14/17] - improved error reporting for badly defined translations. This needs to be handled by the caller for all use cases because the translation parser lacks the context to do a proper error report. --- src/r_data/r_translate.cpp | 261 +++++++++++---------- src/sc_man.cpp | 2 +- src/scripting/thingdef_properties.cpp | 14 +- src/textures/formats/multipatchtexture.cpp | 11 +- 4 files changed, 150 insertions(+), 138 deletions(-) diff --git a/src/r_data/r_translate.cpp b/src/r_data/r_translate.cpp index c11f9be946..5264095e77 100644 --- a/src/r_data/r_translate.cpp +++ b/src/r_data/r_translate.cpp @@ -633,148 +633,140 @@ bool FRemapTable::AddToTranslation(const char *range) sc.OpenMem("translation", range, int(strlen(range))); sc.SetCMode(true); - try + sc.MustGetToken(TK_IntConst); + start = sc.Number; + sc.MustGetToken(':'); + sc.MustGetToken(TK_IntConst); + end = sc.Number; + sc.MustGetToken('='); + if (start < 0 || start > 255 || end < 0 || end > 255) { + sc.ScriptError("Palette index out of range"); + return false; + } + + sc.MustGetAnyToken(); + + if (sc.TokenType == '[') + { + // translation using RGB values + int r1,g1,b1,r2,g2,b2; + sc.MustGetToken(TK_IntConst); - start = sc.Number; + r1 = sc.Number; + sc.MustGetToken(','); + + sc.MustGetToken(TK_IntConst); + g1 = sc.Number; + sc.MustGetToken(','); + + sc.MustGetToken(TK_IntConst); + b1 = sc.Number; + sc.MustGetToken(']'); sc.MustGetToken(':'); + sc.MustGetToken('['); + sc.MustGetToken(TK_IntConst); - end = sc.Number; - sc.MustGetToken('='); - if (start < 0 || start > 255 || end < 0 || end > 255) - { - sc.ScriptError("Palette index out of range"); - return false; - } + r2 = sc.Number; + sc.MustGetToken(','); + + sc.MustGetToken(TK_IntConst); + g2 = sc.Number; + sc.MustGetToken(','); + + sc.MustGetToken(TK_IntConst); + b2 = sc.Number; + sc.MustGetToken(']'); + + return AddColorRange(start, end, r1, g1, b1, r2, g2, b2); + } + else if (sc.TokenType == '%') + { + // translation using RGB values + double r1,g1,b1,r2,g2,b2; + + sc.MustGetToken('['); + sc.MustGetAnyToken(); + if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); + r1 = sc.Float; + sc.MustGetToken(','); sc.MustGetAnyToken(); + if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); + g1 = sc.Float; + sc.MustGetToken(','); - if (sc.TokenType == '[') - { - // translation using RGB values - int r1,g1,b1,r2,g2,b2; + sc.MustGetAnyToken(); + if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); + b1 = sc.Float; + sc.MustGetToken(']'); + sc.MustGetToken(':'); + sc.MustGetToken('['); - sc.MustGetToken(TK_IntConst); - r1 = sc.Number; - sc.MustGetToken(','); + sc.MustGetAnyToken(); + if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); + r2 = sc.Float; + sc.MustGetToken(','); - sc.MustGetToken(TK_IntConst); - g1 = sc.Number; - sc.MustGetToken(','); + sc.MustGetAnyToken(); + if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); + g2 = sc.Float; + sc.MustGetToken(','); - sc.MustGetToken(TK_IntConst); - b1 = sc.Number; - sc.MustGetToken(']'); - sc.MustGetToken(':'); - sc.MustGetToken('['); + sc.MustGetAnyToken(); + if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); + b2 = sc.Float; + sc.MustGetToken(']'); - sc.MustGetToken(TK_IntConst); - r2 = sc.Number; - sc.MustGetToken(','); - - sc.MustGetToken(TK_IntConst); - g2 = sc.Number; - sc.MustGetToken(','); - - sc.MustGetToken(TK_IntConst); - b2 = sc.Number; - sc.MustGetToken(']'); - - return AddColorRange(start, end, r1, g1, b1, r2, g2, b2); - } - else if (sc.TokenType == '%') - { - // translation using RGB values - double r1,g1,b1,r2,g2,b2; - - sc.MustGetToken('['); - sc.MustGetAnyToken(); - if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); - r1 = sc.Float; - sc.MustGetToken(','); - - sc.MustGetAnyToken(); - if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); - g1 = sc.Float; - sc.MustGetToken(','); - - sc.MustGetAnyToken(); - if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); - b1 = sc.Float; - sc.MustGetToken(']'); - sc.MustGetToken(':'); - sc.MustGetToken('['); - - sc.MustGetAnyToken(); - if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); - r2 = sc.Float; - sc.MustGetToken(','); - - sc.MustGetAnyToken(); - if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); - g2 = sc.Float; - sc.MustGetToken(','); - - sc.MustGetAnyToken(); - if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); - b2 = sc.Float; - sc.MustGetToken(']'); - - return AddDesaturation(start, end, r1, g1, b1, r2, g2, b2); - } - else if (sc.TokenType == '#') - { - // Colourise translation - int r, g, b; - sc.MustGetToken('['); - sc.MustGetToken(TK_IntConst); - r = sc.Number; - sc.MustGetToken(','); - sc.MustGetToken(TK_IntConst); - g = sc.Number; - sc.MustGetToken(','); - sc.MustGetToken(TK_IntConst); - b = sc.Number; - sc.MustGetToken(']'); - - return AddColourisation(start, end, r, g, b); - } - else if (sc.TokenType == '@') - { - // Tint translation - int a, r, g, b; - - sc.MustGetToken(TK_IntConst); - a = sc.Number; - sc.MustGetToken('['); - sc.MustGetToken(TK_IntConst); - r = sc.Number; - sc.MustGetToken(','); - sc.MustGetToken(TK_IntConst); - g = sc.Number; - sc.MustGetToken(','); - sc.MustGetToken(TK_IntConst); - b = sc.Number; - sc.MustGetToken(']'); - - return AddTint(start, end, r, g, b, a); - } - else - { - int pal1, pal2; - - sc.TokenMustBe(TK_IntConst); - pal1 = sc.Number; - sc.MustGetToken(':'); - sc.MustGetToken(TK_IntConst); - pal2 = sc.Number; - return AddIndexRange(start, end, pal1, pal2); - } + return AddDesaturation(start, end, r1, g1, b1, r2, g2, b2); } - catch (CRecoverableError &err) + else if (sc.TokenType == '#') { - Printf("Error in translation '%s':\n%s\n", range, err.GetMessage()); - return false; + // Colourise translation + int r, g, b; + sc.MustGetToken('['); + sc.MustGetToken(TK_IntConst); + r = sc.Number; + sc.MustGetToken(','); + sc.MustGetToken(TK_IntConst); + g = sc.Number; + sc.MustGetToken(','); + sc.MustGetToken(TK_IntConst); + b = sc.Number; + sc.MustGetToken(']'); + + return AddColourisation(start, end, r, g, b); + } + else if (sc.TokenType == '@') + { + // Tint translation + int a, r, g, b; + + sc.MustGetToken(TK_IntConst); + a = sc.Number; + sc.MustGetToken('['); + sc.MustGetToken(TK_IntConst); + r = sc.Number; + sc.MustGetToken(','); + sc.MustGetToken(TK_IntConst); + g = sc.Number; + sc.MustGetToken(','); + sc.MustGetToken(TK_IntConst); + b = sc.Number; + sc.MustGetToken(']'); + + return AddTint(start, end, r, g, b, a); + } + else + { + int pal1, pal2; + + sc.TokenMustBe(TK_IntConst); + pal1 = sc.Number; + sc.MustGetToken(':'); + sc.MustGetToken(TK_IntConst); + pal2 = sc.Number; + return AddIndexRange(start, end, pal1, pal2); } } @@ -1529,7 +1521,16 @@ void R_ParseTrnslate() do { sc.MustGetToken(TK_StringConst); - NewTranslation.AddToTranslation(sc.String); + + try + { + NewTranslation.AddToTranslation(sc.String); + } + catch (CRecoverableError &err) + { + sc.ScriptMessage("Error in translation '%s':\n" TEXTCOLOR_YELLOW "%s\n", sc.String, err.GetMessage()); + } + } while (sc.CheckToken(',')); int trans = NewTranslation.StoreTranslation(TRANSLATION_Custom); diff --git a/src/sc_man.cpp b/src/sc_man.cpp index 7eb6b3c3aa..f1b9b9267f 100644 --- a/src/sc_man.cpp +++ b/src/sc_man.cpp @@ -1120,7 +1120,7 @@ void FScanner::ScriptMessage (const char *message, ...) va_end (arglist); } - Printf (TEXTCOLOR_RED "Script error, \"%s\" line %d:\n" TEXTCOLOR_RED "%s\n", ScriptName.GetChars(), + Printf (TEXTCOLOR_RED "Script error, \"%s\"" TEXTCOLOR_RED "line %d:\n" TEXTCOLOR_RED "%s\n", ScriptName.GetChars(), AlreadyGot? AlreadyGotLine : Line, composed.GetChars()); } diff --git a/src/scripting/thingdef_properties.cpp b/src/scripting/thingdef_properties.cpp index f62ad91b72..d54684a486 100644 --- a/src/scripting/thingdef_properties.cpp +++ b/src/scripting/thingdef_properties.cpp @@ -729,7 +729,6 @@ DEFINE_PROPERTY(translation, L, Actor) else { FRemapTable CurrentTranslation; - bool success = true; CurrentTranslation.MakeIdentity(); for(int i = 1; i < PROP_PARM_COUNT; i++) @@ -744,14 +743,17 @@ DEFINE_PROPERTY(translation, L, Actor) else { // parse all ranges to get a complete list of errors, if more than one range fails. - success |= CurrentTranslation.AddToTranslation(str); + try + { + CurrentTranslation.AddToTranslation(str); + } + catch (CRecoverableError &err) + { + bag.ScriptPosition.Message(MSG_WARNING, "Error in translation '%s':\n" TEXTCOLOR_CYAN "%s\n", str, err.GetMessage()); + } } } defaults->Translation = CurrentTranslation.StoreTranslation (TRANSLATION_Decorate); - if (!success) - { - bag.ScriptPosition.Message(MSG_WARNING, "Failed to parse translation"); - } } } diff --git a/src/textures/formats/multipatchtexture.cpp b/src/textures/formats/multipatchtexture.cpp index fb93818086..78fcca56b1 100644 --- a/src/textures/formats/multipatchtexture.cpp +++ b/src/textures/formats/multipatchtexture.cpp @@ -49,6 +49,7 @@ #include "v_video.h" #include "v_text.h" #include "cmdlib.h" +#include "doomerrors.h" // On the Alpha, accessing the shorts directly if they aren't aligned on a // 4-byte boundary causes unaligned access warnings. Why it does this at @@ -954,7 +955,15 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part, TexInit &init) do { sc.MustGetString(); - part.Translation->AddToTranslation(sc.String); + + try + { + part.Translation->AddToTranslation(sc.String); + } + catch (CRecoverableError &err) + { + sc.ScriptMessage("Error in translation '%s':\n" TEXTCOLOR_YELLOW "%s\n", sc.String, err.GetMessage()); + } } while (sc.CheckString(",")); } From 881fc89fe8eb14e824933068ed4d70139f735332 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 16 Dec 2018 11:29:22 +0100 Subject: [PATCH 15/17] - removed redundant std::move. --- src/gl/textures/gl_hwtexture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 01bfdf1b66..9c5f7b8943 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -335,7 +335,7 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i if (!tex->isHardwareCanvas()) { - texbuffer = std::move(tex->CreateTexBuffer(translation, flags | CTF_ProcessData)); + texbuffer = tex->CreateTexBuffer(translation, flags | CTF_ProcessData); w = texbuffer.mWidth; h = texbuffer.mHeight; } From 88751a320c30088b39dcb1aaccb6412a8378c650 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 16 Dec 2018 11:31:05 +0100 Subject: [PATCH 16/17] - fix sky drawers not staying within their numa node --- src/swrenderer/drawers/r_draw_pal.cpp | 37 +++++++++++----------- src/swrenderer/drawers/r_draw_sky32.h | 37 +++++++++++----------- src/swrenderer/drawers/r_draw_sky32_sse2.h | 37 +++++++++++----------- src/swrenderer/drawers/r_thread.cpp | 9 ++---- 4 files changed, 59 insertions(+), 61 deletions(-) diff --git a/src/swrenderer/drawers/r_draw_pal.cpp b/src/swrenderer/drawers/r_draw_pal.cpp index b9501d1576..9af01cffb0 100644 --- a/src/swrenderer/drawers/r_draw_pal.cpp +++ b/src/swrenderer/drawers/r_draw_pal.cpp @@ -551,7 +551,6 @@ namespace swrenderer void DrawSingleSky1PalCommand::Execute(DrawerThread *thread) { uint8_t *dest = args.Dest(); - int count = args.Count(); int pitch = args.Viewport()->RenderTarget->GetPitch(); const uint8_t *source0 = args.FrontTexturePixels(); int textureheight0 = args.FrontTextureHeight(); @@ -559,6 +558,25 @@ namespace swrenderer int32_t frac = args.TextureVPos(); int32_t fracstep = args.TextureVStep(); + if (!args.FadeSky()) + { + int count = thread->count_for_thread(args.DestY(), args.Count()); + + for (int index = 0; index < count; index++) + { + uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS; + *dest = source0[sample_index]; + dest += pitch; + frac += fracstep; + } + + return; + } + + int num_cores = thread->num_cores; + int skipped = thread->skipped_by_thread(args.DestY()); + int count = skipped + thread->count_for_thread(args.DestY(), args.Count()) * num_cores; + // Find bands for top solid color, top fade, center textured, bottom fade, bottom solid color: int start_fade = 2; // How fast it should fade out int fade_length = (1 << (24 - start_fade)); @@ -571,28 +589,11 @@ namespace swrenderer start_fadebottom_y = clamp(start_fadebottom_y, 0, count); end_fadebottom_y = clamp(end_fadebottom_y, 0, count); - int num_cores = thread->num_cores; - int skipped = thread->skipped_by_thread(args.DestY()); dest = thread->dest_for_thread(args.DestY(), pitch, dest); frac += fracstep * skipped; fracstep *= num_cores; pitch *= num_cores; - if (!args.FadeSky()) - { - count = thread->count_for_thread(args.DestY(), count); - - for (int index = 0; index < count; index++) - { - uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS; - *dest = source0[sample_index]; - dest += pitch; - frac += fracstep; - } - - return; - } - uint32_t solid_top = args.SolidTopColor(); uint32_t solid_bottom = args.SolidBottomColor(); diff --git a/src/swrenderer/drawers/r_draw_sky32.h b/src/swrenderer/drawers/r_draw_sky32.h index 59c8826fa7..8640024464 100644 --- a/src/swrenderer/drawers/r_draw_sky32.h +++ b/src/swrenderer/drawers/r_draw_sky32.h @@ -39,7 +39,6 @@ namespace swrenderer void Execute(DrawerThread *thread) override { uint32_t *dest = (uint32_t *)args.Dest(); - int count = args.Count(); int pitch = args.Viewport()->RenderTarget->GetPitch(); const uint32_t *source0 = (const uint32_t *)args.FrontTexturePixels(); int textureheight0 = args.FrontTextureHeight(); @@ -51,6 +50,25 @@ namespace swrenderer uint32_t solid_bottom = args.SolidBottomColor(); bool fadeSky = args.FadeSky(); + if (!fadeSky) + { + int count = thread->count_for_thread(args.DestY(), args.Count()); + + for (int index = 0; index < count; index++) + { + uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS; + *dest = source0[sample_index]; + dest += pitch; + frac += fracstep; + } + + return; + } + + int num_cores = thread->num_cores; + int skipped = thread->skipped_by_thread(args.DestY()); + int count = skipped + thread->count_for_thread(args.DestY(), args.Count()) * num_cores; + // Find bands for top solid color, top fade, center textured, bottom fade, bottom solid color: int start_fade = 2; // How fast it should fade out int fade_length = (1 << (24 - start_fade)); @@ -63,28 +81,11 @@ namespace swrenderer start_fadebottom_y = clamp(start_fadebottom_y, 0, count); end_fadebottom_y = clamp(end_fadebottom_y, 0, count); - int num_cores = thread->num_cores; - int skipped = thread->skipped_by_thread(args.DestY()); dest = thread->dest_for_thread(args.DestY(), pitch, dest); frac += fracstep * skipped; fracstep *= num_cores; pitch *= num_cores; - if (!fadeSky) - { - count = thread->count_for_thread(args.DestY(), count); - - for (int index = 0; index < count; index++) - { - uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS; - *dest = source0[sample_index]; - dest += pitch; - frac += fracstep; - } - - return; - } - BgraColor solid_top_fill = solid_top; BgraColor solid_bottom_fill = solid_bottom; diff --git a/src/swrenderer/drawers/r_draw_sky32_sse2.h b/src/swrenderer/drawers/r_draw_sky32_sse2.h index 401d5bad1f..56fd503004 100644 --- a/src/swrenderer/drawers/r_draw_sky32_sse2.h +++ b/src/swrenderer/drawers/r_draw_sky32_sse2.h @@ -38,7 +38,6 @@ namespace swrenderer void Execute(DrawerThread *thread) override { uint32_t *dest = (uint32_t *)args.Dest(); - int count = args.Count(); int pitch = args.Viewport()->RenderTarget->GetPitch(); const uint32_t *source0 = (const uint32_t *)args.FrontTexturePixels(); int textureheight0 = args.FrontTextureHeight(); @@ -50,6 +49,25 @@ namespace swrenderer uint32_t solid_bottom = args.SolidBottomColor(); bool fadeSky = args.FadeSky(); + if (!fadeSky) + { + int count = thread->count_for_thread(args.DestY(), args.Count()); + + for (int index = 0; index < count; index++) + { + uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS; + *dest = source0[sample_index]; + dest += pitch; + frac += fracstep; + } + + return; + } + + int num_cores = thread->num_cores; + int skipped = thread->skipped_by_thread(args.DestY()); + int count = skipped + thread->count_for_thread(args.DestY(), args.Count()) * num_cores; + // Find bands for top solid color, top fade, center textured, bottom fade, bottom solid color: int start_fade = 2; // How fast it should fade out int fade_length = (1 << (24 - start_fade)); @@ -62,28 +80,11 @@ namespace swrenderer start_fadebottom_y = clamp(start_fadebottom_y, 0, count); end_fadebottom_y = clamp(end_fadebottom_y, 0, count); - int num_cores = thread->num_cores; - int skipped = thread->skipped_by_thread(args.DestY()); dest = thread->dest_for_thread(args.DestY(), pitch, dest); frac += fracstep * skipped; fracstep *= num_cores; pitch *= num_cores; - if (!fadeSky) - { - count = thread->count_for_thread(args.DestY(), count); - - for (int index = 0; index < count; index++) - { - uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS; - *dest = source0[sample_index]; - dest += pitch; - frac += fracstep; - } - - return; - } - __m128i solid_top_fill = _mm_unpacklo_epi8(_mm_cvtsi32_si128(solid_top), _mm_setzero_si128()); __m128i solid_bottom_fill = _mm_unpacklo_epi8(_mm_cvtsi32_si128(solid_bottom), _mm_setzero_si128()); diff --git a/src/swrenderer/drawers/r_thread.cpp b/src/swrenderer/drawers/r_thread.cpp index 31a6f19154..5aa157f272 100644 --- a/src/swrenderer/drawers/r_thread.cpp +++ b/src/swrenderer/drawers/r_thread.cpp @@ -140,6 +140,8 @@ void DrawerThreads::WorkerMain(DrawerThread *thread) // Grab the commands DrawerCommandQueuePtr list = active_commands[thread->current_queue]; thread->current_queue++; + thread->numa_start_y = thread->numa_node * viewheight / thread->num_numa_nodes; + thread->numa_end_y = (thread->numa_node + 1) * viewheight / thread->num_numa_nodes; start_lock.unlock(); // Do the work: @@ -206,8 +208,6 @@ void DrawerThreads::StartThreads() thread->num_cores = I_GetNumaNodeThreadCount(numaNode); thread->numa_node = numaNode; thread->num_numa_nodes = I_GetNumaNodeCount(); - thread->numa_start_y = numaNode * viewheight / I_GetNumaNodeCount(); - thread->numa_end_y = (numaNode + 1) * viewheight / I_GetNumaNodeCount(); thread->thread = std::thread([=]() { queue->WorkerMain(thread); }); I_SetThreadNumaNode(thread->thread, numaNode); } @@ -223,8 +223,6 @@ void DrawerThreads::StartThreads() thread->num_cores = num_threads; thread->numa_node = 0; thread->num_numa_nodes = 1; - thread->numa_start_y = 0; - thread->numa_end_y = viewheight; thread->thread = std::thread([=]() { queue->WorkerMain(thread); }); I_SetThreadNumaNode(thread->thread, 0); } @@ -288,7 +286,4 @@ void MemcpyCommand::Execute(DrawerThread *thread) d += dstep; s += sstep; } - - thread->numa_start_y = thread->numa_node * viewheight / thread->num_numa_nodes; - thread->numa_end_y = (thread->numa_node + 1) * viewheight / thread->num_numa_nodes; } From cc52f893728b0b4eedacda7cf6ef26cc3618c3bc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 16 Dec 2018 12:05:28 +0100 Subject: [PATCH 17/17] - fixed: For non-persistent buffers, sprite vertices need to be recalculated in the splitter code of the translucent sorter. --- src/hwrenderer/scene/hw_drawlist.cpp | 14 ++++++++++++-- src/hwrenderer/scene/hw_drawlist.h | 2 +- src/hwrenderer/scene/hw_sprites.cpp | 1 + 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/hwrenderer/scene/hw_drawlist.cpp b/src/hwrenderer/scene/hw_drawlist.cpp index 067c5dee5f..0cf6a8010f 100644 --- a/src/hwrenderer/scene/hw_drawlist.cpp +++ b/src/hwrenderer/scene/hw_drawlist.cpp @@ -483,7 +483,7 @@ inline double CalcIntersectionVertex(GLSprite *s, GLWall * w2) return ((ay - cy)*(dx - cx) - (ax - cx)*(dy - cy)) / ((bx - ax)*(dy - cy) - (by - ay)*(dx - cx)); } -void HWDrawList::SortSpriteIntoWall(SortNode * head,SortNode * sort) +void HWDrawList::SortSpriteIntoWall(HWDrawInfo *di, SortNode * head,SortNode * sort) { GLWall *wh= walls[drawitems[head->itemindex].index]; GLSprite * ss= sprites[drawitems[sort->itemindex].index]; @@ -560,6 +560,16 @@ void HWDrawList::SortSpriteIntoWall(SortNode * head,SortNode * sort) head->AddToLeft(sort); head->AddToRight(sort2); } + if (screen->BuffersArePersistent()) + { + s->vertexindex = ss->vertexindex = -1; + } + else + { + s->CreateVertices(di); + ss->CreateVertices(di); + } + } } @@ -667,7 +677,7 @@ SortNode * HWDrawList::DoSort(HWDrawInfo *di, SortNode * head) break; case GLDIT_SPRITE: - SortSpriteIntoWall(head,node); + SortSpriteIntoWall(di, head, node); break; case GLDIT_FLAT: break; diff --git a/src/hwrenderer/scene/hw_drawlist.h b/src/hwrenderer/scene/hw_drawlist.h index 303da06fb9..66ae468ed0 100644 --- a/src/hwrenderer/scene/hw_drawlist.h +++ b/src/hwrenderer/scene/hw_drawlist.h @@ -101,7 +101,7 @@ public: void SortWallIntoPlane(SortNode * head,SortNode * sort); void SortSpriteIntoPlane(SortNode * head,SortNode * sort); void SortWallIntoWall(HWDrawInfo *di, SortNode * head,SortNode * sort); - void SortSpriteIntoWall(SortNode * head,SortNode * sort); + void SortSpriteIntoWall(HWDrawInfo *di, SortNode * head,SortNode * sort); int CompareSprites(SortNode * a,SortNode * b); SortNode * SortSpriteList(SortNode * head); SortNode * DoSort(HWDrawInfo *di, SortNode * head); diff --git a/src/hwrenderer/scene/hw_sprites.cpp b/src/hwrenderer/scene/hw_sprites.cpp index c3911b4601..f8c716686a 100644 --- a/src/hwrenderer/scene/hw_sprites.cpp +++ b/src/hwrenderer/scene/hw_sprites.cpp @@ -244,6 +244,7 @@ void GLSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent) { state.SetNormal(0, 0, 0); + if (screen->BuffersArePersistent()) { CreateVertices(di);