📄 cg_draw.c
字号:
#ifdef MISSIONPACK
qhandle_t handle;
#endif
static float colors[4][4] = {
// { 0.2, 1.0, 0.2, 1.0 } , { 1.0, 0.2, 0.2, 1.0 }, {0.5, 0.5, 0.5, 1} };
{ 1.0f, 0.69f, 0.0f, 1.0f }, // normal
{ 1.0f, 0.2f, 0.2f, 1.0f }, // low health
{ 0.5f, 0.5f, 0.5f, 1.0f }, // weapon firing
{ 1.0f, 1.0f, 1.0f, 1.0f } }; // health > 100
if ( cg_drawStatus.integer == 0 ) {
return;
}
// draw the team background
CG_DrawTeamBackground( 0, 420, 640, 60, 0.33f, cg.snap->ps.persistant[PERS_TEAM] );
cent = &cg_entities[cg.snap->ps.clientNum];
ps = &cg.snap->ps;
VectorClear( angles );
// draw any 3D icons first, so the changes back to 2D are minimized
if ( cent->currentState.weapon && cg_weapons[ cent->currentState.weapon ].ammoModel ) {
origin[0] = 70;
origin[1] = 0;
origin[2] = 0;
angles[YAW] = 90 + 20 * sin( cg.time / 1000.0 );
CG_Draw3DModel( CHAR_WIDTH*3 + TEXT_ICON_SPACE, 432, ICON_SIZE, ICON_SIZE,
cg_weapons[ cent->currentState.weapon ].ammoModel, 0, origin, angles );
}
CG_DrawStatusBarHead( 185 + CHAR_WIDTH*3 + TEXT_ICON_SPACE );
if( cg.predictedPlayerState.powerups[PW_REDFLAG] ) {
CG_DrawStatusBarFlag( 185 + CHAR_WIDTH*3 + TEXT_ICON_SPACE + ICON_SIZE, TEAM_RED );
} else if( cg.predictedPlayerState.powerups[PW_BLUEFLAG] ) {
CG_DrawStatusBarFlag( 185 + CHAR_WIDTH*3 + TEXT_ICON_SPACE + ICON_SIZE, TEAM_BLUE );
} else if( cg.predictedPlayerState.powerups[PW_NEUTRALFLAG] ) {
CG_DrawStatusBarFlag( 185 + CHAR_WIDTH*3 + TEXT_ICON_SPACE + ICON_SIZE, TEAM_FREE );
}
if ( ps->stats[ STAT_ARMOR ] ) {
origin[0] = 90;
origin[1] = 0;
origin[2] = -10;
angles[YAW] = ( cg.time & 2047 ) * 360 / 2048.0;
CG_Draw3DModel( 370 + CHAR_WIDTH*3 + TEXT_ICON_SPACE, 432, ICON_SIZE, ICON_SIZE,
cgs.media.armorModel, 0, origin, angles );
}
#ifdef MISSIONPACK
if( cgs.gametype == GT_HARVESTER ) {
origin[0] = 90;
origin[1] = 0;
origin[2] = -10;
angles[YAW] = ( cg.time & 2047 ) * 360 / 2048.0;
if( cg.snap->ps.persistant[PERS_TEAM] == TEAM_BLUE ) {
handle = cgs.media.redCubeModel;
} else {
handle = cgs.media.blueCubeModel;
}
CG_Draw3DModel( 640 - (TEXT_ICON_SPACE + ICON_SIZE), 416, ICON_SIZE, ICON_SIZE, handle, 0, origin, angles );
}
#endif
//
// ammo
//
if ( cent->currentState.weapon ) {
value = ps->ammo[cent->currentState.weapon];
if ( value > -1 ) {
if ( cg.predictedPlayerState.weaponstate == WEAPON_FIRING
&& cg.predictedPlayerState.weaponTime > 100 ) {
// draw as dark grey when reloading
color = 2; // dark grey
} else {
if ( value >= 0 ) {
color = 0; // green
} else {
color = 1; // red
}
}
trap_R_SetColor( colors[color] );
CG_DrawField (0, 432, 3, value);
trap_R_SetColor( NULL );
// if we didn't draw a 3D icon, draw a 2D icon for ammo
if ( !cg_draw3dIcons.integer && cg_drawIcons.integer ) {
qhandle_t icon;
icon = cg_weapons[ cg.predictedPlayerState.weapon ].ammoIcon;
if ( icon ) {
CG_DrawPic( CHAR_WIDTH*3 + TEXT_ICON_SPACE, 432, ICON_SIZE, ICON_SIZE, icon );
}
}
}
}
//
// health
//
value = ps->stats[STAT_HEALTH];
if ( value > 100 ) {
trap_R_SetColor( colors[3] ); // white
} else if (value > 25) {
trap_R_SetColor( colors[0] ); // green
} else if (value > 0) {
color = (cg.time >> 8) & 1; // flash
trap_R_SetColor( colors[color] );
} else {
trap_R_SetColor( colors[1] ); // red
}
// stretch the health up when taking damage
CG_DrawField ( 185, 432, 3, value);
CG_ColorForHealth( hcolor );
trap_R_SetColor( hcolor );
//
// armor
//
value = ps->stats[STAT_ARMOR];
if (value > 0 ) {
trap_R_SetColor( colors[0] );
CG_DrawField (370, 432, 3, value);
trap_R_SetColor( NULL );
// if we didn't draw a 3D icon, draw a 2D icon for armor
if ( !cg_draw3dIcons.integer && cg_drawIcons.integer ) {
CG_DrawPic( 370 + CHAR_WIDTH*3 + TEXT_ICON_SPACE, 432, ICON_SIZE, ICON_SIZE, cgs.media.armorIcon );
}
}
#ifdef MISSIONPACK
//
// cubes
//
if( cgs.gametype == GT_HARVESTER ) {
value = ps->generic1;
if( value > 99 ) {
value = 99;
}
trap_R_SetColor( colors[0] );
CG_DrawField (640 - (CHAR_WIDTH*2 + TEXT_ICON_SPACE + ICON_SIZE), 432, 2, value);
trap_R_SetColor( NULL );
// if we didn't draw a 3D icon, draw a 2D icon for armor
if ( !cg_draw3dIcons.integer && cg_drawIcons.integer ) {
if( cg.snap->ps.persistant[PERS_TEAM] == TEAM_BLUE ) {
handle = cgs.media.redCubeIcon;
} else {
handle = cgs.media.blueCubeIcon;
}
CG_DrawPic( 640 - (TEXT_ICON_SPACE + ICON_SIZE), 432, ICON_SIZE, ICON_SIZE, handle );
}
}
#endif
}
#endif
/*
===========================================================================================
UPPER RIGHT CORNER
===========================================================================================
*/
/*
================
CG_DrawAttacker
================
*/
static float CG_DrawAttacker( float y ) {
int t;
float size;
vec3_t angles;
const char *info;
const char *name;
int clientNum;
if ( cg.predictedPlayerState.stats[STAT_HEALTH] <= 0 ) {
return y;
}
if ( !cg.attackerTime ) {
return y;
}
clientNum = cg.predictedPlayerState.persistant[PERS_ATTACKER];
if ( clientNum < 0 || clientNum >= MAX_CLIENTS || clientNum == cg.snap->ps.clientNum ) {
return y;
}
t = cg.time - cg.attackerTime;
if ( t > ATTACKER_HEAD_TIME ) {
cg.attackerTime = 0;
return y;
}
size = ICON_SIZE * 1.25;
angles[PITCH] = 0;
angles[YAW] = 180;
angles[ROLL] = 0;
CG_DrawHead( 640 - size, y, size, size, clientNum, angles );
info = CG_ConfigString( CS_PLAYERS + clientNum );
name = Info_ValueForKey( info, "n" );
y += size;
CG_DrawBigString( 640 - ( Q_PrintStrlen( name ) * BIGCHAR_WIDTH), y, name, 0.5 );
return y + BIGCHAR_HEIGHT + 2;
}
/*
==================
CG_DrawSnapshot
==================
*/
static float CG_DrawSnapshot( float y ) {
char *s;
int w;
s = va( "time:%i snap:%i cmd:%i", cg.snap->serverTime,
cg.latestSnapshotNum, cgs.serverCommandSequence );
w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
CG_DrawBigString( 635 - w, y + 2, s, 1.0F);
return y + BIGCHAR_HEIGHT + 4;
}
/*
==================
CG_DrawFPS
==================
*/
#define FPS_FRAMES 4
static float CG_DrawFPS( float y ) {
char *s;
int w;
static int previousTimes[FPS_FRAMES];
static int index;
int i, total;
int fps;
static int previous;
int t, frameTime;
// don't use serverTime, because that will be drifting to
// correct for internet lag changes, timescales, timedemos, etc
t = trap_Milliseconds();
frameTime = t - previous;
previous = t;
previousTimes[index % FPS_FRAMES] = frameTime;
index++;
if ( index > FPS_FRAMES ) {
// average multiple frames together to smooth changes out a bit
total = 0;
for ( i = 0 ; i < FPS_FRAMES ; i++ ) {
total += previousTimes[i];
}
if ( !total ) {
total = 1;
}
fps = 1000 * FPS_FRAMES / total;
s = va( "%ifps", fps );
w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
CG_DrawBigString( 635 - w, y + 2, s, 1.0F);
}
return y + BIGCHAR_HEIGHT + 4;
}
/*
=================
CG_DrawTimer
=================
*/
static float CG_DrawTimer( float y ) {
char *s;
int w;
int mins, seconds, tens;
int msec;
msec = cg.time - cgs.levelStartTime;
seconds = msec / 1000;
mins = seconds / 60;
seconds -= mins * 60;
tens = seconds / 10;
seconds -= tens * 10;
s = va( "%i:%i%i", mins, tens, seconds );
w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
CG_DrawBigString( 635 - w, y + 2, s, 1.0F);
return y + BIGCHAR_HEIGHT + 4;
}
/*
=================
CG_DrawTeamOverlay
=================
*/
static float CG_DrawTeamOverlay( float y, qboolean right, qboolean upper ) {
int x, w, h, xx;
int i, j, len;
const char *p;
vec4_t hcolor;
int pwidth, lwidth;
int plyrs;
char st[16];
clientInfo_t *ci;
gitem_t *item;
int ret_y, count;
if ( !cg_drawTeamOverlay.integer ) {
return y;
}
if ( cg.snap->ps.persistant[PERS_TEAM] != TEAM_RED && cg.snap->ps.persistant[PERS_TEAM] != TEAM_BLUE ) {
return y; // Not on any team
}
plyrs = 0;
// max player name width
pwidth = 0;
count = (numSortedTeamPlayers > 8) ? 8 : numSortedTeamPlayers;
for (i = 0; i < count; i++) {
ci = cgs.clientinfo + sortedTeamPlayers[i];
if ( ci->infoValid && ci->team == cg.snap->ps.persistant[PERS_TEAM]) {
plyrs++;
len = CG_DrawStrlen(ci->name);
if (len > pwidth)
pwidth = len;
}
}
if (!plyrs)
return y;
if (pwidth > TEAM_OVERLAY_MAXNAME_WIDTH)
pwidth = TEAM_OVERLAY_MAXNAME_WIDTH;
// max location name width
lwidth = 0;
for (i = 1; i < MAX_LOCATIONS; i++) {
p = CG_ConfigString(CS_LOCATIONS + i);
if (p && *p) {
len = CG_DrawStrlen(p);
if (len > lwidth)
lwidth = len;
}
}
if (lwidth > TEAM_OVERLAY_MAXLOCATION_WIDTH)
lwidth = TEAM_OVERLAY_MAXLOCATION_WIDTH;
w = (pwidth + lwidth + 4 + 7) * TINYCHAR_WIDTH;
if ( right )
x = 640 - w;
else
x = 0;
h = plyrs * TINYCHAR_HEIGHT;
if ( upper ) {
ret_y = y + h;
} else {
y -= h;
ret_y = y;
}
if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_RED ) {
hcolor[0] = 1.0f;
hcolor[1] = 0.0f;
hcolor[2] = 0.0f;
hcolor[3] = 0.33f;
} else { // if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_BLUE )
hcolor[0] = 0.0f;
hcolor[1] = 0.0f;
hcolor[2] = 1.0f;
hcolor[3] = 0.33f;
}
trap_R_SetColor( hcolor );
CG_DrawPic( x, y, w, h, cgs.media.teamStatusBar );
trap_R_SetColor( NULL );
for (i = 0; i < count; i++) {
ci = cgs.clientinfo + sortedTeamPlayers[i];
if ( ci->infoValid && ci->team == cg.snap->ps.persistant[PERS_TEAM]) {
hcolor[0] = hcolor[1] = hcolor[2] = hcolor[3] = 1.0;
xx = x + TINYCHAR_WIDTH;
CG_DrawStringExt( xx, y,
ci->name, hcolor, qfalse, qfalse,
TINYCHAR_WIDTH, TINYCHAR_HEIGHT, TEAM_OVERLAY_MAXNAME_WIDTH);
if (lwidth) {
p = CG_ConfigString(CS_LOCATIONS + ci->location);
if (!p || !*p)
p = "unknown";
len = CG_DrawStrlen(p);
if (len > lwidth)
len = lwidth;
// xx = x + TINYCHAR_WIDTH * 2 + TINYCHAR_WIDTH * pwidth +
// ((lwidth/2 - len/2) * TINYCHAR_WIDTH);
xx = x + TINYCHAR_WIDTH * 2 + TINYCHAR_WIDTH * pwidth;
CG_DrawStringExt( xx, y,
p, hcolor, qfalse, qfalse, TINYCHAR_WIDTH, TINYCHAR_HEIGHT,
TEAM_OVERLAY_MAXLOCATION_WIDTH);
}
CG_GetColorForHealth( ci->health, ci->armor, hcolor );
Com_sprintf (st, sizeof(st), "%3i %3i", ci->health, ci->armor);
xx = x + TINYCHAR_WIDTH * 3 +
TINYCHAR_WIDTH * pwidth + TINYCHAR_WIDTH * lwidth;
CG_DrawStringExt( xx, y,
st, hcolor, qfalse, qfalse,
TINYCHAR_WIDTH, TINYCHAR_HEIGHT, 0 );
// draw weapon icon
xx += TINYCHAR_WIDTH * 3;
if ( cg_weapons[ci->curWeapon].weaponIcon ) {
CG_DrawPic( xx, y, TINYCHAR_WIDTH, TINYCHAR_HEIGHT,
cg_weapons[ci->curWeapon].weaponIcon );
} else {
CG_DrawPic( xx, y, TINYCHAR_WIDTH, TINYCHAR_HEIGHT,
cgs.media.deferShader );
}
// Draw powerup icons
if (right) {
xx = x;
} else {
xx = x + w - TINYCHAR_WIDTH;
}
for (j = 0; j <= PW_NUM_POWERUPS; j++) {
if (ci->powerups & (1 << j)) {
item = BG_FindItemForPowerup( j );
if (item) {
CG_DrawPic( xx, y, TINYCHAR_WIDTH, TINYCHAR_HEIGHT,
trap_R_RegisterShader( item->icon ) );
if (right) {
xx -= TINYCHAR_WIDTH;
} else {
xx += TINYCHAR_WIDTH;
}
}
}
}
y += TINYCHAR_HEIGHT;
}
}
return ret_y;
//#endif
}
/*
=====================
CG_DrawUpperRight
=====================
*/
static void CG_DrawUpperRight( void ) {
float y;
y = 0;
if ( cgs.gametype >= GT_TEAM && cg_drawTeamOverlay.integer == 1 ) {
y = CG_DrawTeamOverlay( y, qtrue, qtrue );
}
if ( cg_drawSnapshot.integer ) {
y = CG_DrawSnapshot( y );
}
if ( cg_drawFPS.integer ) {
y = CG_DrawFPS( y );
}
if ( cg_drawTimer.integer ) {
y = CG_DrawTimer( y );
}
if ( cg_drawAttacker.integer ) {
y = CG_DrawAttacker( y );
}
}
/*
===========================================================================================
LOWER RIGHT CORNER
===========================================================================================
*/
/*
=================
CG_DrawScores
Draw the small two score display
=================
*/
#ifndef MISSIONPACK
static float CG_DrawScores( float y ) {
const char *s;
int s1, s2, score;
int x, w;
int v;
vec4_t color;
float y1;
gitem_t *item;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -