From f1de24b0b21cd22b6aa494af5bc9577ae3f42a5e Mon Sep 17 00:00:00 2001 From: nillerusr Date: Tue, 4 Apr 2023 23:22:06 +0300 Subject: [PATCH 01/10] engine: fix bsp21 loading --- engine/modelloader.cpp | 4 ++++ engine/staticpropmgr.cpp | 5 +++-- public/gamebspfile.h | 6 ++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/engine/modelloader.cpp b/engine/modelloader.cpp index 3070dc55..a51cd110 100644 --- a/engine/modelloader.cpp +++ b/engine/modelloader.cpp @@ -396,6 +396,8 @@ static worldbrushdata_t *s_pMap = NULL; static int s_nMapLoadRecursion = 0; static CUtlBuffer s_MapBuffer; +int s_MapVersion = 0; + // Lump files are patches for a shipped map // List of lump files found when map was loaded. Each entry is the lump file index for that lump id. struct lumpfiles_t @@ -469,6 +471,8 @@ void CMapLoadHelper::Init( model_t *pMapModel, const char *loadname ) return; } + s_MapVersion = s_MapHeader.version; + V_strcpy_safe( s_szLoadName, loadname ); // Store map version, but only do it once so that the communication between the engine and Hammer isn't broken. The map version diff --git a/engine/staticpropmgr.cpp b/engine/staticpropmgr.cpp index fb298443..46a91c0f 100644 --- a/engine/staticpropmgr.cpp +++ b/engine/staticpropmgr.cpp @@ -60,7 +60,7 @@ ConVar r_staticpropinfo( "r_staticpropinfo", "0" ); ConVar r_drawmodeldecals( "r_drawmodeldecals", "1" ); extern ConVar mat_fullbright; static bool g_MakingDevShots = false; -extern dheader_t s_MapHeader; +extern int s_MapVersion; //----------------------------------------------------------------------------- // Index into the fade list //----------------------------------------------------------------------------- @@ -1342,12 +1342,13 @@ void CStaticPropMgr::UnserializeModels( CUtlBuffer& buf ) case 9: UnserializeLump(&lump, buf); break; case 10: { - if( s_MapHeader.version == 21 ) + if( s_MapVersion == 21 ) UnserializeLump(&lump, buf); else UnserializeLump(&lump, buf); break; } + case 11: UnserializeLump(&lump, buf); default: Assert("Unexpected version while deserializing lumps."); } diff --git a/public/gamebspfile.h b/public/gamebspfile.h index 151d160e..597dda03 100644 --- a/public/gamebspfile.h +++ b/public/gamebspfile.h @@ -443,6 +443,12 @@ struct StaticPropLump_t m_FlagsEx = _rhs.m_FlagsEx; return *this; } + + inline StaticPropLump_t& operator=(const StaticPropLumpV11_t& _rhs) + { + (*this) = reinterpret_cast(_rhs); + return *this; + } }; struct StaticPropLeafLump_t From ceda7d8ad038b20438af2922a2503d04f11d7b5b Mon Sep 17 00:00:00 2001 From: nillerusr Date: Thu, 6 Apr 2023 01:27:17 +0300 Subject: [PATCH 02/10] update workflows --- .github/workflows/build.yml | 10 +++++----- .github/workflows/tests.yml | 4 ++-- scripts/build-ubuntu-i386.sh | 3 ++- scripts/tests-ubuntu-i386.sh | 5 +++-- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 779ebc77..7738f3bf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,7 +4,7 @@ on: [push, pull_request] jobs: build-linux-i386: - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 @@ -13,7 +13,7 @@ jobs: scripts/build-ubuntu-i386.sh build-linux-amd64: - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 @@ -22,7 +22,7 @@ jobs: scripts/build-ubuntu-amd64.sh build-android-armv7a: - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 @@ -75,7 +75,7 @@ jobs: ./waf.bat build build-dedicated-linux-i386: - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 @@ -84,7 +84,7 @@ jobs: scripts/build-ubuntu-i386.sh -d build-dedicated-linux-amd64: - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4974855e..c21d0a55 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -4,7 +4,7 @@ on: [push, pull_request] jobs: tests-linux-i386: - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 @@ -13,7 +13,7 @@ jobs: scripts/tests-ubuntu-i386.sh tests-linux-amd64: - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 diff --git a/scripts/build-ubuntu-i386.sh b/scripts/build-ubuntu-i386.sh index feee15b0..c9609cae 100755 --- a/scripts/build-ubuntu-i386.sh +++ b/scripts/build-ubuntu-i386.sh @@ -3,7 +3,8 @@ git submodule init && git submodule update sudo dpkg --add-architecture i386 sudo apt-get update -sudo apt-get install -f -y libopenal-dev:i386 g++-multilib gcc-multilib libpng-dev:i386 libjpeg-dev:i386 libfreetype6-dev:i386 libfontconfig1-dev:i386 libcurl4-gnutls-dev:i386 libsdl2-dev:i386 zlib1g-dev:i386 libbz2-dev:i386 libedit-dev:i386 +sudo apt-get install -y aptitude +sudo aptitude install -y libopenal-dev:i386 g++-multilib gcc-multilib libpng-dev:i386 libjpeg-dev:i386 libfreetype6-dev:i386 libfontconfig1-dev:i386 libcurl4-gnutls-dev:i386 libsdl2-dev:i386 zlib1g-dev:i386 libbz2-dev:i386 libedit-dev:i386 PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig ./waf configure -T debug --disable-warns $* && ./waf build diff --git a/scripts/tests-ubuntu-i386.sh b/scripts/tests-ubuntu-i386.sh index b9a4a427..ee451ee4 100755 --- a/scripts/tests-ubuntu-i386.sh +++ b/scripts/tests-ubuntu-i386.sh @@ -1,9 +1,10 @@ -#!/bin/sh +install#!/bin/sh git submodule init && git submodule update sudo dpkg --add-architecture i386 sudo apt-get update -sudo apt-get install -f -y libopenal-dev:i386 g++-multilib gcc-multilib libpng-dev:i386 libjpeg-dev:i386 libfreetype6-dev:i386 libfontconfig1-dev:i386 libcurl4-gnutls-dev:i386 libsdl2-dev:i386 zlib1g-dev:i386 libbz2-dev:i386 libedit-dev:i386 +sudo apt-get install -y aptitude +sudo aptitude install -y libopenal-dev:i386 g++-multilib gcc-multilib libpng-dev:i386 libjpeg-dev:i386 libfreetype6-dev:i386 libfontconfig1-dev:i386 libcurl4-gnutls-dev:i386 libsdl2-dev:i386 zlib1g-dev:i386 libbz2-dev:i386 libedit-dev:i386 PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig ./waf configure -T release --disable-warns --tests --prefix=out/ $* && ./waf install && From dcdcf6b73398c794f4c3e74a8ab990c0d9ce3af0 Mon Sep 17 00:00:00 2001 From: nillerusr Date: Thu, 6 Apr 2023 14:36:14 +0300 Subject: [PATCH 03/10] togles: don't use alpha channel in dxt1 decompression for textures without it --- togles/linuxwin/cglmtex.cpp | 24 +- togles/linuxwin/decompress.c | 146 +++++--- togles/linuxwin/stb_dxt_104.h | 624 ---------------------------------- 3 files changed, 113 insertions(+), 681 deletions(-) delete mode 100644 togles/linuxwin/stb_dxt_104.h diff --git a/togles/linuxwin/cglmtex.cpp b/togles/linuxwin/cglmtex.cpp index 5ed83df2..f2d62d83 100644 --- a/togles/linuxwin/cglmtex.cpp +++ b/togles/linuxwin/cglmtex.cpp @@ -3409,8 +3409,8 @@ GLvoid *uncompressDXTc(GLsizei width, GLsizei height, GLenum format, GLsizei ima // uncompress a DXTc image // get pixel size of uncompressed image => fixed RGBA int pixelsize = 4; -/* if (format==COMPRESSED_RGB_S3TC_DXT1_EXT) - pixelsize = 3;*/ + if (format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || format == GL_COMPRESSED_SRGB_S3TC_DXT1_EXT) + pixelsize = 3; // check with the size of the input data stream if the stream is in fact uncompressed if (imageSize == width*height*pixelsize || data==NULL) { // uncompressed stream @@ -3469,16 +3469,16 @@ void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, if ((width<=0) || (height<=0)) { return; } - - GLenum format = GL_RGBA; - GLenum intformat = GL_RGBA; - GLenum type = GL_UNSIGNED_BYTE; - GLvoid *pixels = NULL; - - if (isDXTc(internalformat)) { - pixels = NULL; - type = GL_UNSIGNED_BYTE; + bool hasAlpha = (internalformat != GL_COMPRESSED_RGB_S3TC_DXT1_EXT) && (internalformat != GL_COMPRESSED_SRGB_S3TC_DXT1_EXT); + + GLenum format = hasAlpha ? GL_RGBA : GL_RGB; + GLenum intformat = hasAlpha ? GL_RGBA8 : GL_RGB8; + GLenum type = GL_UNSIGNED_BYTE; + GLvoid *pixels = NULL; + + if (isDXTc(internalformat)) + { int srgb = isDXTcSRGB(internalformat); int simpleAlpha = 0; int complexAlpha = 0; @@ -3492,7 +3492,7 @@ void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, } if( srgb ) - intformat = GL_SRGB8_ALPHA8; + intformat = hasAlpha ? GL_SRGB8_ALPHA8 : GL_SRGB8; } gGL->glTexImage2D(target, level, intformat, width, height, border, format, type, pixels); diff --git a/togles/linuxwin/decompress.c b/togles/linuxwin/decompress.c index eabd6893..82b6b4a8 100644 --- a/togles/linuxwin/decompress.c +++ b/togles/linuxwin/decompress.c @@ -92,18 +92,17 @@ static void DecompressBlockDXT1Internal (const uint8_t* block, code = *(const uint32_t*)(block + 4); - if (color0 > color1) { - for (j = 0; j < 4; ++j) { - for (i = 0; i < 4; ++i) { - uint32_t finalColor, positionCode; - uint8_t alpha; + for (j = 0; j < 4; ++j) { + for (i = 0; i < 4; ++i) { + uint32_t finalColor, positionCode; + uint8_t alpha; - alpha = alphaValues [j*4+i]; + finalColor = 0; positionCode = (code >> 2*(4*j+i)) & 0x03; + alpha = alphaValues [j*4+i]; - finalColor = 0; - positionCode = (code >> 2*(4*j+i)) & 0x03; - - switch (positionCode) { + if (color0 > color1) { + switch (positionCode) + { case 0: finalColor = PackRGBA(r0, g0, b0, alpha); break; @@ -117,24 +116,7 @@ static void DecompressBlockDXT1Internal (const uint8_t* block, finalColor = PackRGBA((r0+2*r1)/3, (g0+2*g1)/3, (b0+2*b1)/3, alpha); break; } - if(!alpha) - *simpleAlpha = 1; - else if(alpha<0xff) - *complexAlpha = 1; - output [j*outputStride + i] = finalColor; - } - } - } else { - for (j = 0; j < 4; ++j) { - for (i = 0; i < 4; ++i) { - uint32_t finalColor, positionCode; - uint8_t alpha; - - alpha = alphaValues [j*4+i]; - - finalColor = 0; - positionCode = (code >> 2*(4*j+i)) & 0x03; - + } else { switch (positionCode) { case 0: finalColor = PackRGBA(r0, g0, b0, alpha); @@ -150,18 +132,95 @@ static void DecompressBlockDXT1Internal (const uint8_t* block, finalColor = PackRGBA(0, 0, 0, alpha); break; } - - if(!alpha) - *simpleAlpha = 1; - else if(alpha<0xff) - *complexAlpha = 1; - - output [j*outputStride + i] = finalColor; } + + if(!alpha) + *simpleAlpha = 1; + else if(alpha<0xff) + *complexAlpha = 1; + + output [j*outputStride + i] = finalColor; } } } +static void DecompressBlockDXT1InternalRGB(const uint8_t* block, uint8_t* output, uint32_t outputStride) +{ + uint32_t temp, code; + + uint16_t color0, color1; + uint8_t r0, g0, b0, r1, g1, b1; + + int i, j; + + color0 = *(const uint16_t*)(block); + color1 = *(const uint16_t*)(block + 2); + + temp = (color0 >> 11) * 255 + 16; + r0 = (uint8_t)((temp/32 + temp)/32); + temp = ((color0 & 0x07E0) >> 5) * 255 + 32; + g0 = (uint8_t)((temp/64 + temp)/64); + temp = (color0 & 0x001F) * 255 + 16; + b0 = (uint8_t)((temp/32 + temp)/32); + + temp = (color1 >> 11) * 255 + 16; + r1 = (uint8_t)((temp/32 + temp)/32); + temp = ((color1 & 0x07E0) >> 5) * 255 + 32; + g1 = (uint8_t)((temp/64 + temp)/64); + temp = (color1 & 0x001F) * 255 + 16; + b1 = (uint8_t)((temp/32 + temp)/32); + + code = *(const uint32_t*)(block + 4); + + for (j = 0; j < 4; ++j) { + for (i = 0; i < 4; ++i) { + uint8_t positionCode, finalR, finalG, finalB; + + positionCode = (code >> 2*(4*j+i)) & 0x03; + + if (color0 > color1) { + + switch (positionCode) { + case 0: + finalR = r0; finalG = g0; finalB = b0; + break; + case 1: + finalR = r1; finalG = g1; finalB = b1; + break; + case 2: + + finalR = (2*r0+r1)/3; finalG = (2*g0+g1)/3; finalB = (2*b0+b1)/3; + break; + case 3: + finalR = (r0+2*r1)/3; finalG = (g0+2*g1)/3; finalB = (b0+2*b1)/3; + break; + } + } else { + switch (positionCode) { + case 0: + finalR = r0; finalG = g0; finalB = b0; + break; + case 1: + finalR = r1; finalG = g1; finalB = b1; + break; + case 2: + finalR = (r0+r1)/2; finalG = (g0+g1)/2; finalB = (b0+b1)/2; + break; + case 3: + finalR = finalG = finalB = 0; + break; + } + + } + + output[j*outputStride*3 + i*3] = finalR; + output[j*outputStride*3 + i*3+1] = finalG; + output[j*outputStride*3 + i*3+2] = finalB; + } + } +} + + /* void DecompressBlockDXT1(): Decompresses one block of a DXT1 texture and stores the resulting pixels at the appropriate offset in 'image'. @@ -176,6 +235,7 @@ void DecompressBlockDXT1(uint32_t x, uint32_t y, uint32_t width, int transparent0, int* simpleAlpha, int *complexAlpha, uint32_t* image) { + static const uint8_t const_alpha [] = { 255, 255, 255, 255, 255, 255, 255, 255, @@ -183,8 +243,12 @@ void DecompressBlockDXT1(uint32_t x, uint32_t y, uint32_t width, 255, 255, 255, 255 }; - DecompressBlockDXT1Internal (blockStorage, - image + x + (y * width), width, transparent0, simpleAlpha, complexAlpha, const_alpha); + + if( transparent0 ) + DecompressBlockDXT1Internal (blockStorage, + image + x + (y * width), width, transparent0, simpleAlpha, complexAlpha, const_alpha); + else + DecompressBlockDXT1InternalRGB(blockStorage, ((uint8_t*)image) + x*3 + (y*3 * width), width); } /* @@ -331,11 +395,3 @@ void DecompressBlockDXT3(uint32_t x, uint32_t y, uint32_t width, DecompressBlockDXT1Internal (blockStorage, image + x + (y * width), width, transparent0, simpleAlpha, complexAlpha, alphaValues); } - -// Texture DXT1 / DXT5 compression -// Using STB "on file" library -// go there https://github.com/nothings/stb -// for more details and other libs - -#define STB_DXT_IMPLEMENTATION -#include "stb_dxt_104.h" diff --git a/togles/linuxwin/stb_dxt_104.h b/togles/linuxwin/stb_dxt_104.h deleted file mode 100644 index bec72798..00000000 --- a/togles/linuxwin/stb_dxt_104.h +++ /dev/null @@ -1,624 +0,0 @@ -// stb_dxt.h - v1.04 - DXT1/DXT5 compressor - public domain -// original by fabian "ryg" giesen - ported to C by stb -// use '#define STB_DXT_IMPLEMENTATION' before including to create the implementation -// -// USAGE: -// call stb_compress_dxt_block() for every block (you must pad) -// source should be a 4x4 block of RGBA data in row-major order; -// A is ignored if you specify alpha=0; you can turn on dithering -// and "high quality" using mode. -// -// version history: -// v1.04 - (ryg) default to no rounding bias for lerped colors (as per S3TC/DX10 spec); -// single color match fix (allow for inexact color interpolation); -// optimal DXT5 index finder; "high quality" mode that runs multiple refinement steps. -// v1.03 - (stb) endianness support -// v1.02 - (stb) fix alpha encoding bug -// v1.01 - (stb) fix bug converting to RGB that messed up quality, thanks ryg & cbloom -// v1.00 - (stb) first release - -#ifndef STB_INCLUDE_STB_DXT_H -#define STB_INCLUDE_STB_DXT_H - -// compression mode (bitflags) -#define STB_DXT_NORMAL 0 -#define STB_DXT_DITHER 1 // use dithering. dubious win. never use for normal maps and the like! -#define STB_DXT_HIGHQUAL 2 // high quality mode, does two refinement steps instead of 1. ~30-40% slower. - -void stb_compress_dxt_block(unsigned char *dest, const unsigned char *src, int alpha, int mode); -#define STB_COMPRESS_DXT_BLOCK - -#ifdef STB_DXT_IMPLEMENTATION - -// configuration options for DXT encoder. set them in the project/makefile or just define -// them at the top. - -// STB_DXT_USE_ROUNDING_BIAS -// use a rounding bias during color interpolation. this is closer to what "ideal" -// interpolation would do but doesn't match the S3TC/DX10 spec. old versions (pre-1.03) -// implicitly had this turned on. -// -// in case you're targeting a specific type of hardware (e.g. console programmers): -// NVidia and Intel GPUs (as of 2010) as well as DX9 ref use DXT decoders that are closer -// to STB_DXT_USE_ROUNDING_BIAS. AMD/ATI, S3 and DX10 ref are closer to rounding with no bias. -// you also see "(a*5 + b*3) / 8" on some old GPU designs. -// #define STB_DXT_USE_ROUNDING_BIAS - -#include -#include -#include // memset - -static unsigned char stb__Expand5[32]; -static unsigned char stb__Expand6[64]; -static unsigned char stb__OMatch5[256][2]; -static unsigned char stb__OMatch6[256][2]; -static unsigned char stb__QuantRBTab[256+16]; -static unsigned char stb__QuantGTab[256+16]; - -static int stb__Mul8Bit(int a, int b) -{ - int t = a*b + 128; - return (t + (t >> 8)) >> 8; -} - -static void stb__From16Bit(unsigned char *out, unsigned short v) -{ - int rv = (v & 0xf800) >> 11; - int gv = (v & 0x07e0) >> 5; - int bv = (v & 0x001f) >> 0; - - out[0] = stb__Expand5[rv]; - out[1] = stb__Expand6[gv]; - out[2] = stb__Expand5[bv]; - out[3] = 0; -} - -static unsigned short stb__As16Bit(int r, int g, int b) -{ - return (stb__Mul8Bit(r,31) << 11) + (stb__Mul8Bit(g,63) << 5) + stb__Mul8Bit(b,31); -} - -// linear interpolation at 1/3 point between a and b, using desired rounding type -static int stb__Lerp13(int a, int b) -{ -#ifdef STB_DXT_USE_ROUNDING_BIAS - // with rounding bias - return a + stb__Mul8Bit(b-a, 0x55); -#else - // without rounding bias - // replace "/ 3" by "* 0xaaab) >> 17" if your compiler sucks or you really need every ounce of speed. - return (2*a + b) / 3; -#endif -} - -// lerp RGB color -static void stb__Lerp13RGB(unsigned char *out, unsigned char *p1, unsigned char *p2) -{ - out[0] = stb__Lerp13(p1[0], p2[0]); - out[1] = stb__Lerp13(p1[1], p2[1]); - out[2] = stb__Lerp13(p1[2], p2[2]); -} - -/****************************************************************************/ - -// compute table to reproduce constant colors as accurately as possible -static void stb__PrepareOptTable(unsigned char *Table,const unsigned char *expand,int size) -{ - int i,mn,mx; - for (i=0;i<256;i++) { - int bestErr = 256; - for (mn=0;mn> 4)]; - ep1[0] = bp[ 0] - dp[ 0]; - dp[ 4] = quant[bp[ 4] + ((7*ep1[0] + 3*ep2[2] + 5*ep2[1] + ep2[0]) >> 4)]; - ep1[1] = bp[ 4] - dp[ 4]; - dp[ 8] = quant[bp[ 8] + ((7*ep1[1] + 3*ep2[3] + 5*ep2[2] + ep2[1]) >> 4)]; - ep1[2] = bp[ 8] - dp[ 8]; - dp[12] = quant[bp[12] + ((7*ep1[2] + 5*ep2[3] + ep2[2]) >> 4)]; - ep1[3] = bp[12] - dp[12]; - bp += 16; - dp += 16; - et = ep1, ep1 = ep2, ep2 = et; // swap - } - } -} - -// The color matching function -static unsigned int stb__MatchColorsBlock(unsigned char *block, unsigned char *color,int dither) -{ - unsigned int mask = 0; - int dirr = color[0*4+0] - color[1*4+0]; - int dirg = color[0*4+1] - color[1*4+1]; - int dirb = color[0*4+2] - color[1*4+2]; - int dots[16]; - int stops[4]; - int i; - int c0Point, halfPoint, c3Point; - - for(i=0;i<16;i++) - dots[i] = block[i*4+0]*dirr + block[i*4+1]*dirg + block[i*4+2]*dirb; - - for(i=0;i<4;i++) - stops[i] = color[i*4+0]*dirr + color[i*4+1]*dirg + color[i*4+2]*dirb; - - // think of the colors as arranged on a line; project point onto that line, then choose - // next color out of available ones. we compute the crossover points for "best color in top - // half"/"best in bottom half" and then the same inside that subinterval. - // - // relying on this 1d approximation isn't always optimal in terms of euclidean distance, - // but it's very close and a lot faster. - // http://cbloomrants.blogspot.com/2008/12/12-08-08-dxtc-summary.html - - c0Point = (stops[1] + stops[3]) >> 1; - halfPoint = (stops[3] + stops[2]) >> 1; - c3Point = (stops[2] + stops[0]) >> 1; - - if(!dither) { - // the version without dithering is straightforward - for (i=15;i>=0;i--) { - int dot = dots[i]; - mask <<= 2; - - if(dot < halfPoint) - mask |= (dot < c0Point) ? 1 : 3; - else - mask |= (dot < c3Point) ? 2 : 0; - } - } else { - // with floyd-steinberg dithering - int err[8],*ep1 = err,*ep2 = err+4; - int *dp = dots, y; - - c0Point <<= 4; - halfPoint <<= 4; - c3Point <<= 4; - for(i=0;i<8;i++) - err[i] = 0; - - for(y=0;y<4;y++) - { - int dot,lmask,step; - - dot = (dp[0] << 4) + (3*ep2[1] + 5*ep2[0]); - if(dot < halfPoint) - step = (dot < c0Point) ? 1 : 3; - else - step = (dot < c3Point) ? 2 : 0; - ep1[0] = dp[0] - stops[step]; - lmask = step; - - dot = (dp[1] << 4) + (7*ep1[0] + 3*ep2[2] + 5*ep2[1] + ep2[0]); - if(dot < halfPoint) - step = (dot < c0Point) ? 1 : 3; - else - step = (dot < c3Point) ? 2 : 0; - ep1[1] = dp[1] - stops[step]; - lmask |= step<<2; - - dot = (dp[2] << 4) + (7*ep1[1] + 3*ep2[3] + 5*ep2[2] + ep2[1]); - if(dot < halfPoint) - step = (dot < c0Point) ? 1 : 3; - else - step = (dot < c3Point) ? 2 : 0; - ep1[2] = dp[2] - stops[step]; - lmask |= step<<4; - - dot = (dp[3] << 4) + (7*ep1[2] + 5*ep2[3] + ep2[2]); - if(dot < halfPoint) - step = (dot < c0Point) ? 1 : 3; - else - step = (dot < c3Point) ? 2 : 0; - ep1[3] = dp[3] - stops[step]; - lmask |= step<<6; - - dp += 4; - mask |= lmask << (y*8); - { int *et = ep1; ep1 = ep2; ep2 = et; } // swap - } - } - - return mask; -} - -// The color optimization function. (Clever code, part 1) -static void stb__OptimizeColorsBlock(unsigned char *block, unsigned short *pmax16, unsigned short *pmin16) -{ - int mind = 0x7fffffff,maxd = -0x7fffffff; - unsigned char *minp, *maxp; - double magn; - int v_r,v_g,v_b; - static const int nIterPower = 4; - float covf[6],vfr,vfg,vfb; - - // determine color distribution - int cov[6]; - int mu[3],min[3],max[3]; - int ch,i,iter; - - for(ch=0;ch<3;ch++) - { - const unsigned char *bp = ((const unsigned char *) block) + ch; - int muv,minv,maxv; - - muv = minv = maxv = bp[0]; - for(i=4;i<64;i+=4) - { - muv += bp[i]; - if (bp[i] < minv) minv = bp[i]; - else if (bp[i] > maxv) maxv = bp[i]; - } - - mu[ch] = (muv + 8) >> 4; - min[ch] = minv; - max[ch] = maxv; - } - - // determine covariance matrix - for (i=0;i<6;i++) - cov[i] = 0; - - for (i=0;i<16;i++) - { - int r = block[i*4+0] - mu[0]; - int g = block[i*4+1] - mu[1]; - int b = block[i*4+2] - mu[2]; - - cov[0] += r*r; - cov[1] += r*g; - cov[2] += r*b; - cov[3] += g*g; - cov[4] += g*b; - cov[5] += b*b; - } - - // convert covariance matrix to float, find principal axis via power iter - for(i=0;i<6;i++) - covf[i] = cov[i] / 255.0f; - - vfr = (float) (max[0] - min[0]); - vfg = (float) (max[1] - min[1]); - vfb = (float) (max[2] - min[2]); - - for(iter=0;iter magn) magn = fabs(vfg); - if (fabs(vfb) > magn) magn = fabs(vfb); - - if(magn < 4.0f) { // too small, default to luminance - v_r = 299; // JPEG YCbCr luma coefs, scaled by 1000. - v_g = 587; - v_b = 114; - } else { - magn = 512.0 / magn; - v_r = (int) (vfr * magn); - v_g = (int) (vfg * magn); - v_b = (int) (vfb * magn); - } - - // Pick colors at extreme points - for(i=0;i<16;i++) - { - int dot = block[i*4+0]*v_r + block[i*4+1]*v_g + block[i*4+2]*v_b; - - if (dot < mind) { - mind = dot; - minp = block+i*4; - } - - if (dot > maxd) { - maxd = dot; - maxp = block+i*4; - } - } - - *pmax16 = stb__As16Bit(maxp[0],maxp[1],maxp[2]); - *pmin16 = stb__As16Bit(minp[0],minp[1],minp[2]); -} - -static int stb__sclamp(float y, int p0, int p1) -{ - int x = (int) y; - if (x < p0) return p0; - if (x > p1) return p1; - return x; -} - -// The refinement function. (Clever code, part 2) -// Tries to optimize colors to suit block contents better. -// (By solving a least squares system via normal equations+Cramer's rule) -static int stb__RefineBlock(unsigned char *block, unsigned short *pmax16, unsigned short *pmin16, unsigned int mask) -{ - static const int w1Tab[4] = { 3,0,2,1 }; - static const int prods[4] = { 0x090000,0x000900,0x040102,0x010402 }; - // ^some magic to save a lot of multiplies in the accumulating loop... - // (precomputed products of weights for least squares system, accumulated inside one 32-bit register) - - float frb,fg; - unsigned short oldMin, oldMax, min16, max16; - int i, akku = 0, xx,xy,yy; - int At1_r,At1_g,At1_b; - int At2_r,At2_g,At2_b; - unsigned int cm = mask; - - oldMin = *pmin16; - oldMax = *pmax16; - - if((mask ^ (mask<<2)) < 4) // all pixels have the same index? - { - // yes, linear system would be singular; solve using optimal - // single-color match on average color - int r = 8, g = 8, b = 8; - for (i=0;i<16;++i) { - r += block[i*4+0]; - g += block[i*4+1]; - b += block[i*4+2]; - } - - r >>= 4; g >>= 4; b >>= 4; - - max16 = (stb__OMatch5[r][0]<<11) | (stb__OMatch6[g][0]<<5) | stb__OMatch5[b][0]; - min16 = (stb__OMatch5[r][1]<<11) | (stb__OMatch6[g][1]<<5) | stb__OMatch5[b][1]; - } else { - At1_r = At1_g = At1_b = 0; - At2_r = At2_g = At2_b = 0; - for (i=0;i<16;++i,cm>>=2) { - int step = cm&3; - int w1 = w1Tab[step]; - int r = block[i*4+0]; - int g = block[i*4+1]; - int b = block[i*4+2]; - - akku += prods[step]; - At1_r += w1*r; - At1_g += w1*g; - At1_b += w1*b; - At2_r += r; - At2_g += g; - At2_b += b; - } - - At2_r = 3*At2_r - At1_r; - At2_g = 3*At2_g - At1_g; - At2_b = 3*At2_b - At1_b; - - // extract solutions and decide solvability - xx = akku >> 16; - yy = (akku >> 8) & 0xff; - xy = (akku >> 0) & 0xff; - - frb = 3.0f * 31.0f / 255.0f / (xx*yy - xy*xy); - fg = frb * 63.0f / 31.0f; - - // solve. - max16 = stb__sclamp((At1_r*yy - At2_r*xy)*frb+0.5f,0,31) << 11; - max16 |= stb__sclamp((At1_g*yy - At2_g*xy)*fg +0.5f,0,63) << 5; - max16 |= stb__sclamp((At1_b*yy - At2_b*xy)*frb+0.5f,0,31) << 0; - - min16 = stb__sclamp((At2_r*xx - At1_r*xy)*frb+0.5f,0,31) << 11; - min16 |= stb__sclamp((At2_g*xx - At1_g*xy)*fg +0.5f,0,63) << 5; - min16 |= stb__sclamp((At2_b*xx - At1_b*xy)*frb+0.5f,0,31) << 0; - } - - *pmin16 = min16; - *pmax16 = max16; - return oldMin != min16 || oldMax != max16; -} - -// Color block compression -static void stb__CompressColorBlock(unsigned char *dest, unsigned char *block, int mode) -{ - unsigned int mask; - int i; - int dither; - int refinecount; - unsigned short max16, min16; - unsigned char dblock[16*4],color[4*4]; - - dither = mode & STB_DXT_DITHER; - refinecount = (mode & STB_DXT_HIGHQUAL) ? 2 : 1; - - // check if block is constant - for (i=1;i<16;i++) - if (((unsigned int *) block)[i] != ((unsigned int *) block)[0]) - break; - - if(i == 16) { // constant color - int r = block[0], g = block[1], b = block[2]; - mask = 0xaaaaaaaa; - max16 = (stb__OMatch5[r][0]<<11) | (stb__OMatch6[g][0]<<5) | stb__OMatch5[b][0]; - min16 = (stb__OMatch5[r][1]<<11) | (stb__OMatch6[g][1]<<5) | stb__OMatch5[b][1]; - } else { - // first step: compute dithered version for PCA if desired - if(dither) - stb__DitherBlock(dblock,block); - - // second step: pca+map along principal axis - stb__OptimizeColorsBlock(dither ? dblock : block,&max16,&min16); - if (max16 != min16) { - stb__EvalColors(color,max16,min16); - mask = stb__MatchColorsBlock(block,color,dither); - } else - mask = 0; - - // third step: refine (multiple times if requested) - for (i=0;i> 8); - dest[2] = (unsigned char) (min16); - dest[3] = (unsigned char) (min16 >> 8); - dest[4] = (unsigned char) (mask); - dest[5] = (unsigned char) (mask >> 8); - dest[6] = (unsigned char) (mask >> 16); - dest[7] = (unsigned char) (mask >> 24); -} - -// Alpha block compression (this is easy for a change) -static void stb__CompressAlphaBlock(unsigned char *dest,unsigned char *src,int mode) -{ - int i,dist,bias,dist4,dist2,bits,mask; - - // find min/max color - int mn,mx; - mn = mx = src[3]; - - for (i=1;i<16;i++) - { - if (src[i*4+3] < mn) mn = src[i*4+3]; - else if (src[i*4+3] > mx) mx = src[i*4+3]; - } - - // encode them - ((unsigned char *)dest)[0] = mx; - ((unsigned char *)dest)[1] = mn; - dest += 2; - - // determine bias and emit color indices - // given the choice of mx/mn, these indices are optimal: - // http://fgiesen.wordpress.com/2009/12/15/dxt5-alpha-block-index-determination/ - dist = mx-mn; - dist4 = dist*4; - dist2 = dist*2; - bias = (dist < 8) ? (dist - 1) : (dist/2 + 2); - bias -= mn * 7; - bits = 0,mask=0; - - for (i=0;i<16;i++) { - int a = src[i*4+3]*7 + bias; - int ind,t; - - // select index. this is a "linear scale" lerp factor between 0 (val=min) and 7 (val=max). - t = (a >= dist4) ? -1 : 0; ind = t & 4; a -= dist4 & t; - t = (a >= dist2) ? -1 : 0; ind += t & 2; a -= dist2 & t; - ind += (a >= dist); - - // turn linear scale into DXT index (0/1 are extremal pts) - ind = -ind & 7; - ind ^= (2 > ind); - - // write index - mask |= ind << bits; - if((bits += 3) >= 8) { - *dest++ = mask; - mask >>= 8; - bits -= 8; - } - } -} - -static void stb__InitDXT() -{ - int i; - for(i=0;i<32;i++) - stb__Expand5[i] = (i<<3)|(i>>2); - - for(i=0;i<64;i++) - stb__Expand6[i] = (i<<2)|(i>>4); - - for(i=0;i<256+16;i++) - { - int v = i-8 < 0 ? 0 : i-8 > 255 ? 255 : i-8; - stb__QuantRBTab[i] = stb__Expand5[stb__Mul8Bit(v,31)]; - stb__QuantGTab[i] = stb__Expand6[stb__Mul8Bit(v,63)]; - } - - stb__PrepareOptTable(&stb__OMatch5[0][0],stb__Expand5,32); - stb__PrepareOptTable(&stb__OMatch6[0][0],stb__Expand6,64); -} - -void stb_compress_dxt_block(unsigned char *dest, const unsigned char *src, int alpha, int mode) -{ - static int init=1; - if (init) { - stb__InitDXT(); - init=0; - } - - if (alpha) { - stb__CompressAlphaBlock(dest,(unsigned char*) src,mode); - dest += 8; - } - - stb__CompressColorBlock(dest,(unsigned char*) src,mode); -} -#endif // STB_DXT_IMPLEMENTATION - -#endif // STB_INCLUDE_STB_DXT_H From 4f063c40536884a2378b02f436c24081596f051c Mon Sep 17 00:00:00 2001 From: nillerusr Date: Fri, 7 Apr 2023 13:25:58 +0300 Subject: [PATCH 04/10] unittests: fix library loading --- gameui/BasePanel.cpp | 20 +++- public/dispcoll_common.cpp | 10 +- public/tier0/platform.h | 6 + public/tier0/tslist.h | 15 +-- scripts/tests-ubuntu-amd64.sh | 2 +- scripts/tests-ubuntu-i386.sh | 2 +- tier1/interface.cpp | 12 ++ unittests/tier1test/wscript | 2 +- wscript | 214 +++++++++++++++++----------------- 9 files changed, 156 insertions(+), 127 deletions(-) diff --git a/gameui/BasePanel.cpp b/gameui/BasePanel.cpp index 89ce02ba..a5336366 100644 --- a/gameui/BasePanel.cpp +++ b/gameui/BasePanel.cpp @@ -915,7 +915,7 @@ CBasePanel::CBasePanel() : Panel(NULL, "BaseGameUIPanel") } } - if( IsAndroid() ) +// if( IsAndroid() ) { AddUrlButton( this, "vgui/\x64\x69\x73\x63\x6f\x72\x64\x5f\x6c\x6f\x67\x6f", "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x64\x69\x73\x63\x6f\x72\x64\x2e\x67\x67\x2f\x68\x5a\x52\x42\x37\x57\x4d\x67\x47\x77" ); AddUrlButton( this, "vgui/\x74\x77\x69\x74\x74\x65\x72\x5f\x6c\x6f\x67\x6f", "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x74\x77\x69\x74\x74\x65\x72\x2e\x63\x6f\x6d\x2f\x6e\x69\x6c\x6c\x65\x72\x75\x73\x72" ); @@ -1607,6 +1607,21 @@ CGameMenu *CBasePanel::RecursiveLoadGameMenu(KeyValues *datafile) else menu->AddMenuItem("Console", "CONSOLE", "OpenConsole", this); + bool bFoundServerBrowser = false; + + for (KeyValues *dat = datafile->GetFirstSubKey(); dat != NULL; dat = dat->GetNextKey()) + { + const char *label = dat->GetString("label", ""); + const char *cmd = dat->GetString("command", NULL); + const char *name = dat->GetString("name", label); + + if( cmd && Q_strcmp(cmd, "OpenServerBrowser") == 0 ) + bFoundServerBrowser = true; + } + + if( !bFoundServerBrowser && !ModInfo().IsSinglePlayerOnly() ) + menu->AddMenuItem("AntiM*dG*yButton", "#GameUI_GameMenu_FindServers", "OpenServerBrowser", this); + // loop through all the data adding items to the menu for (KeyValues *dat = datafile->GetFirstSubKey(); dat != NULL; dat = dat->GetNextKey()) { @@ -1614,7 +1629,8 @@ CGameMenu *CBasePanel::RecursiveLoadGameMenu(KeyValues *datafile) const char *cmd = dat->GetString("command", NULL); const char *name = dat->GetString("name", label); - if ( cmd && !Q_stricmp( cmd, "OpenFriendsDialog" ) && bSteamCommunityFriendsVersion ) + if ( cmd && (!Q_stricmp( cmd, "OpenFriendsDialog" ) + || !Q_stricmp( cmd, "engine bug" )) ) continue; menu->AddMenuItem(name, label, cmd, this, dat); diff --git a/public/dispcoll_common.cpp b/public/dispcoll_common.cpp index 307e1408..cfaaba80 100644 --- a/public/dispcoll_common.cpp +++ b/public/dispcoll_common.cpp @@ -429,13 +429,7 @@ void CDispCollTree::AABBTree_CreateLeafs( void ) } } -#if COMPILER_CLANG -#define NOASAN __attribute__((no_sanitize("address"))) -#else -#define NOASAN -#endif - -void NOASAN CDispCollTree::AABBTree_GenerateBoxes_r( int nodeIndex, Vector *pMins, Vector *pMaxs ) +void NO_ASAN CDispCollTree::AABBTree_GenerateBoxes_r( int nodeIndex, Vector *pMins, Vector *pMaxs ) { // leaf ClearBounds( *pMins, *pMaxs ); @@ -467,8 +461,6 @@ void NOASAN CDispCollTree::AABBTree_GenerateBoxes_r( int nodeIndex, Vector *pMin } } -#undef NOASAN - //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- diff --git a/public/tier0/platform.h b/public/tier0/platform.h index 2c912e04..4a4c4883 100644 --- a/public/tier0/platform.h +++ b/public/tier0/platform.h @@ -606,6 +606,12 @@ typedef void * HINSTANCE; #define FMTFUNCTION( a, b ) #endif +#if COMPILER_CLANG || COMPILER_GCC +#define NO_ASAN __attribute__((no_sanitize("address"))) +#else +#define NO_ASAN +#endif + #if defined( _WIN32 ) // Used for dll exporting and importing diff --git a/public/tier0/tslist.h b/public/tier0/tslist.h index a1b2be7f..f5661258 100644 --- a/public/tier0/tslist.h +++ b/public/tier0/tslist.h @@ -123,21 +123,21 @@ union TSLIST_HEAD_ALIGN TSLHead_t // but it could perhaps (?) lead to problems with store forwarding. I don't know 'cause I didn't // performance-test or design original code, I'm just making it work on PowerPC. #ifdef VALVE_BIG_ENDIAN - int16 Sequence; - int16 Depth; + uint16 Sequence; + uint16 Depth; #else - int16 Depth; - int16 Sequence; + uint16 Depth; + uint16 Sequence; #endif #ifdef PLATFORM_64BITS - int32 Padding; + uint32 Padding; #endif } value; struct Value32_t { TSLNodeBase_t *Next_do_not_use_me; - int32 DepthAndSequence; + uint32 DepthAndSequence; } value32; #ifdef PLATFORM_64BITS @@ -254,7 +254,8 @@ public: #endif } - TSLNodeBase_t *Pop() + // TODO(nillerusr): fix asan issue later + NO_ASAN TSLNodeBase_t *Pop() { #ifdef USE_NATIVE_SLIST #ifdef _X360 diff --git a/scripts/tests-ubuntu-amd64.sh b/scripts/tests-ubuntu-amd64.sh index af0c589e..080ef65a 100755 --- a/scripts/tests-ubuntu-amd64.sh +++ b/scripts/tests-ubuntu-amd64.sh @@ -4,7 +4,7 @@ git submodule init && git submodule update sudo apt-get update sudo apt-get install -f -y gdb libopenal-dev g++-multilib gcc-multilib libpng-dev libjpeg-dev libfreetype6-dev libfontconfig1-dev libcurl4-gnutls-dev libsdl2-dev zlib1g-dev libbz2-dev libedit-dev -./waf configure -T release --disable-warns --tests --prefix=out/ --64bits $* && +./waf configure -T release --sanitize=address,undefined --disable-warns --tests --prefix=out/ --64bits $* && ./waf install && cd out && LD_LIBRARY_PATH=bin/ ./unittest diff --git a/scripts/tests-ubuntu-i386.sh b/scripts/tests-ubuntu-i386.sh index ee451ee4..b3d71837 100755 --- a/scripts/tests-ubuntu-i386.sh +++ b/scripts/tests-ubuntu-i386.sh @@ -6,7 +6,7 @@ sudo apt-get update sudo apt-get install -y aptitude sudo aptitude install -y libopenal-dev:i386 g++-multilib gcc-multilib libpng-dev:i386 libjpeg-dev:i386 libfreetype6-dev:i386 libfontconfig1-dev:i386 libcurl4-gnutls-dev:i386 libsdl2-dev:i386 zlib1g-dev:i386 libbz2-dev:i386 libedit-dev:i386 -PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig ./waf configure -T release --disable-warns --tests --prefix=out/ $* && +PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig ./waf configure -T release --sanitize=address,undefined --disable-warns --tests --prefix=out/ $* && ./waf install && cd out && LD_LIBRARY_PATH=bin/ ./unittest diff --git a/tier1/interface.cpp b/tier1/interface.cpp index 78dacc82..47fda8f9 100644 --- a/tier1/interface.cpp +++ b/tier1/interface.cpp @@ -292,6 +292,18 @@ bool foundLibraryWithPrefix( char *pModuleAbsolutePath, size_t AbsolutePathSize, bFound |= stat(pModuleAbsolutePath, &statBuf) == 0; } + if( !bFound ) + { + Q_snprintf(pModuleAbsolutePath, AbsolutePathSize, "%s/lib%s", pPath, str); + bFound |= stat(pModuleAbsolutePath, &statBuf) == 0; + } + + if( !bFound ) + { + Q_snprintf(pModuleAbsolutePath, AbsolutePathSize, "%s/%s", pPath, str); + bFound |= stat(pModuleAbsolutePath, &statBuf) == 0; + } + return bFound; } diff --git a/unittests/tier1test/wscript b/unittests/tier1test/wscript index ba69010a..774398ba 100755 --- a/unittests/tier1test/wscript +++ b/unittests/tier1test/wscript @@ -14,7 +14,7 @@ def configure(conf): conf.define('TIER1TEST_EXPORTS', 1) def build(bld): - source = ['commandbuffertest.cpp', 'utlstringtest.cpp', 'tier1test.cpp'] + source = ['commandbuffertest.cpp', 'utlstringtest.cpp', 'tier1test.cpp'] #, 'lzsstest.cpp'] includes = ['../../public', '../../public/tier0'] defines = [] libs = ['tier0', 'tier1', 'mathlib', 'unitlib'] diff --git a/wscript b/wscript index d5487927..ef760ccc 100644 --- a/wscript +++ b/wscript @@ -165,7 +165,7 @@ def define_platform(conf): # conf.options.GL = False conf.define('DEDICATED', 1) - if conf.options.GL: + if conf.options.GL and not conf.options.TESTS: conf.env.append_unique('DEFINES', [ 'DX_TO_GL_ABSTRACTION', 'GL_GLEXT_PROTOTYPES', @@ -175,7 +175,7 @@ def define_platform(conf): if conf.options.TOGLES: conf.env.append_unique('DEFINES', ['TOGLES']) - if conf.options.SDL: + if conf.options.SDL and not conf.options.TESTS: conf.env.SDL = 1 conf.define('USE_SDL', 1) @@ -285,6 +285,111 @@ def options(opt): opt.load('msvc msdev msvs') opt.load('reconfigure') +def check_deps(conf): + if conf.env.DEST_OS != 'win32': + conf.check_cc(lib='dl', mandatory=False) + conf.check_cc(lib='bz2', mandatory=False) + conf.check_cc(lib='rt', mandatory=False) + + if not conf.env.LIB_M: # HACK: already added in xcompile! + conf.check_cc(lib='m') + else: + # Common Win32 libraries + # Don't check them more than once, to save time + # Usually, they are always available + # but we need them in uselib + a = [ + 'user32', + 'shell32', + 'gdi32', + 'advapi32', + 'dbghelp', + 'psapi', + 'ws2_32', + 'rpcrt4', + 'winmm', + 'wininet', + 'ole32', + 'shlwapi', + 'imm32' + ] + + if conf.env.COMPILER_CC == 'msvc': + for i in a: + conf.check_lib_msvc(i) + else: + for i in a: + conf.check_cc(lib = i) + + + if conf.options.TESTS: + return + + if conf.env.DEST_OS != 'android': + if conf.env.DEST_OS != 'win32': + if conf.options.SDL: + conf.check_cfg(package='sdl2', uselib_store='SDL2', args=['--cflags', '--libs']) + if conf.options.DEDICATED: + conf.check_cfg(package='libedit', uselib_store='EDIT', args=['--cflags', '--libs']) + else: + conf.check_pkg('freetype2', 'FT2', FT2_CHECK) + conf.check_pkg('fontconfig', 'FC', FC_CHECK) + if conf.env.DEST_OS == "darwin": + conf.env.FRAMEWORK_OPENAL = "OpenAL" + else: + conf.check_cfg(package='openal', uselib_store='OPENAL', args=['--cflags', '--libs']) + conf.check_cfg(package='libjpeg', uselib_store='JPEG', args=['--cflags', '--libs']) + conf.check_cfg(package='libpng', uselib_store='PNG', args=['--cflags', '--libs']) + conf.check_cfg(package='libcurl', uselib_store='CURL', args=['--cflags', '--libs']) + conf.check_cfg(package='zlib', uselib_store='ZLIB', args=['--cflags', '--libs']) + + if conf.options.OPUS: + conf.check_cfg(package='opus', uselib_store='OPUS', args=['--cflags', '--libs']) + else: + conf.check(lib='SDL2', uselib_store='SDL2') + conf.check(lib='freetype2', uselib_store='FT2') + conf.check(lib='jpeg', uselib_store='JPEG', define_name='HAVE_JPEG') + conf.check(lib='png', uselib_store='PNG', define_name='HAVE_PNG') + conf.check(lib='curl', uselib_store='CURL', define_name='HAVE_CURL') + conf.check(lib='z', uselib_store='ZLIB', define_name='HAVE_ZLIB') + if conf.env.DEST_CPU != 'aarch64': + conf.check(lib='unwind', uselib_store='UNWIND') + conf.check(lib='crypto', uselib_store='CRYPTO') + conf.check(lib='ssl', uselib_store='SSL') + conf.check(lib='android_support', uselib_store='ANDROID_SUPPORT') + conf.check(lib='opus', uselib_store='OPUS') + + if conf.env.DEST_OS == "darwin": + conf.check(lib='iconv', uselib_store='ICONV') + conf.env.FRAMEWORK_APPKIT = "AppKit" + conf.env.FRAMEWORK_IOKIT = "IOKit" + conf.env.FRAMEWORK_FOUNDATION = "Foundation" + conf.env.FRAMEWORK_COREFOUNDATION = "CoreFoundation" + conf.env.FRAMEWORK_COREGRAPHICS = "CoreGraphics" + conf.env.FRAMEWORK_OPENGL = "OpenGL" + conf.env.FRAMEWORK_CARBON = "Carbon" + conf.env.FRAMEWORK_APPLICATIONSERVICES = "ApplicationServices" + conf.env.FRAMEWORK_CORESERVICES = "CoreServices" + conf.env.FRAMEWORK_COREAUDIO = "CoreAudio" + conf.env.FRAMEWORK_AUDIOTOOLBOX = "AudioToolbox" + conf.env.FRAMEWORK_SYSTEMCONFIGURATION = "SystemConfiguration" + + if conf.env.DEST_OS == 'win32': + conf.check(lib='libz', uselib_store='ZLIB', define_name='USE_ZLIB') + # conf.check(lib='nvtc', uselib_store='NVTC') + # conf.check(lib='ati_compress_mt_vc10', uselib_store='ATI_COMPRESS_MT_VC10') + conf.check(lib='SDL2', uselib_store='SDL2') + conf.check(lib='libjpeg', uselib_store='JPEG', define_name='HAVE_JPEG') + conf.check(lib='libpng', uselib_store='PNG', define_name='HAVE_PNG') + conf.check(lib='d3dx9', uselib_store='D3DX9') + conf.check(lib='d3d9', uselib_store='D3D9') + conf.check(lib='dsound', uselib_store='DSOUND') + conf.check(lib='dxguid', uselib_store='DXGUID') + if conf.options.OPUS: + conf.check(lib='opus', uselib_store='OPUS') + + # conf.multicheck(*a, run_all_tests = True, mandatory = True) + def configure(conf): conf.load('fwgslib reconfigure compiler_optimizations') @@ -428,12 +533,6 @@ def configure(conf): cxxflags += ['-std=c++11','-fpermissive'] if conf.env.COMPILER_CC == 'gcc': -# wrapfunctions = ['freopen','creat','access','__xstat','stat','lstat','fopen64','open64', -# 'opendir','__lxstat','chmod','chown','lchown','symlink','link','__lxstat64','mknod', -# 'utimes','unlink','rename','utime','__xstat64','mount','mkdir','rmdir','scandir','realpath','mkfifo'] - -# for func in wrapfunctions: -# linkflags += ['-Wl,--wrap='+func] conf.define('COMPILER_GCC', 1) elif conf.env.COMPILER_CC == 'msvc': conf.define('COMPILER_MSVC', 1) @@ -459,104 +558,7 @@ def configure(conf): conf.env.append_unique('LINKFLAGS', linkflags) conf.env.append_unique('INCLUDES', [os.path.abspath('common/')]) - if conf.env.DEST_OS != 'android': - if conf.env.DEST_OS != 'win32': - if conf.options.SDL: - conf.check_cfg(package='sdl2', uselib_store='SDL2', args=['--cflags', '--libs']) - if conf.options.DEDICATED: - conf.check_cfg(package='libedit', uselib_store='EDIT', args=['--cflags', '--libs']) - else: - conf.check_pkg('freetype2', 'FT2', FT2_CHECK) - conf.check_pkg('fontconfig', 'FC', FC_CHECK) - if conf.env.DEST_OS == "darwin": - conf.env.FRAMEWORK_OPENAL = "OpenAL" - else: - conf.check_cfg(package='openal', uselib_store='OPENAL', args=['--cflags', '--libs']) - conf.check_cfg(package='libjpeg', uselib_store='JPEG', args=['--cflags', '--libs']) - conf.check_cfg(package='libpng', uselib_store='PNG', args=['--cflags', '--libs']) - conf.check_cfg(package='libcurl', uselib_store='CURL', args=['--cflags', '--libs']) - conf.check_cfg(package='zlib', uselib_store='ZLIB', args=['--cflags', '--libs']) - - if conf.options.OPUS: - conf.check_cfg(package='opus', uselib_store='OPUS', args=['--cflags', '--libs']) - else: - conf.check(lib='SDL2', uselib_store='SDL2') - conf.check(lib='freetype2', uselib_store='FT2') - conf.check(lib='jpeg', uselib_store='JPEG', define_name='HAVE_JPEG') - conf.check(lib='png', uselib_store='PNG', define_name='HAVE_PNG') - conf.check(lib='curl', uselib_store='CURL', define_name='HAVE_CURL') - conf.check(lib='z', uselib_store='ZLIB', define_name='HAVE_ZLIB') - if conf.env.DEST_CPU != 'aarch64': - conf.check(lib='unwind', uselib_store='UNWIND') - conf.check(lib='crypto', uselib_store='CRYPTO') - conf.check(lib='ssl', uselib_store='SSL') - conf.check(lib='android_support', uselib_store='ANDROID_SUPPORT') - conf.check(lib='opus', uselib_store='OPUS') - - if conf.env.DEST_OS == "darwin": - conf.check(lib='iconv', uselib_store='ICONV') - conf.env.FRAMEWORK_APPKIT = "AppKit" - conf.env.FRAMEWORK_IOKIT = "IOKit" - conf.env.FRAMEWORK_FOUNDATION = "Foundation" - conf.env.FRAMEWORK_COREFOUNDATION = "CoreFoundation" - conf.env.FRAMEWORK_COREGRAPHICS = "CoreGraphics" - conf.env.FRAMEWORK_OPENGL = "OpenGL" - conf.env.FRAMEWORK_CARBON = "Carbon" - conf.env.FRAMEWORK_APPLICATIONSERVICES = "ApplicationServices" - conf.env.FRAMEWORK_CORESERVICES = "CoreServices" - conf.env.FRAMEWORK_COREAUDIO = "CoreAudio" - conf.env.FRAMEWORK_AUDIOTOOLBOX = "AudioToolbox" - conf.env.FRAMEWORK_SYSTEMCONFIGURATION = "SystemConfiguration" - - if conf.env.DEST_OS != 'win32': - conf.check_cc(lib='dl', mandatory=False) - conf.check_cc(lib='bz2', mandatory=False) - conf.check_cc(lib='rt', mandatory=False) - - if not conf.env.LIB_M: # HACK: already added in xcompile! - conf.check_cc(lib='m') - else: - # Common Win32 libraries - # Don't check them more than once, to save time - # Usually, they are always available - # but we need them in uselib - a = [ - 'user32', - 'shell32', - 'gdi32', - 'advapi32', - 'dbghelp', - 'psapi', - 'ws2_32', - 'rpcrt4', - 'winmm', - 'wininet', - 'ole32', - 'shlwapi', - 'imm32' - ] - - if conf.env.COMPILER_CC == 'msvc': - for i in a: - conf.check_lib_msvc(i) - else: - for i in a: - conf.check_cc(lib = i) - - conf.check(lib='libz', uselib_store='ZLIB', define_name='USE_ZLIB') - # conf.check(lib='nvtc', uselib_store='NVTC') - # conf.check(lib='ati_compress_mt_vc10', uselib_store='ATI_COMPRESS_MT_VC10') - conf.check(lib='SDL2', uselib_store='SDL2') - conf.check(lib='libjpeg', uselib_store='JPEG', define_name='HAVE_JPEG') - conf.check(lib='libpng', uselib_store='PNG', define_name='HAVE_PNG') - conf.check(lib='d3dx9', uselib_store='D3DX9') - conf.check(lib='d3d9', uselib_store='D3D9') - conf.check(lib='dsound', uselib_store='DSOUND') - conf.check(lib='dxguid', uselib_store='DXGUID') - if conf.options.OPUS: - conf.check(lib='opus', uselib_store='OPUS') - - # conf.multicheck(*a, run_all_tests = True, mandatory = True) + check_deps( conf ) # indicate if we are packaging for Linux/BSD if conf.env.DEST_OS != 'android': From 92028d4e804a7c2f00aead2bbcb8b116c587de25 Mon Sep 17 00:00:00 2001 From: nillerusr Date: Fri, 7 Apr 2023 14:56:56 +0300 Subject: [PATCH 05/10] tier1: fix possible unsafe read in lzss SafeUncompress, make tests pass under asan --- engine/common.cpp | 2 +- gameui/BasePanel.cpp | 2 +- public/tier0/platform.h | 10 ++++ public/tier1/lzss.h | 2 +- tier1/lzss.cpp | 44 +++++++++--------- unittests/tier1test/lzsstest.cpp | 78 ++++++++++++++++++++++++++++++++ unittests/tier1test/wscript | 2 +- 7 files changed, 115 insertions(+), 25 deletions(-) create mode 100644 unittests/tier1test/lzsstest.cpp diff --git a/engine/common.cpp b/engine/common.cpp index c0646734..96a5c7f5 100644 --- a/engine/common.cpp +++ b/engine/common.cpp @@ -1385,7 +1385,7 @@ bool COM_BufferToBufferDecompress( void *dest, unsigned int *destLen, const void if ( pHeader->id == LZSS_ID ) { CLZSS s; - int nActualDecompressedSize = s.SafeUncompress( (byte *)source, (byte *)dest, *destLen ); + int nActualDecompressedSize = s.SafeUncompress( (byte *)source, sourceLen, (byte *)dest, *destLen ); if ( nActualDecompressedSize != nDecompressedSize ) { Warning( "NET_BufferToBufferDecompress: header said %d bytes would be decompressed, but we LZSS decompressed %d\n", nDecompressedSize, nActualDecompressedSize ); diff --git a/gameui/BasePanel.cpp b/gameui/BasePanel.cpp index a5336366..b9f0bb07 100644 --- a/gameui/BasePanel.cpp +++ b/gameui/BasePanel.cpp @@ -915,7 +915,7 @@ CBasePanel::CBasePanel() : Panel(NULL, "BaseGameUIPanel") } } -// if( IsAndroid() ) + if( IsAndroid() ) { AddUrlButton( this, "vgui/\x64\x69\x73\x63\x6f\x72\x64\x5f\x6c\x6f\x67\x6f", "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x64\x69\x73\x63\x6f\x72\x64\x2e\x67\x67\x2f\x68\x5a\x52\x42\x37\x57\x4d\x67\x47\x77" ); AddUrlButton( this, "vgui/\x74\x77\x69\x74\x74\x65\x72\x5f\x6c\x6f\x67\x6f", "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x74\x77\x69\x74\x74\x65\x72\x2e\x63\x6f\x6d\x2f\x6e\x69\x6c\x6c\x65\x72\x75\x73\x72" ); diff --git a/public/tier0/platform.h b/public/tier0/platform.h index 4a4c4883..99ac5b3b 100644 --- a/public/tier0/platform.h +++ b/public/tier0/platform.h @@ -606,6 +606,16 @@ typedef void * HINSTANCE; #define FMTFUNCTION( a, b ) #endif +#if defined(__has_feature) +#if __has_feature(address_sanitizer) +#define USING_ASAN 1 +#endif +#endif + +#if !defined( USING_ASAN ) && defined( __SANITIZE_ADDRESS__ ) +#define USING_ASAN 1 +#endif + #if COMPILER_CLANG || COMPILER_GCC #define NO_ASAN __attribute__((no_sanitize("address"))) #else diff --git a/public/tier1/lzss.h b/public/tier1/lzss.h index 8b3409a9..0a1f3002 100644 --- a/public/tier1/lzss.h +++ b/public/tier1/lzss.h @@ -30,7 +30,7 @@ public: unsigned char* CompressNoAlloc( const unsigned char *pInput, int inputlen, unsigned char *pOutput, unsigned int *pOutputSize ); unsigned int Uncompress( const unsigned char *pInput, unsigned char *pOutput ); //unsigned int Uncompress( unsigned char *pInput, CUtlBuffer &buf ); - unsigned int SafeUncompress( const unsigned char *pInput, unsigned char *pOutput, unsigned int unBufSize ); + unsigned int SafeUncompress( const unsigned char *pInput, unsigned int inputSize, unsigned char *pOutput, unsigned int unBufSize ); static bool IsCompressed( const unsigned char *pInput ); static unsigned int GetActualSize( const unsigned char *pInput ); diff --git a/tier1/lzss.cpp b/tier1/lzss.cpp index 23bdead8..4e6138b1 100644 --- a/tier1/lzss.cpp +++ b/tier1/lzss.cpp @@ -294,59 +294,61 @@ unsigned int CLZSS::Uncompress( unsigned char *pInput, CUtlBuffer &buf ) } */ -unsigned int CLZSS::SafeUncompress( const unsigned char *pInput, unsigned char *pOutput, unsigned int unBufSize ) +unsigned int CLZSS::SafeUncompress( const unsigned char *pInput, unsigned int inputSize, unsigned char *pOutput, unsigned int unBufSize ) { unsigned int totalBytes = 0; int cmdByte = 0; int getCmdByte = 0; unsigned int actualSize = GetActualSize( pInput ); - if ( !actualSize ) - { - // unrecognized - return 0; - } - if ( actualSize > unBufSize ) - { + if ( !actualSize || + actualSize > unBufSize || + inputSize <= sizeof( lzss_header_t ) ) return 0; - } + + const unsigned char *pInputEnd = pInput+inputSize-1; + const unsigned char *pOrigOutput = pOutput; pInput += sizeof( lzss_header_t ); for ( ;; ) { - if ( !getCmdByte ) + if ( !getCmdByte ) { + if( pInput > pInputEnd ) + return 0; + cmdByte = *pInput++; } getCmdByte = ( getCmdByte + 1 ) & 0x07; if ( cmdByte & 0x01 ) { + if( pInput+1 > pInputEnd ) + return 0; + int position = *pInput++ << LZSS_LOOKSHIFT; position |= ( *pInput >> LZSS_LOOKSHIFT ); int count = ( *pInput++ & 0x0F ) + 1; - if ( count == 1 ) - { + if ( count == 1 ) break; - } + unsigned char *pSource = pOutput - position - 1; - if ( totalBytes + count > unBufSize ) - { + if ( totalBytes + count > unBufSize || + pSource < pOrigOutput ) return 0; - } for ( int i=0; i unBufSize ) + if ( totalBytes + 1 > unBufSize || + pInput > pInputEnd ) return 0; *pOutput++ = *pInput++; diff --git a/unittests/tier1test/lzsstest.cpp b/unittests/tier1test/lzsstest.cpp new file mode 100644 index 00000000..3e9d07ff --- /dev/null +++ b/unittests/tier1test/lzsstest.cpp @@ -0,0 +1,78 @@ +#include "tier0/dbg.h" +#include "unitlib/unitlib.h" +#include "tier1/lzss.h" + +#ifdef USING_ASAN +#include +#endif + +DEFINE_TESTSUITE( LZSSSafeUncompressTestSuite ) + +static void SafeUncompressTests() +{ + CLZSS lzss; + char poision1[8192]; + unsigned char in[256]; + + char poision2[8192]; + + unsigned char out[256]; + char poision3[8192]; + +#ifdef USING_ASAN + ASAN_POISON_MEMORY_REGION( poision1, 8192 ); + ASAN_POISON_MEMORY_REGION( poision2, 8192 ); + ASAN_POISON_MEMORY_REGION( poision3, 8192 ); +#endif + + lzss_header_t *pHeader = (lzss_header_t*)in; + pHeader->actualSize = sizeof(in)-sizeof(lzss_header_t); + pHeader->id = LZSS_ID; + + uint result = 0; + + // 0xff bytes test + memset(in+8, 0xFF, sizeof(in)-sizeof(lzss_header_t)); + result = lzss.SafeUncompress( in, sizeof(in), out, sizeof(out) ); + Shipping_Assert( result == 0 ); + + // zero bytes test + memset(in+8, 0x0, sizeof(in)-sizeof(lzss_header_t)); + result = lzss.SafeUncompress( in, sizeof(in), out, sizeof(out) ); + Shipping_Assert( result == 0 ); + + // valid data, invalid header + pHeader->actualSize = 1; + pHeader->id = LZSS_ID; + result = lzss.SafeUncompress( in, sizeof(in), out, sizeof(out) ); + Shipping_Assert( result == 0 ); + + pHeader->actualSize = 999; + pHeader->id = LZSS_ID; + result = lzss.SafeUncompress( in, sizeof(in), out, sizeof(out) ); + Shipping_Assert( result == 0 ); + + pHeader->actualSize = 999; + pHeader->id = 1337; + result = lzss.SafeUncompress( in, sizeof(in), out, sizeof(out) ); + Shipping_Assert( result == 0 ); + + + // valid header, valid data + const unsigned char compressed[] = {0x4c,0x5a,0x53,0x53,0x1a,0x0,0x0,0x0,0x0,0x44,0x6f,0x20,0x79,0x6f,0x75,0x20,0x6c,0x0,0x69,0x6b,0x65,0x20,0x77,0x68,0x61,0x74,0x41,0x0,0xd4,0x73,0x65,0x65,0x3f,0x0,0x0,0x0}; + + pHeader->actualSize = sizeof(compressed); + pHeader->id = LZSS_ID; + result = lzss.SafeUncompress( compressed, sizeof(compressed), out, sizeof(out) ); + + const char data[] = "Do you like what you see?"; + Shipping_Assert( memcmp(out, data, 26) == 0 ); + Shipping_Assert( result == 26 ); +} + +DEFINE_TESTCASE( LZSSSafeUncompressTest, LZSSSafeUncompressTestSuite ) +{ + Msg( "Running CLZSS::SafeUncompress tests\n" ); + + SafeUncompressTests(); +} diff --git a/unittests/tier1test/wscript b/unittests/tier1test/wscript index 774398ba..8421046f 100755 --- a/unittests/tier1test/wscript +++ b/unittests/tier1test/wscript @@ -14,7 +14,7 @@ def configure(conf): conf.define('TIER1TEST_EXPORTS', 1) def build(bld): - source = ['commandbuffertest.cpp', 'utlstringtest.cpp', 'tier1test.cpp'] #, 'lzsstest.cpp'] + source = ['commandbuffertest.cpp', 'utlstringtest.cpp', 'tier1test.cpp', 'lzsstest.cpp'] includes = ['../../public', '../../public/tier0'] defines = [] libs = ['tier0', 'tier1', 'mathlib', 'unitlib'] From b2d168c70120143246aa501146e94d696e4e6bed Mon Sep 17 00:00:00 2001 From: nillerusr Date: Fri, 7 Apr 2023 15:03:12 +0300 Subject: [PATCH 06/10] scripts: remove useless deps from installation --- scripts/tests-ubuntu-amd64.sh | 2 +- scripts/tests-ubuntu-i386.sh | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/tests-ubuntu-amd64.sh b/scripts/tests-ubuntu-amd64.sh index 080ef65a..1cef058e 100755 --- a/scripts/tests-ubuntu-amd64.sh +++ b/scripts/tests-ubuntu-amd64.sh @@ -2,7 +2,7 @@ git submodule init && git submodule update sudo apt-get update -sudo apt-get install -f -y gdb libopenal-dev g++-multilib gcc-multilib libpng-dev libjpeg-dev libfreetype6-dev libfontconfig1-dev libcurl4-gnutls-dev libsdl2-dev zlib1g-dev libbz2-dev libedit-dev +sudo apt-get install -y libbz2-dev ./waf configure -T release --sanitize=address,undefined --disable-warns --tests --prefix=out/ --64bits $* && ./waf install && diff --git a/scripts/tests-ubuntu-i386.sh b/scripts/tests-ubuntu-i386.sh index b3d71837..f14fc361 100755 --- a/scripts/tests-ubuntu-i386.sh +++ b/scripts/tests-ubuntu-i386.sh @@ -3,8 +3,7 @@ install#!/bin/sh git submodule init && git submodule update sudo dpkg --add-architecture i386 sudo apt-get update -sudo apt-get install -y aptitude -sudo aptitude install -y libopenal-dev:i386 g++-multilib gcc-multilib libpng-dev:i386 libjpeg-dev:i386 libfreetype6-dev:i386 libfontconfig1-dev:i386 libcurl4-gnutls-dev:i386 libsdl2-dev:i386 zlib1g-dev:i386 libbz2-dev:i386 libedit-dev:i386 +sudo apt-get install -y g++-multilib gcc-multilib libbz2-dev:i386 PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig ./waf configure -T release --sanitize=address,undefined --disable-warns --tests --prefix=out/ $* && ./waf install && From 3fcf98685364957f699ba18f82ee459f3bb484c6 Mon Sep 17 00:00:00 2001 From: nillerusr Date: Fri, 7 Apr 2023 15:19:35 +0300 Subject: [PATCH 07/10] unittests: don't use ASAN_POISON_MEMORY_REGION with gcc --- unittests/tier1test/lzsstest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unittests/tier1test/lzsstest.cpp b/unittests/tier1test/lzsstest.cpp index 3e9d07ff..7eeff4c3 100644 --- a/unittests/tier1test/lzsstest.cpp +++ b/unittests/tier1test/lzsstest.cpp @@ -19,7 +19,7 @@ static void SafeUncompressTests() unsigned char out[256]; char poision3[8192]; -#ifdef USING_ASAN +#if defined( USING_ASAN ) && !defined( COMPILER_GCC ) ASAN_POISON_MEMORY_REGION( poision1, 8192 ); ASAN_POISON_MEMORY_REGION( poision2, 8192 ); ASAN_POISON_MEMORY_REGION( poision3, 8192 ); From f3b17b77e5c1c597706ed4a869f69ad3c5797a43 Mon Sep 17 00:00:00 2001 From: nillerusr Date: Sat, 8 Apr 2023 13:40:33 +0300 Subject: [PATCH 08/10] update workflows --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7738f3bf..0c29e52e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,7 +4,7 @@ on: [push, pull_request] jobs: build-linux-i386: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 From d23ae89574a81baabe5211042c14b5794539d071 Mon Sep 17 00:00:00 2001 From: SanyaSho <68691958+SanyaSho@users.noreply.github.com> Date: Fri, 7 Apr 2023 17:57:47 +0300 Subject: [PATCH 09/10] game: add another NULL check for CEngineSprite::GetMaterial --- game/client/spritemodel.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/game/client/spritemodel.cpp b/game/client/spritemodel.cpp index 018e918f..ab28e640 100644 --- a/game/client/spritemodel.cpp +++ b/game/client/spritemodel.cpp @@ -417,6 +417,9 @@ IMaterial *CEngineSprite::GetMaterial( RenderMode_t nRenderMode, int nFrame ) IMaterial *pMaterial = m_material[nRenderMode]; + if( !pMaterial ) + return NULL; + IMaterialVar* pFrameVar = pMaterial->FindVarFast( "$frame", &frameCache ); if ( pFrameVar ) { @@ -539,4 +542,4 @@ void CEngineSprite::DrawFrameOfSize( RenderMode_t nRenderMode, int frame, int x, meshBuilder.End(); pMesh->Draw(); -} \ No newline at end of file +} From d719a18fa75255f2c256b24814abad28212fe9f3 Mon Sep 17 00:00:00 2001 From: nillerusr Date: Sun, 9 Apr 2023 09:44:41 +0300 Subject: [PATCH 10/10] engine: fix black screen in changelevel --- engine/client.cpp | 6 +++--- engine/modelloader.cpp | 6 +++--- engine/view.cpp | 12 ++++++++++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/engine/client.cpp b/engine/client.cpp index 712131a2..ee64d786 100644 --- a/engine/client.cpp +++ b/engine/client.cpp @@ -1816,14 +1816,14 @@ void CClientState::FinishSignonState_New() // // This is pretty janky, but doesn't really have any cost (and even makes our one-frozen-frame load screen slightly // less likely to trigger OS "not responding" warnings) -// extern void V_RenderVGuiOnly(); -// V_RenderVGuiOnly(); + extern void V_RenderSwapBuffers(); + V_RenderSwapBuffers(); // Before we do anything with the whitelist, make sure we have the proper map pack mounted // this will load the .bsp by setting the world model the string list at the hardcoded index 1. cl.SetModel( 1 ); - //V_RenderVGuiOnly(); + V_RenderSwapBuffers(); // Check for a new whitelist. It's good to do it early in the connection process here because if we wait until later, // the client may have loaded some files w/o the proper whitelist restrictions and we'd have to reload them. diff --git a/engine/modelloader.cpp b/engine/modelloader.cpp index a51cd110..46e42877 100644 --- a/engine/modelloader.cpp +++ b/engine/modelloader.cpp @@ -956,13 +956,13 @@ void EnableHDR( bool bEnable ) /// ancient bugs, hence the kill switch. bool bUpdateOffline = mod_offline_hdr_switch.GetBool(); #ifndef DEDICATED - extern void V_RenderVGuiOnly(); + extern void V_RenderSwapBuffers(); #endif if ( bUpdateOffline ) { #ifndef DEDICATED - V_RenderVGuiOnly(); + V_RenderSwapBuffers(); #endif materials->ReleaseResources(); } @@ -986,7 +986,7 @@ void EnableHDR( bool bEnable ) #ifndef DEDICATED if ( bUpdateOffline ) { - V_RenderVGuiOnly(); + V_RenderSwapBuffers(); } #endif } diff --git a/engine/view.cpp b/engine/view.cpp index 04772894..61532c57 100644 --- a/engine/view.cpp +++ b/engine/view.cpp @@ -171,6 +171,18 @@ void V_RenderVGuiOnly( void ) Shader_SwapBuffers(); } +void V_RenderSwapBuffers( void ) +{ + materials->BeginFrame( host_frametime ); + g_EngineRenderer->FrameBegin(); + + UpdateMaterialSystemConfig(); + + g_EngineRenderer->FrameEnd( ); + materials->EndFrame(); + + Shader_SwapBuffers(); +} void FullViewColorAdjustment( ) {