diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 81b99b0cd..7a99f764e 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -1001,6 +1001,7 @@ set (PCH_SOURCES core/textures/buildtiles.cpp + core/textures/skytexture.cpp core/textures/hightile.cpp core/music/s_advsound.cpp diff --git a/source/build/include/build.h b/source/build/include/build.h index 68318079d..488369b0e 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -323,7 +323,7 @@ EXTERN char parallaxtype; EXTERN int32_t parallaxyoffs_override, parallaxyscale_override; extern int16_t pskybits_override; -// last sprite in the freelist, that is the spritenum for which +// last sprite in the freelist, that is the spritenum for which // .statnum==MAXSTATUS && nextspritestat[spritenum]==-1 // (or -1 if freelist is empty): EXTERN int16_t tailspritefree; diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp index 038abdf97..b53860fdd 100644 --- a/source/build/src/polymost.cpp +++ b/source/build/src/polymost.cpp @@ -103,6 +103,9 @@ static int32_t hicprecaching = 0; static hitdata_t polymost_hitdata; +FGameTexture* globalskytex = nullptr; +FGameTexture* GetSkyTexture(int basetile, int lognumtiles, const int16_t* tilemap); + void polymost_outputGLDebugMessage(uint8_t severity, const char* format, ...) { } @@ -194,7 +197,7 @@ static void resizeglcheck(void) // +4 means it's a sprite, so wraparound isn't needed // drawpoly's hack globals -static int32_t pow2xsplit = 0, skyclamphack = 0, skyzbufferhack = 0, flatskyrender = 0; +static int32_t pow2xsplit = 0, skyzbufferhack = 0, flatskyrender = 0; static float drawpoly_alpha = 0.f; static uint8_t drawpoly_blend = 0; @@ -331,38 +334,6 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32 float usub = 0; float vsub = 0; -#if 0 - if (skyclamphack) - { - drawpoly_srepeat = false; - drawpoly_trepeat = false; - method = DAMETH_CLAMPED; - - vec2f_t const scale = { 1.f / tsiz.x, 1.f / tsiz.y }; - -#if 0 - usub = FLT_MAX; - vsub = FLT_MAX; - for (int i = 0; i < npoints; i++) - { - float const r = 1.f / dd[i]; - float u = floor(uu[i] * r * scale.x); - float v = floor(vv[i] * r * scale.y); - if (u < usub) usub = u; - if (v < vsub) vsub = v; - } -#endif - - for (int i = 0; i < npoints; i++) - { - float const r = 1.f / dd[i]; - float u = uu[i] * r * scale.x - usub; - float v = vv[i] * r * scale.y - vsub; - if (u < -FLT_EPSILON || u > 1 + FLT_EPSILON) drawpoly_srepeat = true; - if (v < -FLT_EPSILON || v > 1 + FLT_EPSILON) drawpoly_trepeat = true; - } - } -#endif polymost_outputGLDebugMessage(3, "polymost_drawpoly(dpxy:%p, n:%d, method_:%X), method: %X", dpxy, n, method_, method); @@ -377,7 +348,7 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32 int palid = TRANSLATION(Translation_Remap + curbasepal, globalpal); GLInterface.SetFade(globalfloorpal); - bool success = GLInterface.SetTexture(tileGetTexture(globalpicnum), palid, sampleroverride); + bool success = GLInterface.SetTexture(globalskytex? globalskytex : tileGetTexture(globalpicnum), palid, sampleroverride); if (!success) { tsiz.x = tsiz.y = 1; @@ -1301,6 +1272,8 @@ static void polymost_flatskyrender(vec2f_t const* const dpxy, int32_t const n, i float const fglobalang = FixedToFloat(qglobalang); int32_t dapyscale, dapskybits, dapyoffs, daptileyscale; int16_t const * dapskyoff = getpsky(globalpicnum, &dapyscale, &dapskybits, &dapyoffs, &daptileyscale); + globalskytex = skytile? nullptr : GetSkyTexture(globalpicnum, dapskybits, dapskyoff); + if (globalskytex) dapskybits = 0; ghoriz = (qglobalhoriz*(1.f/65536.f)-float(ydimen>>1))*dapyscale*(1.f/65536.f)+float(ydimen>>1)+ghorizcorrect; @@ -1312,8 +1285,6 @@ static void polymost_flatskyrender(vec2f_t const* const dpxy, int32_t const n, i int ti = (1<<(heightBits(globalpicnum))); if (ti != tilesize.y) ti += ti; vec3f_t o; - skyclamphack = 0; - xtex.d = xtex.v = 0; ytex.d = ytex.u = 0; otex.d = dd; @@ -1340,7 +1311,6 @@ static void polymost_flatskyrender(vec2f_t const* const dpxy, int32_t const n, i int y = ((int32_t)(((x0-ghalfx)*o.y)+fglobalang)>>(11-dapskybits)); float fx = x0; - skyclamphack = true; // Hack to make Blood's skies show properly. do { globalpicnum = dapskyoff[y&((1<= 0); - skyclamphack = false; - + globalskytex = nullptr; globalpicnum = picnumbak; flatskyrender = 1; @@ -1601,19 +1570,12 @@ static void polymost_drawalls(int32_t const bunch) } else if ((nextsectnum < 0) || (!(sector[nextsectnum].floorstat&1))) { - //Use clamping for tiled sky textures - //(don't wrap around edges if the sky use multiple panels) - for (bssize_t i=(1<0; i--) - if (dapskyoff[i] != dapskyoff[i-1]) - { skyclamphack = r_parallaxskyclamping; break; } - skyzbufferhack = 1; //if (!hw_hightile || !hicfindskybox(globalpicnum, globalpal)) { float const ghorizbak = ghoriz; pow2xsplit = 0; - skyclamphack = 0; flatskyrender = 1; GLInterface.SetVisibility(0.f); polymost_domost(x0,fy0,x1,fy1); @@ -1629,7 +1591,6 @@ static void polymost_drawalls(int32_t const bunch) static vec2f_t const skywal[4] = { { -512, -512 }, { 512, -512 }, { 512, 512 }, { -512, 512 } }; pow2xsplit = 0; - skyclamphack = 1; for (bssize_t i=0; i<4; i++) { @@ -1796,13 +1757,10 @@ static void polymost_drawalls(int32_t const bunch) polymost_domost(x0,fy0,x1,fy1); - skyclamphack = 0; drawingskybox = 0; } #endif - skyclamphack = 0; - skyzbufferhack = 0; } // Ceiling @@ -1843,19 +1801,12 @@ static void polymost_drawalls(int32_t const bunch) } else if ((nextsectnum < 0) || (!(sector[nextsectnum].ceilingstat&1))) { - //Use clamping for tiled sky textures - //(don't wrap around edges if the sky use multiple panels) - for (bssize_t i=(1<0; i--) - if (dapskyoff[i] != dapskyoff[i-1]) - { skyclamphack = r_parallaxskyclamping; break; } - skyzbufferhack = 1; //if (!hw_hightile || !hicfindskybox(globalpicnum, globalpal)) { float const ghorizbak = ghoriz; pow2xsplit = 0; - skyclamphack = 0; flatskyrender = 1; GLInterface.SetVisibility(0.f); polymost_domost(x1, cy1, x0, cy0); @@ -1871,7 +1822,6 @@ static void polymost_drawalls(int32_t const bunch) static vec2f_t const skywal[4] = { { -512, -512 }, { 512, -512 }, { 512, 512 }, { -512, 512 } }; pow2xsplit = 0; - skyclamphack = 1; for (bssize_t i=0; i<4; i++) { @@ -2038,12 +1988,10 @@ static void polymost_drawalls(int32_t const bunch) xtex.v = -xtex.v; ytex.v = -ytex.v; otex.v = -otex.v; //y-flip skybox floor polymost_domost(x1,cy1,x0,cy0); - skyclamphack = 0; drawingskybox = 0; } #endif - skyclamphack = 0; skyzbufferhack = 0; } @@ -2837,7 +2785,6 @@ static void polymost_drawmaskwallinternal(int32_t wallIndex) return; pow2xsplit = 0; - skyclamphack = 0; polymost_drawpoly(dpxy, n, method, tileSize(globalpicnum)); } diff --git a/source/core/textures/skytexture.cpp b/source/core/textures/skytexture.cpp new file mode 100644 index 000000000..7dbde726a --- /dev/null +++ b/source/core/textures/skytexture.cpp @@ -0,0 +1,77 @@ +/* +** skytexture.cpp +** Composite sky textures for Build. +** +**--------------------------------------------------------------------------- +** Copyright 2019 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +** +*/ + +#include "files.h" +#include "filesystem.h" +#include "image.h" +#include "multipatchtexture.h" +#include "printf.h" +#include "texturemanager.h" +#include "buildtiles.h" + +FGameTexture* GetSkyTexture(int basetile, int lognumtiles, const int16_t *tilemap) +{ + char synthname[60]; + + + if (lognumtiles == 0 || lognumtiles > 4) + { + // no special handling - let the old code do its job as-is + return nullptr; + } + + int numtiles = 1 << lognumtiles; + mysnprintf(synthname, 60, "%04x", basetile); + for(int i = 0; i < numtiles; i++) + { + synthname[4+i] = 'A' + tilemap[i]; + }; + synthname[4+numtiles] = 0; + auto tex = TexMan.FindGameTexture(synthname); + if (tex) return tex; + + TArray build(numtiles, true); + int tilewidth = tileWidth(basetile); + for(int i = 0; i < numtiles; i++) + { + auto tex = tileGetTexture(basetile + tilemap[i]); + if (!tex || !tex->isValid() || tex->GetTexture() == 0) return nullptr; + build[i].TexImage = static_cast(tex->GetTexture()); + build[i].OriginX = tilewidth * i; + } + auto tt = MakeGameTexture(new FImageTexture(new FMultiPatchTexture(tilewidth*numtiles, tileHeight(basetile), build, false, false)), synthname, ETextureType::Override); + TexMan.AddGameTexture(tt, true); + return tt; +}