/* ================= CG_DrawScoreboard Draw the normal in-game scoreboard ================= */ qboolean CG_DrawOldScoreboard( void ) { int y, i, n1, n2; float fade; float *fadeColor; char *s; int maxPlayers; int lineHeight; int topBorderSize, bottomBorderSize; CG_SetScreenPlacement(PLACE_CENTER, PLACE_CENTER); // don't draw amuthing if the menu or console is up if ( cg_paused.integer ) { return qfalse; } if ( cgs.gametype == GT_SINGLE_PLAYER && cg.cur_lc && cg.cur_lc->predictedPlayerState.pm_type == PM_INTERMISSION ) { return qfalse; } // don't draw scoreboard during death while warmup up if ( cg.warmup && cg.cur_lc && !cg.cur_lc->showScores ) { return qfalse; } if ( !cg.cur_lc || cg.cur_lc->showScores || cg.cur_lc->predictedPlayerState.pm_type == PM_DEAD || cg.cur_lc->predictedPlayerState.pm_type == PM_INTERMISSION ) { fade = 1.0; fadeColor = colorWhite; } else { fadeColor = CG_FadeColor( cg.cur_lc->scoreFadeTime, FADE_TIME ); if ( !fadeColor ) { // next time scoreboard comes up, don't print killer cg.cur_lc->killerName[0] = 0; return qfalse; } // ZTM: FIXME?: to actually fade, should be fade=fadeColor[3] and later CG_DrawString should use fadeColor fade = *fadeColor; } // fragged by ... line if ( cg.cur_lc && cg.cur_lc->killerName[0] ) { s = va("Fragged by %s", cg.cur_lc->killerName ); y = SB_HEADER - 6 - CG_DrawStringLineHeight( UI_BIGFONT ) * 2; CG_DrawString( SCREEN_WIDTH / 2, y, s, UI_CENTER|UI_DROPSHADOW|UI_BIGFONT, NULL ); } // current rank if ( cgs.gametype < GT_TEAM) { if (cg.cur_ps && cg.cur_ps->persistant[PERS_TEAM] != TEAM_SPECTATOR ) { s = va("%s place with %i", CG_PlaceString( cg.cur_ps->persistant[PERS_RANK] + 1 ), cg.cur_ps->persistant[PERS_SCORE] ); y = SB_HEADER - 6 - CG_DrawStringLineHeight( UI_BIGFONT ); CG_DrawString( SCREEN_WIDTH / 2, y, s, UI_CENTER|UI_DROPSHADOW|UI_BIGFONT, NULL ); } } else { if ( cg.teamScores[0] == cg.teamScores[1] ) { s = va("Teams are tied at %i", cg.teamScores[0] ); } else if ( cg.teamScores[0] >= cg.teamScores[1] ) { s = va("Red leads %i to %i",cg.teamScores[0], cg.teamScores[1] ); } else { s = va("Blue leads %i to %i",cg.teamScores[1], cg.teamScores[0] ); } y = SB_HEADER - 6 - CG_DrawStringLineHeight( UI_BIGFONT ); CG_DrawString( SCREEN_WIDTH / 2, y, s, UI_CENTER|UI_DROPSHADOW|UI_BIGFONT, NULL ); } // scoreboard y = SB_HEADER; CG_DrawPic( SB_SCORE_X + (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardScore ); CG_DrawPic( SB_PING_X - (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardPing ); CG_DrawPic( SB_TIME_X - (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardTime ); CG_DrawPic( SB_NAME_X - (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardName ); y = SB_TOP; // If there are more than SB_MAXPLAYERS_NORMAL, use the interleaved scores if ( cg.numScores > SB_MAXPLAYERS_NORMAL ) { maxPlayers = SB_MAXPLAYERS_INTER; lineHeight = SB_INTER_HEIGHT; topBorderSize = 8; bottomBorderSize = 16; } else { maxPlayers = SB_MAXPLAYERS_NORMAL; lineHeight = SB_NORMAL_HEIGHT; topBorderSize = 16; bottomBorderSize = 16; } localPlayer = qfalse; if ( cgs.gametype >= GT_TEAM ) { // // teamplay scoreboard // y += lineHeight/2; if ( cg.teamScores[0] >= cg.teamScores[1] ) { n1 = CG_TeamScoreboard( y, TEAM_RED, fade, maxPlayers, lineHeight ); CG_DrawTeamBackground( 0, y - topBorderSize, 640, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED ); y += (n1 * lineHeight) + BIGCHAR_HEIGHT; maxPlayers -= n1; n2 = CG_TeamScoreboard( y, TEAM_BLUE, fade, maxPlayers, lineHeight ); CG_DrawTeamBackground( 0, y - topBorderSize, 640, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE ); y += (n2 * lineHeight) + BIGCHAR_HEIGHT; maxPlayers -= n2; } else { n1 = CG_TeamScoreboard( y, TEAM_BLUE, fade, maxPlayers, lineHeight ); CG_DrawTeamBackground( 0, y - topBorderSize, 640, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE ); y += (n1 * lineHeight) + BIGCHAR_HEIGHT; maxPlayers -= n1; n2 = CG_TeamScoreboard( y, TEAM_RED, fade, maxPlayers, lineHeight ); CG_DrawTeamBackground( 0, y - topBorderSize, 640, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED ); y += (n2 * lineHeight) + BIGCHAR_HEIGHT; maxPlayers -= n2; } n1 = CG_TeamScoreboard( y, TEAM_SPECTATOR, fade, maxPlayers, lineHeight ); y += (n1 * lineHeight) + BIGCHAR_HEIGHT; } else { // // free for all scoreboard // n1 = CG_TeamScoreboard( y, TEAM_FREE, fade, maxPlayers, lineHeight ); y += (n1 * lineHeight) + BIGCHAR_HEIGHT; n2 = CG_TeamScoreboard( y, TEAM_SPECTATOR, fade, maxPlayers - n1, lineHeight ); y += (n2 * lineHeight) + BIGCHAR_HEIGHT; } if (cg.cur_ps && !localPlayer) { // draw local player at the bottom for ( i = 0 ; i < cg.numScores ; i++ ) { if ( cg.scores[i].playerNum == cg.cur_ps->playerNum ) { CG_DrawPlayerScore( y, &cg.scores[i], fadeColor, fade, lineHeight == SB_NORMAL_HEIGHT ); break; } } } return qtrue; }
// Note: Update UI_DrawString in q3_ui if arguments are changed. void CG_DrawStringCommon( int x, int y, const char* str, int style, const fontInfo_t *font, const vec4_t color, float scale, int maxChars, float shadowOffset, float gradient, int cursorPos, int cursorChar, float wrapX ) { int charh; vec4_t newcolor; vec4_t lowlight; const float *drawcolor; int decent; if( !str ) { return; } if ( !color ) { color = colorWhite; } if ((style & UI_BLINK) && ((cg.realTime/BLINK_DIVISOR) & 1)) return; if ( (style & UI_FONTMASK) == UI_NUMBERFONT ) { // the original number bitmaps already have a gradient if ( font->glyphs[(int)'a'].xSkip == 0 ) { style &= ~UI_GRADIENT; } } charh = font->pointSize; if ( shadowOffset == 0 && ( style & UI_DROPSHADOW ) ) { shadowOffset = 2; } if ( gradient == 0 && ( style & UI_GRADIENT ) ) { gradient = 0.4f; } if ( scale <= 0 ) { scale = charh / 48.0f; } else { charh = 48 * scale; } if ( !( style & UI_NOSCALE ) && cg.cur_lc ) { if ( cg.numViewports != 1 ) { shadowOffset *= cg_splitviewTextScale.value; scale *= cg_splitviewTextScale.value; charh *= cg_splitviewTextScale.value; } else { shadowOffset *= cg_hudTextScale.value; scale *= cg_hudTextScale.value; charh *= cg_hudTextScale.value; } } if (style & UI_PULSE) { lowlight[0] = 0.8*color[0]; lowlight[1] = 0.8*color[1]; lowlight[2] = 0.8*color[2]; lowlight[3] = 0.8*color[3]; CG_LerpColor(color,lowlight,newcolor,0.5+0.5*sin(cg.realTime/PULSE_DIVISOR)); drawcolor = newcolor; } else drawcolor = color; if ( wrapX <= 0 ) { switch (style & UI_FORMATMASK) { case UI_CENTER: // center justify at x x = x - Text_Width( str, font, scale, 0 ) / 2; break; case UI_RIGHT: // right justify at x x = x - Text_Width( str, font, scale, 0 ); break; case UI_LEFT: default: // left justify at x break; } switch (style & UI_VA_FORMATMASK) { case UI_VA_CENTER: // center justify at y y = y - charh /*Text_Height( str, font, scale, 0 )*/ / 2; break; case UI_VA_BOTTOM: // bottom justify at y y = y - charh /*Text_Height( str, font, scale, 0 )*/; break; case UI_VA_TOP: default: // top justify at y break; } } // // This function expects that y is top of line, text_paint expects at baseline // decent = -font->glyphs[(int)'g'].top + font->glyphs[(int)'g'].height; y = y + charh - decent * scale * font->glyphScale; if ( decent != 0 ) { // Make TrueType fonts line up with bigchars bitmap font which has 2 transparent pixels above glyphs at 16 point font size y += 2.0f * charh / 16.0f; } if ( cursorChar >= 0 ) { Text_PaintWithCursor( x, y, font, scale, drawcolor, str, cursorPos, cursorChar, 0, maxChars, shadowOffset, gradient, !!( style & UI_FORCECOLOR ), !!( style & UI_INMOTION ) ); } else if ( wrapX > 0 ) { // replace 'char height' in line height with our scaled charh // ZTM: TODO: This text gap handling is kind of messy. Passing scale to CG_DrawStringLineHeight might make cleaner code here. int gap = CG_DrawStringLineHeight( style | UI_NOSCALE ) - font->pointSize; if ( !( style & UI_NOSCALE ) && cg.cur_lc ) { if ( cg.numViewports != 1 ) { gap *= cg_splitviewTextScale.value; } else { gap *= cg_hudTextScale.value; } } Text_Paint_AutoWrapped( x, y, font, scale, drawcolor, str, 0, maxChars, shadowOffset, gradient, !!( style & UI_FORCECOLOR ), !!( style & UI_INMOTION ), wrapX, charh + gap, style ); } else { Text_Paint( x, y, font, scale, drawcolor, str, 0, maxChars, shadowOffset, gradient, !!( style & UI_FORCECOLOR ), !!( style & UI_INMOTION ) ); } }