20 Jul 2010

This commit is contained in:
g-cont 2010-07-20 00:00:00 +04:00 committed by Alibek Omarov
parent 51786687dc
commit 78ae49f588
27 changed files with 2716 additions and 2745 deletions

View File

@ -1,109 +1,4 @@
const unsigned char net_png[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00,
0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
0x00, 0x20, 0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a, 0xf4,
0x00, 0x00, 0x00, 0x3f, 0x74, 0x45, 0x58, 0x74, 0x47, 0x65, 0x6e,
0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x00, 0x47,
0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79,
0x20, 0x74, 0x68, 0x65, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f,
0x70, 0x65, 0x72, 0x27, 0x73, 0x20, 0x49, 0x6d, 0x61, 0x67, 0x65,
0x20, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x20, 0x28, 0x44,
0x65, 0x76, 0x49, 0x4c, 0x29, 0x3e, 0xf9, 0x5b, 0xf1, 0x00, 0x00,
0x00, 0x0e, 0x74, 0x45, 0x58, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f,
0x72, 0x27, 0x73, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0xa7, 0x54,
0x77, 0xc3, 0x00, 0x00, 0x00, 0x12, 0x74, 0x45, 0x58, 0x74, 0x41,
0x75, 0x74, 0x68, 0x6f, 0x72, 0x27, 0x73, 0x20, 0x63, 0x6f, 0x6d,
0x6d, 0x65, 0x6e, 0x74, 0x73, 0x00, 0x57, 0x30, 0xab, 0x86, 0x00,
0x00, 0x03, 0xa5, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0xc5, 0x97,
0xbf, 0x6b, 0x1c, 0x39, 0x14, 0xc7, 0xbf, 0x36, 0xc2, 0x08, 0x33,
0x04, 0x11, 0x96, 0xb0, 0x84, 0x29, 0x44, 0x58, 0xc2, 0x16, 0x26,
0x4c, 0xe1, 0xc2, 0x45, 0x0a, 0x13, 0x4c, 0x6a, 0xff, 0x01, 0x29,
0x52, 0xa4, 0xc8, 0x9f, 0x90, 0xf2, 0x8a, 0x14, 0x29, 0x52, 0xa4,
0xbc, 0x72, 0xff, 0x80, 0x2b, 0x4c, 0x48, 0x71, 0x1c, 0x5b, 0x0c,
0xc6, 0xc5, 0x16, 0x57, 0x0c, 0x21, 0x45, 0x8a, 0x65, 0x51, 0x31,
0x98, 0x21, 0x0c, 0x46, 0x84, 0x61, 0x11, 0x46, 0x5c, 0x52, 0x68,
0x67, 0x34, 0x4f, 0x3b, 0xb3, 0x1b, 0xe2, 0xe4, 0xfc, 0x60, 0xd9,
0xd1, 0x1b, 0x49, 0xef, 0xa3, 0xf7, 0x43, 0x23, 0xed, 0x80, 0x8d,
0xbf, 0xa1, 0x2d, 0xd1, 0x90, 0x34, 0xb9, 0x25, 0x4d, 0x0c, 0x87,
0x86, 0x2a, 0xa0, 0x48, 0xcb, 0x68, 0x4d, 0xdb, 0x41, 0x77, 0x63,
0xa9, 0x82, 0x01, 0xc0, 0x9f, 0x93, 0xbf, 0x1b, 0x85, 0x36, 0x9c,
0x8e, 0x08, 0x00, 0x6c, 0xf5, 0x17, 0x5e, 0xbc, 0x7c, 0xe6, 0x27,
0xac, 0x28, 0x40, 0xf6, 0x6f, 0x16, 0x00, 0x84, 0xc0, 0x5e, 0x9e,
0x3f, 0x7b, 0x89, 0xdd, 0xde, 0xb7, 0xff, 0x93, 0xdc, 0x3a, 0x00,
0x03, 0x00, 0xc3, 0xbc, 0xdb, 0x39, 0x17, 0x30, 0xd7, 0x80, 0xb9,
0xae, 0x7b, 0x18, 0x12, 0x86, 0x48, 0x3c, 0x06, 0xda, 0x71, 0x0c,
0x5c, 0xcc, 0x79, 0xe0, 0xf2, 0x20, 0xe6, 0xa4, 0xbb, 0xe9, 0xf0,
0x40, 0x63, 0xb8, 0x99, 0x60, 0xf3, 0x0a, 0x6e, 0x2a, 0x2c, 0x54,
0xf0, 0x3d, 0x0f, 0xd1, 0x3c, 0xb3, 0x15, 0x88, 0xed, 0x1a, 0xe1,
0x24, 0x4d, 0xa7, 0x00, 0x80, 0xe2, 0x4b, 0x41, 0xf4, 0x66, 0x49,
0x3d, 0x30, 0x1e, 0x1f, 0x6c, 0x06, 0xe8, 0x34, 0xde, 0xd0, 0xf5,
0xad, 0xc3, 0x03, 0xac, 0x95, 0x5d, 0x4b, 0x91, 0x24, 0xd4, 0xb8,
0x03, 0xb0, 0x82, 0x8e, 0xfa, 0xcf, 0xd7, 0x31, 0x67, 0x40, 0x53,
0xe7, 0x2b, 0x90, 0x81, 0x28, 0xd0, 0x2e, 0x75, 0x5d, 0xb8, 0x15,
0xcf, 0x2e, 0x5c, 0xf9, 0x29, 0xa5, 0x21, 0x06, 0x1c, 0x66, 0x69,
0xc1, 0xf7, 0x19, 0x74, 0xe9, 0xe7, 0x1e, 0x8d, 0x0e, 0xa0, 0xab,
0x96, 0x2d, 0xd6, 0xeb, 0x50, 0x2a, 0x52, 0xfa, 0xe7, 0x64, 0x24,
0xfb, 0xba, 0x79, 0xa8, 0x95, 0x51, 0xb3, 0xdc, 0x9e, 0x40, 0xbd,
0x65, 0x38, 0xb8, 0x67, 0x30, 0xb8, 0x67, 0x20, 0x25, 0xc8, 0x8a,
0xf3, 0x4b, 0xdd, 0xf9, 0xfc, 0xb3, 0xb2, 0xe6, 0x81, 0xf1, 0x41,
0xb0, 0x95, 0x56, 0xee, 0xbf, 0x86, 0xa8, 0xb7, 0xda, 0xf8, 0xbe,
0x40, 0x7c, 0x5f, 0x40, 0x17, 0x37, 0x83, 0x60, 0x60, 0x06, 0x22,
0xf2, 0x99, 0x2b, 0x07, 0xfe, 0x5b, 0xa0, 0x16, 0x19, 0xcc, 0x35,
0x07, 0x6f, 0x25, 0xdf, 0x58, 0x0a, 0x07, 0x54, 0x69, 0xe8, 0xb2,
0x80, 0x2e, 0x14, 0x00, 0x20, 0x39, 0x3c, 0xc4, 0xd9, 0xd9, 0x14,
0x42, 0xd0, 0x4c, 0xd5, 0xad, 0xfc, 0x8a, 0xe3, 0x01, 0x74, 0xd9,
0x02, 0xb6, 0x1d, 0x1e, 0x50, 0x0b, 0x97, 0x4c, 0xf2, 0x41, 0x02,
0xf9, 0x20, 0x81, 0xae, 0xaa, 0xa0, 0x47, 0xe9, 0x0c, 0x97, 0x05,
0x44, 0x0b, 0xf6, 0xf4, 0xf4, 0x04, 0xa7, 0xa7, 0x27, 0xf8, 0xf0,
0x3e, 0xc5, 0xf4, 0x9f, 0x94, 0x8c, 0x78, 0xf3, 0xfa, 0x55, 0xaf,
0x07, 0x3a, 0x73, 0x40, 0x2d, 0x32, 0x0f, 0x12, 0xc7, 0xcd, 0x0f,
0x40, 0x63, 0x1c, 0x00, 0x01, 0xa8, 0xe5, 0xe4, 0xe9, 0x31, 0x6d,
0x3f, 0x79, 0xdc, 0x6b, 0xbc, 0x13, 0xa0, 0x5e, 0xb9, 0x5a, 0x64,
0x48, 0xa7, 0x13, 0xa4, 0xb3, 0x99, 0x83, 0xca, 0x73, 0xa8, 0x3c,
0xdf, 0x68, 0xbc, 0x96, 0x37, 0x6f, 0xff, 0xf8, 0x61, 0x80, 0x1d,
0x11, 0xf1, 0x6f, 0x69, 0x3a, 0x69, 0x14, 0xc3, 0x58, 0x34, 0xcf,
0xe9, 0xf9, 0x0c, 0xd5, 0xee, 0x21, 0x62, 0x39, 0x42, 0xae, 0xe6,
0xc8, 0xd5, 0x1c, 0x52, 0xfa, 0xf7, 0x6a, 0xa1, 0x80, 0xaf, 0x39,
0x84, 0x88, 0x1a, 0x1d, 0xbf, 0x23, 0x20, 0xee, 0x0a, 0xa8, 0xb9,
0x6a, 0x40, 0x75, 0x59, 0x42, 0x97, 0x25, 0x00, 0xba, 0xb3, 0xbf,
0x7d, 0x37, 0xe9, 0xdf, 0x07, 0xd2, 0xf3, 0x19, 0xd2, 0xf3, 0x19,
0x86, 0x52, 0x34, 0x00, 0xb1, 0x1c, 0x01, 0x70, 0x13, 0xa5, 0xd3,
0xd4, 0x19, 0x60, 0x86, 0x00, 0xd4, 0x22, 0x57, 0xfb, 0x85, 0xd6,
0xfd, 0xe7, 0x01, 0xa0, 0x23, 0x09, 0x6b, 0xc3, 0x6d, 0xf1, 0xc6,
0x41, 0x8c, 0x77, 0x89, 0xbe, 0xd2, 0x41, 0xbb, 0x6a, 0x56, 0xbf,
0x15, 0x60, 0x32, 0x39, 0x83, 0x41, 0x7f, 0x5d, 0xe7, 0x6a, 0x0e,
0x35, 0xa7, 0x27, 0x9e, 0xae, 0xd5, 0xb7, 0x21, 0x48, 0xd9, 0x75,
0x01, 0x18, 0x08, 0x9c, 0xcd, 0x5c, 0x62, 0x7d, 0xca, 0x2d, 0x2c,
0x3f, 0x06, 0x00, 0x24, 0x8f, 0x5c, 0xd6, 0x1b, 0x44, 0x98, 0x2b,
0x17, 0xb9, 0x2c, 0x1b, 0x82, 0xf3, 0x71, 0x33, 0x38, 0x16, 0x16,
0x51, 0x54, 0xc0, 0x5a, 0x1f, 0x59, 0xb6, 0x4b, 0x9d, 0x2a, 0x04,
0x50, 0x5c, 0xf9, 0x36, 0x6f, 0xa5, 0x3d, 0x67, 0xc2, 0x79, 0xe0,
0x62, 0x7a, 0xb1, 0x91, 0x32, 0x94, 0x58, 0x58, 0xf2, 0x7f, 0x13,
0xe9, 0xfd, 0x16, 0x64, 0x1f, 0x73, 0x24, 0x8f, 0x62, 0x24, 0x89,
0xdb, 0xd9, 0xb2, 0xac, 0xb5, 0xa3, 0x09, 0xfb, 0x4b, 0x8c, 0x03,
0x1b, 0xbe, 0x86, 0x75, 0x08, 0xb2, 0xcc, 0x10, 0xe3, 0x00, 0x90,
0x6b, 0x3f, 0xcc, 0xda, 0x01, 0x79, 0x17, 0x1e, 0xbb, 0xc5, 0x1e,
0x0d, 0x41, 0xb1, 0xf8, 0x4c, 0x01, 0x8c, 0x91, 0xb0, 0xac, 0x75,
0xcc, 0xb6, 0xae, 0xce, 0xcb, 0x2b, 0x0e, 0xa5, 0x38, 0x66, 0xd9,
0x10, 0x30, 0xab, 0x44, 0xe2, 0x02, 0x06, 0xc7, 0x28, 0x2e, 0x73,
0xd7, 0x77, 0x99, 0x03, 0x41, 0x95, 0x31, 0x46, 0xbf, 0x05, 0x55,
0x70, 0x6c, 0x37, 0xa5, 0x9b, 0x5f, 0x3e, 0x3c, 0x82, 0xb1, 0xef,
0xfa, 0x3d, 0x30, 0x57, 0x06, 0x73, 0x65, 0xc0, 0xeb, 0x63, 0x10,
0x17, 0xee, 0x07, 0x80, 0xef, 0xc7, 0x30, 0xcb, 0x1c, 0x7c, 0x3f,
0x06, 0xf6, 0x5a, 0x93, 0x7f, 0xcd, 0xd7, 0xe6, 0x89, 0x84, 0xf4,
0x30, 0x5a, 0x41, 0x3e, 0x3c, 0xa2, 0xc0, 0x7d, 0x00, 0x44, 0xb8,
0x58, 0x57, 0xed, 0xc7, 0xeb, 0xba, 0x3b, 0x31, 0x78, 0xe0, 0x92,
0x3a, 0x24, 0x95, 0x56, 0x2b, 0x18, 0x5a, 0x96, 0xdb, 0x01, 0x5a,
0x2b, 0xff, 0x1d, 0xc2, 0xc0, 0xe0, 0xce, 0xfe, 0x2b, 0x11, 0x91,
0x08, 0x7b, 0x80, 0x50, 0xaf, 0x25, 0xff, 0xe6, 0xad, 0xb6, 0x1e,
0x1b, 0xad, 0xce, 0x09, 0xe4, 0xda, 0x60, 0xf5, 0xed, 0xdf, 0x8c,
0x6e, 0x1d, 0x60, 0x07, 0xfc, 0x88, 0x5e, 0xcf, 0xed, 0xb6, 0x78,
0x87, 0x97, 0x83, 0x6d, 0x21, 0x08, 0xaf, 0x6a, 0xf4, 0xe2, 0xf2,
0x1d, 0x72, 0xf3, 0x92, 0x8e, 0x46, 0xd6, 0xb0, 0x55, 0x00, 0x00,
0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
const unsigned char blank_bmp[] = {
0x42, 0x4d, 0x76, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36,
0x04, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,

View File

@ -24,7 +24,6 @@ loadres_t load_resources[] =
// add new resource description here
{"blank.bmp", blank_bmp, sizeof(blank_bmp)},
{"default.dds", deffont_dds, sizeof(deffont_dds)},
{"net.png", net_png, sizeof(net_png)},
{NULL, NULL, 0 }
};

View File

@ -1,514 +0,0 @@
//=======================================================================
// Copyright XashXT Group 2008 ©
// cl_effects.c - entity effects parsing and management
//=======================================================================
#include "common.h"
#include "client.h"
#include "const.h"
/*
==============================================================
LIGHT STYLE MANAGEMENT
==============================================================
*/
typedef struct
{
int length;
float value[3];
float map[MAX_STRING];
} clightstyle_t;
clightstyle_t cl_lightstyle[MAX_LIGHTSTYLES];
static int lastofs;
/*
================
CL_ClearLightStyles
================
*/
void CL_ClearLightStyles( void )
{
Mem_Set( cl_lightstyle, 0, sizeof( cl_lightstyle ));
lastofs = -1;
}
/*
================
CL_RunLightStyles
light animations
'm' is normal light, 'a' is no light, 'z' is double bright
================
*/
void CL_RunLightStyles( void )
{
int i, ofs;
float l, oldval, curval;
clightstyle_t *ls;
if( cls.state != ca_active ) return;
ofs = (cl.time * 10);
if( !cl_lightstyle_lerping->integer )
{
if( ofs == lastofs ) return;
lastofs = ofs;
}
for( i = 0, ls = cl_lightstyle; i < MAX_LIGHTSTYLES; i++, ls++ )
{
if( ls->length == 0 ) l = 0.0f;
else if( ls->length == 1 ) l = ls->map[0];
else if( cl_lightstyle_lerping->integer )
{
int curnum = (ofs % ls->length);
int oldnum = curnum - 1;
// sequence is ends ?
if( oldnum < 0 )
oldnum += ls->length;
oldval = ls->map[oldnum];
curval = ls->map[curnum];
// don't lerping fast sequences
if( fabs( curval - oldval ) >= 1.0f ) l = curval;
else l = oldval + cl.lerpFrac * (curval - oldval);
}
else l = ls->map[ofs%ls->length];
VectorSet( ls->value, l, l, l );
}
}
void CL_SetLightstyle( int i )
{
char *s;
int j, k;
s = cl.configstrings[i+CS_LIGHTSTYLES];
j = com.strlen( s );
if( j >= MAX_STRING )
Host_Error("CL_SetLightStyle: lightstyle %s is too long\n", s );
cl_lightstyle[i].length = j;
for( k = 0; k < j; k++ )
cl_lightstyle[i].map[k] = (float)(s[k]-'a') / (float)('m'-'a');
}
/*
================
CL_AddLightStyles
================
*/
void CL_AddLightStyles( void )
{
int i;
clightstyle_t *ls;
for( i = 0, ls = cl_lightstyle; i < MAX_LIGHTSTYLES; i++, ls++ )
re->AddLightStyle( i, ls->value );
}
/*
==============================================================
DLIGHT MANAGEMENT
==============================================================
*/
struct dlight_s
{
vec3_t origin;
float radius;
byte color[3];
float die; // stop lighting after this time
float decay; // drop this each second
float minlight; // don't add when contributing less
int key;
bool dark; // subtracts light instead of adding
bool elight; // true when calls with CL_AllocElight
};
dlight_t cl_dlights[MAX_DLIGHTS];
/*
================
CL_ClearDlights
================
*/
void CL_ClearDlights( void )
{
Mem_Set( cl_dlights, 0, sizeof( cl_dlights ));
}
/*
===============
CL_AllocDlight
===============
*/
dlight_t *CL_AllocDlight( int key )
{
dlight_t *dl;
int i;
// first look for an exact key match
if( key )
{
for( i = 0, dl = cl_dlights; i < MAX_DLIGHTS; i++, dl++ )
{
if( dl->key == key )
{
// reuse this light
Mem_Set( dl, 0, sizeof( *dl ));
dl->key = key;
return dl;
}
}
}
// then look for anything else
for( i = 0, dl = cl_dlights; i < MAX_DLIGHTS; i++, dl++ )
{
if( dl->die < cl.time )
{
Mem_Set( dl, 0, sizeof( *dl ));
dl->key = key;
return dl;
}
}
// otherwise grab first dlight
dl = &cl_dlights[0];
Mem_Set( dl, 0, sizeof( *dl ));
dl->key = key;
return dl;
}
/*
===============
CL_AllocElight
===============
*/
dlight_t *CL_AllocElight( int key )
{
dlight_t *dl;
dl = CL_AllocDlight( key );
dl->elight = true;
return dl;
}
/*
===============
CL_AddDlight
copy dlight to renderer
===============
*/
bool CL_AddDlight( dlight_t *dl )
{
int flags = 0;
bool add;
if( dl->dark ) flags |= DLIGHT_DARK;
if( dl->elight ) flags |= DLIGHT_ONLYENTS;
add = re->AddDLight( dl->origin, dl->color, dl->radius, flags );
return add;
}
/*
===============
CL_AddDLights
===============
*/
void CL_AddDLights( void )
{
dlight_t *dl;
float time;
int i;
time = cl.time - cl.oldtime;
for( i = 0, dl = cl_dlights; i < MAX_DLIGHTS; i++, dl++ )
{
if( dl->die < cl.time || !dl->radius )
continue;
dl->radius -= time * dl->decay;
if( dl->radius < 0 ) dl->radius = 0;
CL_AddDlight( dl );
}
}
/*
================
CL_TestLights
if cl_testlights is set, create 32 lights models
================
*/
void CL_TestLights( void )
{
int i, j;
float f, r;
dlight_t dl;
if( !cl_testlights->integer ) return;
Mem_Set( &dl, 0, sizeof( dlight_t ));
for( i = 0; i < bound( 1, cl_testlights->integer, MAX_DLIGHTS ); i++ )
{
r = 64 * ( (i%4) - 1.5 );
f = 64 * (i/4) + 128;
for( j = 0; j < 3; j++ )
dl.origin[j] = cl.refdef.vieworg[j] + cl.refdef.forward[j] * f + cl.refdef.right[j] * r;
dl.color[0] = ((((i%6)+1) & 1)>>0) * 255;
dl.color[1] = ((((i%6)+1) & 2)>>1) * 255;
dl.color[2] = ((((i%6)+1) & 4)>>2) * 255;
dl.radius = 200;
if( !CL_AddDlight( &dl ))
break;
}
}
/*
==============================================================
DECAL MANAGEMENT
==============================================================
*/
/*
===============
CL_DecalShoot
normal temporary decal
===============
*/
void CL_DecalShoot( HSPRITE hDecal, int entityIndex, int modelIndex, float *pos, int flags )
{
rgba_t color;
Vector4Set( color, 255, 255, 255, 255 ); // don't use custom colors
if( re ) re->DecalShoot( hDecal, entityIndex, modelIndex, pos, NULL, flags, color, 0.0f, 0.0f );
}
/*
===============
CL_PlayerDecal
spray custom colored decal (clan logo etc)
===============
*/
void CL_PlayerDecal( HSPRITE hDecal, int entityIndex, float *pos, byte *color )
{
edict_t *pEnt;
int modelIndex = 0;
pEnt = CL_GetEdictByIndex( entityIndex );
if( CL_IsValidEdict( pEnt )) modelIndex = pEnt->v.modelindex;
if( re ) re->DecalShoot( hDecal, entityIndex, modelIndex, pos, NULL, FDECAL_CUSTOM, color, 0.0f, 0.0f );
}
/*
===============
CL_LightForPoint
get lighting color for specified point
===============
*/
void CL_LightForPoint( const vec3_t point, vec3_t ambientLight )
{
if( re ) re->LightForPoint( point, ambientLight );
else VectorClear( ambientLight );
}
/*
===============
CL_ResetEvent
===============
*/
void CL_ResetEvent( event_info_t *ei )
{
Mem_Set( ei, 0, sizeof( *ei ));
}
word CL_PrecacheEvent( const char *name )
{
int i;
if( !name || !name[0] ) return 0;
for( i = 1; i < MAX_EVENTS && cl.configstrings[CS_EVENTS+i][0]; i++ )
if( !com.strcmp( cl.configstrings[CS_EVENTS+i], name ))
return i;
return 0;
}
bool CL_FireEvent( event_info_t *ei )
{
user_event_t *ev;
const char *name;
int i;
if( !ei || !ei->index )
return false;
// get the func pointer
for( i = 0; i < MAX_EVENTS; i++ )
{
ev = clgame.events[i];
if( !ev ) break;
if( ev->index == ei->index )
{
if( ev->func )
{
ev->func( &ei->args );
return true;
}
name = cl.configstrings[CS_EVENTS+ei->index];
MsgDev( D_ERROR, "CL_FireEvent: %s not hooked\n", name );
break;
}
}
return false;
}
void CL_FireEvents( void )
{
int i;
event_state_t *es;
event_info_t *ei;
bool success;
es = &cl.events;
for( i = 0; i < MAX_EVENT_QUEUE; i++ )
{
ei = &es->ei[i];
if( ei->index == 0 )
continue;
if( cls.state == ca_disconnected )
{
CL_ResetEvent( ei );
continue;
}
// delayed event!
if( ei->fire_time && ( ei->fire_time > clgame.globals->time ))
continue;
success = CL_FireEvent( ei );
// zero out the remaining fields
CL_ResetEvent( ei );
}
}
event_info_t *CL_FindEmptyEvent( void )
{
int i;
event_state_t *es;
event_info_t *ei;
es = &cl.events;
// look for first slot where index is != 0
for( i = 0; i < MAX_EVENT_QUEUE; i++ )
{
ei = &es->ei[i];
if( ei->index != 0 )
continue;
return ei;
}
// no slots available
return NULL;
}
event_info_t *CL_FindUnreliableEvent( void )
{
int i;
event_state_t *es;
event_info_t *ei;
es = &cl.events;
for ( i = 0; i < MAX_EVENT_QUEUE; i++ )
{
ei = &es->ei[i];
if( ei->index != 0 )
{
// it's reliable, so skip it
if( ei->flags & FEV_RELIABLE )
continue;
}
return ei;
}
// this should never happen
return NULL;
}
void CL_QueueEvent( int flags, int index, float delay, event_args_t *args )
{
bool unreliable = (flags & FEV_RELIABLE) ? false : true;
event_info_t *ei;
// find a normal slot
ei = CL_FindEmptyEvent();
if( !ei && unreliable )
{
return;
}
// okay, so find any old unreliable slot
if( !ei )
{
ei = CL_FindUnreliableEvent();
if( !ei ) return;
}
ei->index = index;
ei->fire_time = delay ? (clgame.globals->time + delay) : 0.0f;
ei->flags = flags;
// copy in args event data
Mem_Copy( &ei->args, args, sizeof( ei->args ));
}
/*
==============
CL_ClearEffects
==============
*/
void CL_ClearEffects( void )
{
CL_ClearDlights ();
CL_ClearLightStyles ();
}

View File

@ -341,7 +341,6 @@ void CL_AddEntities( void )
CL_AddLightStyles();
// perfomance test
CL_TestEntities();
CL_TestLights();
}

View File

@ -229,55 +229,65 @@ void CL_FadeAlpha( int starttime, int endtime, rgba_t color )
/*
=============
CL_DrawCenterPrint
CL_AdjustXPos
called each frame
adjust text by x pos
=============
*/
void CL_DrawCenterPrint( void )
static int CL_AdjustXPos( float x, int width, int totalWidth )
{
char *start;
int l, x, y, w;
rgba_t color;
int xPos;
if( !re || !clgame.ds.centerPrintTime ) return;
CL_FadeAlpha( clgame.ds.centerPrintTime, scr_centertime->value * 1000, color );
if( *(int *)color == 0x00FFFFFF )
if( x == -1 )
{
// faded out
clgame.ds.centerPrintTime = 0;
return;
xPos = ( clgame.scrInfo.iWidth - width ) * 0.5f;
}
else
{
if ( x < 0 )
xPos = (1.0 + x) * clgame.scrInfo.iWidth - totalWidth; // Alight right
else // align left
xPos = x * clgame.scrInfo.iWidth;
}
re->SetColor( color );
start = clgame.ds.centerPrint;
y = clgame.ds.centerPrintY - clgame.ds.centerPrintLines * BIGCHAR_HEIGHT / 2;
if( xPos + width > clgame.scrInfo.iWidth )
xPos = clgame.scrInfo.iWidth - width;
else if( xPos < 0 )
xPos = 0;
while( 1 )
return xPos;
}
/*
=============
CL_AdjustYPos
adjust text by y pos
=============
*/
static int CL_AdjustYPos( float y, int height )
{
int yPos;
if( y == -1 ) // centered?
{
char linebuffer[1024];
for( l = 0; l < 50; l++ )
{
if( !start[l] || start[l] == '\n' )
break;
linebuffer[l] = start[l];
}
linebuffer[l] = 0;
w = clgame.ds.centerPrintCharWidth * com.cstrlen( linebuffer );
x = (SCREEN_WIDTH - w)>>1;
SCR_DrawStringExt( x, y, clgame.ds.centerPrintCharWidth, SMALLCHAR_HEIGHT, linebuffer, color, false );
y += clgame.ds.centerPrintCharWidth * 1.5;
while( *start && ( *start != '\n' )) start++;
if( !*start ) break;
start++;
yPos = ( clgame.scrInfo.iHeight - height ) * 0.5f;
}
re->SetColor( NULL );
else
{
// Alight bottom?
if( y < 0 )
yPos = (1.0 + y) * clgame.scrInfo.iHeight - height; // Alight bottom
else // align top
yPos = y * clgame.scrInfo.iHeight;
}
if( yPos + height > clgame.scrInfo.iHeight )
yPos = clgame.scrInfo.iHeight - height;
else if( yPos < 0 )
yPos = 0;
return yPos;
}
/*
@ -287,25 +297,35 @@ CL_CenterPrint
print centerscreen message
=============
*/
void CL_CenterPrint( const char *text, int y, int charWidth )
void CL_CenterPrint( const char *text, float y )
{
char *s;
int width = 0;
int length = 0;
com.strncpy( clgame.ds.centerPrint, text, sizeof( clgame.ds.centerPrint ));
clgame.ds.centerPrintTime = host.realtime * 1000;
clgame.ds.centerPrintCharWidth = charWidth;
clgame.ds.centerPrintY = y;
clgame.centerPrint.lines = 1;
clgame.centerPrint.totalWidth = 0;
clgame.centerPrint.time = host.realtime * 1000;
com.strncpy( clgame.centerPrint.message, text, sizeof( clgame.centerPrint.message ));
s = clgame.centerPrint.message;
// count the number of lines for centering
clgame.ds.centerPrintLines = 1;
s = clgame.ds.centerPrint;
while( *s )
{
if( *s == '\n' )
clgame.ds.centerPrintLines++;
{
clgame.centerPrint.lines++;
if( width > clgame.centerPrint.totalWidth )
clgame.centerPrint.totalWidth = width;
width = 0;
}
else width += clgame.scrInfo.charWidths[*s];
s++;
length++;
}
clgame.centerPrint.totalHeight = ( clgame.centerPrint.lines * clgame.scrInfo.iCharHeight );
clgame.centerPrint.y = CL_AdjustYPos( y, clgame.centerPrint.totalHeight );
}
/*
@ -443,6 +463,72 @@ static void SPR_DrawGeneric( int frame, float x, float y, float width, float hei
re->SetColor( NULL );
}
/*
=============
CL_DrawCenterPrint
called each frame
=============
*/
static void CL_DrawCenterPrint( void )
{
char *pText;
int i, j, x, y;
int width, lineLength;
byte line[80];
rgba_t color;
if( !clgame.centerPrint.time )
return;
CL_FadeAlpha( clgame.centerPrint.time, scr_centertime->value * 1000, color );
if( *(int *)color == 0x00FFFFFF )
{
// faded out
clgame.centerPrint.time = 0;
return;
}
pText = clgame.centerPrint.message;
y = clgame.centerPrint.y; // start y
for( i = 0; i < clgame.centerPrint.lines; i++ )
{
lineLength = 0;
width = 0;
while( *pText && *pText != '\n' )
{
byte c = *pText;
line[lineLength] = c;
width += clgame.scrInfo.charWidths[c];
lineLength++;
pText++;
}
pText++; // Skip LineFeed
line[lineLength] = 0;
x = CL_AdjustXPos( -1, width, clgame.centerPrint.totalWidth );
for( j = 0; j < lineLength; j++ )
{
int ch = line[j];
int next = x + clgame.scrInfo.charWidths[ch];
if( x >= 0 && y >= 0 && next <= clgame.scrInfo.iWidth )
{
re->SetColor( color );
clgame.ds.hSprite = clgame.creditsFont.hFontTexture;
re->SetParms( clgame.ds.hSprite, kRenderTransAdd, 0 );
SPR_DrawGeneric( 0, x, y, -1, -1, &clgame.creditsFont.fontRc[ch] );
}
x = next;
}
y += clgame.scrInfo.iCharHeight;
}
}
/*
====================
CL_InitTitles
@ -566,7 +652,7 @@ CL_DrawLoading
draw loading progress bar
=============
*/
void CL_DrawLoading( float percent )
static void CL_DrawLoading( float percent )
{
int x, y, width, height, right;
float xscale, yscale, step, s2;
@ -607,12 +693,28 @@ CL_DrawPause
draw pause sign
=============
*/
void CL_DrawPause( void )
static void CL_DrawPause( void )
{
int w, h;
int x, y, width, height;
float xscale, yscale;
re->GetParms( &w, &h, NULL, 0, cls.pauseIcon );
SCR_DrawPic((SCREEN_WIDTH - w)>>1, ( SCREEN_HEIGHT - h )>>1, w, h, cls.pauseIcon );
if( !re ) return;
re->GetParms( &width, &height, NULL, 0, cls.pauseIcon );
x = ( SCREEN_WIDTH - width ) >> 1;
y = ( SCREEN_HEIGHT - height ) >> 1;
xscale = scr_width->integer / 640.0f;
yscale = scr_height->integer / 480.0f;
x *= xscale;
y *= yscale;
width *= xscale;
height *= yscale;
re->SetColor( NULL );
re->SetParms( cls.pauseIcon, kRenderTransTexture, 0 );
re->DrawStretchPic( x, y, width, height, 0, 0, 1, 1, cls.pauseIcon );
}
void CL_DrawHUD( int state )
@ -1136,6 +1238,8 @@ static void pfnFillRGBA( int x, int y, int width, int height, int r, int g, int
re->SetColor( color );
SPR_AdjustSize( (float *)&x, (float *)&y, (float *)&width, (float *)&height );
re->SetParms( cls.fillShader, kRenderTransTexture, 0 );
re->DrawStretchPic( x, y, width, height, 0, 0, 1, 1, cls.fillShader );
re->SetColor( NULL );
}
@ -1453,7 +1557,7 @@ like trigger_multiple message in q1
static void pfnCenterPrint( const char *string )
{
if( !string || !*string ) return; // someone stupid joke
CL_CenterPrint( string, 160, SMALLCHAR_WIDTH );
CL_CenterPrint( string, -1 );
}
/*

View File

@ -446,6 +446,8 @@ static void pfnFillRGBA( int x, int y, int width, int height, int r, int g, int
re->SetColor( color );
PIC_AdjustSize( (float *)&x, (float *)&y, (float *)&width, (float *)&height );
re->SetParms( cls.fillShader, kRenderTransTexture, 0 );
re->DrawStretchPic( x, y, width, height, 0, 0, 1, 1, cls.fillShader );
re->SetColor( NULL );
}
@ -636,6 +638,16 @@ static void pfnSetPlayerModel( edict_t *ent, const char *path )
ent->v.model = re->RegisterModel( path, MAX_MODELS - 1 );
ent->v.modelindex = MAX_MODELS - 1;
// setup latched controllers state to avoid unexpected poses :)
ent->pvClientData->frame.curstate.controller[0] = 127;
ent->pvClientData->frame.curstate.controller[1] = 127;
ent->pvClientData->frame.curstate.controller[2] = 127;
ent->pvClientData->frame.curstate.controller[3] = 127;
ent->pvClientData->frame.latched.controller[0] = 127;
ent->pvClientData->frame.latched.controller[1] = 127;
ent->pvClientData->frame.latched.controller[2] = 127;
ent->pvClientData->frame.latched.controller[3] = 127;
}
/*

View File

@ -9,6 +9,8 @@
#include "const.h"
#include "pm_defs.h"
#define CONNECTION_PROBLEM_TIME 15.0
bool CL_IsPredicted( void )
{
edict_t *player = CL_GetLocalPlayer();
@ -98,6 +100,7 @@ During normal gameplay, a client packet will contain something like:
void CL_WritePacket( void )
{
sizebuf_t buf;
bool noDelta = false;
byte data[MAX_MSGLEN];
usercmd_t *cmd, *oldcmd;
usercmd_t nullcmd;
@ -118,6 +121,18 @@ void CL_WritePacket( void )
return;
}
if( cl_nodelta->integer || !cl.frame.valid || cls.demowaiting )
noDelta = true;
if(( cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged ) >= CMD_BACKUP )
{
if(( host.realtime - cls.netchan.last_received ) > CONNECTION_PROBLEM_TIME )
{
MsgDev( D_WARN, "^1 Connection Problem^7\n" );
noDelta = true; // request a fullupdate
}
}
// send a userinfo update if needed
if( userinfo->modified )
{
@ -137,8 +152,7 @@ void CL_WritePacket( void )
// let the server know what the last frame we
// got was, so the next message can be delta compressed
if( cl_nodelta->integer || !cl.frame.valid || cls.demowaiting )
MSG_WriteLong( &buf, -1 ); // no compression
if( noDelta ) MSG_WriteLong( &buf, -1 ); // no compression
else MSG_WriteLong( &buf, cl.frame.serverframe );
// send this and the previous cmds in the message, so

View File

@ -919,7 +919,7 @@ void CL_ParseServerMessage( sizebuf_t *msg )
MsgDev( D_INFO, "^6%s\n", MSG_ReadString( msg ));
break;
case svc_centerprint:
CL_CenterPrint( MSG_ReadString( msg ), 160, SMALLCHAR_WIDTH );
CL_CenterPrint( MSG_ReadString( msg ), 0.35f );
break;
case svc_setpause:
cl.refdef.paused = (MSG_ReadByte( msg ) != 0 );

View File

@ -14,7 +14,6 @@ cvar_t *scr_loading;
cvar_t *scr_download;
cvar_t *scr_width;
cvar_t *scr_height;
cvar_t *cl_testentities;
cvar_t *cl_testlights;
cvar_t *cl_allow_levelshots;
cvar_t *cl_levelshot_name;
@ -46,21 +45,6 @@ void SCR_AdjustSize( float *x, float *y, float *w, float *h )
if( h ) *h *= yscale;
}
/*
================
SCR_FillRect
Coordinates are 640*480 virtual values
=================
*/
void SCR_FillRect( float x, float y, float width, float height, const rgba_t color )
{
re->SetColor( color );
SCR_AdjustSize( &x, &y, &width, &height );
re->DrawStretchPic( x, y, width, height, 0, 0, 1, 1, cls.fillShader );
re->SetColor( NULL );
}
/*
================
SCR_DrawPic
@ -253,19 +237,6 @@ void SCR_DrawSmallStringExt( int x, int y, const char *string, rgba_t setColor,
re->SetColor( NULL );
}
/*
==============
SCR_DrawNet
==============
*/
void SCR_DrawNet( void )
{
if( cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged < CMD_BACKUP-1 )
return;
SCR_DrawPic( cl.refdef.viewport[0] + 64, cl.refdef.viewport[1], 48, 48, cls.netIcon );
}
/*
==============
SCR_DrawFPS
@ -397,7 +368,8 @@ void SCR_DrawPlaque( void )
if( re && cl_allow_levelshots->integer && !cls.changelevel )
{
levelshot = re->RegisterShader( cl_levelshot_name->string, SHADER_NOMIP );
SCR_DrawPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, levelshot );
re->SetParms( levelshot, kRenderNormal, 0 );
re->DrawStretchPic( 0, 0, scr_width->integer, scr_height->integer, 0, 0, 1, 1, levelshot );
CL_DrawHUD( CL_LOADING ); // update progress bar
}
@ -536,13 +508,13 @@ void SCR_RegisterShaders( void )
{
if( re )
{
cls.pauseIcon = re->RegisterShader( "gfx/paused", SHADER_NOMIP ); // FIXME: MAKE INTRESOURCE
cls.loadingBar = re->RegisterShader( "gfx/lambda", SHADER_NOMIP ); // FIXME: MAKE INTRESOURCE
// register console images
cls.consoleFont = re->RegisterShader( va( "gfx/fonts/%s", con_font->string ), SHADER_FONT );
cls.clientFont = re->RegisterShader( va( "gfx/fonts/%s", cl_font->string ), SHADER_FONT );
cls.netIcon = re->RegisterShader( "#net.png", SHADER_NOMIP ); // FIXME: INTRESOURCE
cls.pauseIcon = re->RegisterShader( "gfx/paused", SHADER_NOMIP ); // FIXME: INTRESOURCE
cls.fillShader = re->RegisterShader( "*white", SHADER_FONT ); // used for FillRGBA
cls.loadingBar = re->RegisterShader( "gfx/lambda", SHADER_NOMIP ); // FIXME: INTRESOURCE
cls.fillShader = re->RegisterShader( "*white", SHADER_NOMIP ); // used for FillRGBA
clgame.creditsFont.hFontTexture = re->RegisterShader( "gfx/creditsfont", SHADER_NOMIP );
if( host.developer )
@ -551,14 +523,15 @@ void SCR_RegisterShaders( void )
Mem_Set( &clgame.ds, 0, sizeof( clgame.ds )); // reset a draw state
Mem_Set( &gameui.ds, 0, sizeof( gameui.ds )); // reset a draw state
Mem_Set( &clgame.centerPrint, 0, sizeof( clgame.centerPrint ));
}
// vid_state has changed
if( clgame.hInstance ) clgame.dllFuncs.pfnVidInit();
if( gameui.hInstance ) gameui.dllFuncs.pfnVidInit();
g_console_field_width = scr_width->integer / SMALLCHAR_WIDTH - 2;
g_consoleField.widthInChars = g_console_field_width;
// restart console size
Con_VidInit ();
}
/*
@ -580,7 +553,6 @@ void SCR_Init( void )
cl_allow_levelshots = Cvar_Get( "allow_levelshots", "0", CVAR_ARCHIVE, "allow engine to use indivdual levelshots instead of 'loading' image" );
scr_loading = Cvar_Get("scr_loading", "0", 0, "loading bar progress" );
scr_download = Cvar_Get("scr_download", "0", 0, "downloading bar progress" );
cl_testentities = Cvar_Get ("cl_testentities", "0", 0, "test client entities" );
cl_testlights = Cvar_Get ("cl_testlights", "0", 0, "test dynamic lights" );
cl_envshot_size = Cvar_Get( "cl_envshot_size", "256", CVAR_ARCHIVE, "envshot size of cube side" );
cl_font = Cvar_Get( "cl_font", "default", CVAR_ARCHIVE, "in-game messages font" );

View File

@ -5,7 +5,6 @@
#include "common.h"
#include "client.h"
#include "effects_api.h"
#include "tmpent_def.h"
/*
@ -54,38 +53,507 @@ int CL_AddTempEntity( TEMPENTITY *pTemp, shader_t customShader )
}
/*
================
CL_TestEntities
==============================================================
if cl_testentities is set, create 32 player models
LIGHT STYLE MANAGEMENT
==============================================================
*/
typedef struct
{
int length;
float value[3];
float map[MAX_STRING];
} clightstyle_t;
clightstyle_t cl_lightstyle[MAX_LIGHTSTYLES];
static int lastofs;
/*
================
CL_ClearLightStyles
================
*/
void CL_TestEntities( void )
void CL_ClearLightStyles( void )
{
Mem_Set( cl_lightstyle, 0, sizeof( cl_lightstyle ));
lastofs = -1;
}
/*
================
CL_RunLightStyles
light animations
'm' is normal light, 'a' is no light, 'z' is double bright
================
*/
void CL_RunLightStyles( void )
{
int i, ofs;
float l, oldval, curval;
clightstyle_t *ls;
if( cls.state != ca_active ) return;
ofs = (cl.time * 10);
if( !cl_lightstyle_lerping->integer )
{
if( ofs == lastofs ) return;
lastofs = ofs;
}
for( i = 0, ls = cl_lightstyle; i < MAX_LIGHTSTYLES; i++, ls++ )
{
if( ls->length == 0 ) l = 0.0f;
else if( ls->length == 1 ) l = ls->map[0];
else if( cl_lightstyle_lerping->integer )
{
int curnum = (ofs % ls->length);
int oldnum = curnum - 1;
// sequence is ends ?
if( oldnum < 0 )
oldnum += ls->length;
oldval = ls->map[oldnum];
curval = ls->map[curnum];
// don't lerping fast sequences
if( fabs( curval - oldval ) >= 1.0f ) l = curval;
else l = oldval + cl.lerpFrac * (curval - oldval);
}
else l = ls->map[ofs%ls->length];
VectorSet( ls->value, l, l, l );
}
}
void CL_SetLightstyle( int i )
{
char *s;
int j, k;
s = cl.configstrings[i+CS_LIGHTSTYLES];
j = com.strlen( s );
if( j >= MAX_STRING )
Host_Error("CL_SetLightStyle: lightstyle %s is too long\n", s );
cl_lightstyle[i].length = j;
for( k = 0; k < j; k++ )
cl_lightstyle[i].map[k] = (float)(s[k]-'a') / (float)('m'-'a');
}
/*
================
CL_AddLightStyles
================
*/
void CL_AddLightStyles( void )
{
int i;
clightstyle_t *ls;
for( i = 0, ls = cl_lightstyle; i < MAX_LIGHTSTYLES; i++, ls++ )
re->AddLightStyle( i, ls->value );
}
/*
==============================================================
DLIGHT MANAGEMENT
==============================================================
*/
struct dlight_s
{
vec3_t origin;
float radius;
byte color[3];
float die; // stop lighting after this time
float decay; // drop this each second
float minlight; // don't add when contributing less
int key;
bool dark; // subtracts light instead of adding
bool elight; // true when calls with CL_AllocElight
};
dlight_t cl_dlights[MAX_DLIGHTS];
/*
================
CL_ClearDlights
================
*/
void CL_ClearDlights( void )
{
Mem_Set( cl_dlights, 0, sizeof( cl_dlights ));
}
/*
===============
CL_AllocDlight
===============
*/
dlight_t *CL_AllocDlight( int key )
{
dlight_t *dl;
int i;
// first look for an exact key match
if( key )
{
for( i = 0, dl = cl_dlights; i < MAX_DLIGHTS; i++, dl++ )
{
if( dl->key == key )
{
// reuse this light
Mem_Set( dl, 0, sizeof( *dl ));
dl->key = key;
return dl;
}
}
}
// then look for anything else
for( i = 0, dl = cl_dlights; i < MAX_DLIGHTS; i++, dl++ )
{
if( dl->die < cl.time )
{
Mem_Set( dl, 0, sizeof( *dl ));
dl->key = key;
return dl;
}
}
// otherwise grab first dlight
dl = &cl_dlights[0];
Mem_Set( dl, 0, sizeof( *dl ));
dl->key = key;
return dl;
}
/*
===============
CL_AllocElight
===============
*/
dlight_t *CL_AllocElight( int key )
{
dlight_t *dl;
dl = CL_AllocDlight( key );
dl->elight = true;
return dl;
}
/*
===============
CL_AddDlight
copy dlight to renderer
===============
*/
bool CL_AddDlight( dlight_t *dl )
{
int flags = 0;
bool add;
if( dl->dark ) flags |= DLIGHT_DARK;
if( dl->elight ) flags |= DLIGHT_ONLYENTS;
add = re->AddDLight( dl->origin, dl->color, dl->radius, flags );
return add;
}
/*
===============
CL_AddDLights
===============
*/
void CL_AddDLights( void )
{
dlight_t *dl;
float time;
int i;
time = cl.time - cl.oldtime;
for( i = 0, dl = cl_dlights; i < MAX_DLIGHTS; i++, dl++ )
{
if( dl->die < cl.time || !dl->radius )
continue;
dl->radius -= time * dl->decay;
if( dl->radius < 0 ) dl->radius = 0;
CL_AddDlight( dl );
}
}
/*
================
CL_TestLights
if cl_testlights is set, create 32 lights models
================
*/
void CL_TestLights( void )
{
int i, j;
float f, r;
edict_t ent, *pl;
dlight_t dl;
if( !cl_testentities->integer )
return;
if( !cl_testlights->integer ) return;
pl = CL_GetLocalPlayer();
Mem_Set( &ent, 0, sizeof( edict_t ));
V_ClearScene();
for( i = 0; i < 32; i++ )
Mem_Set( &dl, 0, sizeof( dlight_t ));
for( i = 0; i < bound( 1, cl_testlights->integer, MAX_DLIGHTS ); i++ )
{
r = 64 * ((i%4) - 1.5 );
f = 64 * (i/4) + 128;
r = 64 * ((i % 4) - 1.5f );
f = 64 * ( i / 4) + 128;
for( j = 0; j < 3; j++ )
ent.v.origin[j] = cl.refdef.vieworg[j]+cl.refdef.forward[j] * f + cl.refdef.right[j] * r;
dl.origin[j] = cl.refdef.vieworg[j] + cl.refdef.forward[j] * f + cl.refdef.right[j] * r;
ent.v.scale = 1.0f;
ent.serialnumber = pl->serialnumber;
ent.v.controller[0] = ent.v.controller[1] = 90.0f;
ent.v.controller[2] = ent.v.controller[3] = 180.0f;
ent.v.modelindex = pl->v.modelindex;
re->AddRefEntity( &ent, ED_NORMAL, -1 );
dl.color[0] = ((((i % 6) + 1) & 1)>>0) * 255;
dl.color[1] = ((((i % 6) + 1) & 2)>>1) * 255;
dl.color[2] = ((((i % 6) + 1) & 4)>>2) * 255;
dl.radius = 200;
if( !CL_AddDlight( &dl ))
break;
}
}
/*
==============================================================
DECAL MANAGEMENT
==============================================================
*/
/*
===============
CL_DecalShoot
normal temporary decal
===============
*/
void CL_DecalShoot( HSPRITE hDecal, int entityIndex, int modelIndex, float *pos, int flags )
{
rgba_t color;
Vector4Set( color, 255, 255, 255, 255 ); // don't use custom colors
if( re ) re->DecalShoot( hDecal, entityIndex, modelIndex, pos, NULL, flags, color, 0.0f, 0.0f );
}
/*
===============
CL_PlayerDecal
spray custom colored decal (clan logo etc)
===============
*/
void CL_PlayerDecal( HSPRITE hDecal, int entityIndex, float *pos, byte *color )
{
edict_t *pEnt;
int modelIndex = 0;
pEnt = CL_GetEdictByIndex( entityIndex );
if( CL_IsValidEdict( pEnt )) modelIndex = pEnt->v.modelindex;
if( re ) re->DecalShoot( hDecal, entityIndex, modelIndex, pos, NULL, FDECAL_CUSTOM, color, 0.0f, 0.0f );
}
/*
===============
CL_LightForPoint
get lighting color for specified point
===============
*/
void CL_LightForPoint( const vec3_t point, vec3_t ambientLight )
{
if( re ) re->LightForPoint( point, ambientLight );
else VectorClear( ambientLight );
}
/*
===============
CL_ResetEvent
===============
*/
void CL_ResetEvent( event_info_t *ei )
{
Mem_Set( ei, 0, sizeof( *ei ));
}
word CL_PrecacheEvent( const char *name )
{
int i;
if( !name || !name[0] ) return 0;
for( i = 1; i < MAX_EVENTS && cl.configstrings[CS_EVENTS+i][0]; i++ )
if( !com.strcmp( cl.configstrings[CS_EVENTS+i], name ))
return i;
return 0;
}
bool CL_FireEvent( event_info_t *ei )
{
user_event_t *ev;
const char *name;
int i;
if( !ei || !ei->index )
return false;
// get the func pointer
for( i = 0; i < MAX_EVENTS; i++ )
{
ev = clgame.events[i];
if( !ev ) break;
if( ev->index == ei->index )
{
if( ev->func )
{
ev->func( &ei->args );
return true;
}
name = cl.configstrings[CS_EVENTS+ei->index];
MsgDev( D_ERROR, "CL_FireEvent: %s not hooked\n", name );
break;
}
}
return false;
}
void CL_FireEvents( void )
{
int i;
event_state_t *es;
event_info_t *ei;
bool success;
es = &cl.events;
for( i = 0; i < MAX_EVENT_QUEUE; i++ )
{
ei = &es->ei[i];
if( ei->index == 0 )
continue;
if( cls.state == ca_disconnected )
{
CL_ResetEvent( ei );
continue;
}
// delayed event!
if( ei->fire_time && ( ei->fire_time > clgame.globals->time ))
continue;
success = CL_FireEvent( ei );
// zero out the remaining fields
CL_ResetEvent( ei );
}
}
event_info_t *CL_FindEmptyEvent( void )
{
int i;
event_state_t *es;
event_info_t *ei;
es = &cl.events;
// look for first slot where index is != 0
for( i = 0; i < MAX_EVENT_QUEUE; i++ )
{
ei = &es->ei[i];
if( ei->index != 0 )
continue;
return ei;
}
// no slots available
return NULL;
}
event_info_t *CL_FindUnreliableEvent( void )
{
int i;
event_state_t *es;
event_info_t *ei;
es = &cl.events;
for ( i = 0; i < MAX_EVENT_QUEUE; i++ )
{
ei = &es->ei[i];
if( ei->index != 0 )
{
// it's reliable, so skip it
if( ei->flags & FEV_RELIABLE )
continue;
}
return ei;
}
// this should never happen
return NULL;
}
void CL_QueueEvent( int flags, int index, float delay, event_args_t *args )
{
bool unreliable = (flags & FEV_RELIABLE) ? false : true;
event_info_t *ei;
// find a normal slot
ei = CL_FindEmptyEvent();
if( !ei && unreliable )
{
return;
}
// okay, so find any old unreliable slot
if( !ei )
{
ei = CL_FindUnreliableEvent();
if( !ei ) return;
}
ei->index = index;
ei->fire_time = delay ? (clgame.globals->time + delay) : 0.0f;
ei->flags = flags;
// copy in args event data
Mem_Copy( &ei->args, args, sizeof( ei->args ));
}
/*
==============
CL_ClearEffects
==============
*/
void CL_ClearEffects( void )
{
CL_ClearDlights ();
CL_ClearLightStyles ();
}

View File

@ -187,7 +187,6 @@ void V_PostRender( void )
if( cls.scrshot_action == scrshot_inactive )
{
SCR_RSpeeds();
SCR_DrawNet();
SCR_DrawFPS();
UI_UpdateMenu( host.realtime );
Con_DrawConsole();

View File

@ -9,10 +9,9 @@
#include "mathlib.h"
#include "clgame_api.h"
#include "gameui_api.h"
#include "com_world.h"
#include "world.h"
#define MAX_DEMOS 32
#define COMMAND_HISTORY 32
#define MAX_MESSAGES 1024
#define NUM_FOR_EDICT(e) ((int)((edict_t *)(e) - clgame.edicts))
@ -20,15 +19,6 @@
#define STRING( offset ) CL_GetString( offset )
#define MAKE_STRING(str) CL_AllocString( str )
// console stuff
typedef struct
{
string buffer;
int cursor;
int scroll;
int widthInChars;
} field_t;
typedef struct player_info_s
{
char name[CS_SIZE];
@ -216,19 +206,22 @@ typedef struct
int scissor_height;
bool scissor_test;
// centerprint stuff
int centerPrintY;
int centerPrintTime;
int centerPrintCharWidth;
char centerPrint[2048];
int centerPrintLines;
// crosshair members
HSPRITE hCrosshair;
wrect_t rcCrosshair;
rgba_t rgbaCrosshair;
} draw_stuff_t;
typedef struct
{
// centerprint stuff
int lines;
int y, time;
char message[2048];
int totalWidth;
int totalHeight;
} center_print_t;
typedef struct
{
void *hInstance; // pointer to client.dll
@ -256,6 +249,7 @@ typedef struct
entity_state_t *baselines;
draw_stuff_t ds; // draw2d stuff (hud, weaponmenu etc)
center_print_t centerPrint; // centerprint variables
SCREENINFO scrInfo; // actual screen info
cl_font_t creditsFont;
@ -313,7 +307,6 @@ typedef struct
shader_t clientFont; // current client font
shader_t consoleBack; // console background
shader_t fillShader; // used for emulate FillRGBA to avoid wrong draw-sort
shader_t netIcon; // netIcon displayed bad network connection
shader_t pauseIcon; // draw 'paused' when game in-pause
shader_t loadingBar; // 'loading' progress bar
@ -379,7 +372,6 @@ extern cvar_t *cl_font;
extern cvar_t *cl_nodelta;
extern cvar_t *cl_crosshair;
extern cvar_t *cl_showmiss;
extern cvar_t *cl_testentities;
extern cvar_t *cl_testlights;
extern cvar_t *cl_allow_levelshots;
extern cvar_t *cl_levelshot_name;
@ -476,7 +468,7 @@ void CL_InitEdict( edict_t *pEdict );
void CL_FreeEdict( edict_t *pEdict );
string_t CL_AllocString( const char *szValue );
const char *CL_GetString( string_t iString );
void CL_CenterPrint( const char *text, int y, int charWidth );
void CL_CenterPrint( const char *text, float y );
bool CL_IsValidEdict( const edict_t *e );
const char *CL_ClassName( const edict_t *e );
void CL_SetEventIndex( const char *szEvName, int ev_index );
@ -508,7 +500,6 @@ void CL_Download_f( void );
void SCR_RegisterShaders( void );
void SCR_AdjustSize( float *x, float *y, float *w, float *h );
void SCR_DrawPic( float x, float y, float width, float height, shader_t shader );
void SCR_FillRect( float x, float y, float width, float height, const rgba_t color );
void SCR_DrawSmallChar( int x, int y, int ch );
void SCR_DrawChar( int x, int y, float w, float h, int ch );
void SCR_DrawSmallStringExt( int x, int y, const char *string, rgba_t setColor, bool forceColor );
@ -519,7 +510,6 @@ void SCR_MakeScreenShot( void );
void SCR_MakeLevelShot( void );
void SCR_RSpeeds( void );
void SCR_DrawFPS( void );
void SCR_DrawNet( void );
//
// cl_view.c
@ -559,7 +549,6 @@ void CL_GetEntitySpatialization( int ent, vec3_t origin, vec3_t velocity );
//
void CL_ClearEffects( void );
void CL_TestLights( void );
void CL_TestEntities( void );
dlight_t *CL_AllocDlight( int key );
dlight_t *CL_AllocElight( int key );
void CL_LightForPoint( const vec3_t point, vec3_t ambientLight );
@ -582,11 +571,12 @@ int CL_AddEntity( edict_t *pEnt, int ed_type, shader_t customShader );
int CL_AddTempEntity( struct tempent_s *pTemp, shader_t customShader );
//
// cl_con.c
// console.c
//
bool Con_Visible( void );
void Con_CheckResize( void );
void Con_Init( void );
void Con_VidInit( void );
void Con_Clear_f( void );
void Con_ToggleConsole_f( void );
void Con_DrawNotify( void );
@ -598,13 +588,8 @@ void Con_PageDown( void );
void Con_Top( void );
void Con_Bottom( void );
void Con_Close( void );
extern bool chat_team;
extern bool anykeydown;
extern int g_console_field_width;
extern field_t historyEditLines[COMMAND_HISTORY];
extern field_t g_consoleField;
extern field_t chatField;
void Con_CharEvent( int key );
void Key_Console( int key );
//
// cl_menu.c
@ -624,15 +609,6 @@ void UI_CharEvent( int key );
bool UI_MouseInRect( void );
bool UI_IsVisible( void );
//
// cl_keys.c
//
void Field_Clear( field_t *edit );
void Field_CharEvent( field_t *edit, int ch );
void Field_KeyDownEvent( field_t *edit, int key );
void Field_Draw( field_t *edit, int x, int y, int width, bool showCursor );
void Field_BigDraw( field_t *edit, int x, int y, int width, bool showCursor );
//
// cl_video.c
//

File diff suppressed because it is too large Load Diff

View File

@ -1,618 +0,0 @@
//=======================================================================
// Copyright XashXT Group 2007 ©
// con_main.c - client console
//=======================================================================
#include "common.h"
#include "client.h"
cvar_t *con_notifytime;
cvar_t *con_speed;
cvar_t *con_font;
#define DEFAULT_CONSOLE_WIDTH 78
#define COLOR_BLACK '0'
#define COLOR_RED '1'
#define COLOR_GREEN '2'
#define COLOR_YELLOW '3'
#define COLOR_BLUE '4'
#define COLOR_CYAN '5'
#define COLOR_MAGENTA '6'
#define COLOR_WHITE '7'
#define CON_TIMES 5 // need for 4 lines
#define CON_TEXTSIZE (MAX_MSGLEN * 4) // 128 kb buffer
int g_console_field_width = 78;
// console color typeing
rgba_t g_color_table[8] =
{
{ 0, 0, 0, 255},
{255, 0, 0, 255},
{ 0, 255, 0, 255},
{255, 255, 0, 255},
{ 0, 0, 255, 255},
{ 0, 255, 255, 255},
{255, 0, 255, 255},
{255, 255, 255, 255},
};
typedef struct
{
bool initialized;
short text[CON_TEXTSIZE];
int current; // line where next message will be printed
int x; // offset in current line for next print
int display; // bottom of console displays this line
int linewidth; // characters across screen
int totallines; // total lines in console scrollback
float xadjust; // for wide aspect screens
float displayFrac; // aproaches finalFrac at con_speed
float finalFrac; // 0.0 to 1.0 lines of console to display
int vislines; // in scanlines
double times[CON_TIMES]; // host.realtime the line was generated for transparent notify lines
rgba_t color;
} console_t;
static console_t con;
/*
================
Con_Clear_f
================
*/
void Con_Clear_f( void )
{
int i;
for ( i = 0; i < CON_TEXTSIZE; i++ )
con.text[i] = (ColorIndex(COLOR_WHITE)<<8) | ' ';
Con_Bottom(); // go to end
}
/*
================
Con_ClearNotify
================
*/
void Con_ClearNotify( void )
{
int i;
for( i = 0; i < CON_TIMES; i++ )
con.times[i] = 0.0;
}
void Con_ClearTyping( void )
{
Field_Clear( &g_consoleField );
g_consoleField.widthInChars = g_console_field_width;
}
/*
================
Con_ToggleConsole_f
================
*/
void Con_ToggleConsole_f( void )
{
if( !host.developer ) return; // disabled
// show console only in game or by special call from menu
if( cls.state != ca_active || cls.key_dest == key_menu )
return;
Con_ClearTyping();
Con_ClearNotify();
if( cls.key_dest == key_console )
{
UI_SetActiveMenu( false );
cls.key_dest = key_game;
}
else
{
UI_SetActiveMenu( false );
cls.key_dest = key_console;
}
}
/*
================
Con_CheckResize
If the line width has changed, reformat the buffer.
================
*/
void Con_CheckResize( void )
{
int i, j, width, oldwidth, oldtotallines, numlines, numchars;
short tbuf[CON_TEXTSIZE];
width = SCREEN_WIDTH / SMALLCHAR_WIDTH - 2;
if( width == con.linewidth )
return;
if( re == NULL ) // video hasn't been initialized yet
{
width = DEFAULT_CONSOLE_WIDTH;
con.linewidth = width;
con.totallines = CON_TEXTSIZE / con.linewidth;
for(i = 0; i < CON_TEXTSIZE; i++)
con.text[i] = (ColorIndex(COLOR_WHITE)<<8) | ' ';
}
else
{
oldwidth = con.linewidth;
con.linewidth = g_console_field_width;
oldtotallines = con.totallines;
con.totallines = CON_TEXTSIZE / con.linewidth;
numlines = oldtotallines;
if( con.totallines < numlines )
numlines = con.totallines;
numchars = oldwidth;
if( con.linewidth < numchars )
numchars = con.linewidth;
Mem_Copy( tbuf, con.text, CON_TEXTSIZE * sizeof( short ));
for( i = 0; i < CON_TEXTSIZE; i++ )
con.text[i] = (ColorIndex(COLOR_WHITE)<<8) | ' ';
for (i = 0; i < numlines; i++)
{
for (j = 0; j < numchars; j++)
{
con.text[(con.totallines - 1 - i) * con.linewidth + j] =
tbuf[((con.current - i + oldtotallines) % oldtotallines) * oldwidth + j];
}
}
Con_ClearNotify ();
}
con.current = con.totallines - 1;
con.display = con.current;
}
/*
================
Con_Init
================
*/
void Con_Init( void )
{
int i;
Con_CheckResize();
// register our commands
con_notifytime = Cvar_Get( "con_notifytime", "3", 0, "notify time to live" );
con_speed = Cvar_Get( "scr_conspeed", "600", 0, "console moving speed" );
con_font = Cvar_Get( "con_font", "default", CVAR_ARCHIVE, "path to console charset" );
Field_Clear( &g_consoleField );
g_consoleField.widthInChars = g_console_field_width;
for( i = 0; i < COMMAND_HISTORY; i++ )
{
Field_Clear( &historyEditLines[i] );
historyEditLines[i].widthInChars = g_console_field_width;
}
Cmd_AddCommand( "toggleconsole", Con_ToggleConsole_f, "opens or closes the console" );
Cmd_AddCommand( "clear", Con_Clear_f, "clear console history" );
MsgDev( D_NOTE, "Console initialized.\n" );
con.initialized = true;
}
/*
===============
Con_Linefeed
===============
*/
void Con_Linefeed( bool skipnotify )
{
int i;
// mark time for transparent overlay
if( con.current >= 0 )
{
if( skipnotify ) con.times[con.current % CON_TIMES] = 0;
else con.times[con.current % CON_TIMES] = host.realtime;
}
con.x = 0;
if( con.display == con.current ) con.display++;
con.current++;
for( i = 0; i < con.linewidth; i++ )
con.text[(con.current % con.totallines) * con.linewidth+i] = (ColorIndex(COLOR_WHITE)<<8)|' ';
}
/*
================
Con_Print
Handles cursor positioning, line wrapping, etc
All console printing must go through this in order to be logged to disk
If no console is visible, the text will appear at the top of the game window
================
*/
void Con_Print( const char *txt )
{
int y, c, l, color;
bool skipnotify = false;
int prev;
// client not running
if( host.type == HOST_DEDICATED ) return;
if( !con.initialized ) return;
if(!com.strncmp( txt, "[skipnotify]", 12 ))
{
skipnotify = true;
txt += 12;
}
color = ColorIndex( COLOR_WHITE );
while((c = *txt) != 0 )
{
if(IsColorString( txt ))
{
color = ColorIndex(*(txt+1));
txt += 2;
continue;
}
// count word length
for( l = 0; l < con.linewidth; l++ )
{
if( txt[l] <= ' ') break;
}
// word wrap
if( l != con.linewidth && (con.x + l >= con.linewidth ))
Con_Linefeed( skipnotify);
txt++;
switch(c)
{
case '\n':
Con_Linefeed( skipnotify );
break;
case '\r':
con.x = 0;
break;
default: // display character and advance
y = con.current % con.totallines;
con.text[y*con.linewidth+con.x] = (color << 8) | c;
con.x++;
if( con.x >= con.linewidth )
{
Con_Linefeed( skipnotify );
con.x = 0;
}
break;
}
}
// mark time for transparent overlay
if( con.current >= 0 )
{
if( skipnotify )
{
prev = con.current % CON_TIMES - 1;
if( prev < 0 ) prev = CON_TIMES - 1;
con.times[prev] = 0;
}
else con.times[con.current % CON_TIMES] = host.realtime;
}
}
/*
==============================================================================
DRAWING
==============================================================================
*/
/*
================
Con_DrawInput
The input line scrolls horizontally if typing goes beyond the right edge
================
*/
void Con_DrawInput( void )
{
int y;
if( cls.key_dest != key_console )
return; // don't draw anything (always draw if not active)
y = con.vislines - ( SMALLCHAR_HEIGHT * 2 );
re->SetColor( con.color );
Field_Draw( &g_consoleField, con.xadjust + 2 * SMALLCHAR_WIDTH, y, SCREEN_WIDTH - 3 * SMALLCHAR_WIDTH, true );
SCR_DrawSmallChar( con.xadjust + 1 * SMALLCHAR_WIDTH, y, '>' );
}
/*
================
Con_DrawNotify
Draws the last few lines of output transparently over the game top
================
*/
void Con_DrawNotify( void )
{
int i, x, v = 0;
int currentColor;
short *text;
float time;
if( !host.developer ) return;
currentColor = 7;
re->SetColor( g_color_table[currentColor] );
for( i = con.current - CON_TIMES + 1; i <= con.current; i++ )
{
if( i < 0 ) continue;
time = con.times[i % CON_TIMES];
if( time == 0.0 ) continue;
time = host.realtime - time;
if( time > con_notifytime->value ) continue;
text = con.text + (i % con.totallines) * con.linewidth;
for( x = 0; x < con.linewidth; x++ )
{
if((text[x] & 0xff ) == ' ' ) continue;
if(( ( text[x] >> 8 ) & 7 ) != currentColor )
{
currentColor = ( text[x] >> 8 ) & 7;
re->SetColor(g_color_table[currentColor]);
}
SCR_DrawSmallChar( con.xadjust + (x+1) * SMALLCHAR_WIDTH, v, text[x] & 0xff );
}
v += SMALLCHAR_HEIGHT;
}
re->SetColor( NULL );
}
/*
================
Con_DrawConsole
Draws the console with the solid background
================
*/
void Con_DrawSolidConsole( float frac )
{
int i, x, y;
int rows;
short *text;
int row;
int lines;
int currentColor;
string curbuild;
lines = scr_height->integer * frac;
if( lines <= 0 ) return;
if( lines > scr_height->integer ) lines = scr_height->integer;
con.xadjust = 0; // on wide screens, we will center the text
SCR_AdjustSize( &con.xadjust, NULL, NULL, NULL );
// draw the background
y = frac * SCREEN_HEIGHT;
if( y < 1 ) y = 0;
else SCR_DrawPic( 0, y - SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT, cls.consoleBack );
if( host.developer )
{
// draw current version
re->SetColor( g_color_table[ColorIndex(COLOR_YELLOW)] );
com.snprintf( curbuild, MAX_STRING, "Xash3D %g (build %i)", SI->version, com_buildnum( ));
i = com.strlen( curbuild );
for( x = 0; x < i; x++ )
SCR_DrawSmallChar( scr_width->integer - ( i - x ) * SMALLCHAR_WIDTH, (lines - (SMALLCHAR_HEIGHT+SMALLCHAR_HEIGHT/2)), curbuild[x] );
re->SetColor( NULL );
}
// draw the text
con.vislines = lines;
rows = ( lines - SMALLCHAR_WIDTH ) / SMALLCHAR_WIDTH; // rows of text to draw
y = lines - ( SMALLCHAR_HEIGHT * 3 );
// draw from the bottom up
if( con.display != con.current )
{
// draw arrows to show the buffer is backscrolled
re->SetColor( g_color_table[ColorIndex(COLOR_RED)] );
for( x = 0; x < con.linewidth; x += 4 )
SCR_DrawSmallChar( con.xadjust + (x+1) * SMALLCHAR_WIDTH, y, '^' );
y -= SMALLCHAR_HEIGHT;
rows--;
}
row = con.display;
if( con.x == 0 ) row--;
currentColor = 7;
re->SetColor( g_color_table[currentColor] );
for( i = 0; i < rows; i++, y -= SMALLCHAR_HEIGHT, row-- )
{
if( row < 0 ) break;
if( con.current - row >= con.totallines )
{
// past scrollback wrap point
continue;
}
text = con.text + (row % con.totallines) * con.linewidth;
for( x = 0; x < con.linewidth; x++ )
{
if(( text[x] & 0xff ) == ' ' ) continue;
if((( text[x]>>8) & 7 ) != currentColor )
{
currentColor = (text[x]>>8) & 7;
re->SetColor(g_color_table[currentColor]);
}
SCR_DrawSmallChar( con.xadjust + (x+1) * SMALLCHAR_WIDTH, y, text[x] & 0xff );
}
}
// draw the input prompt, user text, and cursor if desired
Con_DrawInput();
re->SetColor( NULL );
}
/*
==================
Con_DrawConsole
==================
*/
void Con_DrawConsole( void )
{
// never draw console whel changelevel in-progress
if( cls.changelevel ) return;
// check for console width changes from a vid mode change
Con_CheckResize ();
if( cls.state == ca_connecting || cls.state == ca_connected )
{
if( !cl_allow_levelshots->integer )
{
con.displayFrac = con.finalFrac = 1.0f;
}
else
{
if( host.developer >= 4 )
{
con.displayFrac = 0.5f; // keep console open
}
else
{
con.finalFrac = 0.0f;
Con_RunConsole();
if( host.developer >= 2 )
Con_DrawNotify(); // draw notify lines
}
}
}
// if disconnected, render console full screen
switch( cls.state )
{
case ca_uninitialized:
break;
case ca_disconnected:
if( cls.key_dest != key_menu && host.developer )
{
Con_DrawSolidConsole( 1.0f );
cls.key_dest = key_console;
}
break;
case ca_connected:
case ca_connecting:
// force to show console always for -dev 3 and higher
if( con.displayFrac ) Con_DrawSolidConsole( con.displayFrac );
break;
case ca_active:
case ca_cinematic:
if( con.displayFrac ) Con_DrawSolidConsole( con.displayFrac );
else if( cls.state == ca_active && cls.key_dest == key_game )
Con_DrawNotify(); // draw notify lines
break;
}
}
/*
==================
Con_RunConsole
Scroll it up or down
==================
*/
void Con_RunConsole( void )
{
// decide on the destination height of the console
if( host.developer && cls.key_dest == key_console )
{
if( cls.state == ca_disconnected )
con.finalFrac = 1.0f;// full screen
else con.finalFrac = 0.5f; // half screen
}
else con.finalFrac = 0; // none visible
// whel level is loading frametime may be is wrong
if( cls.state == ca_connecting || cls.state == ca_connected )
host.realframetime = ( MAX_FPS / host_maxfps->value ) * MIN_FRAMETIME;
if( con.finalFrac < con.displayFrac )
{
con.displayFrac -= con_speed->value * 0.002 * host.realframetime;
if( con.finalFrac > con.displayFrac )
con.displayFrac = con.finalFrac;
}
else if( con.finalFrac > con.displayFrac )
{
con.displayFrac += con_speed->value * 0.002 * host.realframetime;
if( con.finalFrac < con.displayFrac )
con.displayFrac = con.finalFrac;
}
}
void Con_PageUp( void )
{
con.display -= 2;
if( con.current - con.display >= con.totallines )
con.display = con.current - con.totallines + 1;
}
void Con_PageDown( void )
{
con.display += 2;
if( con.display > con.current) con.display = con.current;
}
void Con_Top( void )
{
con.display = con.totallines;
if( con.current - con.display >= con.totallines )
con.display = con.current - con.totallines + 1;
}
void Con_Bottom( void )
{
con.display = con.current;
}
void Con_Close( void )
{
Field_Clear( &g_consoleField );
Con_ClearNotify();
con.finalFrac = 0; // none visible
con.displayFrac = 0;
}
bool Con_Visible( void )
{
return (con.finalFrac != 0.0f);
}

View File

@ -348,7 +348,7 @@ bool Cmd_GetSavesList( const char *s, char *completedname, int length )
{
const char *ext = FS_FileExtension( t->filenames[i] );
if( com.stricmp( ext, "bin" )) continue;
if( com.stricmp( ext, "sav" )) continue;
FS_FileBase( t->filenames[i], matchbuf );
Msg( "%16s\n", matchbuf );
numsaves++;
@ -564,7 +564,7 @@ Prints or complete gamedir name
bool Cmd_GetGamesList( const char *s, char *completedname, int length )
{
int i, numgamedirs;
string gamedirs[128];
string gamedirs[MAX_MODS];
string matchbuf;
// compare gamelist with current keyword

1254
engine/common/console.c Normal file

File diff suppressed because it is too large Load Diff

704
engine/common/keys.c Normal file
View File

@ -0,0 +1,704 @@
//=======================================================================
// Copyright XashXT Group 2007 ©
// con_keys.c - console key events
//=======================================================================
#include "common.h"
#include "input.h"
#include "client.h"
typedef struct key_s
{
bool down;
int repeats; // if > 1, it is autorepeating
const char *binding;
} key_t;
typedef struct keyname_s
{
char *name; // key name
int keynum; // key number
const char *binding; // default bind
} keyname_t;
key_t keys[256];
keyname_t keynames[] =
{
{"TAB", K_TAB, "" },
{"ENTER", K_ENTER, "" },
{"ESCAPE", K_ESCAPE, "cancelselect" }, // hardcoded
{"SPACE", K_SPACE, "+moveup" },
{"BACKSPACE", K_BACKSPACE, "" },
{"UPARROW", K_UPARROW, "+forward" },
{"DOWNARROW", K_DOWNARROW, "+back" },
{"LEFTARROW", K_LEFTARROW, "+left" },
{"RIGHTARROW", K_RIGHTARROW, "+right" },
{"ALT", K_ALT, "+strafe" },
{"CTRL", K_CTRL, "+attack" },
{"SHIFT", K_SHIFT, "+speed" }, // replace with +attack2 ?
{"CAPSLOCK", K_CAPSLOCK, "" },
{"F1", K_F1, "cmd help" },
{"F2", K_F2, "menu_savegame" },
{"F3", K_F3, "menu_loadgame" },
{"F4", K_F4, "menu_keys" },
{"F5", K_F5, "menu_startserver" },
{"F6", K_F6, "savequick" },
{"F7", K_F7, "loadquick" },
{"F8", K_F8, "stop" },
{"F9", K_F9, "" },
{"F10", K_F10, "menu_quit" },
{"F11", K_F11, "" },
{"F12", K_F12, "screenshot" },
{"INS", K_INS, "" },
{"DEL", K_DEL, "+lookdown" },
{"PGDN", K_PGDN, "+lookup" },
{"PGUP", K_PGUP, "" },
{"HOME", K_HOME, "" },
{"END", K_END, "centerview" },
// mouse buttouns
{"MOUSE1", K_MOUSE1, "+attack" },
{"MOUSE2", K_MOUSE2, "+attack2" },
{"MOUSE3", K_MOUSE3, "" },
{"MOUSE4", K_MOUSE4, "" },
{"MOUSE5", K_MOUSE5, "" },
{"MWHEELUP", K_MWHEELUP, "" },
{"MWHEELDOWN", K_MWHEELDOWN, "" },
// digital keyboard
{"KP_HOME", K_KP_HOME, "" },
{"KP_UPARROW", K_KP_UPARROW, "+forward" },
{"KP_PGUP", K_KP_PGUP, "" },
{"KP_LEFTARROW", K_KP_LEFTARROW, "+left" },
{"KP_5", K_KP_5, "" },
{"KP_RIGHTARROW", K_KP_RIGHTARROW, "+right" },
{"KP_END", K_KP_END, "centerview" },
{"KP_DOWNARROW", K_KP_DOWNARROW, "+back" },
{"KP_PGDN", K_KP_PGDN, "+lookup" },
{"KP_ENTER", K_KP_ENTER, "" },
{"KP_INS", K_KP_INS, "" },
{"KP_DEL", K_KP_DEL, "+lookdown" },
{"KP_SLASH", K_KP_SLASH, "" },
{"KP_MINUS", K_KP_MINUS, "" },
{"KP_PLUS", K_KP_PLUS, "" },
{"PAUSE", K_PAUSE, "pause" },
// raw semicolon seperates commands
{"SEMICOLON", ';', "" },
{NULL, 0, NULL },
};
/*
===================
Key_IsDown
===================
*/
bool Key_IsDown( int keynum )
{
if ( keynum == -1 )
return false;
return keys[keynum].down;
}
/*
===================
Key_GetBind
===================
*/
const char *Key_IsBind( int keynum )
{
if( keynum == -1 || !keys[keynum].binding )
return NULL;
return keys[keynum].binding;
}
/*
===================
Key_StringToKeynum
Returns a key number to be used to index keys[] by looking at
the given string. Single ascii characters return themselves, while
the K_* names are matched up.
0x11 will be interpreted as raw hex, which will allow new controlers
to be configured even if they don't have defined names.
===================
*/
int Key_StringToKeynum( const char *str )
{
keyname_t *kn;
if( !str || !str[0] ) return -1;
if( !str[1] ) return str[0];
// check for hex code
if( str[0] == '0' && str[1] == 'x' && com.strlen( str ) == 4 )
{
int n1, n2;
n1 = str[2];
if( n1 >= '0' && n1 <= '9' )
{
n1 -= '0';
}
else if( n1 >= 'a' && n1 <= 'f' )
{
n1 = n1 - 'a' + 10;
}
else n1 = 0;
n2 = str[3];
if( n2 >= '0' && n2 <= '9' )
{
n2 -= '0';
}
else if( n2 >= 'a' && n2 <= 'f' )
{
n2 = n2 - 'a' + 10;
}
else n2 = 0;
return n1 * 16 + n2;
}
// scan for a text match
for( kn = keynames; kn->name; kn++ )
{
if( !com.stricmp( str, kn->name ))
return kn->keynum;
}
return -1;
}
/*
===================
Key_KeynumToString
Returns a string (either a single ascii char, a K_* name, or a 0x11 hex string) for the
given keynum.
===================
*/
const char *Key_KeynumToString( int keynum )
{
keyname_t *kn;
static char tinystr[5];
int i, j;
if ( keynum == -1 ) return "<KEY NOT FOUND>";
if ( keynum < 0 || keynum > 255 ) return "<OUT OF RANGE>";
// check for printable ascii (don't use quote)
if( keynum > 32 && keynum < 127 && keynum != '"' && keynum != ';' )
{
tinystr[0] = keynum;
tinystr[1] = 0;
return tinystr;
}
// check for a key string
for( kn = keynames; kn->name; kn++ )
{
if( keynum == kn->keynum )
return kn->name;
}
// make a hex string
i = keynum >> 4;
j = keynum & 15;
tinystr[0] = '0';
tinystr[1] = 'x';
tinystr[2] = i > 9 ? i - 10 + 'a' : i + '0';
tinystr[3] = j > 9 ? j - 10 + 'a' : j + '0';
tinystr[4] = 0;
return tinystr;
}
/*
===================
Key_SetBinding
===================
*/
void Key_SetBinding( int keynum, const char *binding )
{
if( keynum == -1 ) return;
// free old bindings
if( keys[keynum].binding )
{
Mem_Free((char *)keys[keynum].binding );
keys[keynum].binding = NULL;
}
// allocate memory for new binding
keys[keynum].binding = copystring( binding );
}
/*
===================
Key_GetBinding
===================
*/
const char *Key_GetBinding( int keynum )
{
if( keynum == -1 ) return NULL;
return keys[keynum].binding;
}
/*
===================
Key_GetKey
===================
*/
int Key_GetKey( const char *binding )
{
int i;
if( !binding ) return -1;
for( i = 0; i < 256; i++ )
{
if( keys[i].binding && !com.stricmp( binding, keys[i].binding ))
return i;
}
return -1;
}
/*
===================
Key_Unbind_f
===================
*/
void Key_Unbind_f( void )
{
int b;
if( Cmd_Argc() != 2 )
{
Msg( "Usage: unbind <key> : remove commands from a key\n" );
return;
}
b = Key_StringToKeynum( Cmd_Argv( 1 ));
if( b == -1 )
{
Msg( "\"%s\" isn't a valid key\n", Cmd_Argv( 1 ));
return;
}
Key_SetBinding( b, "" );
}
/*
===================
Key_Unbindall_f
===================
*/
void Key_Unbindall_f( void )
{
int i;
for( i = 0; i < 256; i++ )
{
if( keys[i].binding )
Key_SetBinding( i, "" );
}
}
/*
===================
Key_Reset_f
===================
*/
void Key_Reset_f( void )
{
int i;
keyname_t *kn;
// clear all keys first
for( i = 0; i < 256; i++ )
{
if( keys[i].binding )
Key_SetBinding( i, "" );
}
// apply default values
for( kn = keynames; kn->name; kn++ )
Key_SetBinding( kn->keynum, kn->binding );
}
/*
===================
Key_Bind_f
===================
*/
void Key_Bind_f( void )
{
int i, c, b;
char cmd[1024];
c = Cmd_Argc();
if( c < 2 )
{
Msg( "Usage: bind <key> [command] : attach a command to a key\n" );
return;
}
b = Key_StringToKeynum( Cmd_Argv( 1 ));
if( b == -1 )
{
Msg( "\"%s\" isn't a valid key\n", Cmd_Argv( 1 ));
return;
}
if( c == 2 )
{
if( keys[b].binding )
Msg( "\"%s\" = \"%s\"\n", Cmd_Argv( 1 ), keys[b].binding );
else Msg( "\"%s\" is not bound\n", Cmd_Argv( 1 ));
return;
}
// copy the rest of the command line
cmd[0] = 0; // start out with a null string
for( i = 2; i < c; i++ )
{
com.strcat( cmd, Cmd_Argv( i ));
if( i != ( c - 1 )) com.strcat( cmd, " " );
}
Key_SetBinding( b, cmd );
}
/*
============
Key_WriteBindings
Writes lines containing "bind key value"
============
*/
void Key_WriteBindings( file_t *f )
{
int i;
if( !f ) return;
FS_Printf( f, "unbindall\n" );
for( i = 0; i < 256; i++ )
{
if( keys[i].binding && keys[i].binding[0] )
FS_Printf( f, "bind %s \"%s\"\n", Key_KeynumToString(i), keys[i].binding );
}
}
/*
============
Key_Bindlist_f
============
*/
void Key_Bindlist_f( void )
{
int i;
for( i = 0; i < 256; i++ )
{
if( keys[i].binding && keys[i].binding[0] )
Msg( "%s \"%s\"\n", Key_KeynumToString( i ), keys[i].binding );
}
}
/*
==============================================================================
LINE TYPING INTO THE CONSOLE
==============================================================================
*/
/*
===================
Key_Init
===================
*/
void Key_Init( void )
{
keyname_t *kn;
// register our functions
Cmd_AddCommand( "bind", Key_Bind_f, "binds a command to the specified key in bindmap" );
Cmd_AddCommand( "unbind", Key_Unbind_f, "removes a command on the specified key in bindmap" );
Cmd_AddCommand( "unbindall", Key_Unbindall_f, "removes all commands from all keys in bindmap" );
Cmd_AddCommand( "resetkeys", Key_Reset_f, "reset all keys to their default values" );
Cmd_AddCommand( "bindlist", Key_Bindlist_f, "display current key bindings" );
Cmd_AddCommand( "makehelp", Key_EnumCmds_f, "write help.txt that contains all console cvars and cmds" );
// setup hardcode binding. "unbindall" from keys.rc will be reset it
for( kn = keynames; kn->name; kn++ ) Key_SetBinding( kn->keynum, kn->binding );
}
/*
===================
Key_AddKeyUpCommands
===================
*/
void Key_AddKeyUpCommands( int key, const char *kb )
{
int i;
char button[1024], *buttonPtr;
char cmd[1024];
bool keyevent;
if( !kb ) return;
keyevent = false;
buttonPtr = button;
for( i = 0; ; i++ )
{
if( kb[i] == ';' || !kb[i] )
{
*buttonPtr = '\0';
if( button[0] == '+' )
{
// button commands add keynum as a parm
com.sprintf( cmd, "-%s %i\n", button+1, key );
Cbuf_AddText( cmd );
keyevent = true;
}
else
{
if( keyevent )
{
// down-only command
Cbuf_AddText( button );
Cbuf_AddText( "\n" );
}
}
buttonPtr = button;
while(( kb[i] <= ' ' || kb[i] == ';' ) && kb[i] != 0 )
i++;
}
*buttonPtr++ = kb[i];
if( !kb[i] ) break;
}
}
/*
===================
Key_Event
Called by the system for both key up and key down events
===================
*/
void Key_Event( int key, bool down )
{
const char *kb;
char cmd[1024];
// update auto-repeat status and BUTTON_ANY status
keys[key].down = down;
if( down )
{
keys[key].repeats++;
}
else
{
keys[key].repeats = 0;
}
// console key is hardcoded, so the user can never unbind it
if( key == '`' || key == '~' )
{
if( !down ) return;
Con_ToggleConsole_f();
return;
}
// escape is always handled special
if( key == K_ESCAPE && down )
{
switch( cls.key_dest )
{
case key_game:
break; // handled in client.dll
case key_console:
if( cls.state == ca_active )
{
cls.key_dest = key_game;
}
else
{
UI_SetActiveMenu( true );
return; // don't pass Esc into menu
}
return;
case key_menu:
UI_KeyEvent( key, true );
return;
default:
MsgDev( D_ERROR, "Key_Event: bad cls.key_dest\n" );
return;
}
}
if( cls.key_dest == key_menu )
{
// only non printable keys passed
UI_KeyEvent( key, down );
return;
}
// key up events only perform actions if the game key binding is
// a button command (leading + sign). These will be processed even in
// console mode and menu mode, to keep the character from continuing
// an action started before a mode switch.
if( !down )
{
kb = keys[key].binding;
Key_AddKeyUpCommands( key, kb );
return;
}
// distribute the key down event to the apropriate handler
if( cls.key_dest == key_game )
{
// send the bound action
kb = keys[key].binding;
if( !kb )
{
if( key >= 200 )
Msg( "%s is unbound, use controls menu to set.\n", Key_KeynumToString( key ));
}
else if( kb[0] == '+' )
{
int i;
char button[1024], *buttonPtr;
for( i = 0, buttonPtr = button; ; i++ )
{
if( kb[i] == ';' || !kb[i] )
{
*buttonPtr = '\0';
if( button[0] == '+' )
{
// button commands add keynum and time as parms so that multiple
// sources can be discriminated and subframe corrected
com.sprintf( cmd, "%s %i\n", button, key );
Cbuf_AddText( cmd );
}
else
{
// down-only command
Cbuf_AddText( button );
Cbuf_AddText( "\n" );
}
buttonPtr = button;
while (( kb[i] <= ' ' || kb[i] == ';' ) && kb[i] != 0 )
i++;
}
*buttonPtr++ = kb[i];
if( !kb[i] ) break;
}
}
else
{
// down-only command
Cbuf_AddText( kb );
Cbuf_AddText( "\n" );
}
}
else if( cls.key_dest == key_console )
{
Key_Console( key );
}
}
/*
=========
Key_SetKeyDest
=========
*/
void Key_SetKeyDest( int key_dest )
{
switch( key_dest )
{
case key_game:
cls.key_dest = key_game;
break;
case key_menu:
cls.key_dest = key_menu;
break;
case key_console:
cls.key_dest = key_console;
break;
default:
Host_Error( "Key_SetKeyDest: wrong destination (%i)\n", key_dest );
break;
}
}
/*
===================
Key_ClearStates
===================
*/
void Key_ClearStates( void )
{
int i;
for ( i = 0; i < 256; i++ )
{
if( keys[i].down ) Key_Event( i, false );
keys[i].down = 0;
keys[i].repeats = 0;
}
}
/*
===================
CL_CharEvent
Normal keyboard characters, already shifted / capslocked / etc
===================
*/
void CL_CharEvent( int key )
{
// the console key should never be used as a char
if( key == '`' || key == '~' ) return;
// distribute the key down event to the apropriate handler
if( cls.key_dest == key_console )
{
Con_CharEvent( key );
}
else if( cls.key_dest == key_menu )
{
UI_CharEvent( key );
}
}
/*
=================
CL_MouseEvent
=================
*/
void CL_MouseEvent( int mx, int my )
{
if( UI_IsVisible( ))
{
// if the menu is visible, move the menu cursor
UI_MouseMove( mx, my );
}
else if( cls.key_dest != key_console )
{
// otherwise passed into client.dll
clgame.dllFuncs.pfnMouseEvent( mx, my );
}
}

View File

@ -4,7 +4,7 @@
//=======================================================================
#include "common.h"
#include "com_world.h"
#include "world.h"
#include "pm_defs.h"
#include "mathlib.h"

View File

@ -1,9 +1,9 @@
//=======================================================================
// Copyright XashXT Group 2009 ©
// com_world.h - shared world trace
// world.h - shared world trace
//=======================================================================
#ifndef COM_WORLD_H
#define COM_WORLD_H
#ifndef WORLD_H
#define WORLD_H
#define MOVE_NORMAL 0 // normal trace
#define MOVE_NOMONSTERS 1 // ignore monsters (edicts with flags (FL_MONSTER|FL_FAKECLIENT|FL_CLIENT) set)
@ -113,4 +113,4 @@ typedef struct event_state_s
event_info_t ei[MAX_EVENT_QUEUE];
} event_state_t;
#endif//COM_WORLD_H
#endif//WORLD_H

View File

@ -130,10 +130,6 @@ SOURCE=.\client\cl_demo.c
# End Source File
# Begin Source File
SOURCE=.\client\cl_effects.c
# End Source File
# Begin Source File
SOURCE=.\client\cl_frame.c
# End Source File
# Begin Source File
@ -182,22 +178,14 @@ SOURCE=.\client\cl_world.c
# End Source File
# Begin Source File
SOURCE=.\common\com_keys.c
# End Source File
# Begin Source File
SOURCE=.\common\com_world.c
# End Source File
# Begin Source File
SOURCE=.\common\con_main.c
# End Source File
# Begin Source File
SOURCE=.\common\con_utils.c
# End Source File
# Begin Source File
SOURCE=.\common\console.c
# End Source File
# Begin Source File
SOURCE=.\common\engfuncs.c
# End Source File
# Begin Source File
@ -214,6 +202,10 @@ SOURCE=.\common\input.c
# End Source File
# Begin Source File
SOURCE=.\common\keys.c
# End Source File
# Begin Source File
SOURCE=.\common\net_chan.c
# End Source File
# Begin Source File
@ -272,6 +264,10 @@ SOURCE=.\server\sv_world.c
SOURCE=.\common\titles.c
# End Source File
# Begin Source File
SOURCE=.\common\world.c
# End Source File
# End Group
# Begin Group "Header Files"
@ -292,6 +288,10 @@ SOURCE=.\common\net_msg.h
SOURCE=.\server\server.h
# End Source File
# Begin Source File
SOURCE=.\common\world.h
# End Source File
# End Group
# End Target
# End Project

View File

@ -8,7 +8,7 @@
#include "mathlib.h"
#include "svgame_api.h"
#include "com_world.h"
#include "world.h"
//=============================================================================
#define MAX_MASTERS 8 // max recipients for heartbeat packets
@ -208,6 +208,9 @@ typedef struct
edict_t *msg_ent; // user message member entity
vec3_t msg_org; // user message member origin
// catched user messages (nasty hack)
int gmsgHudText; // -1 if not catched
void *hInstance; // pointer to server.dll
union

View File

@ -638,15 +638,15 @@ Examine all a users info strings
*/
void SV_ClientInfo_f( void )
{
if(Cmd_Argc() != 2)
if( Cmd_Argc() != 2 )
{
Msg("Usage: clientinfo <userid>\n" );
Msg( "Usage: clientinfo <userid>\n" );
return;
}
if(!SV_SetPlayer()) return;
Msg("userinfo\n");
Msg("--------\n");
if( !SV_SetPlayer( )) return;
Msg( "userinfo\n" );
Msg( "--------\n" );
Info_Print( sv_client->userinfo );
}

View File

@ -2330,6 +2330,10 @@ int pfnRegUserMsg( const char *pszName, int iSize )
svgame.msg[i].size = iSize;
svgame.msg[i].number = i; // paranoid mode :-)
// catch some user messages
if( !com.strcmp( pszName, "HudText" ))
svgame.gmsgHudText = i;
if( sv.state == ss_active )
{
MSG_WriteByte( &sv.multicast, svc_usermessage );
@ -3815,6 +3819,9 @@ bool SV_LoadProgs( const char *name )
for( i = 0, e = svgame.edicts; i < svgame.globals->maxEntities; i++, e++ )
e->free = true; // mark all edicts as freed
// clear user messages
svgame.gmsgHudText = -1;
// all done, initialize game
svgame.dllFuncs.pfnGameInit();
pfnRegUserMsg( "svc_bad", 0 ); // register svc_bad message

View File

@ -1739,10 +1739,16 @@ void SV_SaveGame( const char *pName )
SV_BuildSaveComment( comment, sizeof( comment ));
SV_SaveGameSlot( savename, comment );
// UNDONE: get the user controls, use HudMessage instead
MSG_Begin( svc_centerprint );
MSG_WriteString( &sv.multicast, "Game Saved" );
MSG_Send( MSG_ONE, NULL, EDICT_NUM( 1 ));
// HACKHACK: send usermessage from engine
if( com.stricmp( pName, "autosave" ) && svgame.gmsgHudText != -1 )
{
const char *pMsg = "GAMESAVED"; // defined in titles.txt
MSG_Begin( svgame.gmsgHudText );
MSG_WriteByte( &sv.multicast, com.strlen( pMsg ) + 1 );
MSG_WriteString( &sv.multicast, pMsg );
MSG_Send( MSG_ONE, NULL, EDICT_NUM( 1 ));
}
}
/*

View File

@ -139,7 +139,7 @@ static void UI_Credits_DrawFunc( void )
if(( y < ( ActualHeight - h ) / 2 ) && i == uiCredits.numLines - 1 )
{
if( !uiCredits.fadeTime ) uiCredits.fadeTime = uiStatic.realTime;
UI_FadeAlpha( uiCredits.fadeTime, uiCredits.showTime, color );
color = UI_FadeAlpha( uiCredits.fadeTime, uiCredits.showTime );
if( UnpackAlpha( color ))
UI_DrawString( 0, ( ActualHeight - h ) / 2, 1024 * uiStatic.scaleX, h, uiCredits.credits[i], color, true, w, h, 1, true );
}

View File

@ -226,29 +226,26 @@ int KEY_GetKey( const char *binding )
UI_FadeAlpha
================
*/
void UI_FadeAlpha( int starttime, int endtime, int &color )
int UI_FadeAlpha( int starttime, int endtime )
{
int time, fade_time;
if( starttime == 0 )
{
color = 0xFFFFFFFF;
return;
return 0xFFFFFFFF;
}
time = ( gpGlobals->time * 1000 ) - starttime; // FIXME; convert it to float properly
if( time >= endtime )
{
color = 0x00FFFFFF;
return;
return 0x00FFFFFF;
}
// fade time is 1/4 of endtime
fade_time = endtime / 4;
fade_time = bound( 300, fade_time, 10000 );
color = PackRGB( 255, 255, 255 );
int alpha;
// fade out
@ -256,7 +253,7 @@ void UI_FadeAlpha( int starttime, int endtime, int &color )
alpha = bound( 0, (( endtime - time ) * 1.0f / fade_time ) * 255, 255 );
else alpha = 255;
color = PackAlpha( color, alpha );
return PackRGBA( 255, 255, 255, alpha );
}
/*

View File

@ -105,7 +105,7 @@ inline int UnpackAlpha( dword ulRGBA )
extern int ColorStrlen( const char *str ); // returns string length without color symbols
extern const int g_iColorTable[8];
extern void COM_FileBase( const char *in, char *out ); // ripped out from hlsdk 2.3
extern void UI_FadeAlpha( int starttime, int endtime, int &color );
extern int UI_FadeAlpha( int starttime, int endtime );
extern void StringConcat( char *dst, const char *src, size_t size ); // strncat safe prototype
extern char *Info_ValueForKey( const char *s, const char *key );
extern int KEY_GetKey( const char *binding ); // ripped out from engine