aboutsummaryrefslogtreecommitdiff
path: root/sp/src/game/client/message.cpp
diff options
context:
space:
mode:
authorJørgen P. Tjernø <[email protected]>2013-12-02 19:31:46 -0800
committerJørgen P. Tjernø <[email protected]>2013-12-02 19:46:31 -0800
commitf56bb35301836e56582a575a75864392a0177875 (patch)
treede61ddd39de3e7df52759711950b4c288592f0dc /sp/src/game/client/message.cpp
parentMark some more files as text. (diff)
downloadsource-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz
source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip
Fix line endings. WHAMMY.
Diffstat (limited to 'sp/src/game/client/message.cpp')
-rw-r--r--sp/src/game/client/message.cpp2138
1 files changed, 1069 insertions, 1069 deletions
diff --git a/sp/src/game/client/message.cpp b/sp/src/game/client/message.cpp
index 5abc1ba6..fe341e71 100644
--- a/sp/src/game/client/message.cpp
+++ b/sp/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 <ctype.h>
-
-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<<SCREENFADE_FRACBITS) * 5.0f;
- sf.holdTime = (float)(1<<SCREENFADE_FRACBITS) * 1.0f;
- sf.fadeFlags = FFADE_IN | FFADE_PURGE;
- vieweffects->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 number>
-// 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 <ctype.h>
+
+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<<SCREENFADE_FRACBITS) * 5.0f;
+ sf.holdTime = (float)(1<<SCREENFADE_FRACBITS) * 1.0f;
+ sf.fadeFlags = FFADE_IN | FFADE_PURGE;
+ vieweffects->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 number>
+// 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