diff options
| author | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:31:46 -0800 |
|---|---|---|
| committer | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:46:31 -0800 |
| commit | f56bb35301836e56582a575a75864392a0177875 (patch) | |
| tree | de61ddd39de3e7df52759711950b4c288592f0dc /sp/src/game/client/message.cpp | |
| parent | Mark some more files as text. (diff) | |
| download | source-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.cpp | 2138 |
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 |