aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/server/slideshow_display.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/server/slideshow_display.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/server/slideshow_display.cpp')
-rw-r--r--mp/src/game/server/slideshow_display.cpp625
1 files changed, 625 insertions, 0 deletions
diff --git a/mp/src/game/server/slideshow_display.cpp b/mp/src/game/server/slideshow_display.cpp
new file mode 100644
index 00000000..12327ef5
--- /dev/null
+++ b/mp/src/game/server/slideshow_display.cpp
@@ -0,0 +1,625 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Implements the big scary boom-boom machine Antlions fear.
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "EnvMessage.h"
+#include "fmtstr.h"
+#include "vguiscreen.h"
+#include "filesystem.h"
+
+
+#define SLIDESHOW_LIST_BUFFER_MAX 8192
+
+
+struct SlideKeywordList_t
+{
+ char szSlideKeyword[64];
+};
+
+
+class CSlideshowDisplay : public CBaseEntity
+{
+public:
+
+ DECLARE_CLASS( CSlideshowDisplay, CBaseEntity );
+ DECLARE_DATADESC();
+ DECLARE_SERVERCLASS();
+
+ virtual ~CSlideshowDisplay();
+
+ virtual bool KeyValue( const char *szKeyName, const char *szValue );
+
+ virtual int UpdateTransmitState();
+ virtual void SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways );
+
+ virtual void Spawn( void );
+ virtual void Precache( void );
+ virtual void OnRestore( void );
+
+ void ScreenVisible( bool bVisible );
+
+ void Disable( void );
+ void Enable( void );
+
+ void InputDisable( inputdata_t &inputdata );
+ void InputEnable( inputdata_t &inputdata );
+
+ void InputSetDisplayText( inputdata_t &inputdata );
+ void InputRemoveAllSlides( inputdata_t &inputdata );
+ void InputAddSlides( inputdata_t &inputdata );
+
+ void InputSetMinSlideTime( inputdata_t &inputdata );
+ void InputSetMaxSlideTime( inputdata_t &inputdata );
+
+ void InputSetCycleType( inputdata_t &inputdata );
+ void InputSetNoListRepeats( inputdata_t &inputdata );
+
+private:
+
+ // Control panel
+ void GetControlPanelInfo( int nPanelIndex, const char *&pPanelName );
+ void GetControlPanelClassName( int nPanelIndex, const char *&pPanelName );
+ void SpawnControlPanels( void );
+ void RestoreControlPanels( void );
+ void BuildSlideShowImagesList( void );
+
+private:
+
+ CNetworkVar( bool, m_bEnabled );
+
+ CNetworkString( m_szDisplayText, 128 );
+
+ CNetworkString( m_szSlideshowDirectory, 128 );
+ string_t m_String_tSlideshowDirectory;
+
+ CUtlVector<SlideKeywordList_t*> m_SlideKeywordList;
+ CNetworkArray( unsigned char, m_chCurrentSlideLists, 16 );
+
+ CNetworkVar( float, m_fMinSlideTime );
+ CNetworkVar( float, m_fMaxSlideTime );
+
+ CNetworkVar( int, m_iCycleType );
+ CNetworkVar( bool, m_bNoListRepeats );
+
+ int m_iScreenWidth;
+ int m_iScreenHeight;
+
+ bool m_bDoFullTransmit;
+
+ typedef CHandle<CVGuiScreen> ScreenHandle_t;
+ CUtlVector<ScreenHandle_t> m_hScreens;
+};
+
+
+LINK_ENTITY_TO_CLASS( vgui_slideshow_display, CSlideshowDisplay );
+
+//-----------------------------------------------------------------------------
+// Save/load
+//-----------------------------------------------------------------------------
+BEGIN_DATADESC( CSlideshowDisplay )
+ DEFINE_FIELD( m_bEnabled, FIELD_BOOLEAN ),
+
+ DEFINE_AUTO_ARRAY_KEYFIELD( m_szDisplayText, FIELD_CHARACTER, "displaytext" ),
+
+ DEFINE_AUTO_ARRAY( m_szSlideshowDirectory, FIELD_CHARACTER ),
+ DEFINE_KEYFIELD( m_String_tSlideshowDirectory, FIELD_STRING, "directory" ),
+
+ // DEFINE_FIELD( m_SlideKeywordList, CUtlVector < SlideKeywordList_t* > ),
+ DEFINE_AUTO_ARRAY( m_chCurrentSlideLists, FIELD_CHARACTER ),
+
+ DEFINE_KEYFIELD( m_fMinSlideTime, FIELD_FLOAT, "minslidetime" ),
+ DEFINE_KEYFIELD( m_fMaxSlideTime, FIELD_FLOAT, "maxslidetime" ),
+
+ DEFINE_KEYFIELD( m_iCycleType, FIELD_INTEGER, "cycletype" ),
+ DEFINE_KEYFIELD( m_bNoListRepeats, FIELD_BOOLEAN, "nolistrepeats" ),
+
+ DEFINE_KEYFIELD( m_iScreenWidth, FIELD_INTEGER, "width" ),
+ DEFINE_KEYFIELD( m_iScreenHeight, FIELD_INTEGER, "height" ),
+
+ //DEFINE_FIELD( m_bDoFullTransmit, FIELD_BOOLEAN ),
+
+ //DEFINE_UTLVECTOR( m_hScreens, FIELD_EHANDLE ),
+
+ DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ),
+ DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ),
+
+ DEFINE_INPUTFUNC( FIELD_STRING, "SetDisplayText", InputSetDisplayText ),
+
+ DEFINE_INPUTFUNC( FIELD_VOID, "RemoveAllSlides", InputRemoveAllSlides ),
+ DEFINE_INPUTFUNC( FIELD_STRING, "AddSlides", InputAddSlides ),
+
+ DEFINE_INPUTFUNC( FIELD_FLOAT, "SetMinSlideTime", InputSetMinSlideTime ),
+ DEFINE_INPUTFUNC( FIELD_FLOAT, "SetMaxSlideTime", InputSetMaxSlideTime ),
+
+ DEFINE_INPUTFUNC( FIELD_INTEGER, "SetCycleType", InputSetCycleType ),
+ DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetNoListRepeats", InputSetNoListRepeats ),
+
+END_DATADESC()
+
+IMPLEMENT_SERVERCLASS_ST( CSlideshowDisplay, DT_SlideshowDisplay )
+ SendPropBool( SENDINFO(m_bEnabled) ),
+ SendPropString( SENDINFO( m_szDisplayText ) ),
+ SendPropString( SENDINFO( m_szSlideshowDirectory ) ),
+ SendPropArray3( SENDINFO_ARRAY3(m_chCurrentSlideLists), SendPropInt( SENDINFO_ARRAY(m_chCurrentSlideLists), 8, SPROP_UNSIGNED ) ),
+ SendPropFloat( SENDINFO(m_fMinSlideTime), 11, 0, 0.0f, 20.0f ),
+ SendPropFloat( SENDINFO(m_fMaxSlideTime), 11, 0, 0.0f, 20.0f ),
+ SendPropInt( SENDINFO(m_iCycleType), 2, SPROP_UNSIGNED ),
+ SendPropBool( SENDINFO(m_bNoListRepeats) ),
+END_SEND_TABLE()
+
+
+CSlideshowDisplay::~CSlideshowDisplay()
+{
+ int i;
+ // Kill the control panels
+ for ( i = m_hScreens.Count(); --i >= 0; )
+ {
+ DestroyVGuiScreen( m_hScreens[i].Get() );
+ }
+ m_hScreens.RemoveAll();
+}
+
+//-----------------------------------------------------------------------------
+// Read in worldcraft data...
+//-----------------------------------------------------------------------------
+bool CSlideshowDisplay::KeyValue( const char *szKeyName, const char *szValue )
+{
+ //!! temp hack, until worldcraft is fixed
+ // strip the # tokens from (duplicate) key names
+ char *s = (char *)strchr( szKeyName, '#' );
+ if ( s )
+ {
+ *s = '\0';
+ }
+
+ // NOTE: Have to do these separate because they set two values instead of one
+ if( FStrEq( szKeyName, "angles" ) )
+ {
+ Assert( GetMoveParent() == NULL );
+ QAngle angles;
+ UTIL_StringToVector( angles.Base(), szValue );
+
+ // Because the vgui screen basis is strange (z is front, y is up, x is right)
+ // we need to rotate the typical basis before applying it
+ VMatrix mat, rotation, tmp;
+ MatrixFromAngles( angles, mat );
+ MatrixBuildRotationAboutAxis( rotation, Vector( 0, 1, 0 ), 90 );
+ MatrixMultiply( mat, rotation, tmp );
+ MatrixBuildRotateZ( rotation, 90 );
+ MatrixMultiply( tmp, rotation, mat );
+ MatrixToAngles( mat, angles );
+ SetAbsAngles( angles );
+
+ return true;
+ }
+
+ return BaseClass::KeyValue( szKeyName, szValue );
+}
+
+int CSlideshowDisplay::UpdateTransmitState()
+{
+ if ( m_bDoFullTransmit )
+ {
+ m_bDoFullTransmit = false;
+ return SetTransmitState( FL_EDICT_ALWAYS );
+ }
+
+ return SetTransmitState( FL_EDICT_FULLCHECK );
+}
+
+void CSlideshowDisplay::SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways )
+{
+ // Are we already marked for transmission?
+ if ( pInfo->m_pTransmitEdict->Get( entindex() ) )
+ return;
+
+ BaseClass::SetTransmit( pInfo, bAlways );
+
+ // Force our screens to be sent too.
+ for ( int i=0; i < m_hScreens.Count(); i++ )
+ {
+ CVGuiScreen *pScreen = m_hScreens[i].Get();
+ pScreen->SetTransmit( pInfo, bAlways );
+ }
+}
+
+void CSlideshowDisplay::Spawn( void )
+{
+ Q_strcpy( m_szSlideshowDirectory.GetForModify(), m_String_tSlideshowDirectory.ToCStr() );
+ Precache();
+
+ BaseClass::Spawn();
+
+ m_bEnabled = false;
+
+ // Clear out selected list
+ m_chCurrentSlideLists.GetForModify( 0 ) = 0; // Select all slides to begin with
+ for ( int i = 1; i < 16; ++i )
+ m_chCurrentSlideLists.GetForModify( i ) = (unsigned char)-1;
+
+ SpawnControlPanels();
+
+ ScreenVisible( m_bEnabled );
+
+ m_bDoFullTransmit = true;
+}
+
+void CSlideshowDisplay::Precache( void )
+{
+ BaseClass::Precache();
+
+ BuildSlideShowImagesList();
+
+ PrecacheVGuiScreen( "slideshow_display_screen" );
+}
+
+void CSlideshowDisplay::OnRestore( void )
+{
+ BaseClass::OnRestore();
+
+ BuildSlideShowImagesList();
+
+ RestoreControlPanels();
+
+ ScreenVisible( m_bEnabled );
+}
+
+void CSlideshowDisplay::ScreenVisible( bool bVisible )
+{
+ for ( int iScreen = 0; iScreen < m_hScreens.Count(); ++iScreen )
+ {
+ CVGuiScreen *pScreen = m_hScreens[ iScreen ].Get();
+ if ( bVisible )
+ pScreen->RemoveEffects( EF_NODRAW );
+ else
+ pScreen->AddEffects( EF_NODRAW );
+ }
+}
+
+void CSlideshowDisplay::Disable( void )
+{
+ if ( !m_bEnabled )
+ return;
+
+ m_bEnabled = false;
+
+ ScreenVisible( false );
+}
+
+void CSlideshowDisplay::Enable( void )
+{
+ if ( m_bEnabled )
+ return;
+
+ m_bEnabled = true;
+
+ ScreenVisible( true );
+}
+
+
+void CSlideshowDisplay::InputDisable( inputdata_t &inputdata )
+{
+ Disable();
+}
+
+void CSlideshowDisplay::InputEnable( inputdata_t &inputdata )
+{
+ Enable();
+}
+
+
+void CSlideshowDisplay::InputSetDisplayText( inputdata_t &inputdata )
+{
+ Q_strcpy( m_szDisplayText.GetForModify(), inputdata.value.String() );
+}
+
+void CSlideshowDisplay::InputRemoveAllSlides( inputdata_t &inputdata )
+{
+ // Clear out selected list
+ for ( int i = 0; i < 16; ++i )
+ m_chCurrentSlideLists.GetForModify( i ) = (unsigned char)-1;
+}
+
+void CSlideshowDisplay::InputAddSlides( inputdata_t &inputdata )
+{
+ // Find the list with the current keyword
+ int iList;
+ for ( iList = 0; iList < m_SlideKeywordList.Count(); ++iList )
+ {
+ if ( Q_strcmp( m_SlideKeywordList[ iList ]->szSlideKeyword, inputdata.value.String() ) == 0 )
+ break;
+ }
+
+ if ( iList < m_SlideKeywordList.Count() )
+ {
+ // Found the keyword list, so add this index to the selected lists
+ int iNumCurrentSlideLists;
+ for ( iNumCurrentSlideLists = 0; iNumCurrentSlideLists < 16; ++iNumCurrentSlideLists )
+ {
+ if ( m_chCurrentSlideLists[ iNumCurrentSlideLists ] == (unsigned char)-1 )
+ break;
+ }
+
+ if ( iNumCurrentSlideLists >= 16 )
+ return;
+
+ m_chCurrentSlideLists.GetForModify( iNumCurrentSlideLists ) = iList;
+ }
+}
+
+
+void CSlideshowDisplay::InputSetMinSlideTime( inputdata_t &inputdata )
+{
+ m_fMinSlideTime = inputdata.value.Float();
+}
+
+void CSlideshowDisplay::InputSetMaxSlideTime( inputdata_t &inputdata )
+{
+ m_fMaxSlideTime = inputdata.value.Float();
+}
+
+
+void CSlideshowDisplay::InputSetCycleType( inputdata_t &inputdata )
+{
+ m_iCycleType = inputdata.value.Int();
+}
+
+void CSlideshowDisplay::InputSetNoListRepeats( inputdata_t &inputdata )
+{
+ m_bNoListRepeats = inputdata.value.Bool();
+}
+
+
+void CSlideshowDisplay::GetControlPanelInfo( int nPanelIndex, const char *&pPanelName )
+{
+ pPanelName = "slideshow_display_screen";
+}
+
+void CSlideshowDisplay::GetControlPanelClassName( int nPanelIndex, const char *&pPanelName )
+{
+ pPanelName = "vgui_screen";
+}
+
+//-----------------------------------------------------------------------------
+// This is called by the base object when it's time to spawn the control panels
+//-----------------------------------------------------------------------------
+void CSlideshowDisplay::SpawnControlPanels()
+{
+ int nPanel;
+ for ( nPanel = 0; true; ++nPanel )
+ {
+ const char *pScreenName;
+ GetControlPanelInfo( nPanel, pScreenName );
+ if (!pScreenName)
+ continue;
+
+ const char *pScreenClassname;
+ GetControlPanelClassName( nPanel, pScreenClassname );
+ if ( !pScreenClassname )
+ continue;
+
+ float flWidth = m_iScreenWidth;
+ float flHeight = m_iScreenHeight;
+
+ CVGuiScreen *pScreen = CreateVGuiScreen( pScreenClassname, pScreenName, this, this, -1 );
+ pScreen->ChangeTeam( GetTeamNumber() );
+ pScreen->SetActualSize( flWidth, flHeight );
+ pScreen->SetActive( true );
+ pScreen->MakeVisibleOnlyToTeammates( false );
+ pScreen->SetTransparency( true );
+ int nScreen = m_hScreens.AddToTail( );
+ m_hScreens[nScreen].Set( pScreen );
+
+ return;
+ }
+}
+
+void CSlideshowDisplay::RestoreControlPanels( void )
+{
+ int nPanel;
+ for ( nPanel = 0; true; ++nPanel )
+ {
+ const char *pScreenName;
+ GetControlPanelInfo( nPanel, pScreenName );
+ if (!pScreenName)
+ continue;
+
+ const char *pScreenClassname;
+ GetControlPanelClassName( nPanel, pScreenClassname );
+ if ( !pScreenClassname )
+ continue;
+
+ CVGuiScreen *pScreen = (CVGuiScreen *)gEntList.FindEntityByClassname( NULL, pScreenClassname );
+
+ while ( ( pScreen && pScreen->GetOwnerEntity() != this ) || Q_strcmp( pScreen->GetPanelName(), pScreenName ) != 0 )
+ {
+ pScreen = (CVGuiScreen *)gEntList.FindEntityByClassname( pScreen, pScreenClassname );
+ }
+
+ if ( pScreen )
+ {
+ int nScreen = m_hScreens.AddToTail( );
+ m_hScreens[nScreen].Set( pScreen );
+ pScreen->SetActive( true );
+ }
+
+ return;
+ }
+}
+
+void CSlideshowDisplay::BuildSlideShowImagesList( void )
+{
+ FileFindHandle_t matHandle;
+ char szDirectory[_MAX_PATH];
+ char szMatFileName[_MAX_PATH] = {'\0'};
+ char szFileBuffer[ SLIDESHOW_LIST_BUFFER_MAX ];
+ char *pchCurrentLine = NULL;
+
+ if ( IsX360() )
+ {
+ Q_snprintf( szDirectory, sizeof( szDirectory ), "materials/vgui/%s/slides.txt", m_szSlideshowDirectory.Get() );
+
+ FileHandle_t fh = g_pFullFileSystem->Open( szDirectory, "rt" );
+ if ( !fh )
+ {
+ DevWarning( "Couldn't read slideshow image file %s!", szDirectory );
+ return;
+ }
+
+ int iFileSize = MIN( g_pFullFileSystem->Size( fh ), SLIDESHOW_LIST_BUFFER_MAX );
+
+ int iBytesRead = g_pFullFileSystem->Read( szFileBuffer, iFileSize, fh );
+ g_pFullFileSystem->Close( fh );
+
+ // Ensure we don't write outside of our buffer
+ if ( iBytesRead > iFileSize )
+ iBytesRead = iFileSize;
+ szFileBuffer[ iBytesRead ] = '\0';
+
+ pchCurrentLine = szFileBuffer;
+
+ // Seek to end of first line
+ char *pchNextLine = pchCurrentLine;
+ while ( *pchNextLine != '\0' && *pchNextLine != '\n' && *pchNextLine != ' ' )
+ ++pchNextLine;
+
+ if ( *pchNextLine != '\0' )
+ {
+ // Mark end of string
+ *pchNextLine = '\0';
+
+ // Seek to start of next string
+ ++pchNextLine;
+ while ( *pchNextLine != '\0' && ( *pchNextLine == '\n' || *pchNextLine == ' ' ) )
+ ++pchNextLine;
+ }
+
+ Q_strncpy( szMatFileName, pchCurrentLine, sizeof(szMatFileName) );
+ pchCurrentLine = pchNextLine;
+ }
+ else
+ {
+ Q_snprintf( szDirectory, sizeof( szDirectory ), "materials/vgui/%s/*.vmt", m_szSlideshowDirectory.Get() );
+ const char *pMatFileName = g_pFullFileSystem->FindFirst( szDirectory, &matHandle );
+
+ if ( pMatFileName )
+ Q_strncpy( szMatFileName, pMatFileName, sizeof(szMatFileName) );
+ }
+
+ int iSlideIndex = 0;
+
+ while ( szMatFileName[ 0 ] )
+ {
+ char szFileName[_MAX_PATH];
+ Q_snprintf( szFileName, sizeof( szFileName ), "vgui/%s/%s", m_szSlideshowDirectory.Get(), szMatFileName );
+ szFileName[ Q_strlen( szFileName ) - 4 ] = '\0';
+
+ PrecacheMaterial( szFileName );
+
+ // Get material keywords
+ char szFullFileName[_MAX_PATH];
+ Q_snprintf( szFullFileName, sizeof( szFullFileName ), "materials/vgui/%s/%s", m_szSlideshowDirectory.Get(), szMatFileName );
+
+ KeyValues *pMaterialKeys = new KeyValues( "material" );
+ bool bLoaded = pMaterialKeys->LoadFromFile( g_pFullFileSystem, szFullFileName, NULL );
+
+ if ( bLoaded )
+ {
+ char szKeywords[ 256 ];
+ Q_strcpy( szKeywords, pMaterialKeys->GetString( "%keywords", "" ) );
+
+ char *pchKeyword = szKeywords;
+
+ while ( pchKeyword[ 0 ] != '\0' )
+ {
+ char *pNextKeyword = pchKeyword;
+
+ // Skip commas and spaces
+ while ( pNextKeyword[ 0 ] != '\0' && pNextKeyword[ 0 ] != ',' )
+ ++pNextKeyword;
+
+ if ( pNextKeyword[ 0 ] != '\0' )
+ {
+ pNextKeyword[ 0 ] = '\0';
+ ++pNextKeyword;
+
+ while ( pNextKeyword[ 0 ] != '\0' && ( pNextKeyword[ 0 ] == ',' || pNextKeyword[ 0 ] == ' ' ) )
+ ++pNextKeyword;
+ }
+
+ // Find the list with the current keyword
+ int iList;
+ for ( iList = 0; iList < m_SlideKeywordList.Count(); ++iList )
+ {
+ if ( Q_strcmp( m_SlideKeywordList[ iList ]->szSlideKeyword, pchKeyword ) == 0 )
+ break;
+ }
+
+ if ( iList >= m_SlideKeywordList.Count() )
+ {
+ // Couldn't find the list, so create it
+ iList = m_SlideKeywordList.AddToTail( new SlideKeywordList_t );
+ Q_strcpy( m_SlideKeywordList[ iList ]->szSlideKeyword, pchKeyword );
+ }
+
+ pchKeyword = pNextKeyword;
+ }
+ }
+
+ // Find the generic list
+ int iList;
+ for ( iList = 0; iList < m_SlideKeywordList.Count(); ++iList )
+ {
+ if ( Q_strcmp( m_SlideKeywordList[ iList ]->szSlideKeyword, "" ) == 0 )
+ break;
+ }
+
+ if ( iList >= m_SlideKeywordList.Count() )
+ {
+ // Couldn't find the generic list, so create it
+ iList = m_SlideKeywordList.AddToHead( new SlideKeywordList_t );
+ Q_strcpy( m_SlideKeywordList[ iList ]->szSlideKeyword, "" );
+ }
+
+ if ( IsX360() )
+ {
+ // Seek to end of first line
+ char *pchNextLine = pchCurrentLine;
+ while ( *pchNextLine != '\0' && *pchNextLine != '\n' && *pchNextLine != ' ' )
+ ++pchNextLine;
+
+ if ( *pchNextLine != '\0' )
+ {
+ // Mark end of string
+ *pchNextLine = '\0';
+
+ // Seek to start of next string
+ ++pchNextLine;
+ while ( *pchNextLine != '\0' && ( *pchNextLine == '\n' || *pchNextLine == ' ' ) )
+ ++pchNextLine;
+ }
+
+ Q_strncpy( szMatFileName, pchCurrentLine, sizeof(szMatFileName) );
+ pchCurrentLine = pchNextLine;
+ }
+ else
+ {
+ const char *pMatFileName = g_pFullFileSystem->FindNext( matHandle );
+
+ if ( pMatFileName )
+ Q_strncpy( szMatFileName, pMatFileName, sizeof(szMatFileName) );
+ else
+ szMatFileName[ 0 ] = '\0';
+ }
+
+ ++iSlideIndex;
+ }
+
+ if ( !IsX360() )
+ {
+ g_pFullFileSystem->FindClose( matHandle );
+ }
+} \ No newline at end of file