Esempio n. 1
0
/*
* CG_DrawScoreboard
*/
void CG_DrawScoreboard( void )
{
	int pass;
	const char *ptr, *token, *layout;
	char title[MAX_CONFIGSTRING_CHARS], type;
	int team = TEAM_PLAYERS;
	int xpos;
	int ypos, yoffset, maxyoffset;
	struct qfontface_s *font;
	struct qfontface_s *monofont;
	struct qfontface_s *titlefont;
	int width, panelWidth;
	vec4_t whiteTransparent = { 1.0f, 1.0f, 1.0f, 0.5f };

	// no layout defined
	if( !cgs.configStrings[CS_SCB_PLAYERTAB_LAYOUT][0] )
		return;

	if( scoreboardString[0] != '&' ) // nothing to draw
		return;

	font = CG_ScoreboardFont( cg_scoreboardFontFamily, cg_scoreboardFontSize );
	monofont = CG_ScoreboardFont( cg_scoreboardMonoFontFamily, cg_scoreboardFontSize );
	titlefont = CG_ScoreboardFont( cg_scoreboardTitleFontFamily, cg_scoreboardTitleFontSize );

	xpos = (int)( cgs.vidWidth * 0.5 );
	ypos = (int)( cgs.vidHeight * 0.2 ) - 24 * cgs.vidHeight / 600;

	// draw title
	Q_strncpyz( title, cgs.configStrings[CS_GAMETYPETITLE], sizeof( title ) );
	if( !title[0] )
		Q_strncpyz( title, gs.gametypeName, sizeof( title ) );
	Q_strupr( title );

	trap_SCR_DrawString( xpos, ypos, ALIGN_CENTER_TOP, title, titlefont, whiteTransparent );
	ypos += trap_SCR_FontHeight( titlefont );
	trap_SCR_DrawStringWidth( xpos, ypos, ALIGN_CENTER_TOP, cgs.configStrings[CS_HOSTNAME], cgs.vidWidth*0.75, font, whiteTransparent );
	ypos += trap_SCR_FontHeight( font );

	// calculate the panel width from the layout
	panelWidth = 0;
	layout = cgs.configStrings[CS_SCB_PLAYERTAB_LAYOUT];
	while( SCR_GetNextColumnLayout( &layout, NULL, &type, &width, font ) != NULL )
	{
		if( !SCR_SkipColumn( type ) )
			panelWidth += width;
	}

	// parse and draw the scoreboard message
	for ( pass = 0; pass < 2; pass++ )
	{
		yoffset = 0;
		maxyoffset = 0;
		scr_numplayericons = 0;
		ptr = scoreboardString;
		while ( ptr )
		{
			token = COM_ParseExt( &ptr, true );
			if ( token[0] != '&' )
				break;

			if ( !Q_stricmp( token, "&t" ) ) // team tab
			{
				yoffset = 0;
				yoffset += SCR_DrawTeamTab( &ptr, &team, xpos, ypos + yoffset, panelWidth, font, titlefont, pass );
			}
			else if ( !Q_stricmp( token, "&p" ) ) // player tab
			{
				yoffset += SCR_DrawPlayerTab( &ptr, team, xpos, ypos + yoffset, panelWidth, font, pass );
			}
			else if ( !Q_stricmp( token, "&w" ) ) // list of challengers
			{
				if ( yoffset < maxyoffset )
					yoffset = maxyoffset;

				maxyoffset += SCR_DrawChallengers( &ptr, xpos, ypos + yoffset, panelWidth, font, pass );
			}
			else if ( !Q_stricmp( token, "&s" ) ) // list of spectators
			{
				if ( yoffset < maxyoffset )
					yoffset = maxyoffset;

				maxyoffset += SCR_DrawSpectators( &ptr, xpos, ypos + yoffset, panelWidth, font, true, "Spectators", colorYellow, pass );
			}
			else if( !Q_stricmp( token, "&y" ) ) // list of chasers
			{
				if( yoffset < maxyoffset )
					yoffset = maxyoffset;

				if( cg_showChasers->integer )
					maxyoffset += SCR_DrawSpectators( &ptr, xpos, ypos + yoffset, panelWidth, font, false, "Chasers", colorOrange, pass );
				else
					SCR_IgnoreSpectators( &ptr, false );
			}

			if ( yoffset > maxyoffset )
				maxyoffset = yoffset;
		}
		if( !pass )
			SCR_DrawPlayerIcons( font );
	}

	// add the player stats
	yoffset = maxyoffset + trap_SCR_FontHeight( font );
	yoffset += SCB_DrawPlayerStats( xpos, ypos + yoffset, monofont );
}
Esempio n. 2
0
/*
* SCR_DrawTeamTab
*/
static int SCR_DrawTeamTab( const char **ptrptr, int *curteam, int x, int y, int panelWidth, struct qfontface_s *font, struct qfontface_s *titleFont, int pass )
{
	const char *token;
	const char *layout, *titles;
	char type;
	int team, team_score, team_ping;
	int yoffset = 0, xoffset = 0;
	int dir = 0, align, width, height;
	vec4_t teamcolor = { 0.0f, 0.0f, 0.0f, 1.0f }, pingcolor;

	// team tab is always the same. Sets the current team and draws its score

	if( !(*ptrptr) || !(*ptrptr[0]) || *ptrptr[0] == '&' )
		return yoffset;

	team = CG_ParseValue( ptrptr );
	if( team < TEAM_PLAYERS || team > TEAM_BETA )
		CG_Error( "SCR_ParseTeamTab: Invalid team value\n" );

	*curteam = team;

	if( *ptrptr[0] == '&' )
		return yoffset;

	team_score = CG_ParseValue( ptrptr );

	if( *ptrptr[0] == '&' )
		return yoffset;

	team_ping = CG_ParseValue( ptrptr );

	if( ( team == TEAM_ALPHA ) || ( team == TEAM_BETA ) )
		CG_TeamColor( team, teamcolor );
	teamcolor[3] = SCB_BACKGROUND_ALPHA; // make transparent

	if( GS_TeamBasedGametype() ) // we only draw the team tabs in team based gametypes
	{
		dir = ( team == TEAM_ALPHA ) ? -1 : 1;
		align = ( team == TEAM_ALPHA ) ? ALIGN_RIGHT_TOP : ALIGN_LEFT_TOP;

		// draw the tab

		xoffset = ( SCB_CENTERMARGIN * dir );

		width = ( cgs.vidWidth * 0.5 ) - SCB_CENTERMARGIN;
		height = trap_SCR_FontHeight( titleFont ) + 2;

		if( !pass ) {
			CG_DrawAlignPic( x + xoffset, y + yoffset + SCB_SCORENUMBER_SIZE - height,
				width, height, align, teamcolor, cgs.shaderWhite );
		}

		if( pass ) {
			xoffset += ( ( 16 * cgs.vidHeight / 600 ) * dir );

			CG_DrawHUDNumeric( x + xoffset, y + yoffset, align, colorWhite,
				SCB_SCORENUMBER_SIZE, SCB_SCORENUMBER_SIZE, team_score );

			xoffset += ( ( SCB_SCORENUMBER_SIZE * strlen(va("%i", team_score)) + ( 16 * cgs.vidHeight / 600 ) ) * dir );
			trap_SCR_DrawStringWidth( x + xoffset + ( ( SCB_TINYFIELD_PIXELWIDTH + ( 16 * cgs.vidHeight / 600 ) ) * dir ),
				y + yoffset + SCB_SCORENUMBER_SIZE - (trap_SCR_FontHeight( titleFont ) + 1),
				align, GS_TeamName( team ), SCB_TEAMNAME_PIXELWIDTH, titleFont, colorWhite );

			CG_PingColor( team_ping, pingcolor );
			trap_SCR_DrawStringWidth( x + xoffset,
				y + yoffset + SCB_SCORENUMBER_SIZE - (trap_SCR_FontHeight( font ) + 1),
				align, va( "%i", team_ping ), SCB_TINYFIELD_PIXELWIDTH, font, pingcolor );
		}

		yoffset += SCB_SCORENUMBER_SIZE;
	}
	else
	{
		dir = 0;
		align = ALIGN_CENTER_TOP;
	}

	// draw the player tab column titles
	layout = cgs.configStrings[CS_SCB_PLAYERTAB_LAYOUT];
	titles = cgs.configStrings[CS_SCB_PLAYERTAB_TITLES];

	height = trap_SCR_FontHeight( font );

	// start from the center again
	xoffset = CG_HorizontalAlignForWidth( 0, align, panelWidth );
	xoffset += ( SCB_CENTERMARGIN * dir );

	while( ( token = SCR_GetNextColumnLayout( &layout, &titles, &type, &width, font ) ) != NULL )
	{
		if( SCR_SkipColumn( type ) )
			continue;

		if( width )
		{
			if( pass ) {
				trap_SCR_DrawClampString( x + xoffset, y + yoffset, CG_TranslateString( token ),
					x + xoffset, y + yoffset, x + xoffset + width, y + yoffset + height, font, colorWhite );
			}
			xoffset += width;
		}
	}

	yoffset += trap_SCR_FontHeight( font );

	return yoffset;
}
Esempio n. 3
0
void CG_Democam_DrawCenterSubtitle( int y, unsigned int maxwidth, struct qfontface_s *font, char *text ) {
	char *ptr, *s, *t, c, d;
	int x = cgs.vidWidth / 2;

	if( !text || !text[0] ) {
		return;
	}

	int shadowOffset = 2 * cgs.vidHeight / 600;
	if( !shadowOffset ) {
		shadowOffset = 1;
	}

	if( !maxwidth || trap_SCR_strWidth( text, font, 0 ) <= maxwidth ) {
		trap_SCR_DrawStringWidth( x + shadowOffset, y + shadowOffset, ALIGN_CENTER_TOP, COM_RemoveColorTokens( text ), maxwidth, font, colorBlack );
		trap_SCR_DrawStringWidth( x, y, ALIGN_CENTER_TOP, text, maxwidth, font, colorWhite );
		return;
	}

	t = s = ptr = text;
	while( *s ) {
		while( *s && *s != ' ' && *s != '\n' )
			s++;

		if( ( !*s || *s == '\n' ) && trap_SCR_strWidth( ptr, font, 0 ) < maxwidth ) { // new line or end of text, in both cases force write
			c = *s;
			*s = 0;
			trap_SCR_DrawStringWidth( x + shadowOffset, y + shadowOffset, ALIGN_CENTER_TOP, COM_RemoveColorTokens( ptr ), maxwidth, font, colorBlack );
			trap_SCR_DrawStringWidth( x, y, ALIGN_CENTER_TOP, ptr, maxwidth, font, colorWhite );
			*s = c;

			if( !*s ) {
				break;
			}

			t = s;
			s++;
			ptr = s;
		} else {
			c = *s;
			*s = 0;

			if( trap_SCR_strWidth( ptr, font, 0 ) < maxwidth ) {
				*s = c;
				t = s;
				s++;
				continue;
			}

			*s = c;
			d = *t;
			*t = 0;
			trap_SCR_DrawStringWidth( x + shadowOffset, y + shadowOffset, ALIGN_CENTER_TOP, COM_RemoveColorTokens( ptr ), maxwidth, font, colorBlack );
			trap_SCR_DrawStringWidth( x, y, ALIGN_CENTER_TOP, ptr, maxwidth, font, colorWhite );
			*t = d;
			s = t;
			s++;
			ptr = s;
		}

		y += trap_SCR_FontHeight( font );
	}
}
Esempio n. 4
0
/*
* SCB_DrawPlayerStats
*/
static int SCB_DrawPlayerStats( int x, int y, struct qfontface_s *font )
{
	int xoffset, yoffset, lines;
	int i, j, num_weapons, weap, xpos, width, done;
	gsitem_t *it;
	char string[MAX_STRING_CHARS];
	vec4_t color = { 0.5, 0.5, 0.5, 0.5f };

	// don't display stats
	if( !cg_scoreboardStats->integer )
		return 0;

	// total number of weapon
	num_weapons = WEAP_TOTAL-WEAP_GUNBLADE;

	width = ( SCB_TINYFIELD_PIXELWIDTH + 2 * SCB_SMALLFIELD_PIXELWIDTH ) * 2 + SCB_SMALLFIELD_PIXELWIDTH;

	xpos = -width / 2;

	// Center the box
	xoffset = xpos;
	yoffset = trap_SCR_FontHeight( font );

	// Room for header, it's actually written later if we have at least one stat
	yoffset += trap_SCR_FontHeight( font );

	lines = 0;
	for( i = 0; i < num_weapons; )
	{
		xoffset = xpos;

		// two weapons per line
		for( j = 0, done = 0; done < 2 && i + j < num_weapons; j++ )
		{
			weap = WEAP_GUNBLADE + i + j;

			if( scb_player_stats[2*( i+j )] == -1 && scb_player_stats[2*( i+j )+1] == -1 )
				continue;

			it = GS_FindItemByTag( weap );

			// short name
			Q_snprintfz( string, sizeof( string ), "%s%2s", it->color, it->shortname );
			trap_SCR_DrawStringWidth( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, string, SCB_TINYFIELD_PIXELWIDTH, font, colorWhite );

			Q_snprintfz( string, sizeof( string ), "%2d%c", scb_player_stats[2*( i+j )+1], '%' );
			trap_SCR_DrawStringWidth( x + xoffset + 2 * SCB_TINYFIELD_PIXELWIDTH, y + yoffset, ALIGN_CENTER_TOP, string, 2*SCB_SMALLFIELD_PIXELWIDTH, font, colorWhite );

			// separator
			xoffset = 0;
			done++;
		}

		// next line
		if( done > 0 )
		{
			lines++;
			yoffset += trap_SCR_FontHeight( font );
		}

		i += j;
	}

	if( lines )
	{
		// if we drew anything, draw header and box too
		xoffset = xpos;
		yoffset = trap_SCR_FontHeight( font );

		// header
		trap_SCR_DrawStringWidth( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, 
			CG_TranslateString( "Weapon stats" ), width, font, colorMdGrey );
		yoffset += trap_SCR_FontHeight( font );

		// box
		trap_R_DrawStretchPic( x + xoffset - SCB_TINYFIELD_PIXELWIDTH/2, y + yoffset, width + SCB_TINYFIELD_PIXELWIDTH,
			lines * trap_SCR_FontHeight( font ), 0, 0, 1, 1, color, cgs.shaderWhite );

		return ( trap_SCR_FontHeight( font ) * ( 2+lines ) );
	}

	return 0;
}
Esempio n. 5
0
/*
* UI_DrawConnectScreen
*/
void UI_DrawConnectScreen( const char *serverName, const char *rejectmessage, int downloadType, const char *downloadFilename,
						  float downloadPercent, int downloadSpeed, int connectCount, qboolean demoplaying, qboolean backGround )
{
	qboolean localhost, design = qfalse;
	char str[MAX_QPATH];
	int x, y, xoffset, yoffset, width, height;
	unsigned int maxwidth;
	qboolean downloadFromWeb;
	char hostName[MAX_CONFIGSTRING_CHARS], mapname[MAX_CONFIGSTRING_CHARS], mapmessage[MAX_CONFIGSTRING_CHARS],
		gametype[MAX_CONFIGSTRING_CHARS], gametypeTitle[MAX_CONFIGSTRING_CHARS],
		gametypeVersion[MAX_CONFIGSTRING_CHARS], gametypeAuthor[MAX_CONFIGSTRING_CHARS],
		matchName[MAX_CONFIGSTRING_CHARS];

	uis.demoplaying = demoplaying;

	//trap_S_StopBackgroundTrack();

	localhost = (qboolean)( !serverName || !serverName[0] || !Q_stricmp( serverName, "localhost" ) );

	trap_GetConfigString( CS_MAPNAME, mapname, sizeof( mapname ) );
	trap_GetConfigString( CS_MESSAGE, mapmessage, sizeof( mapmessage ) );

	if( backGround )
	{
		Q_snprintfz( str, sizeof( str ), UI_SHADER_BACKGROUND, uis.backgroundNum );
		trap_R_DrawStretchPic( 0, 0, uis.vidWidth, uis.vidHeight, 0, 0, 1, 1, colorWhite, trap_R_RegisterPic( str ) );
	}

	//
	// not yet connected
	//

	x = 64;
	y = 64;
	xoffset = yoffset = 0;

	if( demoplaying )
		Q_snprintfz( str, sizeof( str ), "Loading demo: %s", serverName );
	else if( localhost )
		Q_strncpyz( str, "Loading...", sizeof( str ) );
	else if( mapname[0] )
		Q_snprintfz( str, sizeof( str ), "Connecting to %s", serverName );
	else
		Q_snprintfz( str, sizeof( str ), "Awaiting connection... %i", connectCount );

	trap_SCR_DrawString( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, str, uis.fontSystemBig, colorWhite );
	yoffset += trap_SCR_strHeight( uis.fontSystemBig );

	if( design && !rejectmessage )
		rejectmessage = "Connection was interrupted because the weather sux :P";

	if( rejectmessage )
	{
		x = uis.vidWidth / 2;
		y = uis.vidHeight / 3;

		height = trap_SCR_strHeight( uis.fontSystemMedium ) * 4;
		Q_strncpyz( str, "Refused: ", sizeof( str ) );
		width = max( trap_SCR_strWidth( str, uis.fontSystemMedium, 0 ), trap_SCR_strWidth( rejectmessage, uis.fontSystemSmall, 0 ) );
		width += 32 * 2;

		xoffset = UISCR_HorizontalAlignOffset( ALIGN_CENTER_MIDDLE, width );
		yoffset = UISCR_VerticalAlignOffset( ALIGN_CENTER_MIDDLE, height );

		UI_DrawBox( x + xoffset, y + yoffset, width, height, colorWarsowOrange, colorWhite, NULL, colorDkGrey );

		yoffset += trap_SCR_strHeight( uis.fontSystemMedium );
		xoffset += 32;

		trap_SCR_DrawString( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, str, uis.fontSystemMedium, colorWhite );
		yoffset += trap_SCR_strHeight( uis.fontSystemMedium );

		trap_SCR_DrawString( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, rejectmessage, uis.fontSystemSmall, colorBlack );

		return;
	}

	if( mapname[0] )
	{
		char levelshot[MAX_QPATH];
		struct shader_s *levelshotShader;
		qboolean isDefaultlevelshot = qtrue;

		//
		// connected
		//

		x = 64;
		y = uis.vidHeight - 300;
		xoffset = yoffset = 0;
		width = uis.vidWidth;
		height = 200;

		UI_DrawBox( x + xoffset, y + yoffset, width, height, colorWarsowPurple, colorWhite, NULL, colorDkGrey );
		xoffset += 16;
		yoffset += 16 + 4;

		maxwidth = uis.vidWidth - ( x + xoffset );

		trap_GetConfigString( CS_HOSTNAME, hostName, sizeof( hostName ) );
		trap_GetConfigString( CS_GAMETYPENAME, gametype, sizeof( gametype ) );
		trap_GetConfigString( CS_GAMETYPETITLE, gametypeTitle, sizeof( gametypeTitle ) );
		trap_GetConfigString( CS_GAMETYPEVERSION, gametypeVersion, sizeof( gametypeVersion ) );
		trap_GetConfigString( CS_GAMETYPEAUTHOR, gametypeAuthor, sizeof( gametypeAuthor ) );
		trap_GetConfigString( CS_MATCHNAME, matchName, sizeof( matchName ) );

		Q_snprintfz( levelshot, sizeof( levelshot ), "levelshots/%s.jpg", mapname );

		levelshotShader = trap_R_RegisterLevelshot( levelshot, uis.whiteShader, &isDefaultlevelshot );

		if( !isDefaultlevelshot )
		{
			int lw, lh, lx, ly;

			lh = height - 8;
			lw = lh * ( 4.0f/3.0f );
			lx = uis.vidWidth - lw;
			ly = y + 4;

			trap_R_DrawStretchPic( lx, ly, lw, lh, 0, 0, 1, 1, colorWhite, levelshotShader );
		}

		if( !localhost && !demoplaying )
		{
			Q_snprintfz( str, sizeof( str ), "Server: %s", hostName );
			trap_SCR_DrawStringWidth( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, str, maxwidth, uis.fontSystemSmall, colorWhite );
			yoffset += trap_SCR_strHeight( uis.fontSystemSmall ) + 8;
		}

		if( mapmessage[0] && Q_stricmp( mapname, mapmessage ) )
		{
			Q_snprintfz( str, sizeof( str ), "Level: "S_COLOR_ORANGE"%s", COM_RemoveColorTokens( mapmessage ) );
			trap_SCR_DrawStringWidth( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, str, maxwidth, uis.fontSystemSmall, colorWhite );
			yoffset += trap_SCR_strHeight( uis.fontSystemSmall ) + 8;
		}

		Q_snprintfz( str, sizeof( str ), "Map: %s", mapname );
		trap_SCR_DrawStringWidth( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, str, maxwidth, uis.fontSystemSmall, colorWhite );
		yoffset += trap_SCR_strHeight( uis.fontSystemSmall ) + 8;

		if( matchName[0] )
		{
			Q_snprintfz( str, sizeof( str ), "Match: %s", matchName );
			trap_SCR_DrawStringWidth( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, str, maxwidth, uis.fontSystemSmall, colorWhite );
			yoffset += trap_SCR_strHeight( uis.fontSystemSmall ) + 8;
		}
		yoffset += trap_SCR_strHeight( uis.fontSystemSmall ) + 8;

		Q_snprintfz( str, sizeof( str ), "Gametype: "S_COLOR_ORANGE"%s", COM_RemoveColorTokens( gametypeTitle ) );
		trap_SCR_DrawStringWidth( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, str, maxwidth, uis.fontSystemSmall, colorWhite );
		yoffset += trap_SCR_strHeight( uis.fontSystemSmall ) + 8;

		Q_snprintfz( str, sizeof( str ), "Version: %s", COM_RemoveColorTokens( gametypeVersion ) );
		trap_SCR_DrawStringWidth( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, str, maxwidth, uis.fontSystemSmall, colorWhite );
		yoffset += trap_SCR_strHeight( uis.fontSystemSmall ) + 8;

		Q_snprintfz( str, sizeof( str ), "Author: %s", gametypeAuthor );
		trap_SCR_DrawStringWidth( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, str, maxwidth, uis.fontSystemSmall, colorWhite );
		yoffset += trap_SCR_strHeight( uis.fontSystemSmall ) + 8;
	}

	// downloading

	if( design && !downloadFilename )
	{
		downloadFilename = "http://www.warsow.net/autoupdate/basewsw/map_wdm9a.pk3";
		downloadType = 2;
		downloadPercent = 65.8;
		downloadSpeed = 325;
	}

	if( downloadType && downloadFilename )
	{
		size_t len;
		const char *s;

		downloadFromWeb = ( downloadType == 2 );

		x = uis.vidWidth / 2;
		y = uis.vidHeight / 3;
		width = 400;
		height = 128 - trap_SCR_strHeight( uis.fontSystemSmall );
		if( uis.vidWidth <= width )
			width = uis.vidWidth - 64;

		maxwidth = width - 48;

		xoffset = UISCR_HorizontalAlignOffset( ALIGN_CENTER_MIDDLE, width );
		yoffset = UISCR_VerticalAlignOffset( ALIGN_CENTER_MIDDLE, height );

		// adjust the box size for the extra number of lines needed to draw the file path
		s = downloadFilename;
		while( ( len = trap_SCR_StrlenForWidth( s, uis.fontSystemSmall, maxwidth ) ) > 0 )
		{
			s += len;
			height += trap_SCR_strHeight( uis.fontSystemSmall );
		}

		UI_DrawBox( x + xoffset, y + yoffset, width, height, colorWarsowPurple, colorWhite, NULL, colorDkGrey );

		xoffset += 24;
		yoffset += 24;

		trap_SCR_DrawStringWidth( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, downloadFromWeb ? "Downloading from web" : "Downloading from server", maxwidth, uis.fontSystemSmall, colorWhite );
		yoffset += trap_SCR_strHeight( uis.fontSystemSmall );

		s = downloadFilename;
		while( ( len = trap_SCR_DrawStringWidth( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, s, maxwidth, uis.fontSystemSmall, colorWhite ) ) > 0 )
		{
			s += len;
			yoffset += trap_SCR_strHeight( uis.fontSystemSmall );
		}

		yoffset += 16;

		UI_DrawPicBar( x + xoffset, y + yoffset, maxwidth, 24, ALIGN_LEFT_TOP, downloadPercent, trap_R_RegisterPic( "gfx/ui/progressbar" ),colorDkGrey, colorOrange );
		Q_snprintfz( str, sizeof( str ), "%3.1f%c", downloadPercent, '%' );
		trap_SCR_DrawStringWidth( x + xoffset + 12, y + yoffset + 12, ALIGN_LEFT_MIDDLE, str, maxwidth, uis.fontSystemSmall, colorWhite );
		Q_snprintfz( str, sizeof( str ), "%ik/s", downloadSpeed );
		trap_SCR_DrawStringWidth( x + xoffset + maxwidth - 12, y + yoffset + 12, ALIGN_RIGHT_MIDDLE, str, maxwidth, uis.fontSystemSmall, colorWhite );

		yoffset += 24 + 8;
	}
}