From 050d2a3d0f849a51f8b12455c5360d84688deb9c Mon Sep 17 00:00:00 2001 From: mittorn Date: Thu, 19 Apr 2018 20:11:24 +0000 Subject: [PATCH] Apply Apr18 update --- engine/client/cl_game.c | 56 +++-- engine/client/cl_parse.c | 4 +- engine/client/cl_tent.c | 19 +- engine/client/client.h | 9 + engine/client/gl_alias.c | 6 +- engine/client/gl_draw.c | 1 + engine/client/gl_export.h | 55 +++++ engine/client/gl_image.c | 484 ++++--------------------------------- engine/client/gl_local.h | 24 +- engine/client/gl_rlight.c | 22 +- engine/client/gl_rsurf.c | 13 +- engine/client/gl_sprite.c | 14 +- engine/client/gl_studio.c | 26 +- engine/client/gl_vidnt.c | 212 ++++++++++++++-- engine/client/gl_warp.c | 2 +- engine/common/filesystem.c | 8 +- engine/common/host.c | 2 +- engine/common/keys.c | 4 +- engine/common/library.c | 6 +- engine/common/mod_local.h | 1 - engine/common/model.c | 17 +- engine/server/sv_client.c | 2 +- engine/server/sv_game.c | 4 +- engine/server/sv_save.c | 24 +- engine/studio.h | 1 - 25 files changed, 438 insertions(+), 578 deletions(-) diff --git a/engine/client/cl_game.c b/engine/client/cl_game.c index b3f49ed9..b95871eb 100644 --- a/engine/client/cl_game.c +++ b/engine/client/cl_game.c @@ -1489,14 +1489,33 @@ for parsing half-life scripts - hud.txt etc */ static client_sprite_t *pfnSPR_GetList( char *psz, int *piCount ) { - client_sprite_t *pList; - int index, numSprites = 0; + cached_spritelist_t *pEntry = &clgame.sprlist[0]; + int slot, index, numSprites = 0; char *afile, *pfile; string token; - byte *pool; if( piCount ) *piCount = 0; + // see if already in list + // NOTE: client.dll is cache hud.txt but reparse weapon lists again and again + // obviously there a memory leak by-design. Cache the sprite lists to prevent it + for( slot = 0; slot < MAX_CLIENT_SPRITES && pEntry->szListName[0]; slot++ ) + { + pEntry = &clgame.sprlist[slot]; + + if( !Q_stricmp( pEntry->szListName, psz )) + { + if( piCount ) *piCount = pEntry->count; + return pEntry->pList; + } + } + + if( slot == MAX_CLIENT_SPRITES ) + { + Con_Printf( S_ERROR "SPR_GetList: overflow cache!\n" ); + return NULL; + } + if( !clgame.itemspath[0] ) // typically it's sprites\*.txt COM_ExtractFilePath( psz, clgame.itemspath ); @@ -1507,50 +1526,48 @@ static client_sprite_t *pfnSPR_GetList( char *psz, int *piCount ) pfile = COM_ParseFile( pfile, token ); numSprites = Q_atoi( token ); - if( !cl.video_prepped ) pool = cls.mempool; // static memory - else pool = com_studiocache; // temporary + Q_strncpy( pEntry->szListName, psz, sizeof( pEntry->szListName )); // name, res, pic, x, y, w, h - // NOTE: we must use com_studiocache because it will be purge on next restart or change map - pList = Mem_Alloc( pool, sizeof( client_sprite_t ) * numSprites ); + pEntry->pList = Mem_Alloc( cls.mempool, sizeof( client_sprite_t ) * numSprites ); for( index = 0; index < numSprites; index++ ) { if(( pfile = COM_ParseFile( pfile, token )) == NULL ) break; - Q_strncpy( pList[index].szName, token, sizeof( pList[index].szName )); + Q_strncpy( pEntry->pList[index].szName, token, sizeof( pEntry->pList[0].szName )); // read resolution pfile = COM_ParseFile( pfile, token ); - pList[index].iRes = Q_atoi( token ); + pEntry->pList[index].iRes = Q_atoi( token ); // read spritename pfile = COM_ParseFile( pfile, token ); - Q_strncpy( pList[index].szSprite, token, sizeof( pList[index].szSprite )); + Q_strncpy( pEntry->pList[index].szSprite, token, sizeof( pEntry->pList[0].szSprite )); // parse rectangle pfile = COM_ParseFile( pfile, token ); - pList[index].rc.left = Q_atoi( token ); + pEntry->pList[index].rc.left = Q_atoi( token ); pfile = COM_ParseFile( pfile, token ); - pList[index].rc.top = Q_atoi( token ); + pEntry->pList[index].rc.top = Q_atoi( token ); pfile = COM_ParseFile( pfile, token ); - pList[index].rc.right = pList[index].rc.left + Q_atoi( token ); + pEntry->pList[index].rc.right = pEntry->pList[index].rc.left + Q_atoi( token ); pfile = COM_ParseFile( pfile, token ); - pList[index].rc.bottom = pList[index].rc.top + Q_atoi( token ); + pEntry->pList[index].rc.bottom = pEntry->pList[index].rc.top + Q_atoi( token ); - if( piCount ) (*piCount)++; + pEntry->count++; } if( index < numSprites ) - MsgDev( D_WARN, "SPR_GetList: unexpected end of %s (%i should be %i)\n", psz, numSprites, index ); - + Con_DPrintf( S_WARN "unexpected end of %s (%i should be %i)\n", psz, numSprites, index ); + if( piCount ) *piCount = pEntry->count; Mem_Free( afile ); - return pList; + return pEntry->pList; } /* @@ -3609,6 +3626,7 @@ static event_api_t gEventApi = pfnGetMoveVars, CL_VisTraceLine, pfnGetVisent, + CL_TestLine, }; static demo_api_t gDemoApi = @@ -3877,7 +3895,7 @@ qboolean CL_LoadProgs( const char *name ) CL_InitTempEnts (); if( !R_InitRenderAPI()) // Xash3D extension - MsgDev( D_WARN, "CL_LoadProgs: couldn't get render API\n" ); + Con_Reportf( S_WARN "CL_LoadProgs: couldn't get render API\n" ); CL_InitEdicts (); // initailize local player and world CL_InitClientMove(); // initialize pm_shared diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 1e84f97c..9b19da66 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -544,7 +544,7 @@ void CL_ParseStaticEntity( sizebuf_t *msg ) ent->prevstate = state; // statics may be respawned in game e.g. for demo recording - if( cls.state == ca_connected ) + if( cls.state == ca_connected || cls.state == ca_validate ) ent->trivial_accept = INVALID_HANDLE; // setup the new static entity @@ -1758,7 +1758,7 @@ void CL_RegisterResources( sizebuf_t *msg ) } else { - MsgDev( D_ERROR, "client world model is NULL\n" ); + Con_Printf( S_ERROR "client world model is NULL\n" ); CL_Disconnect(); } } diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index 118a1754..16aba9b8 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -348,7 +348,7 @@ void CL_ClearTempEnts( void ) { cl_tempents[i].next = &cl_tempents[i+1]; cl_tempents[i].entity.trivial_accept = INVALID_HANDLE; - } + } cl_tempents[GI->max_tents-1].next = NULL; cl_free_tents = cl_tempents; @@ -2843,6 +2843,23 @@ void CL_AddEntityEffects( cl_entity_t *ent ) dl->die = cl.time + 0.001; dl->radius = 200; } + + // studio models are handle muzzleflashes difference + if( FBitSet( ent->curstate.effects, EF_MUZZLEFLASH ) && ent->model->type == mod_alias ) + { + dlight_t *dl = CL_AllocDlight( ent->index ); + vec3_t fv; + + ClearBits( ent->curstate.effects, EF_MUZZLEFLASH ); + dl->color.r = dl->color.g = dl->color.b = 100; + VectorCopy( ent->origin, dl->origin ); + AngleVectors( ent->angles, fv, NULL, NULL ); + dl->origin[2] += 16.0f; + VectorMA( dl->origin, 18, fv, dl->origin ); + dl->radius = COM_RandomFloat( 200, 231 ); + dl->die = cl.time + 0.1; + dl->minlight = 32; + } } /* diff --git a/engine/client/client.h b/engine/client/client.h index 55baf787..c863d4fe 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -409,6 +409,13 @@ typedef struct rgba_t textColor; } gameui_draw_t; +typedef struct +{ + char szListName[MAX_QPATH]; + client_sprite_t *pList; + int count; +} cached_spritelist_t; + typedef struct { // centerprint stuff @@ -505,6 +512,8 @@ typedef struct ref_overview_t overView; // overView params color24 palette[256]; // palette used for particle colors + cached_spritelist_t sprlist[MAX_CLIENT_SPRITES]; // client list sprites + client_textmessage_t *titles; // title messages, not network messages int numTitles; diff --git a/engine/client/gl_alias.c b/engine/client/gl_alias.c index cefd8e78..c2812059 100644 --- a/engine/client/gl_alias.c +++ b/engine/client/gl_alias.c @@ -928,9 +928,9 @@ void R_AliasDynamicLight( cl_entity_t *ent, alight_t *plight ) VectorAdd( lightDir, dist, lightDir ); - finalLight[0] += LightToTexGamma( dl->color.r ) * ( add * 512.0f ); - finalLight[1] += LightToTexGamma( dl->color.g ) * ( add * 512.0f ); - finalLight[2] += LightToTexGamma( dl->color.b ) * ( add * 512.0f ); + finalLight[0] += LightToTexGamma( dl->color.r ) * ( add / 256.0f ) * 2.0f; + finalLight[1] += LightToTexGamma( dl->color.g ) * ( add / 256.0f ) * 2.0f; + finalLight[2] += LightToTexGamma( dl->color.b ) * ( add / 256.0f ) * 2.0f; } } diff --git a/engine/client/gl_draw.c b/engine/client/gl_draw.c index 2b93d6de..eab1b3b7 100644 --- a/engine/client/gl_draw.c +++ b/engine/client/gl_draw.c @@ -167,6 +167,7 @@ void R_DrawStretchRaw( float x, float y, float w, float h, int cols, int rows, c } else { + tex->size = cols * rows * 4; tex->width = cols; tex->height = rows; if( dirty ) diff --git a/engine/client/gl_export.h b/engine/client/gl_export.h index 12c4f2a6..22ff3fdc 100644 --- a/engine/client/gl_export.h +++ b/engine/client/gl_export.h @@ -806,6 +806,59 @@ typedef float GLmatrix[16]; #define ERROR_INVALID_VERSION_ARB 0x2095 #define ERROR_INVALID_PROFILE_ARB 0x2096 +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C + +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 + // helper opengl functions GLenum ( APIENTRY *pglGetError )(void); const GLubyte * ( APIENTRY *pglGetString )(GLenum name); @@ -1297,6 +1350,8 @@ BOOL ( WINAPI * pwglRealizeLayerPalette)(HDC, int, BOOL); BOOL ( WINAPI * pwglSwapLayerBuffers)(HDC, UINT); BOOL ( WINAPI * pwglSwapIntervalEXT)( int interval ); HGLRC ( WINAPI * pwglCreateContextAttribsARB)( HDC hDC, HGLRC hShareContext, const int *attribList ); +BOOL ( WINAPI *pwglGetPixelFormatAttribiv)( HDC hDC, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttrib, int *piValues ); +BOOL ( WINAPI *pwglChoosePixelFormat)( HDC hDC, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFmts, int *piFmts, UINT *nNumFmts ); const char *( WINAPI * pwglGetExtensionsStringEXT)( void ); #endif//GL_EXPORT_H \ No newline at end of file diff --git a/engine/client/gl_image.c b/engine/client/gl_image.c index f1161d90..d5444937 100644 --- a/engine/client/gl_image.c +++ b/engine/client/gl_image.c @@ -22,7 +22,7 @@ GNU General Public License for more details. static gltexture_t r_textures[MAX_TEXTURES]; static gltexture_t *r_texturesHashTable[TEXTURES_HASH_SIZE]; -static byte data2D[BLOCK_SIZE_MAX*BLOCK_SIZE_MAX*4]; // intermediate texbuffer +static byte data2D[1024]; // intermediate texbuffer static int r_numTextures; static rgbdata_t r_image; // generic pixelbuffer used for internal textures @@ -400,7 +400,13 @@ static size_t GL_CalcTextureSize( GLenum format, int width, int height, int dept break; case GL_RGB8: case GL_RGB: - size = width * height * depth * 4; + size = width * height * depth * 3; + break; + case GL_RGB5: + size = (width * height * depth * 3) / 2; + break; + case GL_RGBA4: + size = (width * height * depth * 4) / 2; break; case GL_INTENSITY: case GL_LUMINANCE: @@ -531,10 +537,27 @@ static void GL_SetTextureDimensions( gltexture_t *tex, int width, int height, in if( !GL_Support( GL_ARB_TEXTURE_NPOT_EXT )) { - width = (width + 3) & ~3; - height = (height + 3) & ~3; + int step = (int)gl_round_down->value; + int scaled_width, scaled_height; + + for( scaled_width = 1; scaled_width < width; scaled_width <<= 1 ); + + if( step > 0 && width < scaled_width && ( step == 1 || ( scaled_width - width ) > ( scaled_width >> step ))) + scaled_width >>= 1; + + for( scaled_height = 1; scaled_height < height; scaled_height <<= 1 ); + + if( step > 0 && height < scaled_height && ( step == 1 || ( scaled_height - height ) > ( scaled_height >> step ))) + scaled_height >>= 1; + + width = scaled_width; + height = scaled_height; } +#if 1 // TESTTEST + width = (width + 3) & ~3; + height = (height + 3) & ~3; +#endif if( width > maxTextureSize || height > maxTextureSize || depth > maxDepthSize ) { if( tex->target == GL_TEXTURE_1D ) @@ -684,7 +707,7 @@ static void GL_SetTextureFormat( gltexture_t *tex, pixformat_t format, int chann // NOTE: not all the types will be compressed int bits = glw_state.desktopBitsPixel; - switch( GL_CalcTextureSamples( channelMask ) ) + switch( GL_CalcTextureSamples( channelMask )) { case 1: tex->format = GL_LUMINANCE8; break; case 2: tex->format = GL_LUMINANCE8_ALPHA8; break; @@ -1134,7 +1157,7 @@ static qboolean GL_UploadTexture( gltexture_t *tex, rgbdata_t *pic ) if(( pic->width * pic->height ) & 3 ) { // will be resampled, just tell me for debug targets - MsgDev( D_NOTE, "GL_UploadTexture: %s s&3 [%d x %d]\n", tex->name, pic->width, pic->height ); + Con_Reportf( "GL_UploadTexture: %s s&3 [%d x %d]\n", tex->name, pic->width, pic->height ); } buf = pic->buffer; @@ -1965,30 +1988,6 @@ static rgbdata_t *R_InitParticleTexture( texFlags_t *flags ) return &r_image; } -/* -================== -R_InitSkyTexture -================== -*/ -static rgbdata_t *R_InitSkyTexture( texFlags_t *flags ) -{ - int i; - - // skybox texture - for( i = 0; i < 256; i++ ) - ((uint *)&data2D)[i] = 0xFFFFDEB5; - - *flags = 0; - - r_image.buffer = data2D; - r_image.width = r_image.height = 16; - r_image.size = r_image.width * r_image.height * 4; - r_image.flags = IMAGE_HAS_COLOR; - r_image.type = PF_RGBA_32; - - return &r_image; -} - /* ================== R_InitCinematicTexture @@ -1996,11 +1995,12 @@ R_InitCinematicTexture */ static rgbdata_t *R_InitCinematicTexture( texFlags_t *flags ) { - r_image.buffer = data2D; r_image.type = PF_RGBA_32; r_image.flags = IMAGE_HAS_COLOR; - r_image.width = r_image.height = 256; + r_image.width = 640; // same as menu head + r_image.height = 100; r_image.size = r_image.width * r_image.height * 4; + r_image.buffer = NULL; *flags = TF_NOMIPMAP|TF_CLAMP; @@ -2059,403 +2059,22 @@ static rgbdata_t *R_InitBlackTexture( texFlags_t *flags ) /* ================== -R_InitBlankBumpTexture +R_InitDlightTexture ================== */ -static rgbdata_t *R_InitBlankBumpTexture( texFlags_t *flags ) +void R_InitDlightTexture( void ) { - int i; + if( tr.dlightTexture != 0 ) + return; // already initialized - // default normalmap texture - for( i = 0; i < 256; i++ ) - { - data2D[i*4+0] = 127; - data2D[i*4+1] = 127; - data2D[i*4+2] = 255; - } - - *flags = TF_NORMALMAP; - - r_image.buffer = data2D; - r_image.width = r_image.height = 16; - r_image.size = r_image.width * r_image.height * 4; + r_image.width = BLOCK_SIZE; + r_image.height = BLOCK_SIZE; r_image.flags = IMAGE_HAS_COLOR; r_image.type = PF_RGBA_32; - - return &r_image; -} - -/* -================== -R_InitBlankDeluxeTexture -================== -*/ -static rgbdata_t *R_InitBlankDeluxeTexture( texFlags_t *flags ) -{ - int i; - - // default normalmap texture - for( i = 0; i < 256; i++ ) - { - data2D[i*4+0] = 127; - data2D[i*4+1] = 127; - data2D[i*4+2] = 0; // light from ceiling - } - - *flags = TF_NORMALMAP; - - r_image.buffer = data2D; - r_image.width = r_image.height = 16; r_image.size = r_image.width * r_image.height * 4; - r_image.flags = IMAGE_HAS_COLOR; - r_image.type = PF_RGBA_32; + r_image.buffer = NULL; - return &r_image; -} - -/* -================== -R_InitAttenuationTexture -================== -*/ -static rgbdata_t *R_InitAttenTextureGamma( texFlags_t *flags, float gamma ) -{ - int i; - - // 1d attenuation texture - r_image.width = 256; - r_image.height = 1; - r_image.buffer = data2D; - r_image.flags = IMAGE_HAS_COLOR; - r_image.type = PF_RGBA_32; - r_image.size = r_image.width * r_image.height * 4; - - for( i = 0; i < r_image.width; i++ ) - { - float atten = 255 - bound( 0, 255 * pow((i + 0.5f) / r_image.width, gamma ) + 0.5f, 255 ); - - // clear attenuation at ends to prevent light go outside - if( i == (r_image.width - 1) || i == 0 ) - atten = 0.0f; - - data2D[(i * 4) + 0] = (byte)atten; - data2D[(i * 4) + 1] = (byte)atten; - data2D[(i * 4) + 2] = (byte)atten; - data2D[(i * 4) + 3] = (byte)atten; - } - - *flags = TF_NOMIPMAP|TF_CLAMP|TF_TEXTURE_1D; - - return &r_image; -} - -static rgbdata_t *R_InitAttenuationTexture( texFlags_t *flags ) -{ - return R_InitAttenTextureGamma( flags, 1.5f ); -} - -static rgbdata_t *R_InitAttenuationTexture2( texFlags_t *flags ) -{ - return R_InitAttenTextureGamma( flags, 0.5f ); -} - -static rgbdata_t *R_InitAttenuationTexture3( texFlags_t *flags ) -{ - return R_InitAttenTextureGamma( flags, 3.5f ); -} - -static rgbdata_t *R_InitAttenuationTextureNoAtten( texFlags_t *flags ) -{ - // 1d attenuation texture - r_image.width = 256; - r_image.height = 1; - r_image.buffer = data2D; - r_image.flags = IMAGE_HAS_COLOR; - r_image.type = PF_RGBA_32; - r_image.size = r_image.width * r_image.height * 4; - - memset( data2D, 0xFF, r_image.size ); - *flags = TF_NOMIPMAP|TF_CLAMP|TF_TEXTURE_1D; - - return &r_image; -} - -/* -================== -R_InitAttenuationTexture3D -================== -*/ -static rgbdata_t *R_InitAttenTexture3D( texFlags_t *flags ) -{ - vec3_t v = { 0, 0, 0 }; - int x, y, z, d, size, size2, halfsize; - float intensity; - - if( !GL_Support( GL_TEXTURE_3D_EXT )) - return NULL; - - // 3d attenuation texture - r_image.width = 32; - r_image.height = 32; - r_image.depth = 32; - r_image.buffer = data2D; - r_image.flags = IMAGE_HAS_COLOR; - r_image.type = PF_RGBA_32; - r_image.size = r_image.width * r_image.height * r_image.depth * 4; - - size = 32; - halfsize = size / 2; - intensity = halfsize * halfsize; - size2 = size * size; - - for( x = 0; x < r_image.width; x++ ) - { - for( y = 0; y < r_image.height; y++ ) - { - for( z = 0; z < r_image.depth; z++ ) - { - v[0] = (( x + 0.5f ) * ( 2.0f / (float)size ) - 1.0f ); - v[1] = (( y + 0.5f ) * ( 2.0f / (float)size ) - 1.0f ); - if( r_image.depth > 1 ) v[2] = (( z + 0.5f ) * ( 2.0f / (float)size ) - 1.0f ); - - intensity = 1.0f - sqrt( DotProduct( v, v ) ); - if( intensity > 0 ) intensity = intensity * intensity * 215.5f; - d = bound( 0, intensity, 255 ); - - data2D[((z * size + y) * size + x) * 4 + 0] = d; - data2D[((z * size + y) * size + x) * 4 + 1] = d; - data2D[((z * size + y) * size + x) * 4 + 2] = d; - } - } - } - - *flags = TF_NOMIPMAP|TF_CLAMP|TF_TEXTURE_3D; - - return &r_image; -} - -static rgbdata_t *R_InitDlightTexture( texFlags_t *flags ) -{ - // solid color texture - r_image.width = BLOCK_SIZE_DEFAULT; - r_image.height = BLOCK_SIZE_DEFAULT; - r_image.flags = IMAGE_HAS_COLOR; - r_image.type = PF_RGBA_32; - r_image.size = r_image.width * r_image.height * 4; - r_image.buffer = data2D; - - memset( data2D, 0x00, r_image.size ); - - *flags = TF_NOMIPMAP|TF_CLAMP|TF_ATLAS_PAGE; - - return &r_image; -} - -static rgbdata_t *R_InitDlightTexture2( texFlags_t *flags ) -{ - // solid color texture - r_image.width = BLOCK_SIZE_MAX; - r_image.height = BLOCK_SIZE_MAX; - r_image.flags = IMAGE_HAS_COLOR; - r_image.type = PF_RGBA_32; - r_image.size = r_image.width * r_image.height * 4; - r_image.buffer = data2D; - - memset( data2D, 0x00, r_image.size ); - - *flags = TF_NOMIPMAP|TF_CLAMP|TF_ATLAS_PAGE; - - return &r_image; -} - -/* -================== -R_InitNormalizeCubemap -================== -*/ -static rgbdata_t *R_InitNormalizeCubemap( texFlags_t *flags ) -{ - int i, x, y, size = 32; - byte *dataCM = data2D; - float s, t; - vec3_t normal; - - if( !GL_Support( GL_TEXTURE_CUBEMAP_EXT )) - return NULL; - - // normal cube map texture - for( i = 0; i < 6; i++ ) - { - for( y = 0; y < size; y++ ) - { - for( x = 0; x < size; x++ ) - { - s = (((float)x + 0.5f) * (2.0f / size )) - 1.0f; - t = (((float)y + 0.5f) * (2.0f / size )) - 1.0f; - - switch( i ) - { - case 0: VectorSet( normal, 1.0f, -t, -s ); break; - case 1: VectorSet( normal, -1.0f, -t, s ); break; - case 2: VectorSet( normal, s, 1.0f, t ); break; - case 3: VectorSet( normal, s, -1.0f, -t ); break; - case 4: VectorSet( normal, s, -t, 1.0f ); break; - case 5: VectorSet( normal, -s, -t, -1.0f); break; - } - - VectorNormalize( normal ); - - dataCM[4*(y*size+x)+0] = (byte)(128 + 127 * normal[0]); - dataCM[4*(y*size+x)+1] = (byte)(128 + 127 * normal[1]); - dataCM[4*(y*size+x)+2] = (byte)(128 + 127 * normal[2]); - dataCM[4*(y*size+x)+3] = 255; - } - } - dataCM += (size*size*4); // move pointer - } - - *flags = (TF_NOMIPMAP|TF_CUBEMAP|TF_CLAMP); - - r_image.width = r_image.height = size; - r_image.size = r_image.width * r_image.height * 4 * 6; - r_image.flags |= (IMAGE_CUBEMAP|IMAGE_HAS_COLOR); // yes it's cubemap - r_image.buffer = data2D; - r_image.type = PF_RGBA_32; - - return &r_image; -} - -/* -================== -R_InitDlightCubemap -================== -*/ -static rgbdata_t *R_InitDlightCubemap( texFlags_t *flags ) -{ - int i, x, y, size = 4; - byte *dataCM = data2D; - int dx2, dy, d; - - if( !GL_Support( GL_TEXTURE_CUBEMAP_EXT )) - return NULL; - - // normal cube map texture - for( i = 0; i < 6; i++ ) - { - for( x = 0; x < size; x++ ) - { - dx2 = x - size / 2; - dx2 = dx2 * dx2; - - for( y = 0; y < size; y++ ) - { - dy = y - size / 2; - d = 255 - 35 * sqrt( dx2 + dy * dy ); - dataCM[( y * size + x ) * 4 + 0] = bound( 0, d, 255 ); - dataCM[( y * size + x ) * 4 + 1] = bound( 0, d, 255 ); - dataCM[( y * size + x ) * 4 + 2] = bound( 0, d, 255 ); - } - } - dataCM += (size * size * 4); // move pointer - } - - *flags = (TF_NOMIPMAP|TF_CUBEMAP|TF_CLAMP); - - r_image.width = r_image.height = size; - r_image.size = r_image.width * r_image.height * 4 * 6; - r_image.flags |= (IMAGE_CUBEMAP|IMAGE_HAS_COLOR); // yes it's cubemap - r_image.buffer = data2D; - r_image.type = PF_RGBA_32; - - return &r_image; -} - -/* -================== -R_InitGrayCubemap -================== -*/ -static rgbdata_t *R_InitGrayCubemap( texFlags_t *flags ) -{ - int size = 4; - byte *dataCM = data2D; - - if( !GL_Support( GL_TEXTURE_CUBEMAP_EXT )) - return NULL; - - // gray cubemap - just stub for pointlights - memset( dataCM, 0x7F, size * size * 6 * 4 ); - - *flags = (TF_NOMIPMAP|TF_CUBEMAP|TF_CLAMP); - - r_image.width = r_image.height = size; - r_image.size = r_image.width * r_image.height * 4 * 6; - r_image.flags |= (IMAGE_CUBEMAP|IMAGE_HAS_COLOR); // yes it's cubemap - r_image.buffer = data2D; - r_image.type = PF_RGBA_32; - - return &r_image; -} - -/* -================== -R_InitWhiteCubemap -================== -*/ -static rgbdata_t *R_InitWhiteCubemap( texFlags_t *flags ) -{ - int size = 4; - byte *dataCM = data2D; - - if( !GL_Support( GL_TEXTURE_CUBEMAP_EXT )) - return NULL; - - // white cubemap - just stub for pointlights - memset( dataCM, 0xFF, size * size * 6 * 4 ); - - *flags = (TF_NOMIPMAP|TF_CUBEMAP|TF_CLAMP); - - r_image.width = r_image.height = size; - r_image.size = r_image.width * r_image.height * 4 * 6; - r_image.flags |= (IMAGE_CUBEMAP|IMAGE_HAS_COLOR); // yes it's cubemap - r_image.buffer = data2D; - r_image.type = PF_RGBA_32; - - return &r_image; -} - -/* -================== -R_InitVSDCTCubemap -================== -*/ -static rgbdata_t *R_InitVSDCTCubemap( texFlags_t *flags ) -{ - // maps to a 2x3 texture rectangle with normalized coordinates - // +- - // XX - // YY - // ZZ - // stores abs(dir.xy), offset.xy/2.5 - static byte data[4*6] = - { - 0xFF, 0x00, 0x33, 0x33, // +X: <1, 0>, <0.5, 0.5> - 0xFF, 0x00, 0x99, 0x33, // -X: <1, 0>, <1.5, 0.5> - 0x00, 0xFF, 0x33, 0x99, // +Y: <0, 1>, <0.5, 1.5> - 0x00, 0xFF, 0x99, 0x99, // -Y: <0, 1>, <1.5, 1.5> - 0x00, 0x00, 0x33, 0xFF, // +Z: <0, 0>, <0.5, 2.5> - 0x00, 0x00, 0x99, 0xFF, // -Z: <0, 0>, <1.5, 2.5> - }; - - *flags = (TF_NEAREST|TF_CUBEMAP|TF_CLAMP); - - r_image.width = r_image.height = 1; - r_image.size = r_image.width * r_image.height * 4 * 6; - r_image.flags |= (IMAGE_CUBEMAP|IMAGE_HAS_COLOR|IMAGE_HAS_ALPHA); // yes it's cubemap - r_image.buffer = data; - r_image.type = PF_RGBA_32; - - return &r_image; + tr.dlightTexture = GL_LoadTextureInternal( "*dlight", &r_image, TF_NOMIPMAP|TF_CLAMP|TF_ATLAS_PAGE, false ); } /* @@ -2478,29 +2097,14 @@ static void R_InitBuiltinTextures( void ) textures[] = { { "*default", &tr.defaultTexture, R_InitDefaultTexture }, + { "*particle", &tr.particleTexture, R_InitParticleTexture }, { "*white", &tr.whiteTexture, R_InitWhiteTexture }, { "*gray", &tr.grayTexture, R_InitGrayTexture }, - { "*black", &tr.blackTexture, R_InitBlackTexture }, - { "*particle", &tr.particleTexture, R_InitParticleTexture }, - { "*cintexture", &tr.cinTexture, R_InitCinematicTexture }, // force linear filter - { "*dlight", &tr.dlightTexture, R_InitDlightTexture }, - { "*dlight2", &tr.dlightTexture2, R_InitDlightTexture2 }, - { "*atten", &tr.attenuationTexture, R_InitAttenuationTexture }, - { "*atten2", &tr.attenuationTexture2, R_InitAttenuationTexture2 }, - { "*atten3", &tr.attenuationTexture3, R_InitAttenuationTexture3 }, - { "*attnno", &tr.attenuationStubTexture, R_InitAttenuationTextureNoAtten }, - { "*normalize", &tr.normalizeTexture, R_InitNormalizeCubemap }, - { "*blankbump", &tr.blankbumpTexture, R_InitBlankBumpTexture }, - { "*blankdeluxe", &tr.blankdeluxeTexture, R_InitBlankDeluxeTexture }, - { "*lightCube", &tr.dlightCubeTexture, R_InitDlightCubemap }, - { "*grayCube", &tr.grayCubeTexture, R_InitGrayCubemap }, - { "*whiteCube", &tr.whiteCubeTexture, R_InitWhiteCubemap }, - { "*atten3D", &tr.attenuationTexture3D, R_InitAttenTexture3D }, - { "*sky", &tr.skyTexture, R_InitSkyTexture }, - { "*vsdct", &tr.vsdctCubeTexture, R_InitVSDCTCubemap }, + { "*black", &tr.blackTexture, R_InitBlackTexture }, // not used by engine + { "*cintexture", &tr.cinTexture, R_InitCinematicTexture }, // intermediate buffer to renderer cinematic textures { NULL, NULL, NULL } }; - size_t i, num_builtin_textures = sizeof( textures ) / sizeof( textures[0] ) - 1; + size_t i, num_builtin_textures = ARRAYSIZE( textures ) - 1; for( i = 0; i < num_builtin_textures; i++ ) { diff --git a/engine/client/gl_local.h b/engine/client/gl_local.h index 2c78105a..ab3ef9a0 100644 --- a/engine/client/gl_local.h +++ b/engine/client/gl_local.h @@ -165,31 +165,17 @@ typedef struct typedef struct { - int cinTexture; // cinematic texture - int skyTexture; // default sky texture + int defaultTexture; // use for bad textures + int particleTexture; int whiteTexture; int grayTexture; int blackTexture; - int particleTexture; - int defaultTexture; // use for bad textures int solidskyTexture; // quake1 solid-sky layer int alphaskyTexture; // quake1 alpha-sky layer int lightmapTextures[MAX_LIGHTMAPS]; int dlightTexture; // custom dlight texture - int dlightTexture2; // big dlight texture (for big lightmaps) - int attenuationTexture; // normal attenuation - int attenuationTexture2;// dark attenuation - int attenuationTexture3;// bright attenuation - int attenuationTexture3D;// 3D attenuation - int attenuationStubTexture; - int blankbumpTexture; - int blankdeluxeTexture; - int normalizeTexture; - int dlightCubeTexture; // dynamic cubemap - int vsdctCubeTexture; // Virtual Shadow Depth Cubemap Texture - int grayCubeTexture; - int whiteCubeTexture; int skyboxTextures[6]; // skybox sides + int cinTexture; // cinematic texture int skytexturenum; // this not a gl_texturenum! int skyboxbasenum; // start with 5800 @@ -325,6 +311,7 @@ int GL_FindTexture( const char *name ); void GL_FreeTexture( GLenum texnum ); void GL_FreeImage( const char *name ); const char *GL_Target( GLenum target ); +void R_InitDlightTexture( void ); void R_TextureList_f( void ); void R_InitImages( void ); void R_ShutdownImages( void ); @@ -583,6 +570,8 @@ typedef struct GLint max_vertex_uniforms; GLint max_vertex_attribs; + GLint max_multisamples; + int color_bits; int alpha_bits; int depth_bits; @@ -641,6 +630,7 @@ extern convar_t *gl_texture_lodbias; extern convar_t *gl_texture_nearest; extern convar_t *gl_lightmap_nearest; extern convar_t *gl_keeptjunctions; +extern convar_t *gl_round_down; extern convar_t *gl_detailscale; extern convar_t *gl_wireframe; extern convar_t *gl_polyoffset; diff --git a/engine/client/gl_rlight.c b/engine/client/gl_rlight.c index b8142376..9d9fd675 100644 --- a/engine/client/gl_rlight.c +++ b/engine/client/gl_rlight.c @@ -216,15 +216,15 @@ int R_CountSurfaceDlights( msurface_t *surf ) ======================================================================= */ -static float g_trace_fraction; static vec3_t g_trace_lightspot; +static float g_trace_fraction; /* ================= R_RecursiveLightPoint ================= */ -static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f, float p2f, colorVec *cv, const vec3_t start, const vec3_t end, qboolean debug ) +static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f, float p2f, colorVec *cv, const vec3_t start, const vec3_t end ) { float front, back, frac, midf; int i, map, side, size; @@ -249,7 +249,7 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f, side = front < 0; if(( back < 0 ) == side ) - return R_RecursiveLightPoint( model, node->children[side], p1f, p2f, cv, start, end, debug ); + return R_RecursiveLightPoint( model, node->children[side], p1f, p2f, cv, start, end ); frac = front / ( front - back ); @@ -257,7 +257,7 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f, midf = p1f + ( p2f - p1f ) * frac; // co down front side - if( R_RecursiveLightPoint( model, node->children[side], p1f, midf, cv, start, mid, debug )) + if( R_RecursiveLightPoint( model, node->children[side], p1f, midf, cv, start, mid )) return true; // hit something if(( back < 0 ) == side ) @@ -330,15 +330,7 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f, } // go down back side - return R_RecursiveLightPoint( model, node->children[!side], midf, p2f, cv, mid, end, debug ); -} - -int R_LightTraceFilter( physent_t *pe ) -{ - if( !pe || pe->solid != SOLID_BSP || pe->info == 0 ) - return 1; - - return 0; + return R_RecursiveLightPoint( model, node->children[!side], midf, p2f, cv, mid, end ); } /* @@ -354,6 +346,8 @@ colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot ) int i, maxEnts = 1; colorVec light, cv; + if( lspot ) VectorClear( lspot ); + if( cl.worldmodel && cl.worldmodel->lightdata ) { light.r = light.g = light.b = light.a = 0; @@ -391,7 +385,7 @@ colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot ) VectorClear( g_trace_lightspot ); g_trace_fraction = 1.0f; - if( !R_RecursiveLightPoint( pe->model, pnodes, 0.0f, 1.0f, &cv, start_l, end_l, lspot != NULL )) + if( !R_RecursiveLightPoint( pe->model, pnodes, 0.0f, 1.0f, &cv, start_l, end_l )) continue; // didn't hit anything if( g_trace_fraction < last_fraction ) diff --git a/engine/client/gl_rsurf.c b/engine/client/gl_rsurf.c index 7f02ee62..669e6044 100644 --- a/engine/client/gl_rsurf.c +++ b/engine/client/gl_rsurf.c @@ -624,10 +624,7 @@ static void LM_UploadBlock( qboolean dynamic ) height = gl_lms.allocated[i]; } - if( host.features & ENGINE_LARGE_LIGHTMAPS ) - GL_Bind( GL_TEXTURE0, tr.dlightTexture2 ); - else GL_Bind( GL_TEXTURE0, tr.dlightTexture ); - + GL_Bind( GL_TEXTURE0, tr.dlightTexture ); pglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, BLOCK_SIZE, height, GL_RGBA, GL_UNSIGNED_BYTE, gl_lms.lightmap_buffer ); } else @@ -878,10 +875,7 @@ void R_BlendLightmaps( void ) { LM_InitBlock(); - if( host.features & ENGINE_LARGE_LIGHTMAPS ) - GL_Bind( GL_TEXTURE0, tr.dlightTexture2 ); - else GL_Bind( GL_TEXTURE0, tr.dlightTexture ); - + GL_Bind( GL_TEXTURE0, tr.dlightTexture ); newsurf = gl_lms.dynamic_surfaces; for( surf = gl_lms.dynamic_surfaces; surf != NULL; surf = surf->info->lightmapchain ) @@ -2120,6 +2114,9 @@ void GL_BuildLightmaps( void ) tr.realframecount = 1; nColinElim = 0; + // setup the texture for dlights + R_InitDlightTexture(); + // setup all the lightstyles CL_RunLightStyles(); diff --git a/engine/client/gl_sprite.c b/engine/client/gl_sprite.c index b52c9033..0bb57f5b 100644 --- a/engine/client/gl_sprite.c +++ b/engine/client/gl_sprite.c @@ -28,6 +28,7 @@ GNU General Public License for more details. convar_t *r_sprite_lerping; convar_t *r_sprite_lighting; +char sprite_name[MAX_QPATH]; char group_suffix[8]; static uint r_texFlags = 0; static int sprite_version; @@ -67,12 +68,12 @@ static dframetype_t *R_SpriteLoadFrame( model_t *mod, void *pin, mspriteframe_t // build uinque frame name if( FBitSet( mod->flags, MODEL_CLIENT )) // it's a HUD sprite { - Q_snprintf( texname, sizeof( texname ), "#HUD/%s_%s_%i%i.spr", mod->name, group_suffix, num / 10, num % 10 ); + Q_snprintf( texname, sizeof( texname ), "#HUD/%s(%s:%i%i).spr", sprite_name, group_suffix, num / 10, num % 10 ); gl_texturenum = GL_LoadTexture( texname, pin, pinframe->width * pinframe->height * bytes, r_texFlags, NULL ); } else { - Q_snprintf( texname, sizeof( texname ), "#%s_%s_%i%i.spr", mod->name, group_suffix, num / 10, num % 10 ); + Q_snprintf( texname, sizeof( texname ), "#%s(%s:%i%i).spr", sprite_name, group_suffix, num / 10, num % 10 ); gl_texturenum = GL_LoadTexture( texname, pin, pinframe->width * pinframe->height * bytes, r_texFlags, NULL ); } @@ -223,6 +224,9 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui return; } + Q_strncpy( sprite_name, mod->name, sizeof( sprite_name )); + COM_StripExtension( sprite_name ); + if( numi == NULL ) { rgbdata_t *pal; @@ -273,15 +277,15 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui switch( frametype ) { case FRAME_SINGLE: - Q_strncpy( group_suffix, "one", sizeof( group_suffix )); + Q_strncpy( group_suffix, "frame", sizeof( group_suffix )); pframetype = R_SpriteLoadFrame( mod, pframetype + 1, &psprite->frames[i].frameptr, i ); break; case FRAME_GROUP: - Q_strncpy( group_suffix, "grp", sizeof( group_suffix )); + Q_strncpy( group_suffix, "group", sizeof( group_suffix )); pframetype = R_SpriteLoadGroup( mod, pframetype + 1, &psprite->frames[i].frameptr, i ); break; case FRAME_ANGLED: - Q_strncpy( group_suffix, "ang", sizeof( group_suffix )); + Q_strncpy( group_suffix, "angle", sizeof( group_suffix )); pframetype = R_SpriteLoadGroup( mod, pframetype + 1, &psprite->frames[i].frameptr, i ); break; } diff --git a/engine/client/gl_studio.c b/engine/client/gl_studio.c index 0f164033..7a0cbfba 100644 --- a/engine/client/gl_studio.c +++ b/engine/client/gl_studio.c @@ -1625,7 +1625,7 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight ) uint lnum; dlight_t *dl; - if( !plight || !ent ) + if( !plight || !ent || !ent->model ) return; if( !RI.drawWorld || r_fullbright->value || FBitSet( ent->curstate.effects, EF_FULLBRIGHT )) @@ -1643,16 +1643,7 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight ) VectorSet( lightDir, 0.0f, 0.0f, 1.0f ); else VectorSet( lightDir, 0.0f, 0.0f, -1.0f ); - if( ent == RI.currententity ) - { - int sequence = bound( 0, ent->curstate.sequence, m_pStudioHeader->numseq - 1 ); - mstudioseqdesc_t *pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + sequence; - - if( FBitSet( pseqdesc->flags, STUDIO_LIGHT_FROM_ROOT )) - Matrix3x4_OriginFromMatrix( g_studio.lighttransform[0], origin ); - else VectorCopy( ent->origin, origin ); - } - else VectorCopy( ent->origin, origin ); + VectorCopy( ent->origin, origin ); VectorSet( vecSrc, origin[0], origin[1], origin[2] - lightDir[2] * 8.0f ); light.r = light.g = light.b = light.a = 0; @@ -1762,9 +1753,9 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight ) VectorAdd( lightDir, dist, lightDir ); - finalLight[0] += LightToTexGamma( dl->color.r ) * ( add * 512.0f ); - finalLight[1] += LightToTexGamma( dl->color.g ) * ( add * 512.0f ); - finalLight[2] += LightToTexGamma( dl->color.b ) * ( add * 512.0f ); + finalLight[0] += LightToTexGamma( dl->color.r ) * ( add / 256.0f ) * 2.0f; + finalLight[1] += LightToTexGamma( dl->color.g ) * ( add / 256.0f ) * 2.0f; + finalLight[2] += LightToTexGamma( dl->color.b ) * ( add / 256.0f ) * 2.0f; } } @@ -3922,15 +3913,8 @@ void CL_InitStudioAPI( void ) if( !clgame.dllFuncs.pfnGetStudioModelInterface ) return; - Con_DPrintf( "InitStudioAPI " ); - if( clgame.dllFuncs.pfnGetStudioModelInterface( STUDIO_INTERFACE_VERSION, &pStudioDraw, &gStudioAPI )) - { - Con_DPrintf( "- ok\n" ); return; - } - - Con_DPrintf( "- failed\n" ); // NOTE: we always return true even if game interface was not correct // because we need Draw our StudioModels diff --git a/engine/client/gl_vidnt.c b/engine/client/gl_vidnt.c index e45b15b9..30cfbe6b 100644 --- a/engine/client/gl_vidnt.c +++ b/engine/client/gl_vidnt.c @@ -36,6 +36,8 @@ convar_t *gl_keeptjunctions; convar_t *gl_showtextures; convar_t *gl_detailscale; convar_t *gl_check_errors; +convar_t *gl_enable_msaa; +convar_t *gl_round_down; convar_t *gl_polyoffset; convar_t *gl_wireframe; convar_t *gl_finish; @@ -76,6 +78,10 @@ ref_globals_t tr; glconfig_t glConfig; glstate_t glState; glwstate_t glw_state; +static HWND hWndFake; +static HDC hDCFake; +static HGLRC hGLRCFake; +static qboolean debug_context; typedef enum { @@ -522,6 +528,10 @@ static void GL_SetDefaultState( void ) memset( &glState, 0, sizeof( glState )); GL_SetDefaultTexState (); + if( Sys_CheckParm( "-gldebug" ) && host_developer.value ) + debug_context = true; + else debug_context = false; + // init draw stack tr.draw_list = &tr.draw_stack[0]; tr.draw_stack_pos = 0; @@ -570,12 +580,12 @@ qboolean GL_CreateContext( void ) if(!( pwglMakeCurrent( glw_state.hDC, glw_state.hGLRC ))) return GL_DeleteContext(); - if( !Sys_CheckParm( "-gldebug" ) || !host_developer.value ) // debug bit kill the perfomance + if( !debug_context ) // debug bit kill the perfomance return true; pwglCreateContextAttribsARB = GL_GetProcAddress( "wglCreateContextAttribsARB" ); - if( pwglCreateContextAttribsARB != NULL ) + if( debug_context && pwglCreateContextAttribsARB != NULL ) { int attribs[] = { @@ -660,11 +670,50 @@ VID_ChoosePFD */ static int VID_ChoosePFD( PIXELFORMATDESCRIPTOR *pfd, int colorBits, int alphaBits, int depthBits, int stencilBits ) { - int pixelFormat = 0; + if( pwglChoosePixelFormat != NULL ) + { + UINT numPixelFormats; + int pixelFormat = 0; + int attribs[24]; + + attribs[0] = WGL_ACCELERATION_ARB; + attribs[1] = WGL_FULL_ACCELERATION_ARB; + attribs[2] = WGL_DRAW_TO_WINDOW_ARB; + attribs[3] = TRUE; + attribs[4] = WGL_SUPPORT_OPENGL_ARB; + attribs[5] = TRUE; + attribs[6] = WGL_DOUBLE_BUFFER_ARB; + attribs[7] = TRUE; + attribs[8] = WGL_PIXEL_TYPE_ARB; + attribs[9] = WGL_TYPE_RGBA_ARB; + attribs[10] = WGL_COLOR_BITS_ARB; + attribs[11] = colorBits; + attribs[12] = WGL_ALPHA_BITS_ARB; + attribs[13] = alphaBits; + attribs[14] = WGL_DEPTH_BITS_ARB; + attribs[15] = depthBits; + attribs[16] = WGL_STENCIL_BITS_ARB; + attribs[17] = stencilBits; + attribs[18] = WGL_SAMPLE_BUFFERS_ARB; + attribs[19] = 1; + attribs[20] = WGL_SAMPLES_ARB; + attribs[21] = bound( 2, (int)gl_enable_msaa->value, 16 ); + attribs[22] = 0; + attribs[23] = 0; + + pwglChoosePixelFormat( glw_state.hDC, attribs, NULL, 1, &pixelFormat, &numPixelFormats ); + + if( pixelFormat ) + { + attribs[0] = WGL_SAMPLES_ARB; + pwglGetPixelFormatAttribiv( glw_state.hDC, pixelFormat, 0, 1, attribs, &glConfig.max_multisamples ); + if( glConfig.max_multisamples <= 1 ) Con_DPrintf( S_WARN "MSAA is not allowed\n" ); - MsgDev( D_NOTE, "VID_ChoosePFD( color %i, alpha %i, depth %i, stencil %i )\n", colorBits, alphaBits, depthBits, stencilBits ); + return pixelFormat; + } + } - // Fill out the PFD + // fallback: fill out the PFD pfd->nSize = sizeof (PIXELFORMATDESCRIPTOR); pfd->nVersion = 1; pfd->dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER; @@ -699,15 +748,7 @@ static int VID_ChoosePFD( PIXELFORMATDESCRIPTOR *pfd, int colorBits, int alphaBi pfd->dwDamageMask = 0; // count PFDs - pixelFormat = ChoosePixelFormat( glw_state.hDC, pfd ); - - if( !pixelFormat ) - { - Con_Printf( S_ERROR "VID_ChoosePFD failed\n" ); - return 0; - } - - return pixelFormat; + return ChoosePixelFormat( glw_state.hDC, pfd ); } /* @@ -748,6 +789,125 @@ const char *VID_GetModeString( int vid_mode ) return NULL; // out of bounds } +/* +================= +VID_DestroyFakeWindow +================= +*/ +void VID_DestroyFakeWindow( void ) +{ + if( hGLRCFake ) + { + pwglMakeCurrent( NULL, NULL ); + pwglDeleteContext( hGLRCFake ); + hGLRCFake = NULL; + } + + if( hDCFake ) + { + ReleaseDC( hWndFake, hDCFake ); + hDCFake = NULL; + } + + if( hWndFake ) + { + DestroyWindow( hWndFake ); + UnregisterClass( "TestWindow", host.hInst ); + hWndFake = NULL; + } +} + +/* +================= +VID_CreateFakeWindow +================= +*/ +void VID_CreateFakeWindow( void ) +{ + WNDCLASSEX wndClass; + PIXELFORMATDESCRIPTOR pfd; + int pixelFormat; + + // MSAA disabled + if( !gl_enable_msaa->value ) + return; + + memset( &wndClass, 0, sizeof( WNDCLASSEX )); + hGLRCFake = NULL; + hWndFake = NULL; + hDCFake = NULL; + + // register the window class + wndClass.cbSize = sizeof( WNDCLASSEX ); + wndClass.lpfnWndProc = DefWindowProc; + wndClass.hInstance = host.hInst; + wndClass.lpszClassName = "TestWindow"; + + if( !RegisterClassEx( &wndClass )) + return; + + // Create the fake window + if(( hWndFake = CreateWindowEx( 0, "TestWindow", "Xash3D", 0, 0, 0, 100, 100, NULL, NULL, wndClass.hInstance, NULL )) == NULL ) + { + UnregisterClass( "TestWindow", wndClass.hInstance ); + return; + } + + // Get a DC for the fake window + if(( hDCFake = GetDC( hWndFake )) == NULL ) + { + VID_DestroyFakeWindow(); + return; + } + + // Choose a pixel format + memset( &pfd, 0, sizeof( PIXELFORMATDESCRIPTOR )); + + pfd.nSize = sizeof( PIXELFORMATDESCRIPTOR ); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.iLayerType = PFD_MAIN_PLANE; + pfd.cColorBits = 32; + pfd.cAlphaBits = 8; + pfd.cDepthBits = 24; + pfd.cStencilBits = 8; + + if(( pixelFormat = ChoosePixelFormat( hDCFake, &pfd )) == 0 ) + { + VID_DestroyFakeWindow(); + return; + } + + // Set the pixel format + if( !SetPixelFormat( hDCFake, pixelFormat, &pfd )) + { + VID_DestroyFakeWindow(); + return; + } + + // Create the fake GL context + if(( hGLRCFake = pwglCreateContext( hDCFake )) == NULL ) + { + VID_DestroyFakeWindow(); + return; + } + + // Make the fake GL context current + if( !pwglMakeCurrent( hDCFake, hGLRCFake )) + { + VID_DestroyFakeWindow(); + return; + } + + // We only need these function pointers if available + pwglGetPixelFormatAttribiv = GL_GetProcAddress( "wglGetPixelFormatAttribivARB" ); + pwglChoosePixelFormat = GL_GetProcAddress( "wglChoosePixelFormatARB" ); + + // destory now it's no longer needed + VID_DestroyFakeWindow(); +} + /* ================= GL_SetPixelformat @@ -756,9 +916,11 @@ GL_SetPixelformat qboolean GL_SetPixelformat( void ) { PIXELFORMATDESCRIPTOR PFD; + int colorBits = 32; int alphaBits = 8; int stencilBits = 8; int pixelFormat = 0; + int depthBits = 24; if(( glw_state.hDC = GetDC( host.hWnd )) == NULL ) return false; @@ -766,16 +928,22 @@ qboolean GL_SetPixelformat( void ) if( glw_state.desktopBitsPixel < 32 ) { // clear alphabits in case we in 16-bit mode + colorBits = glw_state.desktopBitsPixel; alphaBits = 0; } + else + { + // no reason to trying enable MSAA on a highcolor + VID_CreateFakeWindow(); + } // choose a pixel format - pixelFormat = VID_ChoosePFD( &PFD, 24, alphaBits, 32, stencilBits ); + pixelFormat = VID_ChoosePFD( &PFD, colorBits, alphaBits, depthBits, stencilBits ); if( !pixelFormat ) { // try again with default color/depth/stencil - pixelFormat = VID_ChoosePFD( &PFD, 24, 0, 32, 0 ); + pixelFormat = VID_ChoosePFD( &PFD, colorBits, 0, depthBits, 0 ); if( !pixelFormat ) { @@ -820,7 +988,7 @@ qboolean GL_SetPixelformat( void ) else glState.stencilEnabled = false; // print out PFD specifics - MsgDev( D_NOTE, "GL PFD: color( %d-bits ) alpha( %d-bits ) Z( %d-bit )\n", PFD.cColorBits, PFD.cAlphaBits, PFD.cDepthBits ); + Con_Reportf( "PixelFormat: color: %d-bit, Z-Buffer: %d-bit, stencil: %d-bit\n", PFD.cColorBits, PFD.cDepthBits, PFD.cStencilBits ); return true; } @@ -938,7 +1106,6 @@ qboolean VID_CreateWindow( int width, int height, qboolean fullscreen ) GetWindowRect(WindowHandle, &WindowRect); WindowHeight = WindowRect.bottom - WindowRect.top; #endif - if( !fullscreen ) { x = window_xpos->value; @@ -1272,7 +1439,7 @@ qboolean R_Init_OpenGL( void ) if( !opengl_dll.link ) return false; - if( Sys_CheckParm( "-gldebug" ) && host_developer.value ) + if( debug_context || gl_enable_msaa->value ) GL_CheckExtension( "OpenGL Internal ProcAddress", wglproc_funcs, NULL, GL_WGL_PROCADDRESS ); return VID_SetMode(); @@ -1313,6 +1480,9 @@ static void GL_SetDefaults( void ) pglDepthFunc( GL_LEQUAL ); pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); + if( glConfig.max_multisamples > 1 ) + pglEnable( GL_MULTISAMPLE_ARB ); + if( glState.stencilEnabled ) { pglDisable( GL_STENCIL_TEST ); @@ -1420,6 +1590,7 @@ void GL_InitCommands( void ) window_ypos = Cvar_Get( "_window_ypos", "48", FCVAR_RENDERINFO, "window position by vertical" ); gl_extensions = Cvar_Get( "gl_allow_extensions", "1", FCVAR_GLCONFIG, "allow gl_extensions" ); + gl_enable_msaa = Cvar_Get( "gl_enable_msaa", "4", FCVAR_GLCONFIG, "enable multisample anti-aliasing" ); gl_texture_nearest = Cvar_Get( "gl_texture_nearest", "0", FCVAR_ARCHIVE, "disable texture filter" ); gl_lightmap_nearest = Cvar_Get( "gl_lightmap_nearest", "0", FCVAR_ARCHIVE, "disable lightmap filter" ); gl_check_errors = Cvar_Get( "gl_check_errors", "1", FCVAR_ARCHIVE, "ignore video engine errors" ); @@ -1434,6 +1605,7 @@ void GL_InitCommands( void ) gl_clear = Cvar_Get( "gl_clear", "0", FCVAR_ARCHIVE, "clearing screen after each frame" ); gl_test = Cvar_Get( "gl_test", "0", 0, "engine developer cvar for quick testing new features" ); gl_wireframe = Cvar_Get( "gl_wireframe", "0", FCVAR_ARCHIVE|FCVAR_SPONLY, "show wireframe overlay" ); + gl_round_down = Cvar_Get( "gl_round_down", "2", FCVAR_RENDERINFO, "round texture sizes to nearest POT value" ); // these cvar not used by engine but some mods requires this gl_polyoffset = Cvar_Get( "gl_polyoffset", "2.0", FCVAR_ARCHIVE, "polygon offset for decals" ); @@ -1502,7 +1674,7 @@ void GL_InitExtensions( void ) else glConfig.hardware_type = GLHW_GENERIC; // initalize until base opengl functions loaded (old-context) - if( !Sys_CheckParm( "-gldebug" ) || !host_developer.value ) + if( !debug_context && !gl_enable_msaa->value ) GL_CheckExtension( "OpenGL Internal ProcAddress", wglproc_funcs, NULL, GL_WGL_PROCADDRESS ); // windows-specific extensions diff --git a/engine/client/gl_warp.c b/engine/client/gl_warp.c index 413619cf..d9ba91c8 100644 --- a/engine/client/gl_warp.c +++ b/engine/client/gl_warp.c @@ -383,7 +383,7 @@ void R_DrawSkyBox( void ) if( tr.skyboxTextures[r_skyTexOrder[i]] ) GL_Bind( GL_TEXTURE0, tr.skyboxTextures[r_skyTexOrder[i]] ); - else GL_Bind( GL_TEXTURE0, tr.skyTexture ); // stub + else GL_Bind( GL_TEXTURE0, tr.grayTexture ); // stub pglBegin( GL_QUADS ); MakeSkyVec( RI.skyMins[0][i], RI.skyMins[1][i], i ); diff --git a/engine/common/filesystem.c b/engine/common/filesystem.c index 2093b981..0b8cb225 100644 --- a/engine/common/filesystem.c +++ b/engine/common/filesystem.c @@ -1367,12 +1367,12 @@ void FS_Init( void ) if( FS_CheckNastyPath( fs_basedir, true )) { // this is completely fatal... - Sys_Error( "FS_Init: invalid base directory \"%s\"\n", fs_basedir ); + Sys_Error( "invalid base directory \"%s\"\n", fs_basedir ); } if( FS_CheckNastyPath( fs_gamedir, true )) { - MsgDev( D_ERROR, "FS_Init: invalid game directory \"%s\"\n", fs_gamedir ); + Con_Printf( S_ERROR "invalid game directory \"%s\"\n", fs_gamedir ); Q_strncpy( fs_gamedir, fs_basedir, sizeof( fs_gamedir )); // default dir } @@ -1388,7 +1388,7 @@ void FS_Init( void ) if( !hasGameDir ) { - MsgDev( D_ERROR, "FS_Init: game directory \"%s\" not exist\n", fs_gamedir ); + Con_Printf( S_ERROR "game directory \"%s\" not exist\n", fs_gamedir ); if( hasBaseDir ) Q_strncpy( fs_gamedir, fs_basedir, sizeof( fs_gamedir )); } @@ -1410,7 +1410,7 @@ void FS_Init( void ) stringlistfreecontents( &dirs ); } - MsgDev( D_NOTE, "FS_Init: done\n" ); + Con_Reportf( "FS_Init: done\n" ); } void FS_AllowDirectPaths( qboolean enable ) diff --git a/engine/common/host.c b/engine/common/host.c index 76b4365a..eeed4be4 100644 --- a/engine/common/host.c +++ b/engine/common/host.c @@ -361,7 +361,7 @@ void Host_InitDecals( void ) } if( t ) Mem_Free( t ); - Con_DPrintf( "InitDecals: %i decals\n", num_decals ); + Con_Reportf( "InitDecals: %i decals\n", num_decals ); } /* diff --git a/engine/common/keys.c b/engine/common/keys.c index 6af23bcc..65d2e527 100644 --- a/engine/common/keys.c +++ b/engine/common/keys.c @@ -750,8 +750,8 @@ void CL_CharEvent( int key ) if( cls.key_dest == key_console && !Con_Visible( )) { - if((char)key == ',' || (char)key == '?' ) - return; // don't pass ',' when we open the console + if((char)key == '`' || (char)key == '?' ) + return; // don't pass '`' when we open the console } // distribute the key down event to the apropriate handler diff --git a/engine/common/library.c b/engine/common/library.c index 410d5103..80bc2e02 100644 --- a/engine/common/library.c +++ b/engine/common/library.c @@ -786,7 +786,7 @@ void *COM_LoadLibrary( const char *dllname, int build_ordinals_table, qboolean d if( !hInst->hInstance ) { - Con_DPrintf( "LoadLibrary: Loading %s - failed\n", dllname ); + Con_Reportf( "LoadLibrary: Loading %s - failed\n", dllname ); COM_FreeLibrary( hInst ); return NULL; } @@ -796,13 +796,13 @@ void *COM_LoadLibrary( const char *dllname, int build_ordinals_table, qboolean d { if( !LibraryLoadSymbols( hInst )) { - Con_DPrintf( "LoadLibrary: Loading %s - failed\n", dllname ); + Con_Reportf( "LoadLibrary: Loading %s - failed\n", dllname ); COM_FreeLibrary( hInst ); return NULL; } } - Con_DPrintf( "LoadLibrary: Loading %s - ok\n", dllname ); + Con_Reportf( "LoadLibrary: Loading %s - ok\n", dllname ); return hInst; } diff --git a/engine/common/mod_local.h b/engine/common/mod_local.h index 9f1ebeb1..6b90872e 100644 --- a/engine/common/mod_local.h +++ b/engine/common/mod_local.h @@ -151,7 +151,6 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash ); model_t *Mod_ForName( const char *name, qboolean crash, qboolean trackCRC ); qboolean Mod_ValidateCRC( const char *name, CRC32_t crc ); void Mod_NeedCRC( const char *name, qboolean needCRC ); -void Mod_PurgeStudioCache( void ); void Mod_FreeUnused( void ); // diff --git a/engine/common/model.c b/engine/common/model.c index 4a57483c..5e88fbc7 100644 --- a/engine/common/model.c +++ b/engine/common/model.c @@ -23,7 +23,7 @@ GNU General Public License for more details. #include "gl_local.h" #include "features.h" #include "client.h" -#include "server.h" // LUMP_ error codes +#include "server.h" static model_info_t mod_crcinfo[MAX_MODELS]; static model_t mod_known[MAX_MODELS]; @@ -132,7 +132,7 @@ static void Mod_FreeModel( model_t *mod ) /* =============================================================================== - MODEL INITALIZE\SHUTDOWN + MODEL INITIALIZE\SHUTDOWN =============================================================================== */ @@ -156,11 +156,10 @@ Mod_FreeAll */ void Mod_FreeAll( void ) { - model_t *mod; int i; - for( i = 0, mod = mod_known; i < mod_numknown; i++, mod++ ) - Mod_FreeModel( mod ); + for( i = 0; i < mod_numknown; i++ ) + Mod_FreeModel( &mod_known[i] ); mod_numknown = 0; } @@ -232,7 +231,7 @@ model_t *Mod_FindName( const char *filename, qboolean trackCRC ) if( i == mod_numknown ) { if( mod_numknown == MAX_MODELS ) - Host_Error( "Mod_ForName: MAX_MODELS limit exceeded\n" ); + Host_Error( "MAX_MODELS limit exceeded (%d)\n", MAX_MODELS ); mod_numknown++; } @@ -255,7 +254,7 @@ Loads a model into the cache */ model_t *Mod_LoadModel( model_t *mod, qboolean crash ) { - char tempname[64]; + char tempname[MAX_QPATH]; long length = 0; qboolean loaded; byte *buf; @@ -364,7 +363,7 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash ) if( FBitSet( p->flags, FCRC_CHECKSUM_DONE )) { if( currentCRC != p->initialCRC ) - Host_Error( "Mod_ForName: %s has a bad checksum\n", tempname ); + Host_Error( "%s has a bad checksum\n", tempname ); } else { @@ -397,7 +396,7 @@ Mod_PurgeStudioCache free studio cache on change level ================== */ -void Mod_PurgeStudioCache( void ) +static void Mod_PurgeStudioCache( void ) { int i; diff --git a/engine/server/sv_client.c b/engine/server/sv_client.c index 75034e20..d8e14ad8 100644 --- a/engine/server/sv_client.c +++ b/engine/server/sv_client.c @@ -187,7 +187,7 @@ Determine if client is outside appropriate address range */ int SV_CheckIPRestrictions( netadr_t from ) { - if( !sv_lan.value ) + if( sv_lan.value ) { if( !NET_CompareClassBAdr( from, net_local ) && !NET_IsReservedAdr( from )) return 0; diff --git a/engine/server/sv_game.c b/engine/server/sv_game.c index 3e98688f..4e58ae1a 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -755,7 +755,9 @@ static char *SV_ReadEntityScript( const char *filename, int *flags ) ents = FS_LoadFile( entfilename, NULL, true ); } - if( !ents && lumplen >= 10 ) + // at least entities should contain "{ "classname" "worldspawn" }\0" + // for correct spawn the level + if( !ents && lumplen >= 32 ) { FS_Seek( f, lumpofs, SEEK_SET ); ents = Z_Malloc( lumplen + 1 ); diff --git a/engine/server/sv_save.c b/engine/server/sv_save.c index 9858c187..a8d9c045 100644 --- a/engine/server/sv_save.c +++ b/engine/server/sv_save.c @@ -2154,7 +2154,7 @@ qboolean SV_GetSaveComment( const char *savename, char *comment ) { int i, tag, size, nNumberOfFields, nFieldSize, tokenSize, tokenCount; char *pData, *pSaveData, *pFieldName, **pTokenList; - string name, description; + string mapName, description; file_t *f; if(( f = FS_Open( savename, "rb", true )) == NULL ) @@ -2197,7 +2197,7 @@ qboolean SV_GetSaveComment( const char *savename, char *comment ) return 0; } - name[0] = '\0'; + mapName[0] = '\0'; comment[0] = '\0'; FS_Read( f, &size, sizeof( int )); @@ -2276,7 +2276,7 @@ qboolean SV_GetSaveComment( const char *savename, char *comment ) } else if( !Q_stricmp( pFieldName, "mapName" )) { - Q_strncpy( name, pData, nFieldSize ); + Q_strncpy( mapName, pData, nFieldSize ); } // move to start of next field. @@ -2289,11 +2289,27 @@ qboolean SV_GetSaveComment( const char *savename, char *comment ) FS_Close( f ); // at least mapname should be filled - if( Q_strlen( name ) > 0 ) + if( Q_strlen( mapName ) > 0 ) { time_t fileTime; const struct tm *file_tm; string timestring; + int flags; + + // now check for map problems + flags = SV_MapIsValid( mapName, GI->sp_entity, NULL ); + + if( FBitSet( flags, MAP_INVALID_VERSION )) + { + Q_strncpy( comment, va( "", mapName ), MAX_STRING ); + return 0; + } + + if( !FBitSet( flags, MAP_IS_EXIST )) + { + Q_strncpy( comment, va( "", mapName ), MAX_STRING ); + return 0; + } fileTime = FS_FileTime( savename, true ); file_tm = localtime( &fileTime ); diff --git a/engine/studio.h b/engine/studio.h index 2442b397..233f08ff 100644 --- a/engine/studio.h +++ b/engine/studio.h @@ -103,7 +103,6 @@ Studio models are position independent, so the cache manager can move them. // sequence flags #define STUDIO_LOOPING 0x0001 -#define STUDIO_LIGHT_FROM_ROOT 0x8000 // get lighting point from root bonepos not from entity origin // bone flags #define STUDIO_HAS_NORMALS 0x0001