diff --git a/engine/client/cl_game.c b/engine/client/cl_game.c index 7b32838c..e2008490 100644 --- a/engine/client/cl_game.c +++ b/engine/client/cl_game.c @@ -1495,14 +1495,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 ); @@ -1513,50 +1532,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; } /* @@ -3624,6 +3641,7 @@ static event_api_t gEventApi = pfnGetMoveVars, CL_VisTraceLine, pfnGetVisent, + CL_TestLine, }; static demo_api_t gDemoApi = @@ -3897,7 +3915,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 43af15b4..c5f1068e 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 a4a0a97a..0ce8b5ef 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 6de3492b..97121f1f 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 ca5b8e79..1bcff008 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); @@ -1279,5 +1332,4 @@ void ( APIENTRY *pglGenVertexArrays )( GLsizei n, const GLuint *arrays ); GLboolean ( APIENTRY *pglIsVertexArray )( GLuint array ); void ( APIENTRY * pglSwapInterval) ( int interval ); extern void *pglGetProcAddress( const GLubyte * ); - #endif//GL_EXPORT_H diff --git a/engine/client/gl_image.c b/engine/client/gl_image.c index be1b873d..7d6882c5 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.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; - - 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.width = BLOCK_SIZE; + r_image.height = BLOCK_SIZE; 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 = NULL; - 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 11c62abc..16020102 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 ); @@ -573,6 +560,8 @@ typedef struct GLint max_vertex_uniforms; GLint max_vertex_attribs; + GLint max_multisamples; + int color_bits; int alpha_bits; int depth_bits; @@ -643,6 +632,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 f0c1f7d4..da2576ec 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( XASH_TEXTURE0, tr.dlightTexture2 ); - else GL_Bind( XASH_TEXTURE0, tr.dlightTexture ); - + GL_Bind( XASH_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( XASH_TEXTURE0, tr.dlightTexture2 ); - else GL_Bind( XASH_TEXTURE0, tr.dlightTexture ); - + GL_Bind( XASH_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 5eaccc93..f1188fd1 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 ad2bf0d1..9fb6151b 100644 --- a/engine/client/gl_studio.c +++ b/engine/client/gl_studio.c @@ -1384,7 +1384,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 )) @@ -1402,16 +1402,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; @@ -1521,9 +1512,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; } } @@ -3681,15 +3672,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_warp.c b/engine/client/gl_warp.c index 650b91f5..e9617792 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( XASH_TEXTURE0, tr.skyboxTextures[r_skyTexOrder[i]] ); - else GL_Bind( XASH_TEXTURE0, tr.skyTexture ); // stub + else GL_Bind( XASH_TEXTURE0, tr.grayTexture ); // stub pglBegin( GL_QUADS ); MakeSkyVec( RI.skyMins[0][i], RI.skyMins[1][i], i ); diff --git a/engine/client/keys.c b/engine/client/keys.c index 75739a80..c0a09bae 100644 --- a/engine/client/keys.c +++ b/engine/client/keys.c @@ -764,8 +764,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/client/vid_common.c b/engine/client/vid_common.c index 8722adc1..ee8e3613 100644 --- a/engine/client/vid_common.c +++ b/engine/client/vid_common.c @@ -62,6 +62,7 @@ convar_t *r_lockfrustum; convar_t *r_traceglow; convar_t *r_dynamic; convar_t *r_lightmap; +convar_t *gl_round_down; convar_t *vid_displayfrequency; convar_t *vid_fullscreen; @@ -452,7 +453,7 @@ void GL_InitCommands( void ) gl_wireframe = Cvar_Get( "gl_wireframe", "0", FCVAR_ARCHIVE|FCVAR_SPONLY, "show wireframe overlay" ); gl_msaa = Cvar_Get( "gl_msaa", "0", FCVAR_GLCONFIG, "MSAA samples. Use with caution, engine may fail with some values" ); gl_stencilbits = Cvar_Get( "gl_stencilbits", "8", FCVAR_GLCONFIG, "pixelformat stencil bits (0 - auto)" ); - + 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" ); diff --git a/engine/common/filesystem.c b/engine/common/filesystem.c index e1b223d2..f96b3052 100644 --- a/engine/common/filesystem.c +++ b/engine/common/filesystem.c @@ -1451,12 +1451,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 } @@ -1472,7 +1472,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 )); } @@ -1494,7 +1494,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 3b2e781f..61092fab 100644 --- a/engine/common/host.c +++ b/engine/common/host.c @@ -381,7 +381,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/mod_local.h b/engine/common/mod_local.h index e2a03229..47f9e207 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 58449cbc..d899f01f 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 "enginefeatures.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]; @@ -136,7 +136,7 @@ static void Mod_FreeModel( model_t *mod ) /* =============================================================================== - MODEL INITALIZE\SHUTDOWN + MODEL INITIALIZE\SHUTDOWN =============================================================================== */ @@ -160,11 +160,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; } @@ -236,7 +235,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++; } @@ -259,7 +258,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; @@ -373,7 +372,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 { @@ -406,7 +405,7 @@ Mod_PurgeStudioCache free studio cache on change level ================== */ -void Mod_PurgeStudioCache( void ) +static void Mod_PurgeStudioCache( void ) { int i; diff --git a/engine/platform/win32/win_lib.c b/engine/platform/win32/win_lib.c index 98991d65..76c3dc44 100644 --- a/engine/platform/win32/win_lib.c +++ b/engine/platform/win32/win_lib.c @@ -787,7 +787,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; } @@ -797,13 +797,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/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 4f7eb1f0..4667b585 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -757,7 +757,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 e6ebaaa9..a3f00995 100644 --- a/engine/server/sv_save.c +++ b/engine/server/sv_save.c @@ -2158,7 +2158,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 ) @@ -2201,7 +2201,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 )); @@ -2280,7 +2280,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. @@ -2293,11 +2293,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 c8cf431a..e88c0316 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