From 2e2fe8744549e119da6f6c124d698c2b5d8f1f39 Mon Sep 17 00:00:00 2001 From: Marrub Date: Fri, 23 Nov 2018 17:46:34 -0500 Subject: [PATCH 1/8] Fix null pointer access in p_terrain.cpp --- src/p_terrain.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/p_terrain.cpp b/src/p_terrain.cpp index 73756ec57..d1f6d7e3a 100644 --- a/src/p_terrain.cpp +++ b/src/p_terrain.cpp @@ -556,17 +556,17 @@ static void GenericParse (FScanner &sc, FGenericParse *parser, const char **keyw else { info = PClass::FindClass (sc.String); - if (!info->IsDescendantOf (RUNTIME_CLASS(AActor))) + if (info == NULL) + { + Printf ("Unknown actor %s in %s %s\n", + sc.String, type, name.GetChars()); + } + else if (!info->IsDescendantOf (RUNTIME_CLASS(AActor))) { Printf ("%s is not an Actor (in %s %s)\n", sc.String, type, name.GetChars()); info = NULL; } - else if (info == NULL) - { - Printf ("Unknown actor %s in %s %s\n", - sc.String, type, name.GetChars()); - } } SET_FIELD (const PClass *, info); break; From f11b20122f6f90a9cd8c782df84046d66b1e9835 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 24 Nov 2018 12:51:14 +0200 Subject: [PATCH 2/8] - made ZRock4 solid like in vanilla Hexen https://github.com/videogamepreservation/hexen/blob/9164cc6e0fd1f38b49d58070f062dc18a329ddc6/INFO.C#L5731 https://github.com/chocolate-doom/chocolate-doom/blob/c0c1771e37eb41eed0f0b2e9174ef72c2ec776f4/src/hexen/info.c#L5748 https://forum.zdoom.org/viewtopic.php?t=62660 --- wadsrc/static/zscript/hexen/hexendecorations.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/wadsrc/static/zscript/hexen/hexendecorations.txt b/wadsrc/static/zscript/hexen/hexendecorations.txt index 937034bd8..2d3324168 100644 --- a/wadsrc/static/zscript/hexen/hexendecorations.txt +++ b/wadsrc/static/zscript/hexen/hexendecorations.txt @@ -65,6 +65,7 @@ class ZRock4 : Actor { Radius 20; Height 16; + +SOLID } States { From ee6f4211c0bac1bfeee05b50e9b1087b24ef7626 Mon Sep 17 00:00:00 2001 From: Lucy Phipps Date: Sat, 24 Nov 2018 06:51:28 +0000 Subject: [PATCH 3/8] tnt1a0 is not a png --- wadsrc/static/sprites/{tnt1a0.png => tnt1a0.lmp} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename wadsrc/static/sprites/{tnt1a0.png => tnt1a0.lmp} (100%) diff --git a/wadsrc/static/sprites/tnt1a0.png b/wadsrc/static/sprites/tnt1a0.lmp similarity index 100% rename from wadsrc/static/sprites/tnt1a0.png rename to wadsrc/static/sprites/tnt1a0.lmp From 1b82e2078d72d520552b5f0660ec0a40217f1ed0 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 24 Nov 2018 19:37:01 +0700 Subject: [PATCH 4/8] add monster tags (Friendly Names) for Hexen --- wadsrc/static/language.enu | 18 ++++++++++++++++++ wadsrc/static/zscript/hexen/bishop.txt | 1 + wadsrc/static/zscript/hexen/centaur.txt | 2 ++ wadsrc/static/zscript/hexen/clericboss.txt | 3 ++- wadsrc/static/zscript/hexen/demons.txt | 1 + wadsrc/static/zscript/hexen/dragon.txt | 1 + wadsrc/static/zscript/hexen/ettin.txt | 1 + wadsrc/static/zscript/hexen/fighterboss.txt | 1 + wadsrc/static/zscript/hexen/firedemon.txt | 1 + wadsrc/static/zscript/hexen/heresiarch.txt | 1 + wadsrc/static/zscript/hexen/iceguy.txt | 1 + wadsrc/static/zscript/hexen/korax.txt | 1 + wadsrc/static/zscript/hexen/mageboss.txt | 1 + wadsrc/static/zscript/hexen/serpent.txt | 1 + wadsrc/static/zscript/hexen/wraith.txt | 1 + 15 files changed, 34 insertions(+), 1 deletion(-) diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index c5fe1da0a..5d9ec105b 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -1423,6 +1423,24 @@ TXT_QUIETUS_PIECE = "SEGMENT OF QUIETUS"; TXT_WRAITHVERGE_PIECE = "SEGMENT OF WRAITHVERGE"; TXT_BLOODSCOURGE_PIECE = "SEGMENT OF BLOODSCOURGE"; +// Friendly names + +FN_FIREDEMON = "Afrit"; +FN_DEMON1 = "Serpent"; +FN_ETTIN = "Ettin"; +FN_CENTAUR = "Centaur"; +FN_SLAUGHTAUR = "Slaughtaur"; +FN_BISHOP = "Bishop"; +FN_ICEGUY = "Wendigo"; +FN_SERPENT = "Stalker"; +FN_WRAITH = "Reiver"; +FN_DRAGON = "Death Wyvern"; +FN_KORAX = "Korax"; +FN_FBOSS = "Zedek"; +FN_MBOSS = "Menelkir"; +FN_CBOSS = "Traductus"; +FN_HERESIARCH = "Heresiarch"; + // Strife locks TXT_NEEDKEY = "You don't have the key"; diff --git a/wadsrc/static/zscript/hexen/bishop.txt b/wadsrc/static/zscript/hexen/bishop.txt index 4fd0cde41..63b0168b5 100644 --- a/wadsrc/static/zscript/hexen/bishop.txt +++ b/wadsrc/static/zscript/hexen/bishop.txt @@ -24,6 +24,7 @@ class Bishop : Actor DeathSound "BishopDeath"; ActiveSound "BishopActiveSounds"; Obituary"$OB_BISHOP"; + Tag "$FN_BISHOP"; } States diff --git a/wadsrc/static/zscript/hexen/centaur.txt b/wadsrc/static/zscript/hexen/centaur.txt index 8cd5639a2..4be9860ee 100644 --- a/wadsrc/static/zscript/hexen/centaur.txt +++ b/wadsrc/static/zscript/hexen/centaur.txt @@ -21,6 +21,7 @@ class Centaur : Actor HowlSound "PuppyBeat"; Obituary "$OB_CENTAUR"; DamageFactor "Electric", 3; + Tag "$FN_CENTAUR"; } States { @@ -107,6 +108,7 @@ class CentaurLeader : Centaur Speed 10; Obituary "$OB_SLAUGHTAUR"; HitObituary "$OB_SLAUGHTAURHIT"; + Tag "$FN_SLAUGHTAUR"; } States { diff --git a/wadsrc/static/zscript/hexen/clericboss.txt b/wadsrc/static/zscript/hexen/clericboss.txt index 4bf223517..a472c1ac4 100644 --- a/wadsrc/static/zscript/hexen/clericboss.txt +++ b/wadsrc/static/zscript/hexen/clericboss.txt @@ -15,7 +15,8 @@ class ClericBoss : Actor +DONTMORPH PainSound "PlayerClericPain"; DeathSound "PlayerClericCrazyDeath"; - Obituary "$OBCBOSS"; + Obituary "$OB_CBOSS"; + Tag "$FN_CBOSS"; } States diff --git a/wadsrc/static/zscript/hexen/demons.txt b/wadsrc/static/zscript/hexen/demons.txt index 778bb957e..08f81b2a8 100644 --- a/wadsrc/static/zscript/hexen/demons.txt +++ b/wadsrc/static/zscript/hexen/demons.txt @@ -20,6 +20,7 @@ class Demon1 : Actor DeathSound "DemonDeath"; ActiveSound "DemonActive"; Obituary "$OB_DEMON1"; + Tag "$FN_DEMON1"; } const ChunkFlags = SXF_TRANSFERTRANSLATION | SXF_ABSOLUTEVELOCITY; diff --git a/wadsrc/static/zscript/hexen/dragon.txt b/wadsrc/static/zscript/hexen/dragon.txt index 5eafb3201..bf5d91b16 100644 --- a/wadsrc/static/zscript/hexen/dragon.txt +++ b/wadsrc/static/zscript/hexen/dragon.txt @@ -19,6 +19,7 @@ class Dragon : Actor DeathSound "DragonDeath"; ActiveSound "DragonActive"; Obituary "$OB_DRAGON"; + Tag "$FN_DRAGON"; } States diff --git a/wadsrc/static/zscript/hexen/ettin.txt b/wadsrc/static/zscript/hexen/ettin.txt index 8ddf9e7d2..6650c6a41 100644 --- a/wadsrc/static/zscript/hexen/ettin.txt +++ b/wadsrc/static/zscript/hexen/ettin.txt @@ -22,6 +22,7 @@ class Ettin : Actor ActiveSound "EttinActive"; HowlSound "PuppyBeat"; Obituary "$OB_ETTIN"; + Tag "$FN_ETTIN"; } States { diff --git a/wadsrc/static/zscript/hexen/fighterboss.txt b/wadsrc/static/zscript/hexen/fighterboss.txt index 9871cf571..6ff4c90b1 100644 --- a/wadsrc/static/zscript/hexen/fighterboss.txt +++ b/wadsrc/static/zscript/hexen/fighterboss.txt @@ -17,6 +17,7 @@ class FighterBoss : Actor PainSound "PlayerFighterPain"; DeathSound "PlayerFighterCrazyDeath"; Obituary "$OB_FBOSS"; + Tag "$FN_FBOSS"; } States diff --git a/wadsrc/static/zscript/hexen/firedemon.txt b/wadsrc/static/zscript/hexen/firedemon.txt index e10156402..5ea5e27bd 100644 --- a/wadsrc/static/zscript/hexen/firedemon.txt +++ b/wadsrc/static/zscript/hexen/firedemon.txt @@ -24,6 +24,7 @@ class FireDemon : Actor DeathSound "FireDemonDeath"; ActiveSound "FireDemonActive"; Obituary "$OB_FIREDEMON"; + Tag "$FN_FIREDEMON"; } States diff --git a/wadsrc/static/zscript/hexen/heresiarch.txt b/wadsrc/static/zscript/hexen/heresiarch.txt index cd5502177..d7888ccfd 100644 --- a/wadsrc/static/zscript/hexen/heresiarch.txt +++ b/wadsrc/static/zscript/hexen/heresiarch.txt @@ -70,6 +70,7 @@ class Heresiarch : Actor DeathSound "SorcererDeathScream"; ActiveSound "SorcererActive"; Obituary "$OB_HERESIARCH"; + Tag "$FN_HERESIARCH"; } States diff --git a/wadsrc/static/zscript/hexen/iceguy.txt b/wadsrc/static/zscript/hexen/iceguy.txt index 41105b728..4a293b94e 100644 --- a/wadsrc/static/zscript/hexen/iceguy.txt +++ b/wadsrc/static/zscript/hexen/iceguy.txt @@ -20,6 +20,7 @@ class IceGuy : Actor AttackSound "IceGuyAttack"; ActiveSound "IceGuyActive"; Obituary "$OB_ICEGUY"; + Tag "$FN_ICEGUY"; } diff --git a/wadsrc/static/zscript/hexen/korax.txt b/wadsrc/static/zscript/hexen/korax.txt index b94664bea..316bba1d2 100644 --- a/wadsrc/static/zscript/hexen/korax.txt +++ b/wadsrc/static/zscript/hexen/korax.txt @@ -60,6 +60,7 @@ class Korax : Actor DeathSound "KoraxDeath"; ActiveSound "KoraxActive"; Obituary "$OB_KORAX"; + Tag "$FN_KORAX"; } States diff --git a/wadsrc/static/zscript/hexen/mageboss.txt b/wadsrc/static/zscript/hexen/mageboss.txt index 0c081d786..eea86e33e 100644 --- a/wadsrc/static/zscript/hexen/mageboss.txt +++ b/wadsrc/static/zscript/hexen/mageboss.txt @@ -16,6 +16,7 @@ class MageBoss : Actor PainSound "PlayerMagePain"; DeathSound "PlayerMageCrazyDeath"; Obituary "$OB_MBOSS"; + Tag "$FN_MBOSS"; } States diff --git a/wadsrc/static/zscript/hexen/serpent.txt b/wadsrc/static/zscript/hexen/serpent.txt index 3ebf5aad2..9d6826381 100644 --- a/wadsrc/static/zscript/hexen/serpent.txt +++ b/wadsrc/static/zscript/hexen/serpent.txt @@ -22,6 +22,7 @@ class Serpent : Actor PainSound "SerpentPain"; DeathSound "SerpentDeath"; HitObituary "$OB_SERPENTHIT"; + Tag "$FN_SERPENT"; } States diff --git a/wadsrc/static/zscript/hexen/wraith.txt b/wadsrc/static/zscript/hexen/wraith.txt index 4b90dc4f6..ad4d00db6 100644 --- a/wadsrc/static/zscript/hexen/wraith.txt +++ b/wadsrc/static/zscript/hexen/wraith.txt @@ -21,6 +21,7 @@ class Wraith : Actor ActiveSound "WraithActive"; HitObituary "$OB_WRAITHHIT"; Obituary "$OB_WRAITH"; + Tag "$FN_WRAITH"; } States From 5fcc96a0f2ed7392d5a12ad29889952b66bf0795 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 25 Nov 2018 00:38:04 +0100 Subject: [PATCH 5/8] - fixed: When extracting a MiniBSP for polyobject rendering, the parent subsector must copy all its relevant properties to the children. The sections pointer was not copied here. --- src/p_sectors.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 1abb971b6..743b8dc3b 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -2434,6 +2434,7 @@ void subsector_t::BuildPolyBSP() for (unsigned int i = 0; i < BSP->Subsectors.Size(); ++i) { BSP->Subsectors[i].sector = sector; + BSP->Subsectors[i].section = section; } } From 53175c49a7246cca442586190677a54d5e15d221 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 25 Nov 2018 15:49:15 +0100 Subject: [PATCH 6/8] - change DrawSpanOpt32 to render a scanline in multiple steps as the speed is about the same and it will make it easier to use SSE for each of the steps --- src/polyrenderer/drawers/poly_triangle.h | 11 + src/polyrenderer/drawers/screen_triangle.cpp | 326 +++++++++---------- src/polyrenderer/drawers/screen_triangle.h | 4 +- 3 files changed, 161 insertions(+), 180 deletions(-) diff --git a/src/polyrenderer/drawers/poly_triangle.h b/src/polyrenderer/drawers/poly_triangle.h index 6ed9ee8a4..07eb2b109 100644 --- a/src/polyrenderer/drawers/poly_triangle.h +++ b/src/polyrenderer/drawers/poly_triangle.h @@ -77,6 +77,17 @@ public: return clip_first_line + core_skip - first_line; } + // Varyings + float worldposX[MAXWIDTH]; + float worldposY[MAXWIDTH]; + float worldposZ[MAXWIDTH]; + uint32_t texel[MAXWIDTH]; + int32_t texelV[MAXWIDTH]; + fixed_t lightarray[MAXWIDTH]; + uint16_t dynlights_r[MAXWIDTH]; + uint16_t dynlights_g[MAXWIDTH]; + uint16_t dynlights_b[MAXWIDTH]; + static PolyTriangleThreadData *Get(DrawerThread *thread); private: diff --git a/src/polyrenderer/drawers/screen_triangle.cpp b/src/polyrenderer/drawers/screen_triangle.cpp index 30f023166..46df3eeb3 100644 --- a/src/polyrenderer/drawers/screen_triangle.cpp +++ b/src/polyrenderer/drawers/screen_triangle.cpp @@ -227,7 +227,7 @@ void ScreenTriangle::Draw(const TriDrawTriangleArgs *args, PolyTriangleThreadDat if (x > xstart) { if (writeColor) - drawfunc(y, xstart, x, args); + drawfunc(y, xstart, x, args, thread); if (writeStencil) { @@ -379,29 +379,56 @@ void ScreenTriangle::Draw(const TriDrawTriangleArgs *args, PolyTriangleThreadDat } template -void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) +void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread) { using namespace TriScreenDrawerModes; + uint32_t fixedlight; + uint32_t shade_fade_r, shade_fade_g, shade_fade_b, shade_light_r, shade_light_g, shade_light_b, desaturate, inv_desaturate; + fixed_t fuzzscale; + int _fuzzpos; + const uint32_t *texPixels, *translation; + int texWidth, texHeight; + uint32_t fillcolor; + int actoralpha; float v1X, v1Y, v1W, v1U, v1V, v1WorldX, v1WorldY, v1WorldZ; float startX, startY; float stepW, stepU, stepV, stepWorldX, stepWorldY, stepWorldZ; float posW, posU, posV, posWorldX, posWorldY, posWorldZ; - - PolyLight *lights; - int num_lights; - float worldnormalX, worldnormalY, worldnormalZ; - uint32_t dynlightcolor; - const uint32_t *texPixels, *translation; - int texWidth, texHeight; - uint32_t fillcolor; - int alpha; uint32_t light; fixed_t shade, lightpos, lightstep; - uint32_t shade_fade_r, shade_fade_g, shade_fade_b, shade_light_r, shade_light_g, shade_light_b, desaturate, inv_desaturate; - int16_t dynlights_r[MAXWIDTH / 16], dynlights_g[MAXWIDTH / 16], dynlights_b[MAXWIDTH / 16]; - int16_t posdynlight_r, posdynlight_g, posdynlight_b; - fixed_t lightarray[MAXWIDTH / 16]; + + float *worldposX = thread->worldposX; + float *worldposY = thread->worldposY; + float *worldposZ = thread->worldposZ; + uint32_t *texel = thread->texel; + int32_t *texelV = thread->texelV; + fixed_t *lightarray = thread->lightarray; + uint16_t *dynlights_r = thread->dynlights_r; + uint16_t *dynlights_g = thread->dynlights_g; + uint16_t *dynlights_b = thread->dynlights_b; + + if (!(ModeT::SWFlags & SWSTYLEF_Fill) && !(ModeT::SWFlags & SWSTYLEF_FogBoundary)) + { + texPixels = (const uint32_t*)args->uniforms->TexturePixels(); + texWidth = args->uniforms->TextureWidth(); + texHeight = args->uniforms->TextureHeight(); + } + + if (ModeT::SWFlags & SWSTYLEF_Translated) + { + translation = (const uint32_t*)args->uniforms->Translation(); + } + + if ((ModeT::SWFlags & SWSTYLEF_Fill) || (ModeT::SWFlags & SWSTYLEF_Skycap) || (ModeT::Flags & STYLEF_ColorIsFixed)) + { + fillcolor = args->uniforms->Color(); + } + + if (!(ModeT::Flags & STYLEF_Alpha1)) + { + actoralpha = args->uniforms->Alpha(); + } v1X = args->v1->x; v1Y = args->v1->y; @@ -417,50 +444,6 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) posU = v1U + stepU * startX + args->gradientY.U * startY; posV = v1V + stepV * startX + args->gradientY.V * startY; - texPixels = (const uint32_t*)args->uniforms->TexturePixels(); - translation = (const uint32_t*)args->uniforms->Translation(); - texWidth = args->uniforms->TextureWidth(); - texHeight = args->uniforms->TextureHeight(); - fillcolor = args->uniforms->Color(); - alpha = args->uniforms->Alpha(); - light = args->uniforms->Light(); - - if (OptT::Flags & SWOPT_FixedLight) - { - light += light >> 7; // 255 -> 256 - } - else - { - float globVis = args->uniforms->GlobVis() * (1.0f / 32.0f); - - shade = (fixed_t)((2.0f - (light + 12.0f) / 128.0f) * (float)FRACUNIT); - lightpos = (fixed_t)(globVis * posW * (float)FRACUNIT); - lightstep = (fixed_t)(globVis * stepW * (float)FRACUNIT); - - int affineOffset = x0 / 16 * 16 - x0; - lightpos = lightpos + lightstep * affineOffset; - lightstep = lightstep * 16; - - fixed_t maxvis = 24 * FRACUNIT / 32; - fixed_t maxlight = 31 * FRACUNIT / 32; - - for (int x = x0 / 16; x <= x1 / 16 + 1; x++) - { - lightarray[x] = (FRACUNIT - clamp(shade - MIN(maxvis, lightpos), 0, maxlight)) >> 8; - lightpos += lightstep; - } - - int offset = x0 >> 4; - int t1 = x0 & 15; - int t0 = 16 - t1; - lightpos = (lightarray[offset] * t0 + lightarray[offset + 1] * t1); - - for (int x = x0 / 16; x <= x1 / 16; x++) - { - lightarray[x] = lightarray[x + 1] - lightarray[x]; - } - } - if (OptT::Flags & SWOPT_DynLights) { v1WorldX = args->v1->worldX * v1W; @@ -472,6 +455,61 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) posWorldX = v1WorldX + stepWorldX * startX + args->gradientY.WorldX * startY; posWorldY = v1WorldY + stepWorldY * startX + args->gradientY.WorldY * startY; posWorldZ = v1WorldZ + stepWorldZ * startX + args->gradientY.WorldZ * startY; + } + + if (!(OptT::Flags & SWOPT_FixedLight)) + { + float globVis = args->uniforms->GlobVis() * (1.0f / 32.0f); + + light = args->uniforms->Light(); + shade = (fixed_t)((2.0f - (light + 12.0f) / 128.0f) * (float)FRACUNIT); + lightpos = (fixed_t)(globVis * posW * (float)FRACUNIT); + lightstep = (fixed_t)(globVis * stepW * (float)FRACUNIT); + } + + for (int x = x0; x < x1; x++) + { + if (OptT::Flags & SWOPT_DynLights) + { + float rcp_posW = 1.0f / posW; + worldposX[x] = posWorldX * rcp_posW; + worldposY[x] = posWorldY * rcp_posW; + worldposZ[x] = posWorldZ * rcp_posW; + posWorldX += stepWorldX; + posWorldY += stepWorldY; + posWorldZ += stepWorldZ; + } + + if (!(OptT::Flags & SWOPT_FixedLight)) + { + fixed_t maxvis = 24 * FRACUNIT / 32; + fixed_t maxlight = 31 * FRACUNIT / 32; + lightarray[x] = (FRACUNIT - clamp(shade - MIN(maxvis, lightpos), 0, maxlight)) >> 8; + lightpos += lightstep; + } + + if (!(ModeT::SWFlags & SWSTYLEF_Fill) && !(ModeT::SWFlags & SWSTYLEF_FogBoundary)) + { + float rcpW = 0x01000000 / posW; + int32_t u = (int32_t)(posU * rcpW); + int32_t v = (int32_t)(posV * rcpW); + uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; + uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; + texel[x] = texelX * texHeight + texelY; + texelV[x] = v; + posU += stepU; + posV += stepV; + } + + posW += stepW; + } + + if (OptT::Flags & SWOPT_DynLights) + { + PolyLight *lights; + int num_lights; + float worldnormalX, worldnormalY, worldnormalZ; + uint32_t dynlightcolor; lights = args->uniforms->Lights(); num_lights = args->uniforms->NumLights(); @@ -503,26 +541,12 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) worldnormalZ *= rcplen; } - int affineOffset = x0 / 16 * 16 - x0; - float posLightW = posW + stepW * affineOffset; - posWorldX = posWorldX + stepWorldX * affineOffset; - posWorldY = posWorldY + stepWorldY * affineOffset; - posWorldZ = posWorldZ + stepWorldZ * affineOffset; - float stepLightW = stepW * 16.0f; - stepWorldX *= 16.0f; - stepWorldY *= 16.0f; - stepWorldZ *= 16.0f; - - for (int x = x0 / 16; x <= x1 / 16 + 1; x++) + for (int x = x0; x < x1; x++) { uint32_t lit_r = RPART(dynlightcolor); uint32_t lit_g = GPART(dynlightcolor); uint32_t lit_b = BPART(dynlightcolor); - float rcp_posW = 1.0f / posLightW; - float worldposX = posWorldX * rcp_posW; - float worldposY = posWorldY * rcp_posW; - float worldposZ = posWorldZ * rcp_posW; for (int i = 0; i < num_lights; i++) { float lightposX = lights[i].x; @@ -538,9 +562,9 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) // L = light-pos // dist = sqrt(dot(L, L)) // distance_attenuation = 1 - MIN(dist * (1/radius), 1) - float Lx = lightposX - worldposX; - float Ly = lightposY - worldposY; - float Lz = lightposZ - worldposZ; + float Lx = lightposX - worldposX[x]; + float Ly = lightposY - worldposY[x]; + float Lz = lightposZ - worldposZ[x]; float dist2 = Lx * Lx + Ly * Ly + Lz * Lz; #ifdef NO_SSE //float rcp_dist = 1.0f / sqrt(dist2); @@ -575,26 +599,13 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) dynlights_r[x] = lit_r; dynlights_g[x] = lit_g; dynlights_b[x] = lit_b; - - posLightW += stepLightW; - posWorldX += stepWorldX; - posWorldY += stepWorldY; - posWorldZ += stepWorldZ; } + } - int offset = x0 >> 4; - int t1 = x0 & 15; - int t0 = 16 - t1; - posdynlight_r = (dynlights_r[offset] * t0 + dynlights_r[offset + 1] * t1); - posdynlight_g = (dynlights_g[offset] * t0 + dynlights_g[offset + 1] * t1); - posdynlight_b = (dynlights_b[offset] * t0 + dynlights_b[offset + 1] * t1); - - for (int x = x0 / 16; x <= x1 / 16; x++) - { - dynlights_r[x] = dynlights_r[x + 1] - dynlights_r[x]; - dynlights_g[x] = dynlights_g[x + 1] - dynlights_g[x]; - dynlights_b[x] = dynlights_b[x + 1] - dynlights_b[x]; - } + if (OptT::Flags & SWOPT_FixedLight) + { + fixedlight = args->uniforms->Light(); + fixedlight += fixedlight >> 7; // 255 -> 256 } if (OptT::Flags & SWOPT_ColoredFog) @@ -609,8 +620,6 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) inv_desaturate = 256 - desaturate; } - fixed_t fuzzscale; - int _fuzzpos; if (ModeT::BlendOp == STYLEOP_Fuzz) { fuzzscale = (200 << FRACBITS) / viewheight; @@ -620,19 +629,13 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) uint32_t *dest = (uint32_t*)args->dest; uint32_t *destLine = dest + args->pitch * y; - int x = x0; - while (x < x1) + for (int x = x0; x < x1; x++) { if (ModeT::BlendOp == STYLEOP_Fuzz) { using namespace swrenderer; - float rcpW = 0x01000000 / posW; - int32_t u = (int32_t)(posU * rcpW); - int32_t v = (int32_t)(posV * rcpW); - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - unsigned int sampleshadeout = APART(texPixels[texelX * texHeight + texelY]); + unsigned int sampleshadeout = APART(texPixels[texel[x]]); sampleshadeout += sampleshadeout >> 7; // 255 -> 256 int scaled_x = (x * fuzzscale) >> FRACBITS; @@ -654,14 +657,9 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) } else if (ModeT::SWFlags & SWSTYLEF_Skycap) { - float rcpW = 0x01000000 / posW; - int32_t u = (int32_t)(posU * rcpW); - int32_t v = (int32_t)(posV * rcpW); - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - - uint32_t fg = texPixels[texelX * texHeight + texelY]; + uint32_t fg = texPixels[texel[x]]; + int v = texelV[x]; int start_fade = 2; // How fast it should fade out int alpha_top = clamp(v >> (16 - start_fade), 0, 256); int alpha_bottom = clamp(((2 << 24) - v) >> (16 - start_fade), 0, 256); @@ -695,11 +693,11 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) int lightshade; if (OptT::Flags & SWOPT_FixedLight) { - lightshade = light; + lightshade = fixedlight; } else { - lightshade = lightpos >> 4; + lightshade = lightarray[x]; } uint32_t shadedfg_r, shadedfg_g, shadedfg_b; @@ -731,26 +729,17 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) { fg = fillcolor; } + else if (ModeT::SWFlags & SWSTYLEF_Translated) + { + fg = translation[((const uint8_t*)texPixels)[texel[x]]]; + } + else if (ModeT::Flags & STYLEF_RedIsAlpha) + { + fg = ((const uint8_t*)texPixels)[texel[x]]; + } else { - float rcpW = 0x01000000 / posW; - int32_t u = (int32_t)(posU * rcpW); - int32_t v = (int32_t)(posV * rcpW); - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - - if (ModeT::SWFlags & SWSTYLEF_Translated) - { - fg = translation[((const uint8_t*)texPixels)[texelX * texHeight + texelY]]; - } - else if (ModeT::Flags & STYLEF_RedIsAlpha) - { - fg = ((const uint8_t*)texPixels)[texelX * texHeight + texelY]; - } - else - { - fg = texPixels[texelX * texHeight + texelY]; - } + fg = texPixels[texel[x]]; } if ((ModeT::Flags & STYLEF_ColorIsFixed) && !(ModeT::SWFlags & SWSTYLEF_Fill)) @@ -765,17 +754,17 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) if (!(ModeT::Flags & STYLEF_Alpha1)) { - fgalpha = (fgalpha * alpha) >> 8; + fgalpha = (fgalpha * actoralpha) >> 8; } - int lightshade; + uint32_t lightshade; if (OptT::Flags & SWOPT_FixedLight) { - lightshade = light; + lightshade = fixedlight; } else { - lightshade = lightpos >> 4; + lightshade = lightarray[x]; } uint32_t shadedfg_r, shadedfg_g, shadedfg_b; @@ -792,24 +781,18 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) if (OptT::Flags & SWOPT_DynLights) { - uint32_t lit_r = posdynlight_r >> 4; - uint32_t lit_g = posdynlight_g >> 4; - uint32_t lit_b = posdynlight_b >> 4; - shadedfg_r = MIN(shadedfg_r + ((fg_r * lit_r) >> 8), (uint32_t)255); - shadedfg_g = MIN(shadedfg_g + ((fg_g * lit_g) >> 8), (uint32_t)255); - shadedfg_b = MIN(shadedfg_b + ((fg_b * lit_b) >> 8), (uint32_t)255); + shadedfg_r = MIN(shadedfg_r + ((fg_r * dynlights_r[x]) >> 8), (uint32_t)255); + shadedfg_g = MIN(shadedfg_g + ((fg_g * dynlights_g[x]) >> 8), (uint32_t)255); + shadedfg_b = MIN(shadedfg_b + ((fg_b * dynlights_b[x]) >> 8), (uint32_t)255); } } else { if (OptT::Flags & SWOPT_DynLights) { - uint32_t lit_r = posdynlight_r >> 4; - uint32_t lit_g = posdynlight_g >> 4; - uint32_t lit_b = posdynlight_b >> 4; - shadedfg_r = (RPART(fg) * MIN(lightshade + lit_r, (uint32_t)256)) >> 8; - shadedfg_g = (GPART(fg) * MIN(lightshade + lit_g, (uint32_t)256)) >> 8; - shadedfg_b = (BPART(fg) * MIN(lightshade + lit_b, (uint32_t)256)) >> 8; + shadedfg_r = (RPART(fg) * MIN(lightshade + dynlights_r[x], (uint32_t)256)) >> 8; + shadedfg_g = (GPART(fg) * MIN(lightshade + dynlights_g[x], (uint32_t)256)) >> 8; + shadedfg_b = (BPART(fg) * MIN(lightshade + dynlights_b[x], (uint32_t)256)) >> 8; } else { @@ -927,24 +910,11 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) destLine[x] = MAKEARGB(255, out_r, out_g, out_b); } } - - posW += stepW; - posU += stepU; - posV += stepV; - if (OptT::Flags & SWOPT_DynLights) - { - posdynlight_r += dynlights_r[x >> 4]; - posdynlight_g += dynlights_g[x >> 4]; - posdynlight_b += dynlights_b[x >> 4]; - } - if (!(OptT::Flags & SWOPT_FixedLight)) - lightpos += lightarray[x >> 4]; - x++; } } template -void DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args) +void DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread) { using namespace TriScreenDrawerModes; @@ -953,16 +923,16 @@ void DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args) if (!args->uniforms->FixedLight()) { if (args->uniforms->SimpleShade()) - DrawSpanOpt32(y, x0, x1, args); + DrawSpanOpt32(y, x0, x1, args, thread); else - DrawSpanOpt32(y, x0, x1, args); + DrawSpanOpt32(y, x0, x1, args, thread); } else { if (args->uniforms->SimpleShade()) - DrawSpanOpt32(y, x0, x1, args); + DrawSpanOpt32(y, x0, x1, args, thread); else - DrawSpanOpt32(y, x0, x1, args); + DrawSpanOpt32(y, x0, x1, args, thread); } } else @@ -970,22 +940,22 @@ void DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args) if (!args->uniforms->FixedLight()) { if (args->uniforms->SimpleShade()) - DrawSpanOpt32(y, x0, x1, args); + DrawSpanOpt32(y, x0, x1, args, thread); else - DrawSpanOpt32(y, x0, x1, args); + DrawSpanOpt32(y, x0, x1, args, thread); } else { if (args->uniforms->SimpleShade()) - DrawSpanOpt32(y, x0, x1, args); + DrawSpanOpt32(y, x0, x1, args, thread); else - DrawSpanOpt32(y, x0, x1, args); + DrawSpanOpt32(y, x0, x1, args, thread); } } } template -void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args) +void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread) { using namespace TriScreenDrawerModes; @@ -1501,23 +1471,23 @@ void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args) } template -void DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs *args) +void DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread) { using namespace TriScreenDrawerModes; if (args->uniforms->NumLights() == 0 && args->uniforms->DynLightColor() == 0) { if (!args->uniforms->FixedLight()) - DrawSpanOpt8(y, x0, x1, args); + DrawSpanOpt8(y, x0, x1, args, thread); else - DrawSpanOpt8(y, x0, x1, args); + DrawSpanOpt8(y, x0, x1, args, thread); } else { if (!args->uniforms->FixedLight()) - DrawSpanOpt8(y, x0, x1, args); + DrawSpanOpt8(y, x0, x1, args, thread); else - DrawSpanOpt8(y, x0, x1, args); + DrawSpanOpt8(y, x0, x1, args, thread); } } @@ -2049,7 +2019,7 @@ void DrawRect32(const void *destOrg, int destWidth, int destHeight, int destPitc DrawRectOpt32(destOrg, destWidth, destHeight, destPitch, args, thread); } -void(*ScreenTriangle::SpanDrawers8[])(int, int, int, const TriDrawTriangleArgs *) = +void(*ScreenTriangle::SpanDrawers8[])(int, int, int, const TriDrawTriangleArgs *, PolyTriangleThreadData *) = { &DrawSpan8, &DrawSpan8, @@ -2081,7 +2051,7 @@ void(*ScreenTriangle::SpanDrawers8[])(int, int, int, const TriDrawTriangleArgs * &DrawSpan8 }; -void(*ScreenTriangle::SpanDrawers32[])(int, int, int, const TriDrawTriangleArgs *) = +void(*ScreenTriangle::SpanDrawers32[])(int, int, int, const TriDrawTriangleArgs *, PolyTriangleThreadData *) = { &DrawSpan32, &DrawSpan32, diff --git a/src/polyrenderer/drawers/screen_triangle.h b/src/polyrenderer/drawers/screen_triangle.h index 72c8f8265..dc8809b0d 100644 --- a/src/polyrenderer/drawers/screen_triangle.h +++ b/src/polyrenderer/drawers/screen_triangle.h @@ -142,8 +142,8 @@ class ScreenTriangle public: static void Draw(const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread); - static void(*SpanDrawers8[])(int y, int x0, int x1, const TriDrawTriangleArgs *args); - static void(*SpanDrawers32[])(int y, int x0, int x1, const TriDrawTriangleArgs *args); + static void(*SpanDrawers8[])(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread); + static void(*SpanDrawers32[])(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread); static void(*RectDrawers8[])(const void *, int, int, int, const RectDrawArgs *, PolyTriangleThreadData *); static void(*RectDrawers32[])(const void *, int, int, int, const RectDrawArgs *, PolyTriangleThreadData *); From d30bf44dccb764b3955e6fa389e1b631b93a175a Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 25 Nov 2018 17:11:05 +0100 Subject: [PATCH 7/8] - use SSE for the normal walls --- src/polyrenderer/drawers/poly_triangle.h | 4 +- src/polyrenderer/drawers/screen_triangle.cpp | 64 ++++++++++++++++---- 2 files changed, 52 insertions(+), 16 deletions(-) diff --git a/src/polyrenderer/drawers/poly_triangle.h b/src/polyrenderer/drawers/poly_triangle.h index 07eb2b109..0d369fa00 100644 --- a/src/polyrenderer/drawers/poly_triangle.h +++ b/src/polyrenderer/drawers/poly_triangle.h @@ -84,9 +84,7 @@ public: uint32_t texel[MAXWIDTH]; int32_t texelV[MAXWIDTH]; fixed_t lightarray[MAXWIDTH]; - uint16_t dynlights_r[MAXWIDTH]; - uint16_t dynlights_g[MAXWIDTH]; - uint16_t dynlights_b[MAXWIDTH]; + uint32_t dynlights[MAXWIDTH]; static PolyTriangleThreadData *Get(DrawerThread *thread); diff --git a/src/polyrenderer/drawers/screen_triangle.cpp b/src/polyrenderer/drawers/screen_triangle.cpp index 46df3eeb3..f897684b5 100644 --- a/src/polyrenderer/drawers/screen_triangle.cpp +++ b/src/polyrenderer/drawers/screen_triangle.cpp @@ -404,9 +404,7 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyT uint32_t *texel = thread->texel; int32_t *texelV = thread->texelV; fixed_t *lightarray = thread->lightarray; - uint16_t *dynlights_r = thread->dynlights_r; - uint16_t *dynlights_g = thread->dynlights_g; - uint16_t *dynlights_b = thread->dynlights_b; + uint32_t *dynlights = thread->dynlights; if (!(ModeT::SWFlags & SWSTYLEF_Fill) && !(ModeT::SWFlags & SWSTYLEF_FogBoundary)) { @@ -596,9 +594,7 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyT lit_r = MIN(lit_r, 255); lit_g = MIN(lit_g, 255); lit_b = MIN(lit_b, 255); - dynlights_r[x] = lit_r; - dynlights_g[x] = lit_g; - dynlights_b[x] = lit_b; + dynlights[x] = MAKEARGB(255, lit_r, lit_g, lit_b); } } @@ -629,7 +625,49 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyT uint32_t *dest = (uint32_t*)args->dest; uint32_t *destLine = dest + args->pitch * y; - for (int x = x0; x < x1; x++) + int sseend = x0; +#ifndef NO_SSE + if (ModeT::BlendOp == STYLEOP_Add && + ModeT::BlendSrc == STYLEALPHA_One && + ModeT::BlendDest == STYLEALPHA_Zero && + (ModeT::Flags & STYLEF_Alpha1) && + !(OptT::Flags & SWOPT_ColoredFog) && + !(ModeT::Flags & STYLEF_RedIsAlpha) && + !(ModeT::SWFlags & SWSTYLEF_Skycap) && + !(ModeT::SWFlags & SWSTYLEF_FogBoundary) && + !(ModeT::SWFlags & SWSTYLEF_Fill)) + { + sseend += (x1 - x0) / 2 * 2; + + __m128i mlightshade; + if (OptT::Flags & SWOPT_FixedLight) + mlightshade = _mm_set1_epi16(fixedlight); + + __m128i alphamask = _mm_set1_epi32(0xff000000); + + for (int x = x0; x < sseend; x += 2) + { + __m128i mfg = _mm_unpacklo_epi8(_mm_setr_epi32(texPixels[texel[x]], texPixels[texel[x + 1]], 0, 0), _mm_setzero_si128()); + + if (!(OptT::Flags & SWOPT_FixedLight)) + mlightshade = _mm_shuffle_epi32(_mm_shufflelo_epi16(_mm_loadl_epi64((const __m128i*)&lightarray[x]), _MM_SHUFFLE(2, 2, 0, 0)), _MM_SHUFFLE(1, 1, 0, 0)); + + if (OptT::Flags & SWOPT_DynLights) + { + __m128i mdynlight = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)&dynlights[x]), _mm_setzero_si128()); + mfg = _mm_srli_epi16(_mm_mullo_epi16(_mm_min_epi16(_mm_add_epi16(mdynlight, mlightshade), _mm_set1_epi16(256)), mfg), 8); + } + else + { + mfg = _mm_srli_epi16(_mm_mullo_epi16(mlightshade, mfg), 8); + } + + _mm_storel_epi64((__m128i*)&destLine[x], _mm_or_si128(_mm_packus_epi16(mfg, _mm_setzero_si128()), alphamask)); + } + } +#endif + + for (int x = sseend; x < x1; x++) { if (ModeT::BlendOp == STYLEOP_Fuzz) { @@ -781,18 +819,18 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyT if (OptT::Flags & SWOPT_DynLights) { - shadedfg_r = MIN(shadedfg_r + ((fg_r * dynlights_r[x]) >> 8), (uint32_t)255); - shadedfg_g = MIN(shadedfg_g + ((fg_g * dynlights_g[x]) >> 8), (uint32_t)255); - shadedfg_b = MIN(shadedfg_b + ((fg_b * dynlights_b[x]) >> 8), (uint32_t)255); + shadedfg_r = MIN(shadedfg_r + ((fg_r * RPART(dynlights[x])) >> 8), (uint32_t)255); + shadedfg_g = MIN(shadedfg_g + ((fg_g * GPART(dynlights[x])) >> 8), (uint32_t)255); + shadedfg_b = MIN(shadedfg_b + ((fg_b * BPART(dynlights[x])) >> 8), (uint32_t)255); } } else { if (OptT::Flags & SWOPT_DynLights) { - shadedfg_r = (RPART(fg) * MIN(lightshade + dynlights_r[x], (uint32_t)256)) >> 8; - shadedfg_g = (GPART(fg) * MIN(lightshade + dynlights_g[x], (uint32_t)256)) >> 8; - shadedfg_b = (BPART(fg) * MIN(lightshade + dynlights_b[x], (uint32_t)256)) >> 8; + shadedfg_r = (RPART(fg) * MIN(lightshade + RPART(dynlights[x]), (uint32_t)256)) >> 8; + shadedfg_g = (GPART(fg) * MIN(lightshade + GPART(dynlights[x]), (uint32_t)256)) >> 8; + shadedfg_b = (BPART(fg) * MIN(lightshade + BPART(dynlights[x]), (uint32_t)256)) >> 8; } else { From d79ef939e9811902d4d8fc3b1bb2556778dbd53e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 25 Nov 2018 22:12:21 +0100 Subject: [PATCH 8/8] - fixed: The serializer must treat object that were already destroyed or are declared transient like a null pointer and not ignore them. This caused FraggleScript's SpawnedThings array to go out of sync. --- src/serializer.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/serializer.cpp b/src/serializer.cpp index fe8864a33..e0f74420f 100644 --- a/src/serializer.cpp +++ b/src/serializer.cpp @@ -1586,17 +1586,13 @@ FSerializer &Serialize(FSerializer &arc, const char *key, DObject *&value, DObje if (retcode) *retcode = true; if (arc.isWriting()) { - if (value != nullptr) + if (value != nullptr && !(value->ObjectFlags & (OF_EuthanizeMe | OF_Transient))) { int ndx; if (value == WP_NOCHANGE) { ndx = -1; } - else if (value->ObjectFlags & (OF_EuthanizeMe | OF_Transient)) - { - return arc; - } else { int *pndx = arc.w->mObjectMap.CheckKey(value);