From 7576068202487ee81bd0b9b3b445a7f36a1fe220 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Thu, 24 May 2018 11:58:51 +0300 Subject: [PATCH 01/14] - fixed compilation warning with MSVC 2015 src\polyrenderer\scene/poly_portal.cpp(142): warning C4800: 'line_t *': forcing value to bool 'true' or 'false' (performance warning) --- src/polyrenderer/scene/poly_portal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/polyrenderer/scene/poly_portal.cpp b/src/polyrenderer/scene/poly_portal.cpp index 93fe10053..f85314564 100644 --- a/src/polyrenderer/scene/poly_portal.cpp +++ b/src/polyrenderer/scene/poly_portal.cpp @@ -139,7 +139,7 @@ void PolyDrawLinePortal::Render(int portalDepth) DVector2 pt2 = clipLine->v2->fPos() - PolyRenderer::Instance()->Viewpoint.Pos; bool backfacing = (pt1.Y * (pt1.X - pt2.X) + pt1.X * (pt2.Y - pt1.Y) >= 0); - PortalViewpoint = PolyRenderer::Instance()->SetupPerspectiveMatrix(Mirror); + PortalViewpoint = PolyRenderer::Instance()->SetupPerspectiveMatrix(Mirror != nullptr); PortalViewpoint.StencilValue = StencilValue; PortalViewpoint.PortalDepth = portalDepth; PortalViewpoint.PortalEnterLine = clipLine; From cce6c9a0856a1a32cd98cd1dbea440a193a05b42 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 24 May 2018 20:31:06 +0200 Subject: [PATCH 02/14] - fixed precision issue with dot product. Apparently the shader math is not precise enough to ensure that two supposedly orthogonal vectors are truly orthogonal, resulting in a non-zero dot product --- wadsrc/static/shaders/glsl/material_normal.fp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/shaders/glsl/material_normal.fp b/wadsrc/static/shaders/glsl/material_normal.fp index 6b65de6a3..d02f7504d 100644 --- a/wadsrc/static/shaders/glsl/material_normal.fp +++ b/wadsrc/static/shaders/glsl/material_normal.fp @@ -12,7 +12,7 @@ vec3 lightContribution(int i, vec3 normal) vec3 lightdir = normalize(lightpos.xyz - pixelpos.xyz); float dotprod = dot(normal, lightdir); - if (dotprod < 0.0) return vec3(0.0); // light hits from the backside. This can happen with full sector light lists and must be rejected for all cases. + if (dotprod < -0.0001) return vec3(0.0); // light hits from the backside. This can happen with full sector light lists and must be rejected for all cases. Note that this can cause precision issues. float attenuation = clamp((lightpos.w - lightdistance) / lightpos.w, 0.0, 1.0); From cadc4f2a306b8a9daf8317ad17f295983a11fd1a Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 24 May 2018 21:18:20 +0200 Subject: [PATCH 03/14] - add #include support to TEXTURES lump --- src/textures/texturemanager.cpp | 282 +++++++++++++++++--------------- src/textures/textures.h | 1 + 2 files changed, 151 insertions(+), 132 deletions(-) diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index b922d8bb5..062003caf 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -607,12 +607,6 @@ void FTextureManager::AddHiresTextures (int wadnum) void FTextureManager::LoadTextureDefs(int wadnum, const char *lumpname) { int remapLump, lastLump; - FString src; - bool is32bit; - int width, height; - ETextureType type; - int mode; - TArray tlist; lastLump = 0; @@ -620,142 +614,166 @@ void FTextureManager::LoadTextureDefs(int wadnum, const char *lumpname) { if (Wads.GetLumpFile(remapLump) == wadnum) { - FScanner sc(remapLump); - while (sc.GetString()) + ParseTextureDef(remapLump); + } + } +} + +void FTextureManager::ParseTextureDef(int lump) +{ + TArray tlist; + + FScanner sc(lump); + while (sc.GetString()) + { + if (sc.Compare("remap")) // remap an existing texture + { + sc.MustGetString(); + + // allow selection by type + int mode; + ETextureType type; + if (sc.Compare("wall")) type=ETextureType::Wall, mode=FTextureManager::TEXMAN_Overridable; + else if (sc.Compare("flat")) type=ETextureType::Flat, mode=FTextureManager::TEXMAN_Overridable; + else if (sc.Compare("sprite")) type=ETextureType::Sprite, mode=0; + else type = ETextureType::Any, mode = 0; + + if (type != ETextureType::Any) sc.MustGetString(); + + sc.String[8]=0; + + tlist.Clear(); + int amount = ListTextures(sc.String, tlist); + FName texname = sc.String; + + sc.MustGetString(); + int lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_patches); + if (lumpnum == -1) lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_graphics); + + if (tlist.Size() == 0) { - if (sc.Compare("remap")) // remap an existing texture + Printf("Attempting to remap non-existent texture %s to %s\n", + texname.GetChars(), sc.String); + } + else if (lumpnum == -1) + { + Printf("Attempting to remap texture %s to non-existent lump %s\n", + texname.GetChars(), sc.String); + } + else + { + for(unsigned int i = 0; i < tlist.Size(); i++) { - sc.MustGetString(); + FTexture * oldtex = Textures[tlist[i].GetIndex()].Texture; + int sl; - // allow selection by type - if (sc.Compare("wall")) type=ETextureType::Wall, mode=FTextureManager::TEXMAN_Overridable; - else if (sc.Compare("flat")) type=ETextureType::Flat, mode=FTextureManager::TEXMAN_Overridable; - else if (sc.Compare("sprite")) type=ETextureType::Sprite, mode=0; - else type = ETextureType::Any, mode = 0; - - if (type != ETextureType::Any) sc.MustGetString(); - - sc.String[8]=0; - - tlist.Clear(); - int amount = ListTextures(sc.String, tlist); - FName texname = sc.String; - - sc.MustGetString(); - int lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_patches); - if (lumpnum == -1) lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_graphics); - - if (tlist.Size() == 0) + // only replace matching types. For sprites also replace any MiscPatches + // based on the same lump. These can be created for icons. + if (oldtex->UseType == type || type == ETextureType::Any || + (mode == TEXMAN_Overridable && oldtex->UseType == ETextureType::Override) || + (type == ETextureType::Sprite && oldtex->UseType == ETextureType::MiscPatch && + (sl=oldtex->GetSourceLump()) >= 0 && Wads.GetLumpNamespace(sl) == ns_sprites) + ) { - Printf("Attempting to remap non-existent texture %s to %s\n", - texname.GetChars(), sc.String); - } - else if (lumpnum == -1) - { - Printf("Attempting to remap texture %s to non-existent lump %s\n", - texname.GetChars(), sc.String); - } - else - { - for(unsigned int i = 0; i < tlist.Size(); i++) + FTexture * newtex = FTexture::CreateTexture (lumpnum, ETextureType::Any); + if (newtex != NULL) { - FTexture * oldtex = Textures[tlist[i].GetIndex()].Texture; - int sl; - - // only replace matching types. For sprites also replace any MiscPatches - // based on the same lump. These can be created for icons. - if (oldtex->UseType == type || type == ETextureType::Any || - (mode == TEXMAN_Overridable && oldtex->UseType == ETextureType::Override) || - (type == ETextureType::Sprite && oldtex->UseType == ETextureType::MiscPatch && - (sl=oldtex->GetSourceLump()) >= 0 && Wads.GetLumpNamespace(sl) == ns_sprites) - ) - { - FTexture * newtex = FTexture::CreateTexture (lumpnum, ETextureType::Any); - if (newtex != NULL) - { - // Replace the entire texture and adjust the scaling and offset factors. - newtex->bWorldPanning = true; - newtex->SetScaledSize(oldtex->GetScaledWidth(), oldtex->GetScaledHeight()); - newtex->_LeftOffset[0] = int(oldtex->GetScaledLeftOffset(0) * newtex->Scale.X); - newtex->_LeftOffset[1] = int(oldtex->GetScaledLeftOffset(1) * newtex->Scale.X); - newtex->_TopOffset[0] = int(oldtex->GetScaledTopOffset(0) * newtex->Scale.Y); - newtex->_TopOffset[1] = int(oldtex->GetScaledTopOffset(1) * newtex->Scale.Y); - ReplaceTexture(tlist[i], newtex, true); - } - } + // Replace the entire texture and adjust the scaling and offset factors. + newtex->bWorldPanning = true; + newtex->SetScaledSize(oldtex->GetScaledWidth(), oldtex->GetScaledHeight()); + newtex->_LeftOffset[0] = int(oldtex->GetScaledLeftOffset(0) * newtex->Scale.X); + newtex->_LeftOffset[1] = int(oldtex->GetScaledLeftOffset(1) * newtex->Scale.X); + newtex->_TopOffset[0] = int(oldtex->GetScaledTopOffset(0) * newtex->Scale.Y); + newtex->_TopOffset[1] = int(oldtex->GetScaledTopOffset(1) * newtex->Scale.Y); + ReplaceTexture(tlist[i], newtex, true); } } } - else if (sc.Compare("define")) // define a new "fake" texture - { - sc.GetString(); - - FString base = ExtractFileBase(sc.String, false); - if (!base.IsEmpty()) - { - src = base.Left(8); - - int lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_patches); - if (lumpnum == -1) lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_graphics); - - sc.GetString(); - is32bit = !!sc.Compare("force32bit"); - if (!is32bit) sc.UnGet(); - - sc.MustGetNumber(); - width = sc.Number; - sc.MustGetNumber(); - height = sc.Number; - - if (lumpnum>=0) - { - FTexture *newtex = FTexture::CreateTexture(lumpnum, ETextureType::Override); - - if (newtex != NULL) - { - // Replace the entire texture and adjust the scaling and offset factors. - newtex->bWorldPanning = true; - newtex->SetScaledSize(width, height); - newtex->Name = src; - - FTextureID oldtex = TexMan.CheckForTexture(src, ETextureType::MiscPatch); - if (oldtex.isValid()) - { - ReplaceTexture(oldtex, newtex, true); - newtex->UseType = ETextureType::Override; - } - else AddTexture(newtex); - } - } - } - //else Printf("Unable to define hires texture '%s'\n", tex->Name); - } - else if (sc.Compare("texture")) - { - ParseXTexture(sc, ETextureType::Override); - } - else if (sc.Compare("sprite")) - { - ParseXTexture(sc, ETextureType::Sprite); - } - else if (sc.Compare("walltexture")) - { - ParseXTexture(sc, ETextureType::Wall); - } - else if (sc.Compare("flat")) - { - ParseXTexture(sc, ETextureType::Flat); - } - else if (sc.Compare("graphic")) - { - ParseXTexture(sc, ETextureType::MiscPatch); - } - else - { - sc.ScriptError("Texture definition expected, found '%s'", sc.String); - } } } + else if (sc.Compare("define")) // define a new "fake" texture + { + sc.GetString(); + + FString base = ExtractFileBase(sc.String, false); + if (!base.IsEmpty()) + { + FString src = base.Left(8); + + int lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_patches); + if (lumpnum == -1) lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_graphics); + + sc.GetString(); + bool is32bit = !!sc.Compare("force32bit"); + if (!is32bit) sc.UnGet(); + + sc.MustGetNumber(); + int width = sc.Number; + sc.MustGetNumber(); + int height = sc.Number; + + if (lumpnum>=0) + { + FTexture *newtex = FTexture::CreateTexture(lumpnum, ETextureType::Override); + + if (newtex != NULL) + { + // Replace the entire texture and adjust the scaling and offset factors. + newtex->bWorldPanning = true; + newtex->SetScaledSize(width, height); + newtex->Name = src; + + FTextureID oldtex = TexMan.CheckForTexture(src, ETextureType::MiscPatch); + if (oldtex.isValid()) + { + ReplaceTexture(oldtex, newtex, true); + newtex->UseType = ETextureType::Override; + } + else AddTexture(newtex); + } + } + } + //else Printf("Unable to define hires texture '%s'\n", tex->Name); + } + else if (sc.Compare("texture")) + { + ParseXTexture(sc, ETextureType::Override); + } + else if (sc.Compare("sprite")) + { + ParseXTexture(sc, ETextureType::Sprite); + } + else if (sc.Compare("walltexture")) + { + ParseXTexture(sc, ETextureType::Wall); + } + else if (sc.Compare("flat")) + { + ParseXTexture(sc, ETextureType::Flat); + } + else if (sc.Compare("graphic")) + { + ParseXTexture(sc, ETextureType::MiscPatch); + } + else if (sc.Compare("#include")) + { + sc.MustGetString(); + + // This is not using sc.Open because it can print a more useful error message when done here + int includelump = Wads.CheckNumForFullName(sc.String, true); + if (includelump == -1) + { + sc.ScriptError("Lump '%s' not found", sc.String); + } + else + { + ParseTextureDef(includelump); + } + } + else + { + sc.ScriptError("Texture definition expected, found '%s'", sc.String); + } } } diff --git a/src/textures/textures.h b/src/textures/textures.h index 6b58fe6b5..f4beed822 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -584,6 +584,7 @@ public: void AddPatches (int lumpnum); void AddHiresTextures (int wadnum); void LoadTextureDefs(int wadnum, const char *lumpname); + void ParseTextureDef(int remapLump); void ParseXTexture(FScanner &sc, ETextureType usetype); void SortTexturesByType(int start, int end); bool AreTexturesCompatible (FTextureID picnum1, FTextureID picnum2); From 475d3f0829869d6906a8fcead80aa214067c0c44 Mon Sep 17 00:00:00 2001 From: Raccoon Date: Thu, 24 May 2018 00:56:59 -0500 Subject: [PATCH 04/14] Adds line specials --- src/p_lnspec.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index acf99d5d1..9e2ef889e 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -2765,6 +2765,54 @@ FUNC(LS_Line_SetBlocking) return true; } +FUNC(LS_Line_SetAutomapFlags) +// Line_SetAutomapFlags (id, setflags, clearflags) +{ + static const int flagtrans[] = + { + ML_SECRET, + ML_DONTDRAW, + ML_MAPPED, + ML_REVEALED, + -1 + }; + + if (arg0 == 0) return false; + + int setflags = 0; + int clearflags = 0; + + for (int i = 0; flagtrans[i] != ML_PORTALCONNECT; i++, arg1 >>= 1, arg2 >>= 1) + { + if (arg1 & 1) setflags |= flagtrans[i]; + if (arg2 & 1) clearflags |= flagtrans[i]; + } + + FLineIdIterator itr(arg0); + int line; + while ((line = itr.Next()) >= 0) + { + level.lines[line].flags = (level.lines[line].flags & ~clearflags) | setflags; + } + + return true; +} + +FUNC(LS_Line_SetAutomapStyle) +// Line_SetAutomapStyle (id, setflags, clearflags) +{ + if (arg1 < AMLS_COUNT && arg1 >= 0) { + FLineIdIterator itr(arg0); + int line; + while ((line = itr.Next()) >= 0) + { + level.lines[line].automapstyle = (AutomapLineStyle) arg1; + } + + return true; + } + return false; +} FUNC(LS_ChangeCamera) @@ -3713,6 +3761,8 @@ static lnSpecFunc LineSpecials[] = /* 278 */ LS_Sector_SetCeilingGlow, /* 279 */ LS_Floor_MoveToValueAndCrush, /* 280 */ LS_Ceiling_MoveToValueAndCrush, + /* 281 */ LS_Line_SetAutomapFlags, + /* 282 */ LS_Line_SetAutomapStyle, }; From a936592cfd412b9aed5ab97481fa775572a2be07 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Fri, 25 May 2018 10:59:48 +0300 Subject: [PATCH 05/14] - fixed compilation warning reported by MSVC src\r_videoscale.cpp(105): warning C4244: 'initializing': conversion from 'float' to 'int', possible loss of data --- src/r_videoscale.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_videoscale.cpp b/src/r_videoscale.cpp index 12103e457..e472ad476 100644 --- a/src/r_videoscale.cpp +++ b/src/r_videoscale.cpp @@ -102,7 +102,7 @@ bool ViewportIsScaled43() void R_ShowCurrentScaling() { - int x1 = screen->GetClientWidth(), y1 = screen->GetClientHeight(), x2 = x1 * vid_scalefactor, y2 = y1 * vid_scalefactor; + int x1 = screen->GetClientWidth(), y1 = screen->GetClientHeight(), x2 = int(x1 * vid_scalefactor), y2 = int(y1 * vid_scalefactor); Printf("Current Scale: %f\n", (float)(vid_scalefactor)); Printf("Real resolution: %i x %i\nEmulated resolution: %i x %i\n", x1, y1, x2, y2); } From 1634b78280ae0491528553115207f44f31b78e73 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Fri, 25 May 2018 11:05:30 +0300 Subject: [PATCH 06/14] - fixed typo in error message --- src/wi_stuff.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 2fba4a33d..e3e010fed 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -754,7 +754,7 @@ void WI_Start(wbstartstruct_t *wbstartstruct) cls = PClass::FindClass(screenclass); if (cls == nullptr) { - I_FatalError("Cannot create statis screen"); + I_FatalError("Cannot create status screen"); } } // Set up some global stuff that is always needed. From 31f29bbe8a2ff277da96db8dccaaaf0f6677ab41 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 25 May 2018 19:23:47 +0200 Subject: [PATCH 07/14] - force model light to be attenuated --- src/hwrenderer/dynlights/hw_dynlightdata.cpp | 6 +++--- src/hwrenderer/dynlights/hw_dynlightdata.h | 2 +- src/hwrenderer/scene/hw_spritelight.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hwrenderer/dynlights/hw_dynlightdata.cpp b/src/hwrenderer/dynlights/hw_dynlightdata.cpp index dce24d689..c881f9b4e 100644 --- a/src/hwrenderer/dynlights/hw_dynlightdata.cpp +++ b/src/hwrenderer/dynlights/hw_dynlightdata.cpp @@ -63,7 +63,7 @@ bool FDynLightData::GetLight(int group, Plane & p, ADynamicLight * light, bool c return false; } - AddLightToList(group, light); + AddLightToList(group, light, false); return true; } @@ -72,7 +72,7 @@ bool FDynLightData::GetLight(int group, Plane & p, ADynamicLight * light, bool c // Add one dynamic light to the light data list // //========================================================================== -void FDynLightData::AddLightToList(int group, ADynamicLight * light) +void FDynLightData::AddLightToList(int group, ADynamicLight * light, bool forceAttenuate) { int i = 0; @@ -109,7 +109,7 @@ void FDynLightData::AddLightToList(int group, ADynamicLight * light) bool attenuate; // Store attenuate flag in the sign bit of the float. - if (gl_attenuate == -1) attenuate = !!(light->lightflags & LF_ATTENUATE); + if (gl_attenuate == -1) attenuate = !!(light->lightflags & LF_ATTENUATE) || forceAttenuate; else attenuate = !!gl_attenuate; if (attenuate) shadowIndex = -shadowIndex; diff --git a/src/hwrenderer/dynlights/hw_dynlightdata.h b/src/hwrenderer/dynlights/hw_dynlightdata.h index ec03db05b..f1a1ffb7b 100644 --- a/src/hwrenderer/dynlights/hw_dynlightdata.h +++ b/src/hwrenderer/dynlights/hw_dynlightdata.h @@ -54,7 +54,7 @@ struct FDynLightData } bool GetLight(int group, Plane & p, ADynamicLight * light, bool checkside); - void AddLightToList(int group, ADynamicLight * light); + void AddLightToList(int group, ADynamicLight * light, bool forceAttenuate); }; diff --git a/src/hwrenderer/scene/hw_spritelight.cpp b/src/hwrenderer/scene/hw_spritelight.cpp index 95219dc7b..c44a3179a 100644 --- a/src/hwrenderer/scene/hw_spritelight.cpp +++ b/src/hwrenderer/scene/hw_spritelight.cpp @@ -219,7 +219,7 @@ void hw_GetDynModelLight(AActor *self, FDynLightData &modellightdata) { if (std::find(addedLights.begin(), addedLights.end(), light) == addedLights.end()) // Check if we already added this light from a different subsector { - modellightdata.AddLightToList(group, light); + modellightdata.AddLightToList(group, light, true); addedLights.Push(light); } } From b02736c7059e38aa83c80cfb60d53f0e1183ecd2 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 26 May 2018 12:41:57 +0530 Subject: [PATCH 08/14] Add missing line specials. --- src/actionspecials.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/actionspecials.h b/src/actionspecials.h index 9a8427ebc..7d1ac1d98 100644 --- a/src/actionspecials.h +++ b/src/actionspecials.h @@ -266,5 +266,7 @@ DEFINE_SPECIAL(Sector_SetFloorGlow, 277, 5, 5, 5) DEFINE_SPECIAL(Sector_SetCeilingGlow, 278, 5, 5, 5) DEFINE_SPECIAL(Floor_MoveToValueAndCrush, 279, 4, 5, 5) DEFINE_SPECIAL(Ceiling_MoveToValueAndCrush, 280, 4, 5, 5) +DEFINE_SPECIAL(Line_SetAutomapFlags, 281, 3, 3, 3) +DEFINE_SPECIAL(Line_SetAutomapStyle, 282, 2, 2, 2) #undef DEFINE_SPECIAL From 91f440378e24562d2103e341c759032e115138a9 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 26 May 2018 10:37:01 +0300 Subject: [PATCH 09/14] - fixed minor issues with new line specials --- src/p_lnspec.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 9e2ef889e..253f505e4 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -2782,7 +2782,7 @@ FUNC(LS_Line_SetAutomapFlags) int setflags = 0; int clearflags = 0; - for (int i = 0; flagtrans[i] != ML_PORTALCONNECT; i++, arg1 >>= 1, arg2 >>= 1) + for (int i = 0; flagtrans[i] != -1; i++, arg1 >>= 1, arg2 >>= 1) { if (arg1 & 1) setflags |= flagtrans[i]; if (arg2 & 1) clearflags |= flagtrans[i]; @@ -2799,9 +2799,10 @@ FUNC(LS_Line_SetAutomapFlags) } FUNC(LS_Line_SetAutomapStyle) -// Line_SetAutomapStyle (id, setflags, clearflags) +// Line_SetAutomapStyle (id, style) { - if (arg1 < AMLS_COUNT && arg1 >= 0) { + if (arg1 < AMLS_COUNT && arg1 >= 0) + { FLineIdIterator itr(arg0); int line; while ((line = itr.Next()) >= 0) From 7f908ce75dd46468ef7c9e5962de859da6adbc7d Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 26 May 2018 14:27:54 +0200 Subject: [PATCH 10/14] - implement render styles for the softpoly span drawers --- src/polyrenderer/drawers/screen_triangle.cpp | 610 ++++++++++++++----- src/polyrenderer/drawers/screen_triangle.h | 44 +- 2 files changed, 498 insertions(+), 156 deletions(-) diff --git a/src/polyrenderer/drawers/screen_triangle.cpp b/src/polyrenderer/drawers/screen_triangle.cpp index c8731dc3e..a43818c80 100644 --- a/src/polyrenderer/drawers/screen_triangle.cpp +++ b/src/polyrenderer/drawers/screen_triangle.cpp @@ -1163,7 +1163,8 @@ void ScreenTriangle::DrawSWRender(const TriDrawTriangleArgs *args, PolyTriangleT // Draw the triangle: - auto drawfunc = (args->destBgra) ? DrawSpan32 : DrawSpan8; + int bmode = (int)args->uniforms->BlendMode(); + auto drawfunc = args->destBgra ? ScreenTriangle::SpanDrawers32[bmode] : ScreenTriangle::SpanDrawers8[bmode]; float stepXW = args->gradientX.W; float v1X = args->v1->x; @@ -1248,10 +1249,11 @@ void ScreenTriangle::DrawSWRender(const TriDrawTriangleArgs *args, PolyTriangleT } } -#ifndef NO_SSE - -void ScreenTriangle::DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args) +template +void DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args) { + using namespace TriScreenDrawerModes; + float v1X = args->v1->x; float v1Y = args->v1->y; float v1W = args->v1->w; @@ -1267,127 +1269,12 @@ void ScreenTriangle::DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs float posXV = v1V + stepXV * startX + args->gradientY.V * startY; const uint32_t *texPixels = (const uint32_t*)args->uniforms->TexturePixels(); + const uint32_t *translation = (const uint32_t*)args->uniforms->Translation(); int texWidth = args->uniforms->TextureWidth(); int texHeight = args->uniforms->TextureHeight(); - bool is_fixed_light = args->uniforms->FixedLight(); - uint32_t lightmask = is_fixed_light ? 0 : 0xffffffff; - uint32_t light = args->uniforms->Light(); - float shade = 2.0f - (light + 12.0f) / 128.0f; - float globVis = args->uniforms->GlobVis() * (1.0f / 32.0f); - light += light >> 7; // 255 -> 256 - - uint32_t *dest = (uint32_t*)args->dest; - uint32_t *destLine = dest + args->pitch * y; - - int x = x0; - int sseEnd = x0 + ((x1 - x0) & ~3); - while (x < sseEnd) - { - uint32_t fgcolor[2]; - int32_t lightshade[2]; - - float rcpW = 0x01000000 / posXW; - int32_t u = (int32_t)(posXU * rcpW); - int32_t v = (int32_t)(posXV * rcpW); - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - fgcolor[0] = texPixels[texelX * texHeight + texelY]; - - fixed_t lightpos = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * posXW), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask); - lightshade[0] = lightpos >> 8; - - posXW += stepXW; - posXU += stepXU; - posXV += stepXV; - - rcpW = 0x01000000 / posXW; - u = (int32_t)(posXU * rcpW); - v = (int32_t)(posXV * rcpW); - texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - fgcolor[1] = texPixels[texelX * texHeight + texelY]; - - lightpos = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * posXW), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask); - lightshade[1] = lightpos >> 8; - - posXW += stepXW; - posXU += stepXU; - posXV += stepXV; - - __m128i mfgcolor = _mm_loadl_epi64((const __m128i*)fgcolor); - mfgcolor = _mm_unpacklo_epi8(mfgcolor, _mm_setzero_si128()); - - __m128i mlightshade = _mm_loadl_epi64((const __m128i*)lightshade); - mlightshade = _mm_shuffle_epi32(mlightshade, _MM_SHUFFLE(1, 0, 1, 0)); - mlightshade = _mm_packs_epi32(mlightshade, mlightshade); - - __m128i mdestcolor = _mm_srli_epi16(_mm_mullo_epi16(mfgcolor, mlightshade), 8); - mdestcolor = _mm_packus_epi16(mdestcolor, _mm_setzero_si128()); - mdestcolor = _mm_or_si128(mdestcolor, _mm_set1_epi32(0xff000000)); - - _mm_storel_epi64((__m128i*)(destLine + x), mdestcolor); - - x += 2; - } - - while (x < x1) - { - float rcpW = 0x01000000 / posXW; - int32_t u = (int32_t)(posXU * rcpW); - int32_t v = (int32_t)(posXV * rcpW); - - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - uint32_t fgcolor = texPixels[texelX * texHeight + texelY]; - - uint32_t fgcolor_r = RPART(fgcolor); - uint32_t fgcolor_g = GPART(fgcolor); - uint32_t fgcolor_b = BPART(fgcolor); - uint32_t fgcolor_a = APART(fgcolor); - if (fgcolor_a > 127) - { - fixed_t lightpos = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * posXW), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask); - int lightshade = lightpos >> 8; - - fgcolor_r = (fgcolor_r * lightshade) >> 8; - fgcolor_g = (fgcolor_g * lightshade) >> 8; - fgcolor_b = (fgcolor_b * lightshade) >> 8; - - destLine[x] = 0xff000000 | (fgcolor_r << 16) | (fgcolor_g << 8) | fgcolor_b; - } - - posXW += stepXW; - posXU += stepXU; - posXV += stepXV; - x++; - } -} - -#else - -void ScreenTriangle::DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args) -{ - float v1X = args->v1->x; - float v1Y = args->v1->y; - float v1W = args->v1->w; - float v1U = args->v1->u * v1W; - float v1V = args->v1->v * v1W; - float stepXW = args->gradientX.W; - float stepXU = args->gradientX.U; - float stepXV = args->gradientX.V; - float startX = x0 + (0.5f - v1X); - float startY = y + (0.5f - v1Y); - float posXW = v1W + stepXW * startX + args->gradientY.W * startY; - float posXU = v1U + stepXU * startX + args->gradientY.U * startY; - float posXV = v1V + stepXV * startX + args->gradientY.V * startY; - - const uint32_t *texPixels = (const uint32_t*)args->uniforms->TexturePixels(); - int texWidth = args->uniforms->TextureWidth(); - int texHeight = args->uniforms->TextureHeight(); + int fillcolor = args->uniforms->Color(); + int alpha = args->uniforms->SrcAlpha(); bool is_fixed_light = args->uniforms->FixedLight(); uint32_t lightmask = is_fixed_light ? 0 : 0xffffffff; @@ -1402,29 +1289,197 @@ void ScreenTriangle::DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs int x = x0; while (x < x1) { - float rcpW = 0x01000000 / posXW; - int32_t u = (int32_t)(posXU * rcpW); - int32_t v = (int32_t)(posXV * rcpW); + uint32_t fg; - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - uint32_t fgcolor = texPixels[texelX * texHeight + texelY]; - - uint32_t fgcolor_r = RPART(fgcolor); - uint32_t fgcolor_g = GPART(fgcolor); - uint32_t fgcolor_b = BPART(fgcolor); - uint32_t fgcolor_a = APART(fgcolor); - if (fgcolor_a > 127) + if (ModeT::SWFlags & SWSTYLEF_Fill) { + fg = fillcolor; + } + else if (ModeT::SWFlags & SWSTYLEF_FogBoundary) + { + fg = destLine[x]; + } + else + { + float rcpW = 0x01000000 / posXW; + int32_t u = (int32_t)(posXU * rcpW); + int32_t v = (int32_t)(posXV * 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 + { + fg = texPixels[texelX * texHeight + texelY]; + } + } + + if (ModeT::SWFlags & SWSTYLEF_Skycap) + { + float rcpW = 0x01000000 / posXW; + int32_t v = (int32_t)(posXV * rcpW); + + 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); + int a = MIN(alpha_top, alpha_bottom); + int inv_a = 256 - a; + + if (a == 256) + { + destLine[x] = fg; + } + else + { + uint32_t r = RPART(fg); + uint32_t g = GPART(fg); + uint32_t b = BPART(fg); + uint32_t fg_a = APART(fg); + uint32_t bg_red = RPART(fillcolor); + uint32_t bg_green = GPART(fillcolor); + uint32_t bg_blue = BPART(fillcolor); + r = (r * a + bg_red * inv_a + 127) >> 8; + g = (g * a + bg_green * inv_a + 127) >> 8; + b = (b * a + bg_blue * inv_a + 127) >> 8; + + destLine[x] = RGB256k.All[((r >> 2) << 12) | ((g >> 2) << 6) | (b >> 2)]; + } + } + else + { + if ((ModeT::Flags & STYLEF_ColorIsFixed) && !(ModeT::SWFlags & SWSTYLEF_Fill)) + { + if (ModeT::Flags & STYLEF_RedIsAlpha) + fg = ((fg << 8) & 0xff000000) | (fillcolor & 0x00ffffff); + else + fg = (fg & 0xff000000) | (fillcolor & 0x00ffffff); + } + + uint32_t fgalpha = fg >> 24; + + if (!(ModeT::Flags & STYLEF_Alpha1)) + { + fgalpha = (fgalpha * alpha) >> 8; + } + fixed_t lightpos = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * posXW), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask); int lightshade = lightpos >> 8; + uint32_t shadedfg_r = (RPART(fg) * lightshade) >> 8; + uint32_t shadedfg_g = (GPART(fg) * lightshade) >> 8; + uint32_t shadedfg_b = (BPART(fg) * lightshade) >> 8; - fgcolor_r = (fgcolor_r * lightshade) >> 8; - fgcolor_g = (fgcolor_g * lightshade) >> 8; - fgcolor_b = (fgcolor_b * lightshade) >> 8; + if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_Zero) + { + destLine[x] = MAKEARGB(255, shadedfg_r, shadedfg_g, shadedfg_b); + } + else if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_One) + { + uint32_t dest = destLine[x]; - destLine[x] = 0xff000000 | (fgcolor_r << 16) | (fgcolor_g << 8) | fgcolor_b; + if (ModeT::BlendOp == STYLEOP_Add) + { + uint32_t out_r = MIN(RPART(dest) + shadedfg_r, 255); + uint32_t out_g = MIN(GPART(dest) + shadedfg_g, 255); + uint32_t out_b = MIN(BPART(dest) + shadedfg_b, 255); + destLine[x] = MAKEARGB(255, out_r, out_g, out_b); + } + else if (ModeT::BlendOp == STYLEOP_RevSub) + { + uint32_t out_r = MAX(RPART(dest) - shadedfg_r, 0); + uint32_t out_g = MAX(GPART(dest) - shadedfg_g, 0); + uint32_t out_b = MAX(BPART(dest) - shadedfg_b, 0); + destLine[x] = MAKEARGB(255, out_r, out_g, out_b); + } + else //if (ModeT::BlendOp == STYLEOP_Sub) + { + uint32_t out_r = MAX(shadedfg_r - RPART(dest), 0); + uint32_t out_g = MAX(shadedfg_g - GPART(dest), 0); + uint32_t out_b = MAX(shadedfg_b - BPART(dest), 0); + destLine[x] = MAKEARGB(255, out_r, out_g, out_b); + } + } + else if (ModeT::SWFlags & SWSTYLEF_SrcColorOneMinusSrcColor) + { + uint32_t dest = destLine[x]; + + uint32_t sfactor_r = shadedfg_r; sfactor_r += sfactor_r >> 7; // 255 -> 256 + uint32_t sfactor_g = shadedfg_g; sfactor_g += sfactor_g >> 7; // 255 -> 256 + uint32_t sfactor_b = shadedfg_b; sfactor_b += sfactor_b >> 7; // 255 -> 256 + uint32_t sfactor_a = fgalpha; sfactor_a += sfactor_a >> 7; // 255 -> 256 + uint32_t dfactor_r = 256 - sfactor_r; + uint32_t dfactor_g = 256 - sfactor_g; + uint32_t dfactor_b = 256 - sfactor_b; + uint32_t out_r = (RPART(dest) * dfactor_r + shadedfg_r * sfactor_r + 128) >> 8; + uint32_t out_g = (GPART(dest) * dfactor_g + shadedfg_g * sfactor_g + 128) >> 8; + uint32_t out_b = (BPART(dest) * dfactor_b + shadedfg_b * sfactor_b + 128) >> 8; + + destLine[x] = MAKEARGB(255, out_r, out_g, out_b); + } + else if (fgalpha == 255) + { + destLine[x] = MAKEARGB(255, shadedfg_r, shadedfg_g, shadedfg_b); + } + else if (fgalpha != 0) + { + uint32_t dest = destLine[x]; + + uint32_t sfactor = fgalpha; sfactor += sfactor >> 7; // 255 -> 256 + uint32_t dfactor = 256 - sfactor; + uint32_t src_r = shadedfg_r * sfactor; + uint32_t src_g = shadedfg_g * sfactor; + uint32_t src_b = shadedfg_b * sfactor; + uint32_t dest_r = RPART(dest); + uint32_t dest_g = GPART(dest); + uint32_t dest_b = BPART(dest); + if (ModeT::BlendDest == STYLEALPHA_One) + { + dest_r <<= 8; + dest_g <<= 8; + dest_b <<= 8; + } + else + { + uint32_t dfactor = 256 - sfactor; + dest_r *= dfactor; + dest_g *= dfactor; + dest_b *= dfactor; + } + + uint32_t out_r, out_g, out_b; + if (ModeT::BlendOp == STYLEOP_Add) + { + if (ModeT::BlendDest == STYLEALPHA_One) + { + out_r = MIN((dest_r + src_r + 128) >> 8, 255); + out_g = MIN((dest_g + src_g + 128) >> 8, 255); + out_b = MIN((dest_b + src_b + 128) >> 8, 255); + } + else + { + out_r = (dest_r + src_r + 128) >> 8; + out_g = (dest_g + src_g + 128) >> 8; + out_b = (dest_b + src_b + 128) >> 8; + } + } + else if (ModeT::BlendOp == STYLEOP_RevSub) + { + out_r = MAX(static_cast(dest_r - src_r + 128) >> 8, 0); + out_g = MAX(static_cast(dest_g - src_g + 128) >> 8, 0); + out_b = MAX(static_cast(dest_b - src_b + 128) >> 8, 0); + } + else //if (ModeT::BlendOp == STYLEOP_Sub) + { + out_r = MAX(static_cast(src_r - dest_r + 128) >> 8, 0); + out_g = MAX(static_cast(src_g - dest_g + 128) >> 8, 0); + out_b = MAX(static_cast(src_b - dest_b + 128) >> 8, 0); + } + + destLine[x] = MAKEARGB(255, out_r, out_g, out_b); + } } posXW += stepXW; @@ -1434,10 +1489,11 @@ void ScreenTriangle::DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs } } -#endif - -void ScreenTriangle::DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs *args) +template +void DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs *args) { + using namespace TriScreenDrawerModes; + float v1X = args->v1->x; float v1Y = args->v1->y; float v1W = args->v1->w; @@ -1455,9 +1511,17 @@ void ScreenTriangle::DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs auto colormaps = args->uniforms->BaseColormap(); const uint8_t *texPixels = args->uniforms->TexturePixels(); + const uint8_t *translation = args->uniforms->Translation(); int texWidth = args->uniforms->TextureWidth(); int texHeight = args->uniforms->TextureHeight(); + int fillcolor = args->uniforms->Color(); + int alpha = args->uniforms->SrcAlpha(); + + uint32_t capcolor = fillcolor; + if (ModeT::SWFlags & SWSTYLEF_Skycap) + capcolor = GPalette.BaseColors[capcolor].d; + bool is_fixed_light = args->uniforms->FixedLight(); uint32_t lightmask = is_fixed_light ? 0 : 0xffffffff; uint32_t light = args->uniforms->Light(); @@ -1471,23 +1535,197 @@ void ScreenTriangle::DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs int x = x0; while (x < x1) { - float rcpW = 0x01000000 / posXW; - int32_t u = (int32_t)(posXU * rcpW); - int32_t v = (int32_t)(posXV * rcpW); + int fg; + int fgalpha = 255; - uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; - uint8_t fgcolor = texPixels[texelX * texHeight + texelY]; + if (ModeT::SWFlags & SWSTYLEF_Fill) + { + fg = fillcolor; + } + else if (ModeT::SWFlags & SWSTYLEF_FogBoundary) + { + fg = destLine[x]; + } + else + { + float rcpW = 0x01000000 / posXW; + int32_t u = (int32_t)(posXU * rcpW); + int32_t v = (int32_t)(posXV * rcpW); + uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; + uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; + fg = texPixels[texelX * texHeight + texelY]; - fixed_t lightpos = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * posXW), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); - lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask); - int lightshade = lightpos >> 8; + if (ModeT::SWFlags & SWSTYLEF_Translated) + fg = translation[fg]; - lightshade = ((256 - lightshade) * NUMCOLORMAPS) & 0xffffff00; - uint8_t shadedfg = colormaps[lightshade + fgcolor]; + fgalpha = (fg != 0) ? 255 : 0; + } - if (fgcolor != 0) - destLine[x] = shadedfg; + if (ModeT::SWFlags & SWSTYLEF_Skycap) + { + float rcpW = 0x01000000 / posXW; + int32_t v = (int32_t)(posXV * rcpW); + + 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); + int a = MIN(alpha_top, alpha_bottom); + int inv_a = 256 - a; + + if (a == 256) + { + destLine[x] = fg; + } + else + { + uint32_t texelrgb = GPalette.BaseColors[fg].d; + + uint32_t r = RPART(texelrgb); + uint32_t g = GPART(texelrgb); + uint32_t b = BPART(texelrgb); + uint32_t fg_a = APART(texelrgb); + uint32_t bg_red = RPART(capcolor); + uint32_t bg_green = GPART(capcolor); + uint32_t bg_blue = BPART(capcolor); + r = (r * a + bg_red * inv_a + 127) >> 8; + g = (g * a + bg_green * inv_a + 127) >> 8; + b = (b * a + bg_blue * inv_a + 127) >> 8; + + destLine[x] = RGB256k.All[((r >> 2) << 12) | ((g >> 2) << 6) | (b >> 2)]; + } + } + else + { + if ((ModeT::Flags & STYLEF_ColorIsFixed) && !(ModeT::SWFlags & SWSTYLEF_Fill)) + { + if (ModeT::Flags & STYLEF_RedIsAlpha) + fgalpha = fg; + fg = fillcolor; + } + + if (!(ModeT::Flags & STYLEF_Alpha1)) + { + fgalpha = (fgalpha * alpha) >> 8; + } + + fixed_t lightpos = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * posXW), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); + lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask); + int lightshade = lightpos >> 8; + lightshade = ((256 - lightshade) * NUMCOLORMAPS) & 0xffffff00; + uint8_t shadedfg = colormaps[lightshade + fg]; + + if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_Zero) + { + destLine[x] = shadedfg; + } + else if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_One) + { + uint32_t src = GPalette.BaseColors[shadedfg]; + uint32_t dest = GPalette.BaseColors[destLine[x]]; + + if (ModeT::BlendOp == STYLEOP_Add) + { + uint32_t out_r = MIN(RPART(dest) + RPART(src), 255); + uint32_t out_g = MIN(GPART(dest) + GPART(src), 255); + uint32_t out_b = MIN(BPART(dest) + BPART(src), 255); + destLine[x] = RGB256k.All[((out_r >> 2) << 12) | ((out_g >> 2) << 6) | (out_b >> 2)]; + } + else if (ModeT::BlendOp == STYLEOP_RevSub) + { + uint32_t out_r = MAX(RPART(dest) - RPART(src), 0); + uint32_t out_g = MAX(GPART(dest) - GPART(src), 0); + uint32_t out_b = MAX(BPART(dest) - BPART(src), 0); + destLine[x] = RGB256k.All[((out_r >> 2) << 12) | ((out_g >> 2) << 6) | (out_b >> 2)]; + } + else //if (ModeT::BlendOp == STYLEOP_Sub) + { + uint32_t out_r = MAX(RPART(src) - RPART(dest), 0); + uint32_t out_g = MAX(GPART(src) - GPART(dest), 0); + uint32_t out_b = MAX(BPART(src) - BPART(dest), 0); + destLine[x] = RGB256k.All[((out_r >> 2) << 12) | ((out_g >> 2) << 6) | (out_b >> 2)]; + } + } + else if (ModeT::SWFlags & SWSTYLEF_SrcColorOneMinusSrcColor) + { + uint32_t src = GPalette.BaseColors[shadedfg]; + uint32_t dest = GPalette.BaseColors[destLine[x]]; + + uint32_t sfactor_r = RPART(src); sfactor_r += sfactor_r >> 7; // 255 -> 256 + uint32_t sfactor_g = GPART(src); sfactor_g += sfactor_g >> 7; // 255 -> 256 + uint32_t sfactor_b = BPART(src); sfactor_b += sfactor_b >> 7; // 255 -> 256 + uint32_t sfactor_a = fgalpha; sfactor_a += sfactor_a >> 7; // 255 -> 256 + uint32_t dfactor_r = 256 - sfactor_r; + uint32_t dfactor_g = 256 - sfactor_g; + uint32_t dfactor_b = 256 - sfactor_b; + uint32_t out_r = (RPART(dest) * dfactor_r + RPART(src) * sfactor_r + 128) >> 8; + uint32_t out_g = (GPART(dest) * dfactor_g + GPART(src) * sfactor_g + 128) >> 8; + uint32_t out_b = (BPART(dest) * dfactor_b + BPART(src) * sfactor_b + 128) >> 8; + + destLine[x] = RGB256k.All[((out_r >> 2) << 12) | ((out_g >> 2) << 6) | (out_b >> 2)]; + } + else if (fgalpha == 255) + { + destLine[x] = shadedfg; + } + else if (fgalpha != 0) + { + uint32_t src = GPalette.BaseColors[shadedfg]; + uint32_t dest = GPalette.BaseColors[destLine[x]]; + + uint32_t sfactor = fgalpha; sfactor += sfactor >> 7; // 255 -> 256 + uint32_t dfactor = 256 - sfactor; + uint32_t src_r = RPART(src) * sfactor; + uint32_t src_g = GPART(src) * sfactor; + uint32_t src_b = BPART(src) * sfactor; + uint32_t dest_r = RPART(dest); + uint32_t dest_g = GPART(dest); + uint32_t dest_b = BPART(dest); + if (ModeT::BlendDest == STYLEALPHA_One) + { + dest_r <<= 8; + dest_g <<= 8; + dest_b <<= 8; + } + else + { + uint32_t dfactor = 256 - sfactor; + dest_r *= dfactor; + dest_g *= dfactor; + dest_b *= dfactor; + } + + uint32_t out_r, out_g, out_b; + if (ModeT::BlendOp == STYLEOP_Add) + { + if (ModeT::BlendDest == STYLEALPHA_One) + { + out_r = MIN((dest_r + src_r + 128) >> 8, 255); + out_g = MIN((dest_g + src_g + 128) >> 8, 255); + out_b = MIN((dest_b + src_b + 128) >> 8, 255); + } + else + { + out_r = (dest_r + src_r + 128) >> 8; + out_g = (dest_g + src_g + 128) >> 8; + out_b = (dest_b + src_b + 128) >> 8; + } + } + else if (ModeT::BlendOp == STYLEOP_RevSub) + { + out_r = MAX(static_cast(dest_r - src_r + 128) >> 8, 0); + out_g = MAX(static_cast(dest_g - src_g + 128) >> 8, 0); + out_b = MAX(static_cast(dest_b - src_b + 128) >> 8, 0); + } + else //if (ModeT::BlendOp == STYLEOP_Sub) + { + out_r = MAX(static_cast(src_r - dest_r + 128) >> 8, 0); + out_g = MAX(static_cast(src_g - dest_g + 128) >> 8, 0); + out_b = MAX(static_cast(src_b - dest_b + 128) >> 8, 0); + } + + destLine[x] = RGB256k.All[((out_r >> 2) << 12) | ((out_g >> 2) << 6) | (out_b >> 2)]; + } + } posXW += stepXW; posXU += stepXU; @@ -1496,6 +1734,70 @@ void ScreenTriangle::DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs } } +void(*ScreenTriangle::SpanDrawers8[])(int, int, int, const TriDrawTriangleArgs *) = +{ + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8, + &DrawSpan8 +}; + +void(*ScreenTriangle::SpanDrawers32[])(int, int, int, const TriDrawTriangleArgs *) = +{ + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32, + &DrawSpan32 +}; + void(*ScreenTriangle::TriDrawers8[])(int, int, uint32_t, uint32_t, const TriDrawTriangleArgs *) = { &TriScreenDrawer8::Execute, // TextureOpaque diff --git a/src/polyrenderer/drawers/screen_triangle.h b/src/polyrenderer/drawers/screen_triangle.h index df635a29e..c8a23c707 100644 --- a/src/polyrenderer/drawers/screen_triangle.h +++ b/src/polyrenderer/drawers/screen_triangle.h @@ -139,9 +139,9 @@ class ScreenTriangle public: static void Draw(const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread); static void DrawSWRender(const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread); - static void DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs *args); - static void DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args); + 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(*TriDrawers8[])(int, int, uint32_t, uint32_t, const TriDrawTriangleArgs *); static void(*TriDrawers32[])(int, int, uint32_t, uint32_t, const TriDrawTriangleArgs *); static void(*RectDrawers8[])(const void *, int, int, int, const RectDrawArgs *, PolyTriangleThreadData *); @@ -152,6 +152,46 @@ public: namespace TriScreenDrawerModes { + enum SWStyleFlags + { + SWSTYLEF_Translated = 1, + SWSTYLEF_Skycap = 2, + SWSTYLEF_FogBoundary = 4, + SWSTYLEF_Fill = 8, + SWSTYLEF_SrcColorOneMinusSrcColor = 16 + }; + + struct StyleOpaque { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_One, BlendDest = STYLEALPHA_Zero, Flags = STYLEF_Alpha1, SWFlags = 0; }; + struct StyleSkycap { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_One, BlendDest = STYLEALPHA_Zero, Flags = STYLEF_Alpha1, SWFlags = SWSTYLEF_Skycap; }; + struct StyleFogBoundary { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_One, BlendDest = STYLEALPHA_Zero, Flags = STYLEF_Alpha1, SWFlags = SWSTYLEF_FogBoundary; }; + struct StyleSrcColor { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_Alpha1, SWFlags = SWSTYLEF_SrcColorOneMinusSrcColor; }; + struct StyleFill { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_One, BlendDest = STYLEALPHA_Zero, Flags = STYLEF_Alpha1, SWFlags = SWSTYLEF_Fill; }; + + struct StyleNormal { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_Alpha1, SWFlags = 0; }; + struct StyleFuzzy { static const int BlendOp = STYLEOP_Fuzz, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = 0, SWFlags = 0; }; + struct StyleStencil { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_Alpha1 | STYLEF_ColorIsFixed, SWFlags = 0; }; + struct StyleTranslucent { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = 0, SWFlags = 0; }; + struct StyleAdd { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_One, Flags = 0, SWFlags = 0; }; + struct StyleShaded { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_RedIsAlpha | STYLEF_ColorIsFixed, SWFlags = 0; }; + struct StyleTranslucentStencil { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_ColorIsFixed, SWFlags = 0; }; + struct StyleShadow { static const int BlendOp = STYLEOP_Shadow, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = 0, SWFlags = 0; }; + struct StyleSubtract { static const int BlendOp = STYLEOP_RevSub, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_One, Flags = 0, SWFlags = 0; }; + struct StyleAddStencil { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_One, Flags = STYLEF_ColorIsFixed, SWFlags = 0; }; + struct StyleAddShaded { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_One, Flags = STYLEF_RedIsAlpha | STYLEF_ColorIsFixed, SWFlags = 0; }; + + struct StyleOpaqueTranslated { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_One, BlendDest = STYLEALPHA_Zero, Flags = STYLEF_Alpha1, SWFlags = SWSTYLEF_Translated; }; + struct StyleSrcColorTranslated { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_Alpha1, SWFlags = SWSTYLEF_Translated|SWSTYLEF_SrcColorOneMinusSrcColor; }; + struct StyleNormalTranslated { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_Alpha1, SWFlags = SWSTYLEF_Translated; }; + struct StyleStencilTranslated { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_Alpha1 | STYLEF_ColorIsFixed, SWFlags = SWSTYLEF_Translated; }; + struct StyleTranslucentTranslated { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = 0, SWFlags = SWSTYLEF_Translated; }; + struct StyleAddTranslated { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_One, Flags = 0, SWFlags = SWSTYLEF_Translated; }; + struct StyleShadedTranslated { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_RedIsAlpha | STYLEF_ColorIsFixed, SWFlags = SWSTYLEF_Translated; }; + struct StyleTranslucentStencilTranslated { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_ColorIsFixed, SWFlags = SWSTYLEF_Translated; }; + struct StyleShadowTranslated { static const int BlendOp = STYLEOP_Shadow, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = 0, SWFlags = SWSTYLEF_Translated; }; + struct StyleSubtractTranslated { static const int BlendOp = STYLEOP_RevSub, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_One, Flags = 0, SWFlags = SWSTYLEF_Translated; }; + struct StyleAddStencilTranslated { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_One, Flags = STYLEF_ColorIsFixed, SWFlags = SWSTYLEF_Translated; }; + struct StyleAddShadedTranslated { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_One, Flags = STYLEF_RedIsAlpha | STYLEF_ColorIsFixed, SWFlags = SWSTYLEF_Translated; }; + enum class BlendModes { Opaque, Masked, AddClamp, SubClamp, RevSubClamp, AddSrcColorOneMinusSrcColor, Shaded, AddClampShaded }; struct OpaqueBlend { static const int Mode = (int)BlendModes::Opaque; }; struct MaskedBlend { static const int Mode = (int)BlendModes::Masked; }; From 9fb34fd8e6bbc481f772ab6bb453e9ad965f1c0a Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 26 May 2018 16:15:14 +0200 Subject: [PATCH 11/14] - add SSE2 version of softpoly span drawer --- src/polyrenderer/drawers/screen_triangle.cpp | 165 ++++++++++++++++++- 1 file changed, 164 insertions(+), 1 deletion(-) diff --git a/src/polyrenderer/drawers/screen_triangle.cpp b/src/polyrenderer/drawers/screen_triangle.cpp index a43818c80..1ee1aa947 100644 --- a/src/polyrenderer/drawers/screen_triangle.cpp +++ b/src/polyrenderer/drawers/screen_triangle.cpp @@ -1287,6 +1287,169 @@ void DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args) uint32_t *destLine = dest + args->pitch * y; int x = x0; + +#ifndef NO_SSE + __m128i mfillcolor = _mm_set1_epi32(fillcolor); + __m128i mcapcolor = _mm_unpacklo_epi8(mfillcolor, _mm_setzero_si128()); + __m128i malpha = _mm_set1_epi32(alpha); + + int sseEnd = x0 + ((x1 - x0) & ~3); + while (x < sseEnd) + { + __m128i fg; + + if (ModeT::SWFlags & SWSTYLEF_Fill) + { + fg = mfillcolor; + } + else if (ModeT::SWFlags & SWSTYLEF_FogBoundary) + { + fg = _mm_loadl_epi64((const __m128i*)(destLine + x)); + } + else + { + float rcpW0 = 0x01000000 / posXW; + float rcpW1 = 0x01000000 / (posXW + stepXW); + + int32_t u0 = (int32_t)(posXU * rcpW0); + int32_t u1 = (int32_t)((posXU + stepXU) * rcpW1); + int32_t v0 = (int32_t)(posXV * rcpW0); + int32_t v1 = (int32_t)((posXV + stepXV) * rcpW1); + uint32_t texelX0 = ((((uint32_t)u0 << 8) >> 16) * texWidth) >> 16; + uint32_t texelX1 = ((((uint32_t)u1 << 8) >> 16) * texWidth) >> 16; + uint32_t texelY0 = ((((uint32_t)v0 << 8) >> 16) * texHeight) >> 16; + uint32_t texelY1 = ((((uint32_t)v1 << 8) >> 16) * texHeight) >> 16; + + if (ModeT::SWFlags & SWSTYLEF_Translated) + { + uint32_t fg0 = translation[((const uint8_t*)texPixels)[texelX0 * texHeight + texelY0]]; + uint32_t fg1 = translation[((const uint8_t*)texPixels)[texelX1 * texHeight + texelY1]]; + fg = _mm_setr_epi32(fg0, fg1, 0, 0); + } + else + { + uint32_t fg0 = texPixels[texelX0 * texHeight + texelY0]; + uint32_t fg1 = texPixels[texelX1 * texHeight + texelY1]; + fg = _mm_setr_epi32(fg0, fg1, 0, 0); + } + } + + if (ModeT::SWFlags & SWSTYLEF_Skycap) + { + float rcpW0 = 0x01000000 / posXW; + float rcpW1 = 0x01000000 / (posXW + stepXW); + int32_t v0 = (int32_t)(posXV * rcpW0); + int32_t v1 = (int32_t)((posXV + stepXV) * rcpW1); + + int start_fade = 2; // How fast it should fade out + __m128i v = _mm_setr_epi32(v0, v0, v1, v1); + __m128i alpha_top = _mm_min_epi16(_mm_max_epi16(_mm_srai_epi32(v, 16 - start_fade), _mm_setzero_si128()), _mm_set1_epi16(256)); + __m128i alpha_bottom = _mm_min_epi16(_mm_max_epi16(_mm_srai_epi32(_mm_sub_epi32(_mm_set1_epi32(2 << 24), v), 16 - start_fade), _mm_setzero_si128()), _mm_set1_epi16(256)); + __m128i a = _mm_min_epi16(alpha_top, alpha_bottom); + a = _mm_shufflelo_epi16(_mm_shufflehi_epi16(a, _MM_SHUFFLE(0, 0, 0, 0)), _MM_SHUFFLE(0, 0, 0, 0)); + __m128i inv_a = _mm_sub_epi32(_mm_set1_epi32(256), a); + + fg = _mm_unpacklo_epi8(fg, _mm_setzero_si128()); + __m128i c = _mm_srli_epi16(_mm_add_epi16(_mm_add_epi16(_mm_mullo_epi16(fg, a), _mm_mullo_epi16(mcapcolor, inv_a)), _mm_set1_epi16(127)), 8); + _mm_storel_epi64((__m128i*)(destLine + x), _mm_packus_epi16(c, c)); + } + else + { + if ((ModeT::Flags & STYLEF_ColorIsFixed) && !(ModeT::SWFlags & SWSTYLEF_Fill)) + { + __m128i rgbmask = _mm_set1_epi32(0x00ffffff); + if (ModeT::Flags & STYLEF_RedIsAlpha) + fg = _mm_or_si128(_mm_andnot_si128(rgbmask, _mm_slli_epi32(fg, 8)), _mm_and_si128(rgbmask, mfillcolor)); + else + fg = _mm_or_si128(_mm_andnot_si128(rgbmask, fg), _mm_and_si128(rgbmask, mfillcolor)); + } + + if (!(ModeT::Flags & STYLEF_Alpha1)) + { + __m128i a = _mm_srli_epi32(fg, 24); + a = _mm_srli_epi32(_mm_mullo_epi16(a, malpha), 8); + fg = _mm_or_si128(_mm_and_si128(fg, _mm_set1_epi32(0x00ffffff)), _mm_slli_epi32(a, 24)); + } + + fg = _mm_unpacklo_epi8(fg, _mm_setzero_si128()); + + fixed_t lightpos0 = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * posXW), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); + fixed_t lightpos1 = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * (posXW + stepXW)), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT); + lightpos0 = (lightpos0 & lightmask) | ((light << 8) & ~lightmask); + lightpos1 = (lightpos1 & lightmask) | ((light << 8) & ~lightmask); + int lightshade0 = lightpos0 >> 8; + int lightshade1 = lightpos1 >> 8; + __m128i shadedfg = _mm_srli_epi16(_mm_mullo_epi16(fg, _mm_setr_epi16(lightshade0, lightshade0, lightshade0, 256, lightshade1, lightshade1, lightshade1, 256)), 8); + + __m128i out; + if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_Zero) + { + out = shadedfg; + } + else if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_One) + { + __m128i dest = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(destLine + x)), _mm_setzero_si128()); + if (ModeT::BlendOp == STYLEOP_Add) + { + out = _mm_add_epi16(dest, shadedfg); + } + else if (ModeT::BlendOp == STYLEOP_RevSub) + { + out = _mm_sub_epi16(dest, shadedfg); + } + else //if (ModeT::BlendOp == STYLEOP_Sub) + { + out = _mm_sub_epi16(shadedfg, dest); + } + } + else if (ModeT::SWFlags & SWSTYLEF_SrcColorOneMinusSrcColor) + { + __m128i dest = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(destLine + x)), _mm_setzero_si128()); + __m128i sfactor = _mm_add_epi16(shadedfg, _mm_srli_epi16(shadedfg, 7)); + __m128i dfactor = _mm_sub_epi16(_mm_set1_epi16(256), sfactor); + out = _mm_srli_epi16(_mm_add_epi16(_mm_add_epi16(_mm_mullo_epi16(dest, dfactor), _mm_mullo_epi16(shadedfg, sfactor)), _mm_set1_epi16(127)), 8); + } + else + { + __m128i dest = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(destLine + x)), _mm_setzero_si128()); + + __m128i sfactor = _mm_shufflehi_epi16(_mm_shufflelo_epi16(shadedfg, _MM_SHUFFLE(3, 3, 3, 3)), _MM_SHUFFLE(3, 3, 3, 3)); + sfactor = _mm_add_epi16(sfactor, _mm_srli_epi16(sfactor, 7)); // 255 -> 256 + __m128i dfactor = _mm_sub_epi16(_mm_set1_epi16(256), sfactor); + __m128i src = _mm_mullo_epi16(shadedfg, sfactor); + if (ModeT::BlendDest == STYLEALPHA_One) + { + dest = _mm_slli_epi16(dest, 8); + } + else + { + __m128i dfactor = _mm_sub_epi16(_mm_set1_epi16(256), sfactor); + dest = _mm_mullo_epi16(dest, dfactor); + } + + if (ModeT::BlendOp == STYLEOP_Add) + { + out = _mm_srli_epi16(_mm_add_epi16(_mm_add_epi16(dest, src), _mm_set1_epi16(127)), 8); + } + else if (ModeT::BlendOp == STYLEOP_RevSub) + { + out = _mm_srli_epi16(_mm_add_epi16(_mm_sub_epi16(dest, src), _mm_set1_epi16(127)), 8); + } + else //if (ModeT::BlendOp == STYLEOP_Sub) + { + out = _mm_srli_epi16(_mm_add_epi16(_mm_sub_epi16(src, dest), _mm_set1_epi16(127)), 8); + } + } + _mm_storel_epi64((__m128i*)(destLine + x), _mm_or_si128(_mm_packus_epi16(out, out), _mm_set1_epi32(0xff000000))); + } + + posXW += stepXW + stepXW; + posXU += stepXU + stepXU; + posXV += stepXV + stepXV; + x += 2; + } +#endif + while (x < x1) { uint32_t fg; @@ -1345,7 +1508,7 @@ void DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args) g = (g * a + bg_green * inv_a + 127) >> 8; b = (b * a + bg_blue * inv_a + 127) >> 8; - destLine[x] = RGB256k.All[((r >> 2) << 12) | ((g >> 2) << 6) | (b >> 2)]; + destLine[x] = MAKEARGB(255, r, g, b); } } else From e085a8d58aa465cbcb91c839f4ee39b3c8a69ebf Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 27 May 2018 16:14:18 +0300 Subject: [PATCH 12/14] - garbage collect static event handlers on restart Remaining object(s) led to a potential crash on the next garbage collection cycle Assertion failure was triggered during restarting in Debug configuration --- src/d_main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/d_main.cpp b/src/d_main.cpp index 861318c66..ed986beb7 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2730,6 +2730,7 @@ void D_DoomMain (void) ST_Clear(); D_ErrorCleanup (); DThinker::DestroyThinkersInList(STAT_STATIC); + E_Shutdown(false); P_FreeLevelData(); P_FreeExtraLevelData(); From 36779cf88caeb8d72f3a51bd616b809b647d4c22 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 27 May 2018 16:15:05 +0300 Subject: [PATCH 13/14] - restore startup game state on restart At least values of custom server CVARs were not restored because of this https://forum.zdoom.org/viewtopic.php?t=60711 --- src/d_main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/d_main.cpp b/src/d_main.cpp index ed986beb7..668dcf1ce 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2776,6 +2776,8 @@ void D_DoomMain (void) restart++; PClass::bShutdown = false; PClass::bVMOperational = false; + + gamestate = GS_STARTUP; } while (1); } From 374741b489d864484b1feea1b1cf426c363ed8bb Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Mon, 28 May 2018 08:53:53 +0200 Subject: [PATCH 14/14] Transform UE1 vertex coords to GZDoom's when importing, rather than leaving it up to the end user. --- src/r_data/models/models_ue1.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/r_data/models/models_ue1.cpp b/src/r_data/models/models_ue1.cpp index 98ea08a19..682b5c37e 100644 --- a/src/r_data/models/models_ue1.cpp +++ b/src/r_data/models/models_ue1.cpp @@ -29,11 +29,11 @@ float unpackuvert( uint32_t n, int c ) switch( c ) { case 2: - return ((int16_t)((n&0x7ff)<<5))/127.f; + return ((int16_t)((n&0x7ff)<<5))/128.f; case 1: - return ((int16_t)(((n>>11)&0x7ff)<<5))/127.f; + return ((int16_t)(((n>>11)&0x7ff)<<5))/128.f; case 0: - return ((int16_t)(((n>>22)&0x3ff)<<6))/127.f; + return ((int16_t)(((n>>22)&0x3ff)<<6))/128.f; default: return 0.f; } @@ -98,9 +98,9 @@ void FUE1Model::LoadGeometry() { UE1Vertex Vert; // unpack position - Vert.Pos = FVector3(unpackuvert(averts[j+i*numVerts],0), - unpackuvert(averts[j+i*numVerts],1), - unpackuvert(averts[j+i*numVerts],2)); + Vert.Pos = FVector3(unpackuvert(averts[j+i*numVerts],2), + unpackuvert(averts[j+i*numVerts],0), + -unpackuvert(averts[j+i*numVerts],1)); // push vertex (without normals, will be calculated later) verts.Push(Vert); } @@ -136,8 +136,6 @@ void FUE1Model::LoadGeometry() vert[l] = verts[polys[k].V[l]+numVerts*i].Pos; dir[0] = vert[1]-vert[0]; dir[1] = vert[2]-vert[0]; - dir[0].MakeUnit(); - dir[1].MakeUnit(); norm = dir[0]^dir[1]; nsum += norm.Unit(); } @@ -223,7 +221,7 @@ void FUE1Model::BuildVertexBuffer( FModelRenderer *renderer ) { for ( int k=0; k=0; l-- ) + for ( int l=0; l<3; l++ ) { UE1Vertex V = verts[polys[groups[j].P[k]].V[l]+i*numVerts]; FVector2 C = polys[groups[j].P[k]].C[l];