Пример #1
0
void UI_DrawScaledProportionalString( int x, int y, const char* str, int style, const vector4 *color, float scale ) {
	// having all these different style defines (1 for UI, one for CG, and now one for the re->font stuff)
	//	is dumb, but for now...
	//
	int iStyle = 0;

	switch ( style & (UI_LEFT | UI_CENTER | UI_RIGHT) ) {
	default:
	case UI_LEFT:
		// nada...
		break;

	case UI_CENTER:
		x -= CG_Text_Width( str, scale, FONT_MEDIUM ) / 2;
		break;

	case UI_RIGHT:
		x -= CG_Text_Width( str, scale, FONT_MEDIUM ) / 2;
		break;
	}

	if ( style & UI_DROPSHADOW )
		iStyle = ITEM_TEXTSTYLE_SHADOWED;
	else if ( style & (UI_BLINK | UI_PULSE) )
		iStyle = ITEM_TEXTSTYLE_BLINK;

	CG_Text_Paint( x, y, scale, color, str, 0, 0, iStyle, FONT_MEDIUM );
}
Пример #2
0
void JP_ChatboxDraw( void )
{
	int i = MAX_CHATBOX_ENTRIES-min( cg_chatboxLineCount.integer, currentChatbox->numActiveLines );
	int numLines = 0;
	int done = 0;
	chatEntry_t *last = NULL;

	if ( cg.scoreBoardShowing && !(cg.snap && cg.snap->ps.pm_type == PM_INTERMISSION) )
		return;

	//i is the ideal index. Now offset for scrolling
	i += currentChatbox->scrollAmount;

#if defined(_WIN32) && !defined(OPENJK)
#if 0
	if ( (trap->Key_GetCatcher() & KEYCATCH_MESSAGE) )
	{
		int overStrike = *(int *)0x8859E0;
		int cls_realtime = *(int *)0x8AF224;
		int chatTeam = *(int *)0x8868EC;
		int chatClient = *(int *)0x8868E8;
		char cursorChar = overStrike ? '|' : '_';
		char message[256] = { 0 };
		char name[36] = { 0 };
		char tmp[256] = { 0 };
		int cursorOffset = 0;

		if ( chatTeam )
		{
			Q_strncpyz( message, "^5Say team", sizeof( message ) );
		}
		else
		{
			if ( chatClient == -1 )
				Q_strncpyz( message, "^2Say", sizeof( message ) );
			else
			{
				Q_strncpyz( name, cgs.clientinfo[chatClient].name, sizeof( name ) );
				Q_CleanStr( name );
				Com_sprintf( message, sizeof( message ), "^6Tell (%s)", name );
			}
		}
		cursorOffset = CG_Text_Width( va( "%s: ^7", message ), 64.0, JP_GetChatboxFont() );

		CG_Text_Paint( cg_hudChatX.value, cg_hudChatY.value + (cg_chatLH.value*cg_chatLines.integer), cg_hudChatS.value, colorWhite, va( "%s: ^7%s", message, chatField->buffer ), 0.0f, 0, ITEM_TEXTSTYLE_OUTLINED, JP_GetChatboxFont() );
		Q_strncpyz( tmp, chatField->buffer, min( sizeof( tmp ), chatField->cursor )+1 );
		CG_Text_Paint( cg_hudChatX.value + (CG_Text_Width( tmp, 64.0, JP_GetChatboxFont() )*cg_hudChatS.value*0.015625) + (cursorOffset*cg_hudChatS.value*0.015625), cg_hudChatY.value + (cg_chatLH.value*cg_chatLines.integer), cg_hudChatS.value, colorWhite, va( "%c", ( (int)( cls_realtime >> 8 ) & 1 ) ? '\n' : cursorChar ), 0.0f, 0, ITEM_TEXTSTYLE_OUTLINED, JP_GetChatboxFont() );
	}
Пример #3
0
static void CG_DrawPlayerAmmoValue(rectDef_t *rect, float scale, vector4 *color, qhandle_t shader, int textStyle) {
	char	num[16];
	int		value;
	float	width;
	centity_t	*cent;
	playerState_t	*ps;

	cent = &cg_entities[cg.snap->ps.clientNum];
	ps = &cg.snap->ps;

	if ( cent->currentState.weapon ) {
		value = ps->ammo[cent->currentState.weapon];
		if ( value > -1 ) {
			if (shader) {
				trap->R_SetColor( color );
				CG_DrawPic(rect->x, rect->y, rect->w, rect->h, shader);
				trap->R_SetColor( NULL );
			} else {
				Com_sprintf (num, sizeof(num), "%i", value);
				width = CG_Text_Width(num, scale, 0);
				CG_Text_Paint(rect->x + (rect->w - width) / 2, rect->y + rect->h, scale, color, num, 0, 0, textStyle);
			}
		}
	}

}
Пример #4
0
void CG_DrawMedal(int ownerDraw, rectDef_t *rect, float scale, vector4 *color, qhandle_t shader) {
	score_t *score = &cg.scores[cg.selectedScore];
	float value = 0;
	const char *text = NULL;
	color->a = 0.25f;

	switch (ownerDraw) {
	case CG_ACCURACY:
		value = (float)score->accuracy;
		break;
	case CG_ASSISTS:
		value = (float)score->assistCount;
		break;
	case CG_DEFEND:
		value = (float)score->defendCount;
		break;
	case CG_EXCELLENT:
		value = (float)score->excellentCount;
		break;
	case CG_IMPRESSIVE:
		value = (float)score->impressiveCount;
		break;
	case CG_PERFECT:
		value = (float)score->perfect;
		break;
	case CG_CAPTURES:
		value = (float)score->captures;
		break;
	}

	if (value > 0) {
		if (ownerDraw != CG_PERFECT) {
			if (ownerDraw == CG_ACCURACY) {
				text = va("%i%%", (int)value);
				if (value > 50) {
					color->a = 1.0f;
				}
			} else {
				text = va("%i", (int)value);
				color->a = 1.0f;
			}
		} else {
			if (value) {
				color->a = 1.0f;
			}
			text = "Wow";
		}
	}

	trap->R_SetColor(color);
	CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader );

	if (text) {
		color->a = 1.0f;
		value = (float)CG_Text_Width(text, scale, 0);
		CG_Text_Paint(rect->x + (rect->w - value) / 2, rect->y + rect->h + 10 , scale, color, text, 0, 0, 0);
	}
	trap->R_SetColor(NULL);

}
Пример #5
0
int CG_TrimLeftPixels(char *instr, float scale, float w, int size)
{
	char            buffer[1024];
	char           *p, *s;
	int             tw;
	int             i;

	Q_strncpyz(buffer, instr, 1024);
	memset(instr, 0, size);

	for(i = 0, p = buffer; *p; p++, i++)
	{
		instr[i] = *p;
		tw = CG_Text_Width(instr, scale, 0);
		if(tw >= w)
		{
			memset(instr, 0, size);
			for(s = instr, p = &buffer[i + 1]; *p && ((s - instr) < size); p++, s++)
			{
				*s = *p;
			}
			return tw - w;
		}
	}

	return -1;
}
Пример #6
0
static void CG_DrawKiller(rectDef_t *rect, float scale, vector4 *color, qhandle_t shader, int textStyle ) {
	// fragged by ... line
	if ( cg.killerName[0] ) {
		float x = rect->x + rect->w / 2;
		CG_Text_Paint(x - CG_Text_Width(CG_GetKillerText(), scale, 0) / 2, rect->y + rect->h, scale, color, CG_GetKillerText(), 0, 0, textStyle);
	}

}
Пример #7
0
void CG_DrawTeamSpectators(rectDef_t *rect, float scale, vector4 *color, qhandle_t shader) {
	if (cg.spectatorLen) {
		float maxX;

		if (cg.spectatorWidth == -1) {
			cg.spectatorWidth = 0;
			cg.spectatorPaintX = rect->x + 1;
			cg.spectatorPaintX2 = -1;
		}

		if (cg.spectatorOffset > cg.spectatorLen) {
			cg.spectatorOffset = 0;
			cg.spectatorPaintX = rect->x + 1;
			cg.spectatorPaintX2 = -1;
		}

		if (cg.time > cg.spectatorTime) {
			cg.spectatorTime = cg.time + 10;
			if (cg.spectatorPaintX <= rect->x + 2) {
				if (cg.spectatorOffset < cg.spectatorLen) {
					cg.spectatorPaintX += CG_Text_Width(&cg.spectatorList[cg.spectatorOffset], scale, 1) - 1;
					cg.spectatorOffset++;
				} else {
					cg.spectatorOffset = 0;
					if (cg.spectatorPaintX2 >= 0) {
						cg.spectatorPaintX = cg.spectatorPaintX2;
					} else {
						cg.spectatorPaintX = rect->x + rect->w - 2;
					}
					cg.spectatorPaintX2 = -1;
				}
			} else {
				cg.spectatorPaintX--;
				if (cg.spectatorPaintX2 >= 0) {
					cg.spectatorPaintX2--;
				}
			}
		}

		maxX = rect->x + rect->w - 2;
		CG_Text_Paint_Limit(&maxX, (float)cg.spectatorPaintX, rect->y + rect->h - 3, scale, color, &cg.spectatorList[cg.spectatorOffset], 0, 0); 
		if (cg.spectatorPaintX2 >= 0) {
			float maxX2 = rect->x + rect->w - 2;
			CG_Text_Paint_Limit(&maxX2, (float)cg.spectatorPaintX2, rect->y + rect->h - 3, scale, color, cg.spectatorList, 0, cg.spectatorOffset); 
		}
		if (cg.spectatorOffset && maxX > 0) {
			// if we have an offset ( we are skipping the first part of the string ) and we fit the string
			if (cg.spectatorPaintX2 == -1) {
				cg.spectatorPaintX2 = rect->x + rect->w - 2;
			}
		} else {
			cg.spectatorPaintX2 = -1;
		}

	}
}
Пример #8
0
void CG_FitTextToWidth2(char *instr, float scale, float w, int size)
{
	char            buffer[1024];
	char           *s, *p, *c, *ls;
	int             l;

	Q_strncpyz(buffer, instr, 1024);
	memset(instr, 0, size);

	c = s = instr;
	p = buffer;
	ls = NULL;
	l = 0;
	while(*p)
	{
		*c = *p++;
		l++;

		if(*c == ' ')
		{
			ls = c;
		}						// store last space, to try not to break mid word

		c++;

		if(*p == '\n')
		{
			s = c + 1;
			l = 0;
		}
		else if(CG_Text_Width(s, scale, 0) > w)
		{
			if(ls)
			{
				*ls = '\n';
				s = ls + 1;
			}
			else
			{
				*c = *(c - 1);
				*(c - 1) = '\n';
				s = c++;
			}

			ls = NULL;
			l = 0;
		}
	}

	if(c != buffer && (*(c - 1) != '\n'))
	{
		*c++ = '\n';
	}

	*c = '\0';
}
Пример #9
0
/*
===================
CG_DrawItemSelectText
===================
*/
void CG_DrawItemSelectText( rectDef_t *rect, float scale, int textStyle )
{
  int x, w;
  char  *name;
  float *color;

  color = CG_FadeColor( cg.weaponSelectTime, WEAPON_SELECT_TIME );
  if( !color )
    return;

  trap_R_SetColor( color );

  // draw the selected name
  if( cg.weaponSelect <= 32 )
  {
    if( cg_weapons[ cg.weaponSelect ].registered &&
        BG_InventoryContainsWeapon( cg.weaponSelect, cg.snap->ps.stats ) )
    {
      if( ( name = cg_weapons[ cg.weaponSelect ].humanName ) )
      {
        w = CG_Text_Width( name, scale, 0 );
        x = rect->x + rect->w / 2;
        CG_Text_Paint( x - w / 2, rect->y + rect->h, scale, color, name, 0, 0, textStyle );
      }
    }
  }
  else if( cg.weaponSelect > 32 )
  {
    if( cg_upgrades[ cg.weaponSelect - 32 ].registered &&
        BG_InventoryContainsUpgrade( cg.weaponSelect - 32, cg.snap->ps.stats ) )
    {
      if( ( name = cg_upgrades[ cg.weaponSelect - 32 ].humanName ) )
      {
        w = CG_Text_Width( name, scale, 0 );
        x = rect->x + rect->w / 2;
        CG_Text_Paint( x - w / 2, rect->y + rect->h, scale, color, name, 0, 0, textStyle );
      }
    }
  }

  trap_R_SetColor( NULL );
}
Пример #10
0
void UI_DrawProportionalString( int x, int y, const char* str, int style, vec4_t color ) 
{
	// having all these different style defines (1 for UI, one for CG, and now one for the re->font stuff) 
	//	is dumb, but for now...
	//
	int iStyle = 0;
	int iMenuFont = (style & UI_SMALLFONT) ? FONT_SMALL : FONT_MEDIUM;

	switch (style & (UI_LEFT|UI_CENTER|UI_RIGHT))
	{
		default:
		case UI_LEFT:
		{
			// nada...
		}
		break;

		case UI_CENTER:
		{
			x -= CG_Text_Width(str, 1.0, iMenuFont) / 2;
		}
		break;

		case UI_RIGHT:
		{
			x -= CG_Text_Width(str, 1.0, iMenuFont) / 2;
		}
		break;
	}

	if (style & UI_DROPSHADOW)
	{
		iStyle = ITEM_TEXTSTYLE_SHADOWED;
	}
	else
	if ( style & (UI_BLINK|UI_PULSE) )
	{
		iStyle = ITEM_TEXTSTYLE_BLINK;
	}

	CG_Text_Paint(x, y, 1.0, color, str, 0, 0, iStyle, iMenuFont);
}
Пример #11
0
static void CG_Text_Paint_Limit(float *maxX, float x, float y, float scale, vector4 *color, const char* text, float adjust, int limit) {
	size_t len, count;
	vector4 newColor;
	glyphInfo_t *glyph;
	if (text) {
		const char *s = text;
		float max = *maxX;
		float useScale;
		fontInfo_t *font = &cgDC.Assets.textFont;
		if (scale <= ui_smallFont->value) {
			font = &cgDC.Assets.smallFont;
		} else if (scale > ui_bigFont->value) {
			font = &cgDC.Assets.bigFont;
		}
		useScale = scale * font->glyphScale;
		trap->R_SetColor( color );
		len = strlen(text);					 
		if (limit > 0 && len > limit) {
			len = limit;
		}
		count = 0;
		while (s && *s && count < len) {
			glyph = &font->glyphs[(int)*s]; // TTimo: FIXME: getting nasty warnings without the cast, hopefully this doesn't break the VM build
			if ( Q_IsColorString( s ) ) {
				memcpy( &newColor, &g_color_table[ColorIndex(*(s+1))], sizeof( newColor ) );
				newColor.a = color->a;
				trap->R_SetColor( &newColor );
				s += 2;
				continue;
			} else {
				float yadj = useScale * glyph->top;
				if (CG_Text_Width(s, useScale, 1) + x > max) {
					*maxX = 0;
					break;
				}
				CG_Text_PaintChar(x, y - yadj, 
					(float)glyph->imageWidth,
					(float)glyph->imageHeight,
					useScale, 
					glyph->s,
					glyph->t,
					glyph->s2,
					glyph->t2,
					glyph->glyph);
				x += (glyph->xSkip * useScale) + adjust;
				*maxX = x;
				count++;
				s++;
			}
		}
		trap->R_SetColor( NULL );
	}

}
Пример #12
0
static void CG_DrawBlueScore(rectDef_t *rect, float scale, vector4 *color, qhandle_t shader, int textStyle ) {
	char	num[16];
	float	width;

	if ( cgs.scores2 == SCORE_NOT_PRESENT )
		Com_sprintf (num, sizeof(num), "-");
	else
		Com_sprintf (num, sizeof(num), "%i", cgs.scores2);

	width = CG_Text_Width(num, scale, 0);
	CG_Text_Paint(rect->x + rect->w - width, rect->y + rect->h, scale, color, num, 0, 0, textStyle);
}
Пример #13
0
static int JPLua_Export_Font_StringLengthPixels( lua_State *L ) {
	const char *text = lua_tostring(L, 1);
	float scale = lua_tonumber(L, 2);
	qhandle_t font = lua_tointeger(L, 3);
	qboolean customfont = lua_toboolean(L, 4);

	if (customfont)
		trap->R_Font_StrLenPixels(text, font, scale);
	else
		lua_pushnumber(L, CG_Text_Width(text, scale, font));
	return 1;
}
Пример #14
0
static void CG_DrawPlayerScore( rectDef_t *rect, float scale, vector4 *color, qhandle_t shader, int textStyle ) {
	char num[16];
	int value = cg.snap->ps.persistent[PERS_SCORE];
	float width;

	if (shader) {
		trap->R_SetColor( color );
		CG_DrawPic(rect->x, rect->y, rect->w, rect->h, shader);
		trap->R_SetColor( NULL );
	} else {
		Com_sprintf (num, sizeof(num), "%i", value);
		width = CG_Text_Width(num, scale, 0);
		CG_Text_Paint(rect->x + (rect->w - width) / 2, rect->y + rect->h, scale, color, num, 0, 0, textStyle);
	}
}
Пример #15
0
void CG_FitTextToWidth_SingleLine( char* instr, float scale, float w, int size) {
	char	*s, *p;
	char	buffer[1024];

	Q_strncpyz(buffer, instr, 1024);
	memset(instr, 0, size);
	p = instr;
	
	for( s = buffer; *s; s++, p++ ) {
		*p = *s;
		if(CG_Text_Width( instr, scale, 0 ) > w) {
			*p = '\0';
			return;
		}
	}
}
Пример #16
0
void CG_DrawInformation( void ) {
	const char	*s;
	const char	*info;
	const char	*sysInfo;
	//int			y;
	//int			value, valueNOFP;
	qhandle_t	levelshot;
	//char		buf[1024];
//	int			iPropHeight = 18;	// I know, this is total crap, but as a post release asian-hack....  -Ste
	
	info = CG_ConfigString( CS_SERVERINFO );
	sysInfo = CG_ConfigString( CS_SYSTEMINFO );

	s = Info_ValueForKey( info, "mapname" );
	levelshot = trap->R_RegisterShaderNoMip( va( "levelshots/%s", s ) );
	if ( !levelshot ) {
		levelshot = trap->R_RegisterShaderNoMip( "menu/art/unknownmap_mp" );
	}
	trap->R_SetColor( NULL );
	CG_DrawPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, levelshot );

	CG_LoadBar();

	// the first 150 rows are reserved for the client connection
	// screen to write into
	if ( cg.infoScreenText[0] ) {
		const char *psLoading = CG_GetStringEdString("MENUS", "LOADING_MAPNAME");
		UI_DrawProportionalString( 425, 105, ( const char * ) va(( char * ) /*"Loading... %s"*/ psLoading, cg.infoScreenText),
			UI_RIGHT|UI_BIGFONT|UI_DROPSHADOW, colorWhite, FONT_SMALL3 );		
	} else {
		const char *psAwaitingSnapshot = CG_GetStringEdString("MENUS", "AWAITING_SNAPSHOT");
		UI_DrawProportionalString( 425, 128-32, ( const char * )  /*"Awaiting snapshot..."*/psAwaitingSnapshot,
			UI_RIGHT|UI_INFOFONT|UI_DROPSHADOW, colorWhite, FONT_SMALL3 );			
	}

	// Draw the loading screen tip
	if (cg_loadingTips.size() > 0 && cg_displayTipNumber != -1)
	{
		const char* loadingTip = CG_GetStringEdString2(cg_loadingTips.at(cg_displayTipNumber).tipText);
		int x = 320 - CG_Text_Width(loadingTip, 0.3f, FONT_SMALL) / 2;
		int y = 440;
		CG_Text_Paint(x, y, 0.3, colorWhite, loadingTip, 0, 0, ITEM_TEXTSTYLE_SHADOWED, FONT_SMALL);
	}
}
Пример #17
0
static void DrawChatboxTabs( void )
{
	chatBox_t *cb = chatboxList;
	float xOffset = 0.0f;
	int cls_realtime = *(int *)0x8AF224;

	while ( cb )
	{
		char *name = cb->shortname;
		float textWidth = CG_Text_Width( name, cg.chatbox.size.scale, JP_GetChatboxFont() );
		float textHeight = CG_Text_Height( name, cg.chatbox.size.scale, JP_GetChatboxFont() );

		CG_FillRect( cg.chatbox.pos.x + xOffset, cg.chatbox.pos.y + (cg_chatboxLineHeight.value*cg_chatboxLineCount.integer) + (textHeight*0.25f), textWidth+16.0f, cg_chatboxLineHeight.value, (cb==currentChatbox) ? &colorTable[CT_DKGREY] : &colorTable[CT_BLACK] );
		CG_Text_Paint( cg.chatbox.pos.x + xOffset+8.0f, cg.chatbox.pos.y + (cg_chatboxLineHeight.value*cg_chatboxLineCount.integer), cg.chatbox.size.scale, &colorWhite, va( "^%c%s", (cb==currentChatbox) ? '2' : (cb->notification && ( (int)( cls_realtime >> 8 ) & 1 ) ) ? '1' : '7', cb->shortname ), 0.0f, 0, ITEM_TEXTSTYLE_OUTLINED, JP_GetChatboxFont() );

		xOffset += textWidth + 16.0f;
		cb = cb->next;
	}
}
Пример #18
0
static void CG_DrawPlayerArmorValue(rectDef_t *rect, float scale, vector4 *color, qhandle_t shader, int textStyle) {
	char	num[16];
	int		value;
	float	width;
	playerState_t	*ps;

	ps = &cg.snap->ps;

	value = ps->stats[STAT_ARMOR];

	if (shader) {
		trap->R_SetColor( color );
		CG_DrawPic(rect->x, rect->y, rect->w, rect->h, shader);
		trap->R_SetColor( NULL );
	} else {
		Com_sprintf (num, sizeof(num), "%i", value);
		width = CG_Text_Width(num, scale, 0);
		CG_Text_Paint(rect->x + (rect->w - width) / 2, rect->y + rect->h, scale, color, num, 0, 0, textStyle);
	}
}
Пример #19
0
static void DrawSpectators( float fade ) {
	const qhandle_t fontHandle = MenuFontToHandle( JP_GetScoreboardFont() );
	const float fontScale = 0.5f, lineHeight = 14.0f;
	float y = 128.0f;
	vector4 white = { 1.0f, 1.0f, 1.0f, 1.0f };
	white.a = fade;

	CG_BuildSpectatorString();
	cg.scoreboard.spectatorWidth = CG_Text_Width( cg.scoreboard.spectatorList, fontScale, fontHandle );

	if ( cg.scoreboard.spectatorLen ) {
		const float dt = (cg.time - cg.scoreboard.spectatorResetTime)*0.0625f;
		cg.scoreboard.spectatorX = SCREEN_WIDTH - (1.0f)*dt;

		if ( cg.scoreboard.spectatorX < 0 - cg.scoreboard.spectatorWidth ) {
			cg.scoreboard.spectatorX = SCREEN_WIDTH;
			cg.scoreboard.spectatorResetTime = cg.time;
		}
		CG_Text_Paint( cg.scoreboard.spectatorX, (y + lineHeight * 20) - 3, fontScale, &white, cg.scoreboard.spectatorList,
			0, 0, ITEM_TEXTSTYLE_SHADOWED, fontHandle );
	}
}
Пример #20
0
static float CG_OwnerDrawWidth (int ownerDraw, float scale, int fontIndex)
{
	 const fontInfo_t *font;
	 const char *s;

	 if (fontIndex <= 0) {
		 font = &cgDC.Assets.textFont;
	 } else {
		 font = &cgDC.Assets.extraFonts[fontIndex];
	 }

	switch (ownerDraw) {
	  case CG_GAME_TYPE:
		  return CG_Text_Width(CG_GameTypeString(), scale, 0, font);
      case CG_GAME_STATUS:
		  return CG_Text_Width(CG_GetGameStatusText(), scale, 0, font);
		  break;
	  case CG_KILLER:
		  return CG_Text_Width(CG_GetKillerText(), scale, 0, font);
		  break;
	  case CG_RED_NAME:
		  //return CG_Text_Width(cg_redTeamName.string, scale, 0, font);
		  return CG_Text_Width(cgs.redTeamName, scale, 0, font);
		  break;
	  case CG_BLUE_NAME:
		  //return CG_Text_Width(cg_blueTeamName.string, scale, 0, font);
		  return CG_Text_Width(cgs.blueTeamName, scale, 0, font);
		  break;
	case UI_KEYBINDSTATUS:
		if (Display_KeyBindPending()) {
			s = "Waiting for new key... Press ESCAPE to cancel";
		} else {
			s = "Press ENTER or CLICK to change, Press BACKSPACE to clear";
		}
		return CG_Text_Width(s, scale, 0, font);
		break;
	default:
		Com_Printf("CG_OwnerDrawWidth() unknown ownerDraw %d\n", ownerDraw);
		break;
	}
	return 0;
}
Пример #21
0
static int JPLua_Export_Font_StringLengthPixels( lua_State *L ) {
	lua_pushnumber( L, CG_Text_Width( lua_tostring( L, 1 ), (float)lua_tonumber( L, 2 ), lua_tointeger( L, 3 ) ) );
	return 1;
}
Пример #22
0
/*
=================
CG_DrawScoreboard

Draw the normal in-game scoreboard
=================
*/
qboolean CG_DrawOldScoreboard( void ) {
	int		x, y, w, i, n1, n2;
	float	fade;
	float	*fadeColor;
	char	*s;
	int maxClients;
	int lineHeight;
	int topBorderSize, bottomBorderSize;

	// don't draw amuthing if the menu or console is up
	if ( cg_paused.integer ) {
		cg.deferredPlayerLoading = 0;
		return qfalse;
	}

	// don't draw scoreboard during death while warmup up
	if ( cg.warmup && !cg.showScores ) {
		return qfalse;
	}

	if ( cg.showScores || cg.predictedPlayerState.pm_type == PM_DEAD ||
		 cg.predictedPlayerState.pm_type == PM_INTERMISSION ) {
		fade = 1.0;
		fadeColor = colorWhite;
	} else {
		fadeColor = CG_FadeColor( cg.scoreFadeTime, FADE_TIME );

		if ( !fadeColor ) {
			// next time scoreboard comes up, don't print killer
			cg.deferredPlayerLoading = 0;
			cg.killerName[0] = 0;
			return qfalse;
		}
		fade = *fadeColor;
	}

	// fragged by ... line
	// or if in intermission and duel, prints the winner of the duel round
	if (cgs.gametype == GT_TOURNAMENT && cgs.duelWinner != -1 &&
		cg.predictedPlayerState.pm_type == PM_INTERMISSION)
	{
		s = va("%s %s", cgs.clientinfo[cgs.duelWinner].name, CG_GetStripEdString("INGAMETEXT", "DUEL_WINS") );
		/*w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
		x = ( SCREEN_WIDTH - w ) / 2;
		y = 40;
		CG_DrawBigString( x, y, s, fade );
		*/
		x = ( SCREEN_WIDTH ) / 2;
		y = 40;
		CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2, y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
	}
	else if (cgs.gametype == GT_TOURNAMENT && cgs.duelist1 != -1 && cgs.duelist2 != -1 &&
		cg.predictedPlayerState.pm_type == PM_INTERMISSION)
	{
		s = va("%s %s %s", cgs.clientinfo[cgs.duelist1].name, CG_GetStripEdString("INGAMETEXT", "SPECHUD_VERSUS"), cgs.clientinfo[cgs.duelist2].name );
		/*w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
		x = ( SCREEN_WIDTH - w ) / 2;
		y = 40;
		CG_DrawBigString( x, y, s, fade );
		*/
		x = ( SCREEN_WIDTH ) / 2;
		y = 40;
		CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2, y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
	}
	else if ( cg.killerName[0] ) {
		s = va("%s %s", CG_GetStripEdString("INGAMETEXT", "KILLEDBY"), cg.killerName );
		/*w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
		x = ( SCREEN_WIDTH - w ) / 2;
		y = 40;
		CG_DrawBigString( x, y, s, fade );
		*/
		x = ( SCREEN_WIDTH ) / 2;
		y = 40;
		CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2, y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
	}

	// current rank
	if ( !GT_Team(cgs.gametype)) {
		if (cg.snap->ps.persistant[PERS_TEAM] != TEAM_SPECTATOR )
		{
			char sPlace[256];
			char sOf[256];
			char sWith[256];

			trap_SP_GetStringTextString("INGAMETEXT_PLACE",	sPlace,	sizeof(sPlace));
			trap_SP_GetStringTextString("INGAMETEXT_OF",	sOf,	sizeof(sOf));
			trap_SP_GetStringTextString("INGAMETEXT_WITH",	sWith,	sizeof(sWith));

			s = va("%s %s (%s %i) %s %i",
				CG_PlaceString( cg.snap->ps.persistant[PERS_RANK] + 1 ),
				sPlace,
				sOf,
				cg.numScores,
				sWith,
				cg.snap->ps.persistant[PERS_SCORE] );
			w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
			x = ( SCREEN_WIDTH ) / 2;
			y = 60;
			//CG_DrawBigString( x, y, s, fade );
			UI_DrawProportionalString(x, y, s, UI_CENTER|UI_DROPSHADOW, colorTable[CT_WHITE]);
		}
	} 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] );
		}

		x = ( SCREEN_WIDTH ) / 2;
		y = 60;

		CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2, y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
	}

	// scoreboard
	y = SB_HEADER;

	CG_DrawPic ( SB_SCORELINE_X - 40, y - 5, SB_SCORELINE_WIDTH + 80, 40, trap_R_RegisterShaderNoMip ( "gfx/menus/menu_buttonback.tga" ) );

	// "NAME", "SCORE", "PING", "TIME" weren't localised, GODDAMMIT!!!!!!!!
	//
	// Unfortunately, since it's so sodding late now and post release I can't enable the localisation code (REM'd) since some of
	//	the localised strings don't fit - since no-one's ever seen them to notice this.  Smegging brilliant. Thanks people.
	//
	CG_Text_Paint ( SB_NAME_X, y, 1.0f, colorWhite, /*CG_GetStripEdString("MENUS3", "NAME")*/"Name",0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
	if (cgs.gametype == GT_TOURNAMENT)
	{
		char sWL[100];
		trap_SP_GetStringTextString("INGAMETEXT_W_L", sWL,	sizeof(sWL));

		CG_Text_Paint ( SB_SCORE_X, y, 1.0f, colorWhite, sWL, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
	}
	else
	{
		CG_Text_Paint ( SB_SCORE_X, y, 1.0f, colorWhite, /*CG_GetStripEdString("MENUS3", "SCORE")*/"Score", 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
	}
	CG_Text_Paint ( SB_PING_X, y, 1.0f, colorWhite, /*CG_GetStripEdString("MENUS0", "PING")*/"Ping", 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
	CG_Text_Paint ( SB_TIME_X, y, 1.0f, colorWhite, /*CG_GetStripEdString("MENUS3", "TIME")*/"Time", 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );

	y = SB_TOP;

	// If there are more than SB_MAXCLIENTS_NORMAL, use the interleaved scores
	if ( cg.numScores > SB_MAXCLIENTS_NORMAL ) {
		maxClients = SB_MAXCLIENTS_INTER;
		lineHeight = SB_INTER_HEIGHT;
		topBorderSize = 8;
		bottomBorderSize = 16;
	} else {
		maxClients = SB_MAXCLIENTS_NORMAL;
		lineHeight = SB_NORMAL_HEIGHT;
		topBorderSize = 8;
		bottomBorderSize = 8;
	}

	localClient = qfalse;


	//I guess this should end up being able to display 19 clients at once.
	//In a team game, if there are 9 or more clients on the team not in the lead,
	//we only want to show 10 of the clients on the team in the lead, so that we
	//have room to display the clients in the lead on the losing team.

	//I guess this can be accomplished simply by printing the first teams score with a maxClients
	//value passed in related to how many players are on both teams.
	if ( GT_Team(cgs.gametype) ) {
		//
		// teamplay scoreboard
		//
		y += lineHeight/2;

		if ( cg.teamScores[0] >= cg.teamScores[1] ) {
			int team1MaxCl = CG_GetTeamCount(TEAM_RED, maxClients);
			int team2MaxCl = CG_GetTeamCount(TEAM_BLUE, maxClients);

			if (team1MaxCl > 10 && (team1MaxCl+team2MaxCl) > maxClients)
			{
				team1MaxCl -= team2MaxCl;
				//subtract as many as you have to down to 10, once we get there
				//we just set it to 10

				if (team1MaxCl < 10)
				{
					team1MaxCl = 10;
				}
			}

			team2MaxCl = (maxClients-team1MaxCl); //team2 can display however many is left over after team1's display

			n1 = CG_TeamScoreboard( y, TEAM_RED, fade, team1MaxCl, lineHeight, qtrue );
			CG_DrawTeamBackground( SB_SCORELINE_X - 5, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED );
			CG_TeamScoreboard( y, TEAM_RED, fade, team1MaxCl, lineHeight, qfalse );
			y += (n1 * lineHeight) + BIGCHAR_HEIGHT;

			//maxClients -= n1;

			n2 = CG_TeamScoreboard( y, TEAM_BLUE, fade, team2MaxCl, lineHeight, qtrue );
			CG_DrawTeamBackground( SB_SCORELINE_X - 5, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE );
			CG_TeamScoreboard( y, TEAM_BLUE, fade, team2MaxCl, lineHeight, qfalse );
			y += (n2 * lineHeight) + BIGCHAR_HEIGHT;

			//maxClients -= n2;

			maxClients -= (team1MaxCl+team2MaxCl);
		} else {
			int team1MaxCl = CG_GetTeamCount(TEAM_BLUE, maxClients);
			int team2MaxCl = CG_GetTeamCount(TEAM_RED, maxClients);

			if (team1MaxCl > 10 && (team1MaxCl+team2MaxCl) > maxClients)
			{
				team1MaxCl -= team2MaxCl;
				//subtract as many as you have to down to 10, once we get there
				//we just set it to 10

				if (team1MaxCl < 10)
				{
					team1MaxCl = 10;
				}
			}

			team2MaxCl = (maxClients-team1MaxCl); //team2 can display however many is left over after team1's display

			n1 = CG_TeamScoreboard( y, TEAM_BLUE, fade, team1MaxCl, lineHeight, qtrue );
			CG_DrawTeamBackground( SB_SCORELINE_X - 5, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE );
			CG_TeamScoreboard( y, TEAM_BLUE, fade, team1MaxCl, lineHeight, qfalse );
			y += (n1 * lineHeight) + BIGCHAR_HEIGHT;

			//maxClients -= n1;

			n2 = CG_TeamScoreboard( y, TEAM_RED, fade, team2MaxCl, lineHeight, qtrue );
			CG_DrawTeamBackground( SB_SCORELINE_X - 5, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED );
			CG_TeamScoreboard( y, TEAM_RED, fade, team2MaxCl, lineHeight, qfalse );
			y += (n2 * lineHeight) + BIGCHAR_HEIGHT;

			//maxClients -= n2;

			maxClients -= (team1MaxCl+team2MaxCl);
		}
		n1 = CG_TeamScoreboard( y, TEAM_SPECTATOR, fade, maxClients, lineHeight, qfalse );
		y += (n1 * lineHeight) + BIGCHAR_HEIGHT;

	} else {
		//
		// free for all scoreboard
		//
		n1 = CG_TeamScoreboard( y, TEAM_FREE, fade, maxClients, lineHeight, qfalse );
		y += (n1 * lineHeight) + BIGCHAR_HEIGHT;
		n2 = CG_TeamScoreboard( y, TEAM_SPECTATOR, fade, maxClients - n1, lineHeight, qfalse );
		y += (n2 * lineHeight) + BIGCHAR_HEIGHT;
	}

	if (!localClient) {
		// draw local client at the bottom
		for ( i = 0 ; i < cg.numScores ; i++ ) {
			if ( cg.scores[i].client == cg.snap->ps.clientNum ) {
				CG_DrawClientScore( y, &cg.scores[i], fadeColor, fade, lineHeight == SB_NORMAL_HEIGHT );
				break;
			}
		}
	}

	// load any models that have been deferred
	if ( ++cg.deferredPlayerLoading > 10 ) {
		CG_LoadDeferredPlayers();
	}

	return qtrue;
}
Пример #23
0
qboolean CG_DrawOldScoreboard( void ) {
	int		x, y, i, n1, n2;
	float	fade;
	vector4 *fadeColor;
	char	*s;
	int maxClients, realMaxClients;
	int lineHeight;
	int topBorderSize, bottomBorderSize;

#if 0
	// don't draw amuthing if the menu or console is up
	if ( cg_paused.integer ) {
		cg.deferredPlayerLoading = 0;
		return qfalse;
	}
#endif

	// don't draw scoreboard during death while warmup up
	if ( cg.warmup && !cg.showScores ) {
		return qfalse;
	}

	if ( cg.showScores || cg.predictedPlayerState.pm_type == PM_DEAD ||
		 cg.predictedPlayerState.pm_type == PM_INTERMISSION ) {
		fade = 1.0;
		fadeColor = &colorWhite;
	} else {
		fadeColor = CG_FadeColor( cg.scoreFadeTime, FADE_TIME );
		
		if ( !fadeColor ) {
			// next time scoreboard comes up, don't print killer
			cg.deferredPlayerLoading = 0;
			cg.killerName[0] = 0;
			return qfalse;
		}
		fade = fadeColor->a;
	}

	// fragged by ... line
	// or if in intermission and duel, prints the winner of the duel round
	if ((cgs.gametype == GT_DUEL || cgs.gametype == GT_POWERDUEL) && cgs.duelWinner != -1 &&
		cg.predictedPlayerState.pm_type == PM_INTERMISSION)
	{
		s = va("%s^7 %s", cgs.clientinfo[cgs.duelWinner].name, CG_GetStringEdString("MP_INGAME", "DUEL_WINS") );
		/*w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
		x = ( SCREEN_WIDTH - w ) / 2;
		y = 40;
		CG_DrawBigString( x, y, s, fade );
		*/
		x = ( SCREEN_WIDTH ) / 2;
		y = 40;
		CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2, y, 1.0f, &colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
	}
	else if ((cgs.gametype == GT_DUEL || cgs.gametype == GT_POWERDUEL) && cgs.duelist1 != -1 && cgs.duelist2 != -1 &&
		cg.predictedPlayerState.pm_type == PM_INTERMISSION)
	{
		if (cgs.gametype == GT_POWERDUEL && cgs.duelist3 != -1)
		{
			s = va("%s^7 %s %s^7 %s %s", cgs.clientinfo[cgs.duelist1].name, CG_GetStringEdString("MP_INGAME", "SPECHUD_VERSUS"), cgs.clientinfo[cgs.duelist2].name, CG_GetStringEdString("MP_INGAME", "AND"), cgs.clientinfo[cgs.duelist3].name );
		}
		else
		{
			s = va("%s^7 %s %s", cgs.clientinfo[cgs.duelist1].name, CG_GetStringEdString("MP_INGAME", "SPECHUD_VERSUS"), cgs.clientinfo[cgs.duelist2].name );
		}
		/*w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
		x = ( SCREEN_WIDTH - w ) / 2;
		y = 40;
		CG_DrawBigString( x, y, s, fade );
		*/
		x = ( SCREEN_WIDTH ) / 2;
		y = 40;
		CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2, y, 1.0f, &colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
	}
	else if ( cg.killerName[0] ) {
		s = va("%s %s", CG_GetStringEdString("MP_INGAME", "KILLEDBY"), cg.killerName );
		/*w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
		x = ( SCREEN_WIDTH - w ) / 2;
		y = 40;
		CG_DrawBigString( x, y, s, fade );
		*/
		x = ( SCREEN_WIDTH ) / 2;
		y = 32;
		CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2, y, 1.0f, &colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
	}
	else
	{
		x = ( SCREEN_WIDTH ) / 2;
		y = SB_HEADER;
		//CG_DrawBigString( x, y, s, fade );
		s = cgs.japp.serverName;
			CG_Text_Paint( x-(CG_Text_Width( s, 0.75f, FONT_NONE )/2), y,		0.75f, &colorTable[CT_WHITE], s, 0.0f, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_NONE );

		if ( cgs.gametype >= GT_TEAM )
		{
			int redCount=0, blueCount=0, specCount=0;
			for ( i=0; i<cg.numScores; i++ )
			{
				if ( cgs.clientinfo[cg.scores[i].client].team == TEAM_RED )
					redCount++;
				else if ( cgs.clientinfo[cg.scores[i].client].team == TEAM_BLUE )
					blueCount++;
				else if ( cgs.clientinfo[cg.scores[i].client].team == TEAM_SPECTATOR )
					specCount++;
			}
			s = va( "Players: ^2%i^7/^2%i ^7(^1%i^7/^5%i^7) - %i spectators", cg.numScores, cgs.maxclients, redCount, blueCount, specCount );
		}
		else
		{
			int specCount=0;
			for ( i=0; i<cg.numScores; i++ )
			{
				if ( cgs.clientinfo[cg.scores[i].client].team == TEAM_SPECTATOR )
					specCount++;
			}
			s = va( "Players: %i/%i - %i spectators", cg.numScores, cgs.maxclients, specCount );
		}
		CG_Text_Paint( x-(CG_Text_Width( s, 0.75f, FONT_NONE )/2), y+15,	0.75f, &colorTable[CT_WHITE], s, 0.0f, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_NONE );

		s = va( "%s (%s)", (char *)CG_ConfigString( CS_MESSAGE ), cgs.mapname );
			CG_Text_Paint( x-(CG_Text_Width( s, 0.75f, FONT_NONE )/2), y+30,	0.75f, &colorTable[CT_WHITE], s, 0.0f, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_NONE );
	}


	// current rank
	if (cgs.gametype == GT_POWERDUEL)
	{ //do nothing?
	}
	else if ( cgs.gametype < GT_TEAM)
	{
#if 0
		if (cg.snap->ps.persistant[PERS_TEAM] != TEAM_SPECTATOR ) 
		{
			char sPlace[256];
			char sOf[256];
			char sWith[256];

			trap->SE_GetStringTextString("MP_INGAME_PLACE",	sPlace,	sizeof(sPlace));
			trap->SE_GetStringTextString("MP_INGAME_OF",		sOf,	sizeof(sOf));
			trap->SE_GetStringTextString("MP_INGAME_WITH",	sWith,	sizeof(sWith));

			s = va("%s %s (%s %i) %s %i",
				CG_PlaceString( cg.snap->ps.persistant[PERS_RANK] + 1 ),
				sPlace,
				sOf,
				cg.numScores,
				sWith,
				cg.snap->ps.persistant[PERS_SCORE] );
			w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
		//	x = ( 480 ) / 2;
		//	y = SB_HEADER-24;
			x = ( SCREEN_WIDTH ) / 2;
			y = SB_HEADER-24;
			//CG_DrawBigString( x, y, s, fade );
			UI_DrawProportionalString(x, y, s, UI_CENTER|UI_DROPSHADOW, colorTable[CT_WHITE]);
		}
#else

#endif
	}
	else if (cgs.gametype != GT_SIEGE)
	{
		if ( cg.teamScores[0] == cg.teamScores[1] ) {
			s = va("%s %i", CG_GetStringEdString("MP_INGAME", "TIEDAT"), cg.teamScores[0] );
		} else if ( cg.teamScores[0] >= cg.teamScores[1] ) {
			s = va("%s, %i / %i", CG_GetStringEdString("MP_INGAME", "RED_LEADS"), cg.teamScores[0], cg.teamScores[1] );
		} else {
			s = va("%s, %i / %i", CG_GetStringEdString("MP_INGAME", "BLUE_LEADS"), cg.teamScores[1], cg.teamScores[0] );
		}

	//	x = ( 460 ) / 2;
	//	y = SB_HEADER-24;
		x = ( SCREEN_WIDTH ) / 2;
		y = SB_HEADER-24;
		
		CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2, y, 1.0f, &colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
	}
	else if (cgs.gametype == GT_SIEGE && (cg_siegeWinTeam == 1 || cg_siegeWinTeam == 2))
	{
		if (cg_siegeWinTeam == 1)
		{
			s = va("%s", CG_GetStringEdString("MP_INGAME", "SIEGETEAM1WIN") );
		}
		else
		{
			s = va("%s", CG_GetStringEdString("MP_INGAME", "SIEGETEAM2WIN") );
		}

		x = ( SCREEN_WIDTH ) / 2;
		y = 60;
		
		CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2, y, 1.0f, &colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
	}

	// scoreboard
	y = SB_TOP-24; //SB_HEADER

//	CG_DrawPic ( SB_SCORELINE_X - 40, y - 5, SB_SCORELINE_WIDTH + 80, 40, trap->R_RegisterShaderNoMip ( "gfx/menus/menu_buttonback.tga" ) );

	CG_Text_Paint ( SB_NAME_X, y, 1.0f, &colorWhite, CG_GetStringEdString("MP_INGAME", "NAME"),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
	if (cgs.gametype == GT_DUEL || cgs.gametype == GT_POWERDUEL)
	{
		char sWL[100];
		trap->SE_GetStringTextString("MP_INGAME_W_L", sWL,	sizeof(sWL));

		CG_Text_Paint ( SB_SCORE_X, y, 1.0f, &colorWhite, sWL, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
	}
	else
	{
		CG_Text_Paint ( SB_SCORE_X, y, 1.0f, &colorWhite, CG_GetStringEdString("MP_INGAME", "SCORE"), 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
	}
	CG_Text_Paint ( SB_PING_X, y, 1.0f, &colorWhite, CG_GetStringEdString("MP_INGAME", "PING"), 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
	CG_Text_Paint ( SB_TIME_X, y, 1.0f, &colorWhite, CG_GetStringEdString("MP_INGAME", "TIME"), 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );

	y = SB_TOP;

	// If there are more than SB_MAXCLIENTS_NORMAL, use the interleaved scores
	if ( cg.numScores > SB_MAXCLIENTS_NORMAL ) {
		maxClients = SB_MAXCLIENTS_INTER;
		lineHeight = SB_INTER_HEIGHT;
		topBorderSize = 8;
		bottomBorderSize = 16;
	} else {
		maxClients = SB_MAXCLIENTS_NORMAL;
		lineHeight = SB_NORMAL_HEIGHT;
		topBorderSize = 8;
		bottomBorderSize = 8;
	}
	realMaxClients = maxClients;

	localClient = qfalse;


	//I guess this should end up being able to display 19 clients at once.
	//In a team game, if there are 9 or more clients on the team not in the lead,
	//we only want to show 10 of the clients on the team in the lead, so that we
	//have room to display the clients in the lead on the losing team.

	//I guess this can be accomplished simply by printing the first teams score with a maxClients
	//value passed in related to how many players are on both teams.
	if ( cgs.gametype >= GT_TEAM ) {
		//
		// teamplay scoreboard
		//
		y += lineHeight/2;

		if ( cg.teamScores[0] >= cg.teamScores[1] ) {
			int team1MaxCl = CG_GetTeamCount(TEAM_RED, maxClients);
			int team2MaxCl = CG_GetTeamCount(TEAM_BLUE, maxClients);

			if (team1MaxCl > 10 && (team1MaxCl+team2MaxCl) > maxClients)
			{
				team1MaxCl -= team2MaxCl;
				//subtract as many as you have to down to 10, once we get there
				//we just set it to 10

				if (team1MaxCl < 10)
				{
					team1MaxCl = 10;
				}
			}

			team2MaxCl = (maxClients-team1MaxCl); //team2 can display however many is left over after team1's display

			n1 = CG_TeamScoreboard( y, TEAM_RED, fade, team1MaxCl, lineHeight, qtrue );
			CG_DrawTeamBackground( SB_SCORELINE_X - 5, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED );
			CG_TeamScoreboard( y, TEAM_RED, fade, team1MaxCl, lineHeight, qfalse );
			y += (n1 * lineHeight) + BIGCHAR_HEIGHT;

			//maxClients -= n1;

			n2 = CG_TeamScoreboard( y, TEAM_BLUE, fade, team2MaxCl, lineHeight, qtrue );
			CG_DrawTeamBackground( SB_SCORELINE_X - 5, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE );
			CG_TeamScoreboard( y, TEAM_BLUE, fade, team2MaxCl, lineHeight, qfalse );
			y += (n2 * lineHeight) + BIGCHAR_HEIGHT;

			//maxClients -= n2;

			maxClients -= (team1MaxCl+team2MaxCl);
		} else {
			int team1MaxCl = CG_GetTeamCount(TEAM_BLUE, maxClients);
			int team2MaxCl = CG_GetTeamCount(TEAM_RED, maxClients);

			if (team1MaxCl > 10 && (team1MaxCl+team2MaxCl) > maxClients)
			{
				team1MaxCl -= team2MaxCl;
				//subtract as many as you have to down to 10, once we get there
				//we just set it to 10

				if (team1MaxCl < 10)
				{
					team1MaxCl = 10;
				}
			}

			team2MaxCl = (maxClients-team1MaxCl); //team2 can display however many is left over after team1's display

			n1 = CG_TeamScoreboard( y, TEAM_BLUE, fade, team1MaxCl, lineHeight, qtrue );
			CG_DrawTeamBackground( SB_SCORELINE_X - 5, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE );
			CG_TeamScoreboard( y, TEAM_BLUE, fade, team1MaxCl, lineHeight, qfalse );
			y += (n1 * lineHeight) + BIGCHAR_HEIGHT;

			//maxClients -= n1;

			n2 = CG_TeamScoreboard( y, TEAM_RED, fade, team2MaxCl, lineHeight, qtrue );
			CG_DrawTeamBackground( SB_SCORELINE_X - 5, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED );
			CG_TeamScoreboard( y, TEAM_RED, fade, team2MaxCl, lineHeight, qfalse );
			y += (n2 * lineHeight) + BIGCHAR_HEIGHT;

			//maxClients -= n2;

			maxClients -= (team1MaxCl+team2MaxCl);
		}
		maxClients = realMaxClients;
		n1 = CG_TeamScoreboard( y, TEAM_SPECTATOR, fade, maxClients, lineHeight, qfalse );
		y += (n1 * lineHeight) + BIGCHAR_HEIGHT;

	} else {
		//
		// free for all scoreboard
		//
		n1 = CG_TeamScoreboard( y, TEAM_FREE, fade, maxClients, lineHeight, qfalse );
		y += (n1 * lineHeight) + BIGCHAR_HEIGHT;
		n2 = CG_TeamScoreboard( y, TEAM_SPECTATOR, fade, maxClients - n1, lineHeight, qfalse );
		y += (n2 * lineHeight) + BIGCHAR_HEIGHT;
	}

	if (!localClient) {
		// draw local client at the bottom
		for ( i = 0 ; i < cg.numScores ; i++ ) {
			if ( cg.scores[i].client == cg.snap->ps.clientNum ) {
				CG_DrawClientScore( y, &cg.scores[i], fadeColor, fade, lineHeight == SB_NORMAL_HEIGHT );
				break;
			}
		}
	}

	// load any models that have been deferred
	if ( ++cg.deferredPlayerLoading > 10 ) {
		CG_LoadDeferredPlayers();
	}

	return qtrue;
}
Пример #24
0
// This function is called recursively when a logical message has to be split into multiple lines
void CG_ChatboxAdd( const char *message, qboolean multiLine ) {
	chatEntry_t *chat = &chatbox.chatBuffer[MAX_CHATBOX_ENTRIES-1];
	size_t strLength = 0;
	int i = 0;
	float accumLength = 0.0f;

	chatbox.numActiveLines++;

	//Stop scrolling up if we've already scrolled, similar to console behaviour
	if ( chatbox.scrollAmount < 0 )
		chatbox.scrollAmount = MAX( chatbox.scrollAmount - 1, chatbox.numActiveLines >= cg_chatboxLineCount->integer ? ((MIN(chatbox.numActiveLines, MAX_CHATBOX_ENTRIES)-cg_chatboxLineCount->integer)*-1) : 0 ); //cb->scrollAmount--;

	for ( i=0, strLength=strlen( message );
		 i<strLength && i<CHAT_MESSAGE_LENGTH;
		 i++ )
	{
		char *p = (char*)&message[i];
		char buf[1];

		buf[0] = *p;

		if ( !Q_IsColorString( p ) && (i > 0 && !Q_IsColorString( p-1 )) )
			accumLength += CG_Text_Width( buf, CHATBOX_FONT_SCALE, -1 );

		if ( accumLength > SCREEN_WIDTH && (i>0 && !Q_IsColorString( p-1 )) ) {
			char lastColor = '2';
			int j = i;
			int savedOffset = i;
			char tempMessage[CHAT_MESSAGE_LENGTH];

			//Attempt to back-track, find a space (' ') within X characters or pixels
			//RAZTODO: Another method using character width? Meh
			while ( message[i] != ' ' )
			{
				if ( i <= 0 || i < savedOffset-16 )
				{
					i = j = savedOffset;
					break;
				}
				i--;
				j--;
			}

			memmove( &chatbox.chatBuffer[0], &chatbox.chatBuffer[1], sizeof( chatbox.chatBuffer ) - sizeof( chatEntry_t ) );
			memset( chat, 0, sizeof( chatEntry_t ) ); //Clear the last element, ready for writing
			Q_strncpyz( chat->message, message, i+1 );
			chat->time = cg.time + cg_chatboxMsgTime->integer*1000;

			chat->isUsed = qtrue;
			for ( j=i; j>=0; j-- )
			{
				if ( message[j] == '^' && message[j+1] >= '0' && message[j+1] <= '9' )
				{
					lastColor = message[j+1];
					break;
				}
			}
			Com_sprintf( tempMessage, sizeof( tempMessage ), "^%c%s", lastColor, (const char *)(message + i) );

			//Recursively insert until we don't have to split the message
			CG_ChatboxAdd( tempMessage, qtrue );
			return;
		}
	}

	memmove( &chatbox.chatBuffer[0], &chatbox.chatBuffer[1], sizeof( chatbox.chatBuffer ) - sizeof( chatEntry_t ) );
	memset( chat, 0, sizeof( chatEntry_t ) ); //Clear the last element, ready for writing
	Q_strncpyz( chat->message, message, i+1 );

	chat->time = cg.time + cg_chatboxMsgTime->integer*1000;
	chat->isUsed = qtrue;
}
int
UI_DisplayContextCG::textWidth( const char *text, float scale, int limit )
{
	return CG_Text_Width( text, scale, limit );
}
Пример #26
0
// This function is called recursively when a logical message has to be split into multiple lines
void JP_ChatboxAdd( const char *message, qboolean multiLine, char *cbName )
{
	chatBox_t *cb = GetChatboxByName( cbName );
	chatEntry_t *chat = &cb->chatBuffer[MAX_CHATBOX_ENTRIES-1];
	int strLength = 0;
	int i = 0;
	float accumLength = 0.0f; //cg_chatTimeStamp.integer ? CG_Text_Width( EXAMPLE_TIMESTAMP, cg_hudChatS.value, JP_GetChatboxFont() ) : 0.0f;
	char buf[CHAT_MESSAGE_LENGTH] = { 0 };
	struct tm *timeinfo;
	time_t tm;

	accumLength = cg_chatboxTimeShow.integer ? CG_Text_Width( EXAMPLE_TIMESTAMP_CLEAN, cg.chatbox.size.scale, JP_GetChatboxFont() ) : 0.0f;

	cb->numActiveLines++;

	if ( cb != currentChatbox )
		cb->notification = qtrue;

	//Stop scrolling up if we've already scrolled, similar to console behaviour
	if ( cb->scrollAmount < 0 )
		cb->scrollAmount = max( cb->scrollAmount - 1, cb->numActiveLines >= cg_chatboxLineCount.integer ? ((min(cb->numActiveLines,MAX_CHATBOX_ENTRIES)-cg_chatboxLineCount.integer)*-1) : 0 ); //cb->scrollAmount--;

	for ( i=0, strLength=strlen( message );
		 i<strLength && i<CHAT_MESSAGE_LENGTH;
		 i++ )
	{
		char *p = (char*)&message[i];
		Com_sprintf( buf, sizeof( buf ), "%c", *p );
		if ( !Q_IsColorString( p ) && (i > 0 && !Q_IsColorString( p-1 )) )
			accumLength += CG_Text_Width( buf, cg.chatbox.size.scale, JP_GetChatboxFont() );
		//HACK: Compensate for ^x effectively being 0
	//	if ( Q_IsColorString( p ) )
	//		accumLength -= CG_Text_Width( "^0",  chatVars.scale, JP_GetChatboxFont() );

		if ( accumLength > max( cg.chatbox.size.width, 192.0f ) && (i>0 && !Q_IsColorString( p-1 )) )
		{
			char lastColor = '2';
			int j = i;
			int savedOffset = i;
			char tempMessage[CHAT_MESSAGE_LENGTH];

			//Attempt to back-track, find a space (' ') within X characters or pixels
			//RAZTODO: Another method using character width? Meh
			while ( message[i] != ' ' )
			{
				if ( i <= 0 || i < savedOffset-16 )
				{
					i = j = savedOffset;
					break;
				}
				i--;
				j--;
			}

			memmove( &cb->chatBuffer[0], &cb->chatBuffer[1], sizeof( cb->chatBuffer ) - sizeof( chatEntry_t ) );
			memset( chat, 0, sizeof( chatEntry_t ) ); //Clear the last element, ready for writing
			Q_strncpyz( chat->message, message, i+1 );
			chat->time = cg.time + cg_chatbox.integer;

			if ( !multiLine )
			{//Insert time-stamp, only for entries on the first line
				if ( cg_chatboxTimeShow.integer == 1 )
				{
					time( &tm );
					timeinfo = localtime ( &tm );

					if ( !cg.japp.timestamp24Hour && timeinfo->tm_hour > 12 )
						timeinfo->tm_hour -= 12;

					Com_sprintf( chat->timeStamp, sizeof( chat->timeStamp ), "[^%c%02i:%02i:%02i^7] ", *(char *)cg_chatboxTimeColour.string, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec );
				}
				else if ( cg_chatboxTimeShow.integer == 2 )
				{
					int msec, seconds, mins, hours;

					msec	= cg.time-cgs.levelStartTime;	seconds = msec / 1000;
					mins	= seconds / 60;					seconds	-= mins * 60;
					hours	= mins / 60;					mins -= hours * 60;

					Com_sprintf( chat->timeStamp, sizeof( chat->timeStamp ), "[^%c%02i:%02i:%02i^7] ", *(char *)cg_chatboxTimeColour.string, hours, mins, seconds );
				}
			}

			chat->isUsed = qtrue;
			for ( j=i; j>=0; j-- )
			{
				if ( message[j] == '^' && message[j+1] >= '0' && message[j+1] <= '9' )
				{
					lastColor = message[j+1];
					break;
				}
			}
			Com_sprintf( tempMessage, sizeof( tempMessage ), "^%c%s", lastColor, (const char *)(message + i) );

			//Recursively insert until we don't have to split the message
			JP_ChatboxAdd( tempMessage, qtrue, cbName );
			return;
		}
	}

	memmove( &cb->chatBuffer[0], &cb->chatBuffer[1], sizeof( cb->chatBuffer ) - sizeof( chatEntry_t ) );
	memset( chat, 0, sizeof( chatEntry_t ) ); //Clear the last element, ready for writing
	Q_strncpyz( chat->message, message, i+1 );

	chat->time = cg.time + cg_chatbox.integer;

	if ( !multiLine )
	{//Insert time-stamp, only for entries on the first line
		if ( cg_chatboxTimeShow.integer == 1 )
		{
			time( &tm );
			timeinfo = localtime ( &tm );

			if ( !cg.japp.timestamp24Hour && timeinfo->tm_hour > 12 )
				timeinfo->tm_hour -= 12;

			Com_sprintf( chat->timeStamp, sizeof( chat->timeStamp ), "[^%c%02i:%02i:%02i^7] ", *(char *)cg_chatboxTimeColour.string, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec );
		}
		else if ( cg_chatboxTimeShow.integer == 2 )
		{
			int msec, seconds, mins, hours;

			msec	= cg.time-cgs.levelStartTime;	seconds = msec / 1000;
			mins	= seconds / 60;					seconds	-= mins * 60;
			hours	= mins / 60;					mins -= hours * 60;

			Com_sprintf( chat->timeStamp, sizeof( chat->timeStamp ), "[^%c%02i:%02i:%02i^7] ", *(char *)cg_chatboxTimeColour.string, hours, mins, seconds );
		}
	}

	chat->isUsed = qtrue;
}
Пример #27
0
/*
=================
CG_DrawScoreboard
=================
*/
static void CG_DrawClientScore( int y, score_t *score, float *color, float fade, qboolean largeFormat ) {
	char			string[1024];
	vec3_t			headAngles;
	clientInfo_t	*ci;
	int				iconx, headx;
	float			scale = 0.35;
	int				h = CG_Text_Height( "Tj", scale, 0 );
	//int				ty;

	if ( score->client < 0 || score->client >= cgs.maxclients ) {
		Com_Printf( "Bad score->client: %i\n", score->client );
		return;
	}
	color[3] = fade;
	
	ci = &cgs.clientinfo[score->client];

	iconx = SB_BOTICON_X + (SB_RATING_WIDTH / 2);
	headx = SB_HEAD_X + (SB_RATING_WIDTH / 2);

	// draw the handicap or bot skill marker (unless player has flag)
	if ( ci->powerups & ( 1 << PW_NEUTRALFLAG ) ) {
		if( largeFormat ) {
			CG_DrawFlagModel( iconx, y - SB_LARGE_SPACER, SB_LARGE_ICON, SB_LARGE_ICON, TEAM_FREE, qfalse, SCR_CENTER );
		} else {
			CG_DrawFlagModel( iconx, y - SB_SMALL_SPACER, SB_SMALL_ICON, SB_SMALL_ICON, TEAM_FREE, qfalse, SCR_CENTER );
		}
	} else if ( ci->powerups & ( 1 << PW_REDFLAG ) ) {
		if( largeFormat ) {
			CG_DrawFlagModel( iconx, y - SB_LARGE_SPACER, SB_LARGE_ICON, SB_LARGE_ICON, TEAM_RED, qfalse, SCR_CENTER );
		} else {
			CG_DrawFlagModel( iconx, y - SB_SMALL_SPACER, SB_SMALL_ICON, SB_SMALL_ICON, TEAM_RED, qfalse, SCR_CENTER );
		}
	} else if ( ci->powerups & ( 1 << PW_BLUEFLAG ) ) {
		if( largeFormat ) {
			CG_DrawFlagModel( iconx, y - SB_LARGE_SPACER, SB_LARGE_ICON, SB_LARGE_ICON, TEAM_BLUE, qfalse, SCR_CENTER );
		} else {
			CG_DrawFlagModel( iconx, y - SB_SMALL_SPACER, SB_SMALL_ICON, SB_SMALL_ICON, TEAM_BLUE, qfalse, SCR_CENTER );
		}
	} else {
		if ( ci->botSkill > 0 && ci->botSkill <= 5 ) {
			if ( cg_drawIcons.integer ) {
				if( largeFormat ) {
					CG_DrawColorPic( iconx, y - SB_LARGE_SPACER, SB_LARGE_ICON, SB_LARGE_ICON, cgs.media.botSkillShaders[ci->botSkill - 1], SCR_CENTER, color );
				} else {
					CG_DrawColorPic( iconx, y - SB_SMALL_SPACER, SB_SMALL_ICON, SB_SMALL_ICON, cgs.media.botSkillShaders[ci->botSkill - 1], SCR_CENTER, color );
				}
			}
		} else if ( ci->handicap < 100 ) {
			Com_sprintf( string, sizeof( string ), "%i", ci->handicap );
			if ( gt[cgs.gametype].duel ) {
				if ( cg_highResFonts.integer ) {
					CG_Text_Paint( iconx, y + h + ((float)h/2), scale, color, string, 0, 0, ITEM_TEXTSTYLE_SHADOWED, SCR_CENTER );
				} else {
					CG_DrawSmallStringColor( iconx, y - SMALLCHAR_HEIGHT/2, string, color, SCR_CENTER );
				}
			} else {
				if ( cg_highResFonts.integer ) {
					//w = CG_Text_Width(s, scale, 0);
					h = CG_Text_Height(string, scale, 0);
					CG_Text_Paint( iconx, y + h, scale, color, string, 0, 0, ITEM_TEXTSTYLE_SHADOWED, SCR_CENTER );
				} else {
					CG_DrawSmallStringColor( iconx, y, string, color, SCR_CENTER );
				}
			}
		}

		// draw the wins / losses
		if ( gt[cgs.gametype].duel ) {
			Com_sprintf( string, sizeof( string ), "%i/%i", ci->wins, ci->losses );
			if ( ci->handicap < 100 && !ci->botSkill ) {
				if ( cg_highResFonts.integer ) {
					CG_Text_Paint( iconx, y + h + ((float)h/2), scale, color, string, 0, 0, ITEM_TEXTSTYLE_SHADOWED, SCR_CENTER );
				} else {
					CG_DrawSmallStringColor( iconx, y + SMALLCHAR_HEIGHT/2, string, color, SCR_CENTER );
				}
			} else {
				if ( cg_highResFonts.integer ) {
					CG_Text_Paint( iconx, y + h, scale, color, string, 0, 0, ITEM_TEXTSTYLE_SHADOWED, SCR_CENTER );
				} else {
					CG_DrawSmallStringColor( iconx, y, string, color, SCR_CENTER );
				}
			}
		}
	}

	// draw the face
	VectorClear( headAngles );
	headAngles[YAW] = 180;
	if ( largeFormat ) {
		CG_DrawHead( headx, y - SB_LARGE_SPACER*2, ICON_SIZE, ICON_SIZE, 
			score->client, headAngles, SCR_CENTER, color );
	} else {
		CG_DrawHead( headx, y + SB_SMALL_SPACER, SB_SMALL_ICON, SB_SMALL_ICON, score->client, headAngles, SCR_CENTER, color );
	}

	// draw the score line

	// highlight your position
	if ( score->client == cg.snap->ps.clientNum ) {
		float	hcolor[4];
		int		rank;

		localClient = qtrue;

		if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR ) {
			rank = -1;
		} else {
			rank = cg.snap->ps.persistant[PERS_RANK] & ~RANK_TIED_FLAG;
		}
		if ( rank == 0 ) {
			hcolor[0] = 0;
			hcolor[1] = 0;
			hcolor[2] = 0.7f;
		} else if ( rank == 1 ) {
			hcolor[0] = 0.7f;
			hcolor[1] = 0;
			hcolor[2] = 0;
		} else if ( rank == 2 ) {
			hcolor[0] = 0.7f;
			hcolor[1] = 0.7f;
			hcolor[2] = 0;
		} else {
			hcolor[0] = 0.4f;
			hcolor[1] = 0.4f;
			hcolor[2] = 0.4f;
		}

		hcolor[3] = fade * 0.7;
/*
		CG_DrawTeamBackground( SB_SCORELINE_X + BIGCHAR_WIDTH + (SB_RATING_WIDTH / 2), y, 
			SCREEN_WIDTH - SB_SCORELINE_X - BIGCHAR_WIDTH, BIGCHAR_HEIGHT+1, 1, gt[cgs.gametype].teams ? cg.snap->ps.persistant[PERS_TEAM] : hcolor, SCR_CENTER );
*/		
		CG_FillRect( SB_SCORELINE_X + BIGCHAR_WIDTH + (SB_RATING_WIDTH / 2), y, 
			SCREEN_WIDTH - SB_SCORELINE_X - BIGCHAR_WIDTH, BIGCHAR_HEIGHT+2, gt[cgs.gametype].teams ? CG_TeamColorDark(cg.snap->ps.persistant[PERS_TEAM], fade) : hcolor, SCR_CENTER );
	}


	// draw client score strings
	if ( cg_highResFonts.integer ) {
		qboolean spec = ci->team == TEAM_SPECTATOR;
		int		w;
		char	*s;

		// score
		s = (score->ping == -1) ? "CONN" : spec ? "SPEC" : cg.warmup ? "-" : va("%i", score->score);
		w = CG_Text_Width( s, scale, 0 );
		CG_Text_Paint( SB_SCORE_X + (SB_RATING_WIDTH / 2) + 64-w, y + h, scale, color, s, 0, 0, ITEM_TEXTSTYLE_SHADOWED, SCR_CENTER );
		// ping
		s = va( "%i", score->ping );
		w = CG_Text_Width( s, scale, 0 );
		CG_Text_Paint( SB_PING_X - (SB_RATING_WIDTH + BIGCHAR_WIDTH )/2 + 64-w, y + h, scale, color, s, 0, 0, ITEM_TEXTSTYLE_SHADOWED, SCR_CENTER );
		// time
		s = va( "%i", score->time );	//CG_IntToTime( score->time*1000, qtrue, qfalse );
		w = CG_Text_Width( s, scale, 0 );
		CG_Text_Paint( SB_TIME_X - (SB_RATING_WIDTH + BIGCHAR_WIDTH )/2 + 64-w, y + h, scale, color, s, 0, 0, ITEM_TEXTSTYLE_SHADOWED, SCR_CENTER );
		// name
		CG_Text_Paint( SB_NAME_X - (SB_RATING_WIDTH / 2), y + h, scale, color, ci->name, 0, 0, ITEM_TEXTSTYLE_SHADOWED, SCR_CENTER );
	} else {
		if ( score->ping == -1 ) {
			Com_sprintf(string, sizeof(string),
				" connecting    %s", ci->name);
		} else if ( ci->team == TEAM_SPECTATOR ) {
			Com_sprintf(string, sizeof(string),
				" SPECT %3i %4i %s", score->ping, score->time, ci->name);
		} else {
			Com_sprintf(string, sizeof(string),
				"%5i %4i %4i %s", score->score, score->ping, score->time, ci->name);
		}
		CG_DrawBigString( SB_SCORELINE_X + (SB_RATING_WIDTH / 2), y, string, fade, SCR_CENTER );
	}

	// add the "ready" marker for intermission exiting
	if ( cg.snap->ps.stats[STAT_CLIENTS_READY] & ( 1 << score->client ) ) {
		if ( cg_highResFonts.integer ) {
			CG_Text_Paint( iconx, y + h, scale, color, "READY", 0, 0, ITEM_TEXTSTYLE_SHADOWED, SCR_CENTER );
		} else {
			CG_DrawBigStringColor( iconx, y, "READY", color, SCR_CENTER );
		}
	}
}
Пример #28
0
void CG_DrawNewTeamInfo(rectDef_t *rect, float text_x, float text_y, float scale, vector4 *color, qhandle_t shader) {
	int			i, j, count, xx;
	const char	*p;
	vector4		hcolor;
	float		pwidth, lwidth, maxx, leftOver, len, y;
	clientInfo_t *ci;
	const gitem_t	*item;

	// 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.persistent[PERS_TEAM]) {
			len = CG_Text_Width( ci->name, scale, 0);
			if (len > pwidth)
				pwidth = (float)len;
		}
	}

	// max location name width
	lwidth = 0;
	for (i = 1; i < MAX_LOCATIONS; i++) {
		p = CG_ConfigString(CS_LOCATIONS + i);
		if (p && *p) {
			len = CG_Text_Width(p, scale, 0);
			if (len > lwidth)
				lwidth = (float)len;
		}
	}

	y = rect->y;

	for (i = 0; i < count; i++) {
		ci = cgs.clientinfo + sortedTeamPlayers[i];
		if ( ci->infoValid && ci->team == cg.snap->ps.persistent[PERS_TEAM]) {

			xx = (int)rect->x + 1;
			for (j = 0; j <= PW_NUM_POWERUPS; j++) {
				if (ci->powerups & (1 << j)) {

					item = BG_FindItemForPowerup( j );

					if (item) {
						CG_DrawPic( (float)xx, y, PIC_WIDTH, PIC_WIDTH, trap->R_RegisterShader( item->icon ) );
						xx += PIC_WIDTH;
					}
				}
			}

			// FIXME: max of 3 powerups shown properly
			xx = (int)rect->x + (PIC_WIDTH * 3) + 2;

			CG_GetColorForHealth( ci->health, ci->armor, &hcolor );
			trap->R_SetColor(&hcolor);
			CG_DrawPic( (float)xx, y + 1, PIC_WIDTH - 2, PIC_WIDTH - 2, cgs.media.heartShader );

			//Com_sprintf (st, sizeof(st), "%3i %3i", ci->health,	ci->armor);
			//CG_Text_Paint(xx, y + text_y, scale, hcolor, st, 0, 0); 

			// draw weapon icon
			xx += PIC_WIDTH + 1;

			// weapon used is not that useful, use the space for task
#if 0
			if ( cg_weapons[ci->curWeapon].weaponIcon ) {
				CG_DrawPic( xx, y, PIC_WIDTH, PIC_WIDTH, cg_weapons[ci->curWeapon].weaponIcon );
			} else {
				CG_DrawPic( xx, y, PIC_WIDTH, PIC_WIDTH, cgs.media.deferShader );
			}
#endif

			trap->R_SetColor(NULL);

			leftOver = rect->w - xx;
			maxx = xx + leftOver / 3;



			CG_Text_Paint_Limit(&maxx, (float)xx, y + text_y, scale, color, ci->name, 0, 0); 

			p = CG_ConfigString(CS_LOCATIONS + ci->location);
			if (!p || !*p) {
				p = "unknown";
			}

			xx += (int)(leftOver/3 + 2);
			maxx = rect->w - 4;

			CG_Text_Paint_Limit(&maxx, (float)xx, y + text_y, scale, color, p, 0, 0); 
			y += text_y + 2;
			if ( y + text_y + 2 > rect->y + rect->h ) {
				break;
			}

		}
	}
}
Пример #29
0
/*
=================
CG_DrawQ3Scoreboard

Draw the normal in-game scoreboard
=================
*/
qboolean CG_DrawQ3Scoreboard( void ) {
	int		x, y, w, i, n1, n2;
	float	*fadeColor, fade;
	char	*s;
	int maxClients;
	int lineHeight;
	int topBorderSize, bottomBorderSize;

	// don't draw anything if the menu or console is up
	if ( cg_paused.integer ) {
		cg.deferredPlayerLoading = 0;
		return qfalse;
	}

	if ( cgs.gametype == GT_SINGLE_PLAYER && cg.predictedPlayerState.pm_type == PM_INTERMISSION ) {
		cg.deferredPlayerLoading = 0;
		return qfalse;
	}

	// don't draw scoreboard during death while warmup up
	if ( cg.warmup && !cg.showScores && cg.time > cg.scoreFadeTime + FADE_TIME ) {
		return qfalse;
	}
//#if 0
	if ( cg.showScores || cg.predictedPlayerState.pm_type == PM_DEAD ||
		 cg.predictedPlayerState.pm_type == PM_INTERMISSION ) {
		fadeColor = colorWhite;
	} else {
		fadeColor = CG_FadeColor( cg.scoreFadeTime, FADE_TIME );
		
		if ( !fadeColor ) {
			// next time scoreboard comes up, don't print killer
			cg.deferredPlayerLoading = 0;
			cg.killerName[0] = 0;
			return qfalse;
		}
	}
//#endif
	//fadeColor = colorWhite;
	fade = fadeColor[3];
//#if 0
	// request more scores regularly
	if ( cg.scoresRequestTime + 2000 < cg.time ) {
		cg.scoresRequestTime = cg.time;
		trap_SendClientCommand( "score" );
	}
	//CG_Printf( "scoresRequestTime = %i\n", cg.scoresRequestTime );
	//CG_Printf( "scoreFadeTime = %i, fade = %f\n", cg.scoreFadeTime, fade );
//#endif					
	// fragged by ... line
	if ( !cg.warmup ) {
		if ( cg.killerName[0] ) {
			s = va( "Fragged by %s", cg.killerName );
			y = 40;
			if ( cg_highResFonts.integer ) {
				float scale = 0.35;
				int h;
				w = CG_Text_Width(s, scale, 0);
				h = CG_Text_Height(s, scale, 0);
				x = (SCREEN_WIDTH - w) / 2;
				CG_Text_Paint( x, y + h, scale, fadeColor, s, 0, 0, ITEM_TEXTSTYLE_SHADOWED, SCR_CENTER );
			} else {
				w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
				x = ( SCREEN_WIDTH - w ) / 2;
				CG_DrawBigString( x, y, s, fade, SCR_CENTER );
			}
		}

		// current rank
		{
			s = CG_GetGameStatusText();
			if ( s[0] ) {
				y = 60;

				if ( cg_highResFonts.integer ) {
					float scale = 0.35f;
					int h;
					w = CG_Text_Width(s, scale, 0);
					h = CG_Text_Height(s, scale, 0);
					x = (SCREEN_WIDTH - w) / 2;
					CG_Text_Paint( x, y + h, scale, fadeColor, s, 0, 0, ITEM_TEXTSTYLE_SHADOWED, SCR_CENTER );
				} else {
					w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
					x = ( SCREEN_WIDTH - w ) / 2;
					CG_DrawBigString( x, y, s, fade, SCR_CENTER );
				}
			}
		}
	}

	// scoreboard
	y = SB_HEADER;

	CG_DrawColorPic( SB_SCORE_X + (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardScore, SCR_CENTER, fadeColor );
	CG_DrawColorPic( SB_PING_X - (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardPing, SCR_CENTER, fadeColor );
	CG_DrawColorPic( SB_TIME_X - (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardTime, SCR_CENTER, fadeColor );
	CG_DrawColorPic( SB_NAME_X - (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardName, SCR_CENTER, fadeColor );

	y = SB_TOP;

	// If there are more than SB_MAXCLIENTS_NORMAL, use the interleaved scores
	if ( cg.numScores > SB_MAXCLIENTS_NORMAL ) {
		maxClients = SB_MAXCLIENTS_INTER;
		lineHeight = SB_INTER_HEIGHT;
		topBorderSize = 8;
		bottomBorderSize = 16;
	} else {
		maxClients = SB_MAXCLIENTS_NORMAL;
		lineHeight = SB_NORMAL_HEIGHT;
		topBorderSize = 16;
		bottomBorderSize = 16;
	}

	localClient = qfalse;

	if ( gt[cgs.gametype].teams ) {
		float team_opacity = 0.33f;
		//
		// teamplay scoreboard
		//
		y += lineHeight/2;

		if ( cg.teamScores[0] >= cg.teamScores[1] ) {
			n1 = CG_TeamScoreCount( TEAM_RED, maxClients );
			CG_DrawTeamBackground( 0, y - topBorderSize, SCREEN_WIDTH, n1 * lineHeight + bottomBorderSize, team_opacity, TEAM_RED, SCR_NONE );
			CG_TeamScoreboard( y, TEAM_RED, fade, maxClients, lineHeight );
			y += (n1 * lineHeight) + BIGCHAR_HEIGHT;
			maxClients -= n1;
			n2 = CG_TeamScoreCount( TEAM_BLUE, maxClients );
			CG_DrawTeamBackground( 0, y - topBorderSize, SCREEN_WIDTH, n2 * lineHeight + bottomBorderSize, team_opacity, TEAM_BLUE, SCR_NONE );
			CG_TeamScoreboard( y, TEAM_BLUE, fade, maxClients, lineHeight );
			y += (n2 * lineHeight) + BIGCHAR_HEIGHT;
			maxClients -= n2;
		} else {
			n1 = CG_TeamScoreCount( TEAM_BLUE, maxClients );
			CG_DrawTeamBackground( 0, y - topBorderSize, SCREEN_WIDTH, n1 * lineHeight + bottomBorderSize, team_opacity, TEAM_BLUE, SCR_NONE );
			CG_TeamScoreboard( y, TEAM_BLUE, fade, maxClients, lineHeight );
			y += (n1 * lineHeight) + BIGCHAR_HEIGHT;
			maxClients -= n1;
			n2 = CG_TeamScoreCount( TEAM_RED, maxClients );
			CG_DrawTeamBackground( 0, y - topBorderSize, SCREEN_WIDTH, n2 * lineHeight + bottomBorderSize, team_opacity, TEAM_RED, SCR_NONE );
			CG_TeamScoreboard( y, TEAM_RED, fade, maxClients, lineHeight );
			y += (n2 * lineHeight) + BIGCHAR_HEIGHT;
			maxClients -= n2;
		}
/*
		n1 = CG_TeamScoreCount( TEAM_SPECTATOR, maxClients );
		CG_TeamScoreboard( y, TEAM_SPECTATOR, fade, maxClients, lineHeight );
*/
		n1 = CG_TeamScoreboard( y, TEAM_SPECTATOR, fade, maxClients, lineHeight );
		y += (n1 * lineHeight) + BIGCHAR_HEIGHT;

	} else {
		//
		// free for all scoreboard
		//
/*
		n1 = CG_TeamScoreCount( TEAM_SPECTATOR, maxClients );
		CG_TeamScoreboard( y, TEAM_FREE, fade, maxClients, lineHeight );
		y += (n1 * lineHeight) + BIGCHAR_HEIGHT;
		n2 = CG_TeamScoreCount( TEAM_SPECTATOR, maxClients );
		CG_TeamScoreboard( y, TEAM_SPECTATOR, fade, maxClients - n1, lineHeight );
		y += (n2 * lineHeight) + BIGCHAR_HEIGHT;
*/
		n1 = CG_TeamScoreboard( y, TEAM_FREE, fade, maxClients, lineHeight );
		y += (n1 * lineHeight) + BIGCHAR_HEIGHT;
		n2 = CG_TeamScoreboard( y, TEAM_SPECTATOR, fade, maxClients - n1, lineHeight );
		y += (n2 * lineHeight) + BIGCHAR_HEIGHT;
	}

	if (!localClient) {
		// draw local client at the bottom
		for ( i = 0 ; i < cg.numScores ; i++ ) {
			if ( cg.scores[i].client == cg.snap->ps.clientNum ) {
				CG_DrawClientScore( y, &cg.scores[i], fadeColor, fade, lineHeight == SB_NORMAL_HEIGHT );
				break;
			}
		}
	}

	// load any models that have been deferred
	if ( ++cg.deferredPlayerLoading > 10 ) {
		CG_LoadDeferredPlayers();
	}

	return qtrue;
}