From f56bb35301836e56582a575a75864392a0177875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20P=2E=20Tjern=C3=B8?= Date: Mon, 2 Dec 2013 19:31:46 -0800 Subject: Fix line endings. WHAMMY. --- mp/src/game/client/message.cpp | 2138 ++++++++++++++++++++-------------------- 1 file changed, 1069 insertions(+), 1069 deletions(-) (limited to 'mp/src/game/client/message.cpp') diff --git a/mp/src/game/client/message.cpp b/mp/src/game/client/message.cpp index 5abc1ba6..fe341e71 100644 --- a/mp/src/game/client/message.cpp +++ b/mp/src/game/client/message.cpp @@ -1,1070 +1,1070 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// -// -// Message.cpp -// -// implementation of CHudMessage class -// -#include "cbase.h" -#include "hudelement.h" -#include "hud_macros.h" -#include "itextmessage.h" -#include "iclientmode.h" -#include "vgui_controls/Controls.h" -#include "vgui_controls/Panel.h" -#include "vgui/ILocalize.h" -#include "vgui/IScheme.h" -#include "vgui/ISurface.h" -#include "client_textmessage.h" -#include "VGuiMatSurface/IMatSystemSurface.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -#include - -using namespace vgui; - -#define NETWORK_MESSAGE1 "__NETMESSAGE__1" -#define NETWORK_MESSAGE2 "__NETMESSAGE__2" -#define NETWORK_MESSAGE3 "__NETMESSAGE__3" -#define NETWORK_MESSAGE4 "__NETMESSAGE__4" -#define NETWORK_MESSAGE5 "__NETMESSAGE__5" -#define NETWORK_MESSAGE6 "__NETMESSAGE__6" -#define MAX_NETMESSAGE 6 - -// Simultaneous message limit -#define MAX_TEXTMESSAGE_CHARS 2048 - -static const char *s_NetworkMessageNames[MAX_NETMESSAGE] = { NETWORK_MESSAGE1, NETWORK_MESSAGE2, NETWORK_MESSAGE3, NETWORK_MESSAGE4, NETWORK_MESSAGE5, NETWORK_MESSAGE6 }; - -const int maxHUDMessages = 16; -struct message_parms_t -{ - client_textmessage_t *pMessage; - float time; - int x, y; - int totalWidth, totalHeight; - int width; - int lines; - int lineLength; - int length; - int r, g, b; - int text; - int fadeBlend; - float charTime; - float fadeTime; - const char *vguiFontName; - vgui::HFont font; -}; - -// -//----------------------------------------------------- -// - -class CHudMessage: public CHudElement, public vgui::Panel, public ITextMessage -{ - DECLARE_CLASS_SIMPLE( CHudMessage, vgui::Panel ); -public: - - enum - { - TYPE_UNKNOWN = 0, - TYPE_POSITION, - TYPE_CHARACTER, - TYPE_FONT, - }; - - struct message_t - { - vgui::HFont font; - short x, y; - wchar_t ch; - byte type; - byte r, g, b, a; - }; - - CHudMessage( const char *pElementName ); - ~CHudMessage(); - - void Init( void ); - void VidInit( void ); - bool ShouldDraw( void ); - virtual void Paint(); - void MsgFunc_HudText(bf_read &msg); - void MsgFunc_GameTitle(bf_read &msg); - void MsgFunc_HudMsg(bf_read &msg); - - float FadeBlend( float fadein, float fadeout, float hold, float localTime ); - int XPosition( float x, int width, int lineWidth ); - int YPosition( float y, int height ); - - void MessageAdd( const char *pName ); - void MessageDrawScan( client_textmessage_t *pMessage, float time ); - void MessageScanStart( void ); - void MessageScanNextChar( void ); - void Reset( void ); - - virtual void ApplySchemeSettings( IScheme *scheme ); - - void SetFont( HScheme scheme, const char *pFontName ); - -public: // ITextMessage - virtual void SetPosition( int x, int y ); - virtual void AddChar( int r, int g, int b, int a, wchar_t ch ); - - virtual void GetLength( int *wide, int *tall, const char *string ); - virtual int GetFontInfo( FONTABC *pABCs, vgui::HFont hFont ); - - virtual void SetFont( vgui::HFont hCustomFont ); - virtual void SetDefaultFont( void ); - -private: - - message_t *AllocMessage( void ); - void ResetCharacters( void ); - void PaintCharacters(); - virtual void GetTextExtents( int *wide, int *tall, const char *string ); - - - client_textmessage_t *m_pMessages[maxHUDMessages]; - float m_startTime[maxHUDMessages]; - message_parms_t m_parms; - float m_gameTitleTime; - client_textmessage_t *m_pGameTitle; - bool m_bHaveMessage; - - CHudTexture *m_iconTitleLife; - CHudTexture *m_iconTitleHalf; - - vgui::HFont m_hFont; - vgui::HFont m_hDefaultFont; - CUtlVector< message_t > m_Messages; -}; - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void DispatchHudText( const char *pszText ) -{ - CHudMessage *pHudMessage = (CHudMessage *)GET_HUDELEMENT( CHudMessage ); - if ( pHudMessage ) - { - if ( pszText == NULL ) - { - pHudMessage->Reset(); - } - else - { - pHudMessage->MessageAdd( pszText ); - } - } -} - -// -//----------------------------------------------------- -// - -DECLARE_HUDELEMENT( CHudMessage ); -DECLARE_HUD_MESSAGE( CHudMessage, HudText ); -DECLARE_HUD_MESSAGE( CHudMessage, GameTitle ); -DECLARE_HUD_MESSAGE( CHudMessage, HudMsg ); - -ITextMessage *textmessage = NULL; - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -CHudMessage::CHudMessage( const char *pElementName ) : - CHudElement( pElementName ), BaseClass( NULL, "HudMessage" ) -{ - vgui::Panel *pParent = g_pClientMode->GetViewport(); - SetParent( pParent ); - textmessage = this; - m_hFont = g_hFontTrebuchet24; - m_hDefaultFont = m_hFont; - // Clear memory out - ResetCharacters(); -} - -CHudMessage::~CHudMessage() -{ - textmessage = NULL; -} - -void CHudMessage::ApplySchemeSettings( IScheme *scheme ) -{ - BaseClass::ApplySchemeSettings( scheme ); - - SetPaintBackgroundEnabled( false ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CHudMessage::Init(void) -{ - HOOK_HUD_MESSAGE( CHudMessage, HudText ); - HOOK_HUD_MESSAGE( CHudMessage, GameTitle ); - HOOK_HUD_MESSAGE( CHudMessage, HudMsg ); - - Reset(); -}; - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CHudMessage::VidInit( void ) -{ - m_iconTitleHalf = gHUD.GetIcon( "title_half" ); - m_iconTitleLife = gHUD.GetIcon( "title_life" ); -}; - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CHudMessage::Reset( void ) -{ - memset( m_pMessages, 0, sizeof( m_pMessages[0] ) * maxHUDMessages ); - memset( m_startTime, 0, sizeof( m_startTime[0] ) * maxHUDMessages ); - - m_gameTitleTime = 0; - m_pGameTitle = NULL; - m_bHaveMessage = false; -} - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -float CHudMessage::FadeBlend( float fadein, float fadeout, float hold, float localTime ) -{ - float fadeTime = fadein + hold; - float fadeBlend; - - if ( localTime < 0 ) - return 0; - - if ( localTime < fadein ) - { - fadeBlend = 1 - ((fadein - localTime) / fadein); - } - else if ( localTime > fadeTime ) - { - if ( fadeout > 0 ) - fadeBlend = 1 - ((localTime - fadeTime) / fadeout); - else - fadeBlend = 0; - } - else - fadeBlend = 1; - - return fadeBlend; -} - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -int CHudMessage::XPosition( float x, int width, int totalWidth ) -{ - int xPos; - - if ( x == -1 ) - { - xPos = (ScreenWidth() - width) / 2; - } - else - { - if ( x < 0 ) - xPos = (1.0 + x) * ScreenWidth() - totalWidth; // Align to right - else - xPos = x * ScreenWidth(); - } - - if ( xPos + width > ScreenWidth() ) - xPos = ScreenWidth() - width; - else if ( xPos < 0 ) - xPos = 0; - - return xPos; -} - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -int CHudMessage::YPosition( float y, int height ) -{ - int yPos; - - if ( y == -1 ) // Centered? - yPos = (ScreenHeight() - height) * 0.5; - else - { - // Alight bottom? - if ( y < 0 ) - yPos = (1.0 + y) * ScreenHeight() - height; // Alight bottom - else // align top - yPos = y * ScreenHeight(); - } - - if ( yPos + height > ScreenHeight() ) - yPos = ScreenHeight() - height; - else if ( yPos < 0 ) - yPos = 0; - - return yPos; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CHudMessage::MessageScanNextChar( void ) -{ - int srcRed, srcGreen, srcBlue, destRed, destGreen, destBlue; - int blend; - - srcRed = m_parms.pMessage->r1; - srcGreen = m_parms.pMessage->g1; - srcBlue = m_parms.pMessage->b1; - blend = 0; // Pure source - - destRed = destGreen = destBlue = 0; - - switch( m_parms.pMessage->effect ) - { - // Fade-in / Fade-out - case 0: - case 1: - destRed = destGreen = destBlue = 0; - blend = m_parms.fadeBlend; - break; - - case 2: - m_parms.charTime += m_parms.pMessage->fadein; - if ( m_parms.charTime > m_parms.time ) - { - srcRed = srcGreen = srcBlue = 0; - blend = 0; // pure source - } - else - { - float deltaTime = m_parms.time - m_parms.charTime; - - destRed = destGreen = destBlue = 0; - if ( m_parms.time > m_parms.fadeTime ) - { - blend = m_parms.fadeBlend; - } - else if ( deltaTime > m_parms.pMessage->fxtime ) - blend = 0; // pure dest - else - { - destRed = m_parms.pMessage->r2; - destGreen = m_parms.pMessage->g2; - destBlue = m_parms.pMessage->b2; - blend = 255 - (deltaTime * (1.0/m_parms.pMessage->fxtime) * 255.0 + 0.5); - } - } - break; - } - if ( blend > 255 ) - blend = 255; - else if ( blend < 0 ) - blend = 0; - - m_parms.r = ((srcRed * (255-blend)) + (destRed * blend)) >> 8; - m_parms.g = ((srcGreen * (255-blend)) + (destGreen * blend)) >> 8; - m_parms.b = ((srcBlue * (255-blend)) + (destBlue * blend)) >> 8; - -#if 0 - if ( m_parms.pMessage->effect == 1 && m_parms.charTime != 0 ) - { - textmessage->AddChar( m_parms.pMessage->r2, m_parms.pMessage->g2, m_parms.pMessage->b2, 255, m_parms.text ); - } -#endif -} - - -void CHudMessage::SetFont( HScheme scheme, const char *pFontName ) -{ - vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( scheme ); - - if ( pScheme ) - { - vgui::HFont font = pScheme->GetFont( pFontName ); - textmessage->SetFont( font ); - m_parms.font = font; - } -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CHudMessage::MessageScanStart( void ) -{ - switch( m_parms.pMessage->effect ) - { - // Fade-in / out with flicker - case 1: - case 0: - m_parms.fadeTime = m_parms.pMessage->fadein + m_parms.pMessage->holdtime; - - - if ( m_parms.time < m_parms.pMessage->fadein ) - { - m_parms.fadeBlend = ((m_parms.pMessage->fadein - m_parms.time) * (1.0/m_parms.pMessage->fadein) * 255); - } - else if ( m_parms.time > m_parms.fadeTime ) - { - if ( m_parms.pMessage->fadeout > 0 ) - m_parms.fadeBlend = (((m_parms.time - m_parms.fadeTime) / m_parms.pMessage->fadeout) * 255); - else - m_parms.fadeBlend = 255; // Pure dest (off) - } - else - m_parms.fadeBlend = 0; // Pure source (on) - m_parms.charTime = 0; - - if ( m_parms.pMessage->effect == 1 && (rand()%100) < 10 ) - m_parms.charTime = 1; - break; - - case 2: - m_parms.fadeTime = (m_parms.pMessage->fadein * m_parms.length) + m_parms.pMessage->holdtime; - - if ( m_parms.time > m_parms.fadeTime && m_parms.pMessage->fadeout > 0 ) - m_parms.fadeBlend = (((m_parms.time - m_parms.fadeTime) / m_parms.pMessage->fadeout) * 255); - else - m_parms.fadeBlend = 0; - break; - } - - m_parms.font = g_hFontTrebuchet24; - - if ( m_parms.vguiFontName != NULL && - m_parms.vguiFontName[ 0 ] ) - { - - SetFont( vgui::scheme()->GetDefaultScheme(), m_parms.vguiFontName ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CHudMessage::MessageDrawScan( client_textmessage_t *pMessage, float time ) -{ - int i, j, length, width; - const wchar_t *pText; - wchar_t textBuf[ 1024 ]; - - { - // look up in localization table - // strip off any trailing newlines - int len = Q_strlen( pMessage->pMessage ); - int tempLen = len + 2; - char *localString = (char *)_alloca( tempLen ); - Q_strncpy( localString, pMessage->pMessage, tempLen ); - if (V_iscntrl(localString[len - 1])) - { - localString[len - 1] = 0; - } - - pText = g_pVGuiLocalize->Find( localString ); - if ( !pText ) - { - g_pVGuiLocalize->ConvertANSIToUnicode( pMessage->pMessage, textBuf, sizeof( textBuf ) ); - pText = textBuf; - } - } - - const wchar_t *pPerm = pText; - - // Count lines - m_parms.lines = 1; - m_parms.time = time; - m_parms.pMessage = pMessage; - length = 0; - width = 0; - m_parms.totalWidth = 0; - m_parms.vguiFontName = pMessage->pVGuiSchemeFontName; - - m_parms.font = g_hFontTrebuchet24; - - while ( *pText ) - { - if ( *pText == '\n' ) - { - m_parms.lines++; - if ( width > m_parms.totalWidth ) - m_parms.totalWidth = width; - width = 0; - } - else - { - width += vgui::surface()->GetCharacterWidth( m_parms.font, *pText ); - } - pText++; - length++; - } - if ( width > m_parms.totalWidth ) - m_parms.totalWidth = width; - m_parms.length = length; - - int fontHeight = vgui::surface()->GetFontTall( m_parms.font ); - - m_parms.totalHeight = ( m_parms.lines * fontHeight ); - - m_parms.y = YPosition( pMessage->y, m_parms.totalHeight ); - pText = pPerm; - - m_parms.charTime = 0; - - float flBoxPixels = 0.0f; - - MessageScanStart(); - - if ( pMessage->bRoundedRectBackdropBox ) - { - // 2.0f since we have extra space at both the top and bottom - flBoxPixels = pMessage->flBoxSize * fontHeight; - - // Draw the box - int boxx = XPosition( pMessage->x, m_parms.totalWidth, m_parms.totalWidth ); - int boxy = YPosition( pMessage->y, m_parms.totalHeight ); - - boxx -= flBoxPixels; - boxy -= flBoxPixels * 0.5f; - - float flAlphaScale = clamp( ( 255.0f - (float)m_parms.fadeBlend ) / 255.0f, 0.0f, 1.0f ); - Color boxColor( - pMessage->boxcolor[ 0 ], - pMessage->boxcolor[ 1 ], - pMessage->boxcolor[ 2 ], - pMessage->boxcolor[ 3 ] * flAlphaScale ); - - DrawBox( boxx, boxy, m_parms.totalWidth + 2.0f * flBoxPixels, m_parms.totalHeight + 2.0f * flBoxPixels * 0.5f, boxColor, 1.0f ); - } - - wchar_t line[ 512 ]; - for ( i = 0; i < m_parms.lines; i++ ) - { - m_parms.lineLength = 0; - m_parms.width = 0; - while ( *pText && *pText != '\n' ) - { - wchar_t c = *pText; - line[m_parms.lineLength] = c; - m_parms.width += vgui::surface()->GetCharacterWidth( m_parms.font, c); - m_parms.lineLength++; - if ( m_parms.lineLength > (ARRAYSIZE(line)-1) ) - { - m_parms.lineLength = ARRAYSIZE(line)-1; - } - pText++; - } - pText++; // Skip LF - line[m_parms.lineLength] = 0; - - m_parms.x = XPosition( pMessage->x, m_parms.width, m_parms.totalWidth ); - - textmessage->SetPosition( m_parms.x, m_parms.y ); - - if (m_parms.fadeBlend > 255) - m_parms.fadeBlend = 255; - - for ( j = 0; j < m_parms.lineLength; j++ ) - { - m_parms.text = line[j]; - MessageScanNextChar(); - textmessage->AddChar( m_parms.r, m_parms.g, m_parms.b, 255 - m_parms.fadeBlend, m_parms.text ); - } - - m_parms.y += vgui::surface()->GetFontTall( m_parms.font ); - } - - // Restore default font - textmessage->SetDefaultFont(); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -bool CHudMessage::ShouldDraw( void ) -{ - return ( CHudElement::ShouldDraw() && - ( m_bHaveMessage || m_Messages.Count() ) ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CHudMessage::Paint() -{ - int i, drawn; - client_textmessage_t *pMessage; - float endTime; - - drawn = 0; - - if ( m_gameTitleTime > 0 ) - { - float localTime = gpGlobals->curtime - m_gameTitleTime; - float brightness; - - // Maybe timer isn't set yet - if ( m_gameTitleTime > gpGlobals->curtime ) - { - m_gameTitleTime = gpGlobals->curtime; - } - - if ( localTime > (m_pGameTitle->fadein + m_pGameTitle->holdtime + m_pGameTitle->fadeout) ) - { - m_gameTitleTime = 0; - } - else - { - brightness = FadeBlend( m_pGameTitle->fadein, m_pGameTitle->fadeout, m_pGameTitle->holdtime, localTime ); - - int halfWidth = m_iconTitleHalf->Width(); - int fullWidth = halfWidth + m_iconTitleLife->Width(); - int fullHeight = m_iconTitleHalf->Height(); - - int x = XPosition( m_pGameTitle->x, fullWidth, fullWidth ); - int y = YPosition( m_pGameTitle->y, fullHeight ); - - m_iconTitleHalf->DrawSelf( x, y, Color( m_pGameTitle->r1, m_pGameTitle->g1, m_pGameTitle->b1, brightness * 255 ) ); - m_iconTitleLife->DrawSelf( x + halfWidth, y, Color( m_pGameTitle->r1, m_pGameTitle->g1, m_pGameTitle->b1, brightness * 255 ) ); - drawn = 1; - } - } - - // Fixup level transitions - for ( i = 0; i < maxHUDMessages; i++ ) - { - // Assume m_parms.time contains last time - if ( m_pMessages[i] ) - { - pMessage = m_pMessages[i]; - if ( m_startTime[i] > gpGlobals->curtime ) - m_startTime[i] = gpGlobals->curtime + m_parms.time - m_startTime[i] + 0.2; // Server takes 0.2 seconds to spawn, adjust for this - } - } - - for ( i = 0; i < maxHUDMessages; i++ ) - { - if ( m_pMessages[i] ) - { - pMessage = m_pMessages[i]; - - // This is when the message is over - switch( pMessage->effect ) - { - case 0: - case 1: - endTime = m_startTime[i] + pMessage->fadein + pMessage->fadeout + pMessage->holdtime; - break; - - // Fade in is per character in scanning messages - case 2: - endTime = m_startTime[i] + (pMessage->fadein * strlen( pMessage->pMessage )) + pMessage->fadeout + pMessage->holdtime; - break; - - default: - endTime = 0; - break; - } - - if ( gpGlobals->curtime <= endTime ) - { - float messageTime = gpGlobals->curtime - m_startTime[i]; - - // Draw the message - // effect 0 is fade in/fade out - // effect 1 is flickery credits - // effect 2 is write out (training room) - MessageDrawScan( pMessage, messageTime ); - - drawn++; - } - else - { - // The message is over - m_pMessages[i] = NULL; - } - } - } - - // Remember the time -- to fix up level transitions - m_parms.time = gpGlobals->curtime; - - // Did we draw any messages? - if ( !drawn ) - { - m_bHaveMessage = false; - } - - PaintCharacters(); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CHudMessage::MessageAdd( const char *pName ) -{ - int i; - - float time = gpGlobals->curtime; - - client_textmessage_t *pMessage = NULL; - - if ( pName[0] == '#' ) - { - pMessage = TextMessageGet( pName+1 ); - } - else - { - pMessage = TextMessageGet( pName ); - } - - if ( !pMessage ) - return; - - if ( pMessage->pClearMessage ) - { - for ( i = 0; i < maxHUDMessages; i++ ) - { - if ( m_pMessages[ i ] && !Q_stricmp( m_pMessages[ i ]->pName, pMessage->pClearMessage ) ) - { - m_startTime[ i ] = 0.0f; - m_pMessages[ i ] = NULL; - break; - } - } - } - - for ( i = 0; i < maxHUDMessages; i++ ) - { - if ( !m_pMessages[i] ) - { - m_pMessages[i] = pMessage; - m_startTime[i] = time; - break; - } - } - - // Remember the time -- to fix up level transitions - m_parms.time = time; - - m_bHaveMessage = true; - // Force this now so that SCR_UpdateScreen will paint the panel immediately!!! - SetVisible( true ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CHudMessage::MsgFunc_HudText( bf_read &msg ) -{ - char szString[2048]; - msg.ReadString( szString, sizeof(szString) ); - - MessageAdd( szString ); -} - -#include "ivieweffects.h" -#include "shake.h" - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CHudMessage::MsgFunc_GameTitle( bf_read &msg ) -{ - m_pGameTitle = TextMessageGet( "GAMETITLE" ); - if ( m_pGameTitle != NULL ) - { - m_gameTitleTime = gpGlobals->curtime; - - m_bHaveMessage = true; - } - -// if ( READ_BYTE() ) - { - ScreenFade_t sf; - memset( &sf, 0, sizeof( sf ) ); - sf.a = 255; - sf.r = 0; - sf.g = 0; - sf.b = 0; - sf.duration = (float)(1<Fade( sf ); - - Msg( "%i gametitle fade\n", gpGlobals->framecount ); - } -} - - -void CHudMessage::MsgFunc_HudMsg(bf_read &msg) -{ -// Position command $position x y -// x & y are from 0 to 1 to be screen resolution independent -// -1 means center in each dimension -// Effect command $effect -// effect 0 is fade in/fade out -// effect 1 is flickery credits -// effect 2 is write out (training room) -// Text color r g b command $color -// Text color r g b command $color2 -// fadein time fadeout time / hold time -// $fadein (message fade in time - per character in effect 2) -// $fadeout (message fade out time) -// $holdtime (stay on the screen for this long) - - int channel = msg.ReadByte() % MAX_NETMESSAGE; // Pick the buffer - - client_textmessage_t *pNetMessage = TextMessageGet( s_NetworkMessageNames[ channel ] ); - - if ( !pNetMessage || !pNetMessage->pMessage ) - return; - - pNetMessage->x = msg.ReadFloat(); - pNetMessage->y = msg.ReadFloat(); - - pNetMessage->r1 = msg.ReadByte(); - pNetMessage->g1 = msg.ReadByte(); - pNetMessage->b1 = msg.ReadByte(); - pNetMessage->a1 = msg.ReadByte(); - - pNetMessage->r2 = msg.ReadByte(); - pNetMessage->g2 = msg.ReadByte(); - pNetMessage->b2 = msg.ReadByte(); - pNetMessage->a2 = msg.ReadByte(); - - pNetMessage->effect = msg.ReadByte(); - - pNetMessage->fadein = msg.ReadFloat(); - pNetMessage->fadeout = msg.ReadFloat(); - pNetMessage->holdtime = msg.ReadFloat(); - pNetMessage->fxtime = msg.ReadFloat(); - - pNetMessage->pName = s_NetworkMessageNames[ channel ]; - - // see tmessage.cpp why 512 - msg.ReadString( (char*)pNetMessage->pMessage, 512 ); - - MessageAdd( pNetMessage->pName ); -} - -//----------------------------------------------------------------------------- -// Purpose: Get font sizes -// Input : *pWidth - -// Output : int -//----------------------------------------------------------------------------- -int CHudMessage::GetFontInfo( FONTABC *pABCs, vgui::HFont hFont ) -{ - int i; - - if ( !hFont ) - { - hFont = m_hFont; - } - - if ( !hFont ) - return 0; - - if ( pABCs ) - { - for ( i =0; i < 256; i++ ) - { - int a, b, c; - vgui::surface()->GetCharABCwide( hFont, (char)i, a, b, c ); - pABCs[i].abcA = a; - pABCs[i].abcB = b; - pABCs[i].abcC = c; - pABCs[i].total = a+b+c; - } - } - - return vgui::surface()->GetFontTall( hFont ); -} - -//----------------------------------------------------------------------------- -// Purpose: Clear all messages out of active list, etc. -//----------------------------------------------------------------------------- -void CHudMessage::ResetCharacters( void ) -{ - m_Messages.Purge(); -} - -//----------------------------------------------------------------------------- -// Purpose: Grab next free message, if any -// Output : CTextMessagePanel::message_t -//----------------------------------------------------------------------------- -CHudMessage::message_t *CHudMessage::AllocMessage( void ) -{ - message_t *msg; - - if ( m_Messages.Count() >= MAX_TEXTMESSAGE_CHARS ) - return NULL; - - msg = &m_Messages[ m_Messages.AddToTail() ]; - - msg->type = TYPE_UNKNOWN; - msg->x = 0; - msg->y = 0; - msg->ch = 0; - msg->r = 0; - msg->g = 0; - msg->b = 0; - msg->a = 0; - msg->font = 0; - - SetVisible( true ); - - return msg; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : x - -// y - -//----------------------------------------------------------------------------- -void CHudMessage::SetPosition( int x, int y ) -{ - message_t *msg = AllocMessage(); - if ( !msg ) - return; - - msg->type = TYPE_POSITION; - - // Used fields - msg->x = x; - msg->y = y; -} - -//----------------------------------------------------------------------------- -// Purpose: Adds a character to the active list, if possible -// Input : x - -// y - -// r - -// g - -// b - -// a - -// ch - -// Output : int -//----------------------------------------------------------------------------- -void CHudMessage::AddChar( int r, int g, int b, int a, wchar_t ch ) -{ - message_t *msg = AllocMessage(); - if ( !msg ) - return; - - msg->type = TYPE_CHARACTER; - - // Used fields - msg->r = r; - msg->g = g; - msg->b = b; - msg->a = a; - msg->ch = ch; -} - -//----------------------------------------------------------------------------- -// Purpose: Determine width and height of specified string -// Input : *wide - -// *tall - -// *string - -//----------------------------------------------------------------------------- -void CHudMessage::GetTextExtents( int *wide, int *tall, const char *string ) -{ - *wide = g_pMatSystemSurface->DrawTextLen( m_hFont, (char *)string ); - *tall = vgui::surface()->GetFontTall( m_hFont ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CHudMessage::SetFont( vgui::HFont hCustomFont ) -{ - m_hFont = hCustomFont; - - message_t *msg = AllocMessage(); - if ( !msg ) - return; - - msg->type = TYPE_FONT; - - // Used fields - msg->font = m_hFont; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CHudMessage::SetDefaultFont( void ) -{ - SetFont( m_hDefaultFont ); -} - -//----------------------------------------------------------------------------- -// Purpose: Draw current text items -//----------------------------------------------------------------------------- -void CHudMessage::PaintCharacters() -{ - int xpos = 0, ypos = 0; - vgui::surface()->DrawSetTextFont( m_hFont ); - - int messageCount = m_Messages.Count(); - for ( int i = 0 ; i < messageCount; ++i ) - { - message_t *msg = &m_Messages[ i ]; - - switch ( msg->type ) - { - default: - case TYPE_UNKNOWN: - Assert( 0 ); - break; - case TYPE_POSITION: - xpos = msg->x; - ypos = msg->y; - break; - case TYPE_FONT: - m_hFont = msg->font; - vgui::surface()->DrawSetTextFont( m_hFont ); - break; - case TYPE_CHARACTER: - if ( m_hFont ) - { - int a, b, c; - vgui::surface()->GetCharABCwide( m_hFont, msg->ch, a, b, c ); - - if ( msg->ch > 32 ) - { - vgui::surface()->DrawSetTextColor( msg->r, msg->g, msg->b, msg->a ); - vgui::surface()->DrawSetTextPos( xpos, ypos ); - vgui::surface()->DrawUnicodeChar( msg->ch ); - } - xpos += a + b + c; - } - break; - } - } - - ResetCharacters(); -} - -void CHudMessage::GetLength( int *wide, int *tall, const char *string ) -{ - GetTextExtents( wide, tall, string ); +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// +// Message.cpp +// +// implementation of CHudMessage class +// +#include "cbase.h" +#include "hudelement.h" +#include "hud_macros.h" +#include "itextmessage.h" +#include "iclientmode.h" +#include "vgui_controls/Controls.h" +#include "vgui_controls/Panel.h" +#include "vgui/ILocalize.h" +#include "vgui/IScheme.h" +#include "vgui/ISurface.h" +#include "client_textmessage.h" +#include "VGuiMatSurface/IMatSystemSurface.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#include + +using namespace vgui; + +#define NETWORK_MESSAGE1 "__NETMESSAGE__1" +#define NETWORK_MESSAGE2 "__NETMESSAGE__2" +#define NETWORK_MESSAGE3 "__NETMESSAGE__3" +#define NETWORK_MESSAGE4 "__NETMESSAGE__4" +#define NETWORK_MESSAGE5 "__NETMESSAGE__5" +#define NETWORK_MESSAGE6 "__NETMESSAGE__6" +#define MAX_NETMESSAGE 6 + +// Simultaneous message limit +#define MAX_TEXTMESSAGE_CHARS 2048 + +static const char *s_NetworkMessageNames[MAX_NETMESSAGE] = { NETWORK_MESSAGE1, NETWORK_MESSAGE2, NETWORK_MESSAGE3, NETWORK_MESSAGE4, NETWORK_MESSAGE5, NETWORK_MESSAGE6 }; + +const int maxHUDMessages = 16; +struct message_parms_t +{ + client_textmessage_t *pMessage; + float time; + int x, y; + int totalWidth, totalHeight; + int width; + int lines; + int lineLength; + int length; + int r, g, b; + int text; + int fadeBlend; + float charTime; + float fadeTime; + const char *vguiFontName; + vgui::HFont font; +}; + +// +//----------------------------------------------------- +// + +class CHudMessage: public CHudElement, public vgui::Panel, public ITextMessage +{ + DECLARE_CLASS_SIMPLE( CHudMessage, vgui::Panel ); +public: + + enum + { + TYPE_UNKNOWN = 0, + TYPE_POSITION, + TYPE_CHARACTER, + TYPE_FONT, + }; + + struct message_t + { + vgui::HFont font; + short x, y; + wchar_t ch; + byte type; + byte r, g, b, a; + }; + + CHudMessage( const char *pElementName ); + ~CHudMessage(); + + void Init( void ); + void VidInit( void ); + bool ShouldDraw( void ); + virtual void Paint(); + void MsgFunc_HudText(bf_read &msg); + void MsgFunc_GameTitle(bf_read &msg); + void MsgFunc_HudMsg(bf_read &msg); + + float FadeBlend( float fadein, float fadeout, float hold, float localTime ); + int XPosition( float x, int width, int lineWidth ); + int YPosition( float y, int height ); + + void MessageAdd( const char *pName ); + void MessageDrawScan( client_textmessage_t *pMessage, float time ); + void MessageScanStart( void ); + void MessageScanNextChar( void ); + void Reset( void ); + + virtual void ApplySchemeSettings( IScheme *scheme ); + + void SetFont( HScheme scheme, const char *pFontName ); + +public: // ITextMessage + virtual void SetPosition( int x, int y ); + virtual void AddChar( int r, int g, int b, int a, wchar_t ch ); + + virtual void GetLength( int *wide, int *tall, const char *string ); + virtual int GetFontInfo( FONTABC *pABCs, vgui::HFont hFont ); + + virtual void SetFont( vgui::HFont hCustomFont ); + virtual void SetDefaultFont( void ); + +private: + + message_t *AllocMessage( void ); + void ResetCharacters( void ); + void PaintCharacters(); + virtual void GetTextExtents( int *wide, int *tall, const char *string ); + + + client_textmessage_t *m_pMessages[maxHUDMessages]; + float m_startTime[maxHUDMessages]; + message_parms_t m_parms; + float m_gameTitleTime; + client_textmessage_t *m_pGameTitle; + bool m_bHaveMessage; + + CHudTexture *m_iconTitleLife; + CHudTexture *m_iconTitleHalf; + + vgui::HFont m_hFont; + vgui::HFont m_hDefaultFont; + CUtlVector< message_t > m_Messages; +}; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void DispatchHudText( const char *pszText ) +{ + CHudMessage *pHudMessage = (CHudMessage *)GET_HUDELEMENT( CHudMessage ); + if ( pHudMessage ) + { + if ( pszText == NULL ) + { + pHudMessage->Reset(); + } + else + { + pHudMessage->MessageAdd( pszText ); + } + } +} + +// +//----------------------------------------------------- +// + +DECLARE_HUDELEMENT( CHudMessage ); +DECLARE_HUD_MESSAGE( CHudMessage, HudText ); +DECLARE_HUD_MESSAGE( CHudMessage, GameTitle ); +DECLARE_HUD_MESSAGE( CHudMessage, HudMsg ); + +ITextMessage *textmessage = NULL; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CHudMessage::CHudMessage( const char *pElementName ) : + CHudElement( pElementName ), BaseClass( NULL, "HudMessage" ) +{ + vgui::Panel *pParent = g_pClientMode->GetViewport(); + SetParent( pParent ); + textmessage = this; + m_hFont = g_hFontTrebuchet24; + m_hDefaultFont = m_hFont; + // Clear memory out + ResetCharacters(); +} + +CHudMessage::~CHudMessage() +{ + textmessage = NULL; +} + +void CHudMessage::ApplySchemeSettings( IScheme *scheme ) +{ + BaseClass::ApplySchemeSettings( scheme ); + + SetPaintBackgroundEnabled( false ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudMessage::Init(void) +{ + HOOK_HUD_MESSAGE( CHudMessage, HudText ); + HOOK_HUD_MESSAGE( CHudMessage, GameTitle ); + HOOK_HUD_MESSAGE( CHudMessage, HudMsg ); + + Reset(); +}; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudMessage::VidInit( void ) +{ + m_iconTitleHalf = gHUD.GetIcon( "title_half" ); + m_iconTitleLife = gHUD.GetIcon( "title_life" ); +}; + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudMessage::Reset( void ) +{ + memset( m_pMessages, 0, sizeof( m_pMessages[0] ) * maxHUDMessages ); + memset( m_startTime, 0, sizeof( m_startTime[0] ) * maxHUDMessages ); + + m_gameTitleTime = 0; + m_pGameTitle = NULL; + m_bHaveMessage = false; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +float CHudMessage::FadeBlend( float fadein, float fadeout, float hold, float localTime ) +{ + float fadeTime = fadein + hold; + float fadeBlend; + + if ( localTime < 0 ) + return 0; + + if ( localTime < fadein ) + { + fadeBlend = 1 - ((fadein - localTime) / fadein); + } + else if ( localTime > fadeTime ) + { + if ( fadeout > 0 ) + fadeBlend = 1 - ((localTime - fadeTime) / fadeout); + else + fadeBlend = 0; + } + else + fadeBlend = 1; + + return fadeBlend; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int CHudMessage::XPosition( float x, int width, int totalWidth ) +{ + int xPos; + + if ( x == -1 ) + { + xPos = (ScreenWidth() - width) / 2; + } + else + { + if ( x < 0 ) + xPos = (1.0 + x) * ScreenWidth() - totalWidth; // Align to right + else + xPos = x * ScreenWidth(); + } + + if ( xPos + width > ScreenWidth() ) + xPos = ScreenWidth() - width; + else if ( xPos < 0 ) + xPos = 0; + + return xPos; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int CHudMessage::YPosition( float y, int height ) +{ + int yPos; + + if ( y == -1 ) // Centered? + yPos = (ScreenHeight() - height) * 0.5; + else + { + // Alight bottom? + if ( y < 0 ) + yPos = (1.0 + y) * ScreenHeight() - height; // Alight bottom + else // align top + yPos = y * ScreenHeight(); + } + + if ( yPos + height > ScreenHeight() ) + yPos = ScreenHeight() - height; + else if ( yPos < 0 ) + yPos = 0; + + return yPos; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudMessage::MessageScanNextChar( void ) +{ + int srcRed, srcGreen, srcBlue, destRed, destGreen, destBlue; + int blend; + + srcRed = m_parms.pMessage->r1; + srcGreen = m_parms.pMessage->g1; + srcBlue = m_parms.pMessage->b1; + blend = 0; // Pure source + + destRed = destGreen = destBlue = 0; + + switch( m_parms.pMessage->effect ) + { + // Fade-in / Fade-out + case 0: + case 1: + destRed = destGreen = destBlue = 0; + blend = m_parms.fadeBlend; + break; + + case 2: + m_parms.charTime += m_parms.pMessage->fadein; + if ( m_parms.charTime > m_parms.time ) + { + srcRed = srcGreen = srcBlue = 0; + blend = 0; // pure source + } + else + { + float deltaTime = m_parms.time - m_parms.charTime; + + destRed = destGreen = destBlue = 0; + if ( m_parms.time > m_parms.fadeTime ) + { + blend = m_parms.fadeBlend; + } + else if ( deltaTime > m_parms.pMessage->fxtime ) + blend = 0; // pure dest + else + { + destRed = m_parms.pMessage->r2; + destGreen = m_parms.pMessage->g2; + destBlue = m_parms.pMessage->b2; + blend = 255 - (deltaTime * (1.0/m_parms.pMessage->fxtime) * 255.0 + 0.5); + } + } + break; + } + if ( blend > 255 ) + blend = 255; + else if ( blend < 0 ) + blend = 0; + + m_parms.r = ((srcRed * (255-blend)) + (destRed * blend)) >> 8; + m_parms.g = ((srcGreen * (255-blend)) + (destGreen * blend)) >> 8; + m_parms.b = ((srcBlue * (255-blend)) + (destBlue * blend)) >> 8; + +#if 0 + if ( m_parms.pMessage->effect == 1 && m_parms.charTime != 0 ) + { + textmessage->AddChar( m_parms.pMessage->r2, m_parms.pMessage->g2, m_parms.pMessage->b2, 255, m_parms.text ); + } +#endif +} + + +void CHudMessage::SetFont( HScheme scheme, const char *pFontName ) +{ + vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( scheme ); + + if ( pScheme ) + { + vgui::HFont font = pScheme->GetFont( pFontName ); + textmessage->SetFont( font ); + m_parms.font = font; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudMessage::MessageScanStart( void ) +{ + switch( m_parms.pMessage->effect ) + { + // Fade-in / out with flicker + case 1: + case 0: + m_parms.fadeTime = m_parms.pMessage->fadein + m_parms.pMessage->holdtime; + + + if ( m_parms.time < m_parms.pMessage->fadein ) + { + m_parms.fadeBlend = ((m_parms.pMessage->fadein - m_parms.time) * (1.0/m_parms.pMessage->fadein) * 255); + } + else if ( m_parms.time > m_parms.fadeTime ) + { + if ( m_parms.pMessage->fadeout > 0 ) + m_parms.fadeBlend = (((m_parms.time - m_parms.fadeTime) / m_parms.pMessage->fadeout) * 255); + else + m_parms.fadeBlend = 255; // Pure dest (off) + } + else + m_parms.fadeBlend = 0; // Pure source (on) + m_parms.charTime = 0; + + if ( m_parms.pMessage->effect == 1 && (rand()%100) < 10 ) + m_parms.charTime = 1; + break; + + case 2: + m_parms.fadeTime = (m_parms.pMessage->fadein * m_parms.length) + m_parms.pMessage->holdtime; + + if ( m_parms.time > m_parms.fadeTime && m_parms.pMessage->fadeout > 0 ) + m_parms.fadeBlend = (((m_parms.time - m_parms.fadeTime) / m_parms.pMessage->fadeout) * 255); + else + m_parms.fadeBlend = 0; + break; + } + + m_parms.font = g_hFontTrebuchet24; + + if ( m_parms.vguiFontName != NULL && + m_parms.vguiFontName[ 0 ] ) + { + + SetFont( vgui::scheme()->GetDefaultScheme(), m_parms.vguiFontName ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudMessage::MessageDrawScan( client_textmessage_t *pMessage, float time ) +{ + int i, j, length, width; + const wchar_t *pText; + wchar_t textBuf[ 1024 ]; + + { + // look up in localization table + // strip off any trailing newlines + int len = Q_strlen( pMessage->pMessage ); + int tempLen = len + 2; + char *localString = (char *)_alloca( tempLen ); + Q_strncpy( localString, pMessage->pMessage, tempLen ); + if (V_iscntrl(localString[len - 1])) + { + localString[len - 1] = 0; + } + + pText = g_pVGuiLocalize->Find( localString ); + if ( !pText ) + { + g_pVGuiLocalize->ConvertANSIToUnicode( pMessage->pMessage, textBuf, sizeof( textBuf ) ); + pText = textBuf; + } + } + + const wchar_t *pPerm = pText; + + // Count lines + m_parms.lines = 1; + m_parms.time = time; + m_parms.pMessage = pMessage; + length = 0; + width = 0; + m_parms.totalWidth = 0; + m_parms.vguiFontName = pMessage->pVGuiSchemeFontName; + + m_parms.font = g_hFontTrebuchet24; + + while ( *pText ) + { + if ( *pText == '\n' ) + { + m_parms.lines++; + if ( width > m_parms.totalWidth ) + m_parms.totalWidth = width; + width = 0; + } + else + { + width += vgui::surface()->GetCharacterWidth( m_parms.font, *pText ); + } + pText++; + length++; + } + if ( width > m_parms.totalWidth ) + m_parms.totalWidth = width; + m_parms.length = length; + + int fontHeight = vgui::surface()->GetFontTall( m_parms.font ); + + m_parms.totalHeight = ( m_parms.lines * fontHeight ); + + m_parms.y = YPosition( pMessage->y, m_parms.totalHeight ); + pText = pPerm; + + m_parms.charTime = 0; + + float flBoxPixels = 0.0f; + + MessageScanStart(); + + if ( pMessage->bRoundedRectBackdropBox ) + { + // 2.0f since we have extra space at both the top and bottom + flBoxPixels = pMessage->flBoxSize * fontHeight; + + // Draw the box + int boxx = XPosition( pMessage->x, m_parms.totalWidth, m_parms.totalWidth ); + int boxy = YPosition( pMessage->y, m_parms.totalHeight ); + + boxx -= flBoxPixels; + boxy -= flBoxPixels * 0.5f; + + float flAlphaScale = clamp( ( 255.0f - (float)m_parms.fadeBlend ) / 255.0f, 0.0f, 1.0f ); + Color boxColor( + pMessage->boxcolor[ 0 ], + pMessage->boxcolor[ 1 ], + pMessage->boxcolor[ 2 ], + pMessage->boxcolor[ 3 ] * flAlphaScale ); + + DrawBox( boxx, boxy, m_parms.totalWidth + 2.0f * flBoxPixels, m_parms.totalHeight + 2.0f * flBoxPixels * 0.5f, boxColor, 1.0f ); + } + + wchar_t line[ 512 ]; + for ( i = 0; i < m_parms.lines; i++ ) + { + m_parms.lineLength = 0; + m_parms.width = 0; + while ( *pText && *pText != '\n' ) + { + wchar_t c = *pText; + line[m_parms.lineLength] = c; + m_parms.width += vgui::surface()->GetCharacterWidth( m_parms.font, c); + m_parms.lineLength++; + if ( m_parms.lineLength > (ARRAYSIZE(line)-1) ) + { + m_parms.lineLength = ARRAYSIZE(line)-1; + } + pText++; + } + pText++; // Skip LF + line[m_parms.lineLength] = 0; + + m_parms.x = XPosition( pMessage->x, m_parms.width, m_parms.totalWidth ); + + textmessage->SetPosition( m_parms.x, m_parms.y ); + + if (m_parms.fadeBlend > 255) + m_parms.fadeBlend = 255; + + for ( j = 0; j < m_parms.lineLength; j++ ) + { + m_parms.text = line[j]; + MessageScanNextChar(); + textmessage->AddChar( m_parms.r, m_parms.g, m_parms.b, 255 - m_parms.fadeBlend, m_parms.text ); + } + + m_parms.y += vgui::surface()->GetFontTall( m_parms.font ); + } + + // Restore default font + textmessage->SetDefaultFont(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CHudMessage::ShouldDraw( void ) +{ + return ( CHudElement::ShouldDraw() && + ( m_bHaveMessage || m_Messages.Count() ) ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudMessage::Paint() +{ + int i, drawn; + client_textmessage_t *pMessage; + float endTime; + + drawn = 0; + + if ( m_gameTitleTime > 0 ) + { + float localTime = gpGlobals->curtime - m_gameTitleTime; + float brightness; + + // Maybe timer isn't set yet + if ( m_gameTitleTime > gpGlobals->curtime ) + { + m_gameTitleTime = gpGlobals->curtime; + } + + if ( localTime > (m_pGameTitle->fadein + m_pGameTitle->holdtime + m_pGameTitle->fadeout) ) + { + m_gameTitleTime = 0; + } + else + { + brightness = FadeBlend( m_pGameTitle->fadein, m_pGameTitle->fadeout, m_pGameTitle->holdtime, localTime ); + + int halfWidth = m_iconTitleHalf->Width(); + int fullWidth = halfWidth + m_iconTitleLife->Width(); + int fullHeight = m_iconTitleHalf->Height(); + + int x = XPosition( m_pGameTitle->x, fullWidth, fullWidth ); + int y = YPosition( m_pGameTitle->y, fullHeight ); + + m_iconTitleHalf->DrawSelf( x, y, Color( m_pGameTitle->r1, m_pGameTitle->g1, m_pGameTitle->b1, brightness * 255 ) ); + m_iconTitleLife->DrawSelf( x + halfWidth, y, Color( m_pGameTitle->r1, m_pGameTitle->g1, m_pGameTitle->b1, brightness * 255 ) ); + drawn = 1; + } + } + + // Fixup level transitions + for ( i = 0; i < maxHUDMessages; i++ ) + { + // Assume m_parms.time contains last time + if ( m_pMessages[i] ) + { + pMessage = m_pMessages[i]; + if ( m_startTime[i] > gpGlobals->curtime ) + m_startTime[i] = gpGlobals->curtime + m_parms.time - m_startTime[i] + 0.2; // Server takes 0.2 seconds to spawn, adjust for this + } + } + + for ( i = 0; i < maxHUDMessages; i++ ) + { + if ( m_pMessages[i] ) + { + pMessage = m_pMessages[i]; + + // This is when the message is over + switch( pMessage->effect ) + { + case 0: + case 1: + endTime = m_startTime[i] + pMessage->fadein + pMessage->fadeout + pMessage->holdtime; + break; + + // Fade in is per character in scanning messages + case 2: + endTime = m_startTime[i] + (pMessage->fadein * strlen( pMessage->pMessage )) + pMessage->fadeout + pMessage->holdtime; + break; + + default: + endTime = 0; + break; + } + + if ( gpGlobals->curtime <= endTime ) + { + float messageTime = gpGlobals->curtime - m_startTime[i]; + + // Draw the message + // effect 0 is fade in/fade out + // effect 1 is flickery credits + // effect 2 is write out (training room) + MessageDrawScan( pMessage, messageTime ); + + drawn++; + } + else + { + // The message is over + m_pMessages[i] = NULL; + } + } + } + + // Remember the time -- to fix up level transitions + m_parms.time = gpGlobals->curtime; + + // Did we draw any messages? + if ( !drawn ) + { + m_bHaveMessage = false; + } + + PaintCharacters(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudMessage::MessageAdd( const char *pName ) +{ + int i; + + float time = gpGlobals->curtime; + + client_textmessage_t *pMessage = NULL; + + if ( pName[0] == '#' ) + { + pMessage = TextMessageGet( pName+1 ); + } + else + { + pMessage = TextMessageGet( pName ); + } + + if ( !pMessage ) + return; + + if ( pMessage->pClearMessage ) + { + for ( i = 0; i < maxHUDMessages; i++ ) + { + if ( m_pMessages[ i ] && !Q_stricmp( m_pMessages[ i ]->pName, pMessage->pClearMessage ) ) + { + m_startTime[ i ] = 0.0f; + m_pMessages[ i ] = NULL; + break; + } + } + } + + for ( i = 0; i < maxHUDMessages; i++ ) + { + if ( !m_pMessages[i] ) + { + m_pMessages[i] = pMessage; + m_startTime[i] = time; + break; + } + } + + // Remember the time -- to fix up level transitions + m_parms.time = time; + + m_bHaveMessage = true; + // Force this now so that SCR_UpdateScreen will paint the panel immediately!!! + SetVisible( true ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudMessage::MsgFunc_HudText( bf_read &msg ) +{ + char szString[2048]; + msg.ReadString( szString, sizeof(szString) ); + + MessageAdd( szString ); +} + +#include "ivieweffects.h" +#include "shake.h" + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudMessage::MsgFunc_GameTitle( bf_read &msg ) +{ + m_pGameTitle = TextMessageGet( "GAMETITLE" ); + if ( m_pGameTitle != NULL ) + { + m_gameTitleTime = gpGlobals->curtime; + + m_bHaveMessage = true; + } + +// if ( READ_BYTE() ) + { + ScreenFade_t sf; + memset( &sf, 0, sizeof( sf ) ); + sf.a = 255; + sf.r = 0; + sf.g = 0; + sf.b = 0; + sf.duration = (float)(1<Fade( sf ); + + Msg( "%i gametitle fade\n", gpGlobals->framecount ); + } +} + + +void CHudMessage::MsgFunc_HudMsg(bf_read &msg) +{ +// Position command $position x y +// x & y are from 0 to 1 to be screen resolution independent +// -1 means center in each dimension +// Effect command $effect +// effect 0 is fade in/fade out +// effect 1 is flickery credits +// effect 2 is write out (training room) +// Text color r g b command $color +// Text color r g b command $color2 +// fadein time fadeout time / hold time +// $fadein (message fade in time - per character in effect 2) +// $fadeout (message fade out time) +// $holdtime (stay on the screen for this long) + + int channel = msg.ReadByte() % MAX_NETMESSAGE; // Pick the buffer + + client_textmessage_t *pNetMessage = TextMessageGet( s_NetworkMessageNames[ channel ] ); + + if ( !pNetMessage || !pNetMessage->pMessage ) + return; + + pNetMessage->x = msg.ReadFloat(); + pNetMessage->y = msg.ReadFloat(); + + pNetMessage->r1 = msg.ReadByte(); + pNetMessage->g1 = msg.ReadByte(); + pNetMessage->b1 = msg.ReadByte(); + pNetMessage->a1 = msg.ReadByte(); + + pNetMessage->r2 = msg.ReadByte(); + pNetMessage->g2 = msg.ReadByte(); + pNetMessage->b2 = msg.ReadByte(); + pNetMessage->a2 = msg.ReadByte(); + + pNetMessage->effect = msg.ReadByte(); + + pNetMessage->fadein = msg.ReadFloat(); + pNetMessage->fadeout = msg.ReadFloat(); + pNetMessage->holdtime = msg.ReadFloat(); + pNetMessage->fxtime = msg.ReadFloat(); + + pNetMessage->pName = s_NetworkMessageNames[ channel ]; + + // see tmessage.cpp why 512 + msg.ReadString( (char*)pNetMessage->pMessage, 512 ); + + MessageAdd( pNetMessage->pName ); +} + +//----------------------------------------------------------------------------- +// Purpose: Get font sizes +// Input : *pWidth - +// Output : int +//----------------------------------------------------------------------------- +int CHudMessage::GetFontInfo( FONTABC *pABCs, vgui::HFont hFont ) +{ + int i; + + if ( !hFont ) + { + hFont = m_hFont; + } + + if ( !hFont ) + return 0; + + if ( pABCs ) + { + for ( i =0; i < 256; i++ ) + { + int a, b, c; + vgui::surface()->GetCharABCwide( hFont, (char)i, a, b, c ); + pABCs[i].abcA = a; + pABCs[i].abcB = b; + pABCs[i].abcC = c; + pABCs[i].total = a+b+c; + } + } + + return vgui::surface()->GetFontTall( hFont ); +} + +//----------------------------------------------------------------------------- +// Purpose: Clear all messages out of active list, etc. +//----------------------------------------------------------------------------- +void CHudMessage::ResetCharacters( void ) +{ + m_Messages.Purge(); +} + +//----------------------------------------------------------------------------- +// Purpose: Grab next free message, if any +// Output : CTextMessagePanel::message_t +//----------------------------------------------------------------------------- +CHudMessage::message_t *CHudMessage::AllocMessage( void ) +{ + message_t *msg; + + if ( m_Messages.Count() >= MAX_TEXTMESSAGE_CHARS ) + return NULL; + + msg = &m_Messages[ m_Messages.AddToTail() ]; + + msg->type = TYPE_UNKNOWN; + msg->x = 0; + msg->y = 0; + msg->ch = 0; + msg->r = 0; + msg->g = 0; + msg->b = 0; + msg->a = 0; + msg->font = 0; + + SetVisible( true ); + + return msg; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : x - +// y - +//----------------------------------------------------------------------------- +void CHudMessage::SetPosition( int x, int y ) +{ + message_t *msg = AllocMessage(); + if ( !msg ) + return; + + msg->type = TYPE_POSITION; + + // Used fields + msg->x = x; + msg->y = y; +} + +//----------------------------------------------------------------------------- +// Purpose: Adds a character to the active list, if possible +// Input : x - +// y - +// r - +// g - +// b - +// a - +// ch - +// Output : int +//----------------------------------------------------------------------------- +void CHudMessage::AddChar( int r, int g, int b, int a, wchar_t ch ) +{ + message_t *msg = AllocMessage(); + if ( !msg ) + return; + + msg->type = TYPE_CHARACTER; + + // Used fields + msg->r = r; + msg->g = g; + msg->b = b; + msg->a = a; + msg->ch = ch; +} + +//----------------------------------------------------------------------------- +// Purpose: Determine width and height of specified string +// Input : *wide - +// *tall - +// *string - +//----------------------------------------------------------------------------- +void CHudMessage::GetTextExtents( int *wide, int *tall, const char *string ) +{ + *wide = g_pMatSystemSurface->DrawTextLen( m_hFont, (char *)string ); + *tall = vgui::surface()->GetFontTall( m_hFont ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudMessage::SetFont( vgui::HFont hCustomFont ) +{ + m_hFont = hCustomFont; + + message_t *msg = AllocMessage(); + if ( !msg ) + return; + + msg->type = TYPE_FONT; + + // Used fields + msg->font = m_hFont; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudMessage::SetDefaultFont( void ) +{ + SetFont( m_hDefaultFont ); +} + +//----------------------------------------------------------------------------- +// Purpose: Draw current text items +//----------------------------------------------------------------------------- +void CHudMessage::PaintCharacters() +{ + int xpos = 0, ypos = 0; + vgui::surface()->DrawSetTextFont( m_hFont ); + + int messageCount = m_Messages.Count(); + for ( int i = 0 ; i < messageCount; ++i ) + { + message_t *msg = &m_Messages[ i ]; + + switch ( msg->type ) + { + default: + case TYPE_UNKNOWN: + Assert( 0 ); + break; + case TYPE_POSITION: + xpos = msg->x; + ypos = msg->y; + break; + case TYPE_FONT: + m_hFont = msg->font; + vgui::surface()->DrawSetTextFont( m_hFont ); + break; + case TYPE_CHARACTER: + if ( m_hFont ) + { + int a, b, c; + vgui::surface()->GetCharABCwide( m_hFont, msg->ch, a, b, c ); + + if ( msg->ch > 32 ) + { + vgui::surface()->DrawSetTextColor( msg->r, msg->g, msg->b, msg->a ); + vgui::surface()->DrawSetTextPos( xpos, ypos ); + vgui::surface()->DrawUnicodeChar( msg->ch ); + } + xpos += a + b + c; + } + break; + } + } + + ResetCharacters(); +} + +void CHudMessage::GetLength( int *wide, int *tall, const char *string ) +{ + GetTextExtents( wide, tall, string ); } \ No newline at end of file -- cgit v1.2.3