aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/client/vgui_messagechars.cpp
diff options
context:
space:
mode:
authorJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
committerJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
commit39ed87570bdb2f86969d4be821c94b722dc71179 (patch)
treeabc53757f75f40c80278e87650ea92808274aa59 /mp/src/game/client/vgui_messagechars.cpp
downloadsource-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz
source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/game/client/vgui_messagechars.cpp')
-rw-r--r--mp/src/game/client/vgui_messagechars.cpp466
1 files changed, 466 insertions, 0 deletions
diff --git a/mp/src/game/client/vgui_messagechars.cpp b/mp/src/game/client/vgui_messagechars.cpp
new file mode 100644
index 00000000..ac587bc1
--- /dev/null
+++ b/mp/src/game/client/vgui_messagechars.cpp
@@ -0,0 +1,466 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $Workfile: $
+// $Date: $
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include <stdarg.h>
+#include "imessagechars.h"
+#include <vgui/IVGui.h>
+#include "VGuiMatSurface/IMatSystemSurface.h"
+#include <vgui_controls/Panel.h>
+#include <vgui_controls/Controls.h>
+#include <vgui/IScheme.h>
+#include <vgui/ISurface.h>
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+// Simultaneous message limit
+#define MAX_MESSAGECHARS_MESSAGES 1024
+#define MAX_MESSAGECHARSPANEL_LEN 1024
+
+//-----------------------------------------------------------------------------
+// Purpose: Panel for displaying console characters at specified locations
+//-----------------------------------------------------------------------------
+class CMessageCharsPanel : public vgui::Panel
+{
+ typedef vgui::Panel BaseClass;
+public:
+ // Internal pool of such messages
+ typedef struct message_s
+ {
+ struct message_s *next;
+ int x, y;
+ byte r, g, b, a;
+ char *text;
+ vgui::HFont hCustomFont;
+ float fTTL;
+ int messageID;
+ } message_t;
+
+ // Construct/destruct
+ CMessageCharsPanel( vgui::VPANEL parent );
+ virtual ~CMessageCharsPanel( void );
+
+ // Add block of text to list
+ virtual int AddText(
+ float flTime,
+ vgui::HFont hCustomFont,
+ int x,
+ int y,
+ int r,
+ int g,
+ int b,
+ int a,
+ char *fmt,
+ int messageID,
+ ... );
+
+ // Determine text side and height
+ virtual void GetTextExtents( vgui::HFont hCustomFont, int *wide, int *tall, const char *string );
+
+ virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
+ virtual void Paint();
+ virtual void OnTick( void );
+
+ virtual bool ShouldDraw( void );
+
+ void RemoveStringsByID( int messageID );
+
+ void Clear( void );
+
+private:
+ // Allocate a new message
+ message_t *AllocMessage( void );
+ // Clear out all messages
+ void Reset( void );
+
+ vgui::HFont m_hFont;
+
+ // Pool of messages
+ message_t m_Messages[ MAX_MESSAGECHARS_MESSAGES ];
+ message_t *m_pActive;
+ message_t *m_pFree;
+};
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *parent -
+// Output :
+//-----------------------------------------------------------------------------
+CMessageCharsPanel::CMessageCharsPanel( vgui::VPANEL parent ) :
+ BaseClass( NULL, "CMessageCharsPanel" )
+{
+ SetParent( parent );
+ SetSize( ScreenWidth(), ScreenHeight() );
+ SetPos( 0, 0 );
+ SetVisible( true );
+ SetCursor( null );
+ SetKeyBoardInputEnabled( false );
+ SetMouseInputEnabled( false );
+
+ m_hFont = vgui::INVALID_FONT;
+
+ SetFgColor( Color( 0, 0, 0, 255 ) );
+ SetPaintBackgroundEnabled( false );
+
+ Q_memset( m_Messages, 0, sizeof( m_Messages ) );
+
+ Reset();
+
+ vgui::ivgui()->AddTickSignal( GetVPanel(), 100 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output :
+//-----------------------------------------------------------------------------
+CMessageCharsPanel::~CMessageCharsPanel( void )
+{
+}
+
+void CMessageCharsPanel::ApplySchemeSettings(vgui::IScheme *pScheme)
+{
+ BaseClass::ApplySchemeSettings(pScheme);
+
+ m_hFont = pScheme->GetFont( "Default" );
+ Assert( m_hFont != vgui::INVALID_FONT );
+
+ SetSize( ScreenWidth(), ScreenHeight() );
+ SetPos( 0, 0 );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CMessageCharsPanel::Clear( void )
+{
+ Reset();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Reset all messages
+//-----------------------------------------------------------------------------
+void CMessageCharsPanel::Reset( void )
+{
+ m_pActive = NULL;
+ int i;
+ for( i = 0; i < MAX_MESSAGECHARS_MESSAGES-1; i++ )
+ {
+ if ( m_Messages[ i ].text )
+ {
+ delete[] m_Messages[ i ].text;
+ m_Messages[ i ].text = NULL;
+ }
+ m_Messages[ i ].next = &m_Messages[ i + 1 ];
+ }
+ m_Messages[ i ].next = NULL;
+ m_pFree = &m_Messages[ 0 ];
+ SetVisible( false );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Allocate a message if possible
+// Output : CMessageCharsPanel::message_t
+//-----------------------------------------------------------------------------
+CMessageCharsPanel::message_t *CMessageCharsPanel::AllocMessage( void )
+{
+ CMessageCharsPanel::message_t *msg;
+
+ if ( !m_pFree )
+ return NULL;
+
+ msg = m_pFree;
+ m_pFree = m_pFree->next;
+
+ msg->next = m_pActive;
+ m_pActive = msg;
+
+ msg->x = 0;
+ msg->y = 0;
+ msg->text = NULL;
+
+ msg->hCustomFont = NULL;
+
+ return msg;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Allocate message and fill in data
+// Input : x -
+// y -
+// *fmt -
+// ... -
+// Output : int
+//-----------------------------------------------------------------------------
+int CMessageCharsPanel::AddText(
+ float flTime,
+ vgui::HFont hCustomFont,
+ int x,
+ int y,
+ int r,
+ int g,
+ int b,
+ int a,
+ char *fmt,
+ int messageID,
+ ... )
+{
+ va_list argptr;
+ char data[ MAX_MESSAGECHARSPANEL_LEN ];
+ int len;
+
+ va_start(argptr, messageID);
+ len = Q_vsnprintf(data, sizeof( data ), fmt, argptr);
+ va_end(argptr);
+
+ data[ MAX_MESSAGECHARSPANEL_LEN - 1 ] = 0;
+
+ CMessageCharsPanel::message_t *msg = AllocMessage();
+ if ( !msg )
+ return x;
+
+ msg->x = x;
+ msg->y = y;
+ msg->r = r;
+ msg->g = g;
+ msg->b = b;
+ msg->a = a;
+ msg->messageID = messageID;
+
+ Assert( !msg->text );
+
+ msg->text = new char[ Q_strlen( data ) + 1 ];
+ Assert( msg->text );
+ Q_strncpy( msg->text, data, sizeof( msg->text ) );
+
+ if ( flTime )
+ msg->fTTL = gpGlobals->curtime + flTime;
+ else
+ msg->fTTL = 0;
+ SetVisible( true );
+
+ if ( hCustomFont )
+ msg->hCustomFont = hCustomFont;
+ else
+ msg->hCustomFont = m_hFont;
+
+ // Return new cursor position
+ return x + g_pMatSystemSurface->DrawTextLen( msg->hCustomFont, data );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Determine text size ahead of time
+// Input : *wide -
+// *tall -
+// *string -
+//-----------------------------------------------------------------------------
+void CMessageCharsPanel::GetTextExtents( vgui::HFont hCustomFont, int *wide, int *tall, const char *string )
+{
+ if ( !hCustomFont )
+ {
+ // Make sure we actually have the font...
+ vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( GetScheme() );
+ hCustomFont = pScheme->GetFont( "Default" );
+ }
+
+ Assert( hCustomFont );
+
+ *wide = g_pMatSystemSurface->DrawTextLen( hCustomFont, (char *)string );
+ *tall = vgui::surface()->GetFontTall( hCustomFont );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CMessageCharsPanel::OnTick( void )
+{
+ bool bVisible = ShouldDraw();
+ if ( IsVisible() != bVisible )
+ {
+ SetVisible( bVisible );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CMessageCharsPanel::ShouldDraw( void )
+{
+ if ( !m_pActive )
+ return false;
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input :
+//-----------------------------------------------------------------------------
+void CMessageCharsPanel::Paint()
+{
+ CMessageCharsPanel::message_t *msg = m_pActive;
+ while ( msg )
+ {
+ g_pMatSystemSurface->DrawColoredText( msg->hCustomFont, msg->x, msg->y, msg->r, msg->g, msg->b, msg->a, msg->text );
+ msg = msg->next;
+ }
+
+ // Clear our dead messages
+ message_t *pPrev = NULL;
+ message_t *pCurrent = m_pActive;
+ while ( pCurrent )
+ {
+ if ( pCurrent->fTTL <= gpGlobals->curtime )
+ {
+ // Move it to the free list
+ if ( !pPrev )
+ {
+ m_pActive = pCurrent->next;
+ }
+ else
+ {
+ pPrev->next = pCurrent->next;
+ }
+
+ // Store off next one, because we're about to move the current
+ message_t *pNext = pCurrent->next;
+ delete[] pCurrent->text;
+ pCurrent->text = NULL;
+ pCurrent->next = m_pFree;
+ m_pFree = pCurrent;
+
+ // Don't advance pPrev
+ pCurrent = pNext;
+ continue;
+ }
+
+ pPrev = pCurrent;
+ pCurrent = pCurrent->next;
+ }
+}
+
+
+void CMessageCharsPanel::RemoveStringsByID( int messageID )
+{
+ for ( message_t *pCurrent = m_pActive; pCurrent; pCurrent = pCurrent->next )
+ {
+ if ( pCurrent->messageID == messageID )
+ pCurrent->fTTL = gpGlobals->curtime - 1000;
+ }
+}
+
+class CMessageChars : public IMessageChars
+{
+private:
+ CMessageCharsPanel *messageCharsPanel;
+public:
+ CMessageChars( void )
+ {
+ messageCharsPanel = NULL;
+ }
+
+ void Create( vgui::VPANEL parent )
+ {
+ messageCharsPanel = new CMessageCharsPanel( parent );
+ }
+
+ void Destroy( void )
+ {
+ if ( messageCharsPanel )
+ {
+ messageCharsPanel->SetParent( (vgui::Panel *)NULL );
+ delete messageCharsPanel;
+ messageCharsPanel = NULL;
+ }
+ }
+
+ int DrawStringForTime( float flTime, vgui::HFont hCustomFont, int x, int y, int r, int g, int b, int a, const char *fmt, int messageID, ... )
+ {
+ va_list argptr;
+ char data[ MAX_MESSAGECHARSPANEL_LEN ];
+ int len;
+
+ va_start(argptr, messageID);
+ len = Q_vsnprintf(data, sizeof( data ), fmt, argptr);
+ va_end(argptr);
+
+ data[ MAX_MESSAGECHARSPANEL_LEN - 1 ] = 0;
+
+ if ( !messageCharsPanel )
+ return x;
+
+ return messageCharsPanel->AddText( flTime, hCustomFont, x, y, r, g, b, a, data, messageID );
+ }
+
+ int DrawStringForTime( float flTime, vgui::HFont hCustomFont, int x, int y, const char *fmt, int messageID, ... )
+ {
+ int r = 192, g = 192, b = 192;
+
+ va_list argptr;
+ va_start(argptr, messageID);
+ int result = DrawString( hCustomFont, x, y, r, g, b, 255, fmt, messageID, argptr );
+ va_end( argptr );
+ return result;
+ }
+
+ virtual void RemoveStringsByID( int messageID )
+ {
+ messageCharsPanel->RemoveStringsByID( messageID );
+ }
+
+ int DrawString( vgui::HFont hCustomFont, int x, int y, int r, int g, int b, int a, const char *fmt, int messageID, ... )
+ {
+ va_list argptr;
+ va_start(argptr, messageID);
+ int result = DrawStringForTime( 0, hCustomFont, x, y, r, g, b, a, fmt, messageID, argptr );
+ va_end( argptr );
+ return result;
+ }
+
+ int DrawString( vgui::HFont hCustomFont, int x, int y, const char *fmt, int messageID, ... )
+ {
+ va_list argptr;
+ va_start(argptr, messageID);
+ int result = DrawStringForTime( 0, hCustomFont, x, y, fmt, messageID, argptr );
+ va_end( argptr );
+ return result;
+ }
+
+ void GetStringLength( vgui::HFont hCustomFont, int *width, int *height, const char *fmt, ... )
+ {
+ if ( !messageCharsPanel )
+ {
+ return;
+ }
+
+ va_list argptr;
+ char data[ MAX_MESSAGECHARSPANEL_LEN ];
+ int len;
+
+ va_start(argptr, fmt);
+ len = Q_vsnprintf(data, sizeof( data ), fmt, argptr);
+ va_end(argptr);
+
+ data[ MAX_MESSAGECHARSPANEL_LEN - 1 ] = 0;
+
+ messageCharsPanel->GetTextExtents( hCustomFont, width, height, data );
+ }
+
+ void Clear( void )
+ {
+ if ( !messageCharsPanel )
+ return;
+ messageCharsPanel->Clear();
+ }
+};
+
+static CMessageChars g_MessageChars;
+IMessageChars *messagechars = ( IMessageChars * )&g_MessageChars;