Browse Source

Apply Apr18 update

pull/2/head
mittorn 7 years ago
parent
commit
050d2a3d0f
  1. 56
      engine/client/cl_game.c
  2. 4
      engine/client/cl_parse.c
  3. 17
      engine/client/cl_tent.c
  4. 9
      engine/client/client.h
  5. 6
      engine/client/gl_alias.c
  6. 1
      engine/client/gl_draw.c
  7. 55
      engine/client/gl_export.h
  8. 484
      engine/client/gl_image.c
  9. 24
      engine/client/gl_local.h
  10. 22
      engine/client/gl_rlight.c
  11. 13
      engine/client/gl_rsurf.c
  12. 14
      engine/client/gl_sprite.c
  13. 26
      engine/client/gl_studio.c
  14. 210
      engine/client/gl_vidnt.c
  15. 2
      engine/client/gl_warp.c
  16. 8
      engine/common/filesystem.c
  17. 2
      engine/common/host.c
  18. 4
      engine/common/keys.c
  19. 6
      engine/common/library.c
  20. 1
      engine/common/mod_local.h
  21. 17
      engine/common/model.c
  22. 2
      engine/server/sv_client.c
  23. 4
      engine/server/sv_game.c
  24. 24
      engine/server/sv_save.c
  25. 1
      engine/studio.h

56
engine/client/cl_game.c

@ -1489,14 +1489,33 @@ for parsing half-life scripts - hud.txt etc @@ -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 ) @@ -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 = @@ -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 ) @@ -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

4
engine/client/cl_parse.c

@ -544,7 +544,7 @@ void CL_ParseStaticEntity( sizebuf_t *msg ) @@ -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 ) @@ -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();
}
}

17
engine/client/cl_tent.c

@ -2843,6 +2843,23 @@ void CL_AddEntityEffects( cl_entity_t *ent ) @@ -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;
}
}
/*

9
engine/client/client.h

@ -409,6 +409,13 @@ typedef struct @@ -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 @@ -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;

6
engine/client/gl_alias.c

@ -928,9 +928,9 @@ void R_AliasDynamicLight( cl_entity_t *ent, alight_t *plight ) @@ -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;
}
}

1
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 @@ -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 )

55
engine/client/gl_export.h

@ -806,6 +806,59 @@ typedef float GLmatrix[16]; @@ -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); @@ -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

484
engine/client/gl_image.c

@ -22,7 +22,7 @@ GNU General Public License for more details. @@ -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 @@ -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 @@ -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 @@ -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 ) @@ -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 ) @@ -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 @@ -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 ) @@ -2059,403 +2059,22 @@ static rgbdata_t *R_InitBlackTexture( texFlags_t *flags )
/*
==================
R_InitBlankBumpTexture
==================
*/
static rgbdata_t *R_InitBlankBumpTexture( 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] = 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
R_InitDlightTexture
==================
*/
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.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 )
void R_InitDlightTexture( void )
{
// 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;
if( tr.dlightTexture != 0 )
return; // already initialized
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.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 = 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.buffer = NULL;
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 ) @@ -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++ )
{

24
engine/client/gl_local.h

@ -165,31 +165,17 @@ typedef struct @@ -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 ); @@ -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 @@ -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; @@ -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;

22
engine/client/gl_rlight.c

@ -216,15 +216,15 @@ int R_CountSurfaceDlights( msurface_t *surf ) @@ -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, @@ -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, @@ -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, @@ -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 ) @@ -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 ) @@ -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 )

13
engine/client/gl_rsurf.c

@ -624,10 +624,7 @@ static void LM_UploadBlock( qboolean dynamic ) @@ -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 ) @@ -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 ) @@ -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();

14
engine/client/gl_sprite.c

@ -28,6 +28,7 @@ GNU General Public License for more details. @@ -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 @@ -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 @@ -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 @@ -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;
}

26
engine/client/gl_studio.c

@ -1625,7 +1625,7 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight ) @@ -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 ) @@ -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 ) @@ -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 ) @@ -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

210
engine/client/gl_vidnt.c

@ -36,6 +36,8 @@ convar_t *gl_keeptjunctions; @@ -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; @@ -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 ) @@ -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 ) @@ -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 @@ -660,11 +670,50 @@ VID_ChoosePFD
*/
static int VID_ChoosePFD( PIXELFORMATDESCRIPTOR *pfd, int colorBits, int alphaBits, int depthBits, int stencilBits )
{
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 @@ -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 ) @@ -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 @@ -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 ) @@ -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 ) @@ -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 ) @@ -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 ) @@ -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 ) @@ -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 ) @@ -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 ) @@ -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 ) @@ -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

2
engine/client/gl_warp.c

@ -383,7 +383,7 @@ void R_DrawSkyBox( void ) @@ -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 );

8
engine/common/filesystem.c

@ -1367,12 +1367,12 @@ void FS_Init( void ) @@ -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 ) @@ -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 ) @@ -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 )

2
engine/common/host.c

@ -361,7 +361,7 @@ void Host_InitDecals( void ) @@ -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 );
}
/*

4
engine/common/keys.c

@ -750,8 +750,8 @@ void CL_CharEvent( int key ) @@ -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

6
engine/common/library.c

@ -786,7 +786,7 @@ void *COM_LoadLibrary( const char *dllname, int build_ordinals_table, qboolean d @@ -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 @@ -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;
}

1
engine/common/mod_local.h

@ -151,7 +151,6 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash ); @@ -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 );
//

17
engine/common/model.c

@ -23,7 +23,7 @@ GNU General Public License for more details. @@ -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 ) @@ -132,7 +132,7 @@ static void Mod_FreeModel( model_t *mod )
/*
===============================================================================
MODEL INITALIZE\SHUTDOWN
MODEL INITIALIZE\SHUTDOWN
===============================================================================
*/
@ -156,11 +156,10 @@ Mod_FreeAll @@ -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 ) @@ -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 @@ -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 ) @@ -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 @@ -397,7 +396,7 @@ Mod_PurgeStudioCache
free studio cache on change level
==================
*/
void Mod_PurgeStudioCache( void )
static void Mod_PurgeStudioCache( void )
{
int i;

2
engine/server/sv_client.c

@ -187,7 +187,7 @@ Determine if client is outside appropriate address range @@ -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;

4
engine/server/sv_game.c

@ -755,7 +755,9 @@ static char *SV_ReadEntityScript( const char *filename, int *flags ) @@ -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 );

24
engine/server/sv_save.c

@ -2154,7 +2154,7 @@ qboolean SV_GetSaveComment( const char *savename, char *comment ) @@ -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 ) @@ -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 ) @@ -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 ) @@ -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( "<map %s has invalid format>", mapName ), MAX_STRING );
return 0;
}
if( !FBitSet( flags, MAP_IS_EXIST ))
{
Q_strncpy( comment, va( "<map %s is missed>", mapName ), MAX_STRING );
return 0;
}
fileTime = FS_FileTime( savename, true );
file_tm = localtime( &fileTime );

1
engine/studio.h

@ -103,7 +103,6 @@ Studio models are position independent, so the cache manager can move them. @@ -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

Loading…
Cancel
Save