mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2024-12-27 07:15:31 +03:00
Merge pull request #107 from mapbase-source/feature/asw-movies
Alien Swarm SDK videos and movies
This commit is contained in:
commit
7221aab090
26
sp/src/game/client/c_movie_display.cpp
Normal file
26
sp/src/game/client/c_movie_display.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
//========= Copyright © 1996-2009, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//
|
||||
//=====================================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_movie_display.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_MovieDisplay, DT_MovieDisplay, CMovieDisplay )
|
||||
RecvPropBool( RECVINFO( m_bEnabled ) ),
|
||||
RecvPropBool( RECVINFO( m_bLooping ) ),
|
||||
RecvPropString( RECVINFO( m_szMovieFilename ) ),
|
||||
RecvPropString( RECVINFO( m_szGroupName ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
C_MovieDisplay::C_MovieDisplay()
|
||||
{
|
||||
}
|
||||
|
||||
C_MovieDisplay::~C_MovieDisplay()
|
||||
{
|
||||
}
|
34
sp/src/game/client/c_movie_display.h
Normal file
34
sp/src/game/client/c_movie_display.h
Normal file
@ -0,0 +1,34 @@
|
||||
//========= Copyright © 1996-2009, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=====================================================================================//
|
||||
|
||||
#ifndef C_MOVIE_DISPLAY_H
|
||||
#define C_MOVIE_DISPLAY_H
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
class C_MovieDisplay : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_MovieDisplay, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_MovieDisplay();
|
||||
~C_MovieDisplay();
|
||||
|
||||
bool IsEnabled( void ) const { return m_bEnabled; }
|
||||
bool IsLooping( void ) const { return m_bLooping; }
|
||||
|
||||
const char *GetMovieFilename( void ) const { return m_szMovieFilename; }
|
||||
const char *GetGroupName( void ) const { return m_szGroupName; }
|
||||
|
||||
private:
|
||||
bool m_bEnabled;
|
||||
bool m_bLooping;
|
||||
char m_szMovieFilename[128];
|
||||
char m_szGroupName[128];
|
||||
};
|
||||
|
||||
#endif //C_MOVIE_DISPLAY_H
|
@ -31,6 +31,9 @@ $Project
|
||||
$File "c_postprocesscontroller.cpp"
|
||||
$File "c_postprocesscontroller.h"
|
||||
$File "c_env_dof_controller.cpp"
|
||||
$File "c_movie_display.cpp"
|
||||
$File "c_movie_display.h"
|
||||
$File "vgui_movie_display.cpp"
|
||||
|
||||
$Folder "Mapbase"
|
||||
{
|
||||
|
437
sp/src/game/client/vgui_movie_display.cpp
Normal file
437
sp/src/game/client/vgui_movie_display.cpp
Normal file
@ -0,0 +1,437 @@
|
||||
//========= Copyright © 1996-2009, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=====================================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_vguiscreen.h"
|
||||
#include "vgui_controls/Label.h"
|
||||
#include "vgui_BitmapPanel.h"
|
||||
#include <vgui/IVGUI.h>
|
||||
#include "c_slideshow_display.h"
|
||||
#include "ienginevgui.h"
|
||||
#include "fmtstr.h"
|
||||
#include "vgui_controls/ImagePanel.h"
|
||||
#include <vgui/ISurface.h>
|
||||
#include "video/ivideoservices.h"
|
||||
#include "engine/ienginesound.h"
|
||||
#include "VGUIMatSurface/IMatSystemSurface.h"
|
||||
#include "c_movie_display.h"
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
struct VideoPlaybackInfo_t
|
||||
{
|
||||
VideoPlaybackInfo_t( void ) :
|
||||
m_pMaterial ( NULL ),
|
||||
m_nSourceHeight(0), m_nSourceWidth(0),
|
||||
m_flU(0.0f),m_flV(0.0f) {}
|
||||
|
||||
IMaterial *m_pMaterial;
|
||||
int m_nSourceHeight, m_nSourceWidth; // Source movie's dimensions
|
||||
float m_flU, m_flV; // U,V ranges for video on its sheet
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Control screen
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMovieDisplayScreen : public CVGuiScreenPanel
|
||||
{
|
||||
DECLARE_CLASS( CMovieDisplayScreen, CVGuiScreenPanel );
|
||||
|
||||
public:
|
||||
CMovieDisplayScreen( vgui::Panel *parent, const char *panelName );
|
||||
~CMovieDisplayScreen( void );
|
||||
|
||||
virtual void ApplySchemeSettings( IScheme *pScheme );
|
||||
|
||||
virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData );
|
||||
virtual void OnTick( void );
|
||||
virtual void Paint( void );
|
||||
|
||||
private:
|
||||
bool IsActive( void );
|
||||
|
||||
void SetupMovie( void );
|
||||
void UpdateMovie( void );
|
||||
bool BeginPlayback( const char *pFilename );
|
||||
void CalculatePlaybackDimensions( int nSrcWidth, int nSrcHeight );
|
||||
|
||||
inline void GetPanelPos( int &xpos, int &ypos )
|
||||
{
|
||||
xpos = ( (float) ( GetWide() - m_nPlaybackWidth ) / 2 );
|
||||
ypos = ( (float) ( GetTall() - m_nPlaybackHeight ) / 2 );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// BINK playback info
|
||||
IVideoMaterial *m_VideoMaterial;
|
||||
VideoPlaybackInfo_t m_playbackInfo;
|
||||
CHandle<C_VGuiScreen> m_hVGUIScreen;
|
||||
CHandle<C_MovieDisplay> m_hScreenEntity;
|
||||
|
||||
int m_nTextureId;
|
||||
int m_nPlaybackHeight; // Playback dimensions (proper ration adjustments)
|
||||
int m_nPlaybackWidth;
|
||||
bool m_bBlackBackground;
|
||||
bool m_bSlaved;
|
||||
bool m_bInitialized;
|
||||
|
||||
bool m_bLastActiveState; // HACK: I'd rather get a real callback...
|
||||
|
||||
// VGUI specifics
|
||||
Label *m_pDisplayTextLabel;
|
||||
|
||||
Color m_cDefault;
|
||||
Color m_cInvisible;
|
||||
|
||||
bool bIsAlreadyVisible;
|
||||
};
|
||||
|
||||
DECLARE_VGUI_SCREEN_FACTORY( CMovieDisplayScreen, "movie_display_screen" );
|
||||
|
||||
CUtlVector <CMovieDisplayScreen *> g_MovieDisplays;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor:
|
||||
//-----------------------------------------------------------------------------
|
||||
CMovieDisplayScreen::CMovieDisplayScreen( vgui::Panel *parent, const char *panelName )
|
||||
: BaseClass( parent, "CMovieDisplayScreen", vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/MovieDisplayScreen.res", "MovieDisplayScreen" ) )
|
||||
{
|
||||
m_pDisplayTextLabel = new vgui::Label( this, "NumberDisplay", "testing!");
|
||||
|
||||
m_VideoMaterial = NULL;
|
||||
m_nTextureId = -1;
|
||||
m_bBlackBackground = true;
|
||||
m_bSlaved = false;
|
||||
m_bInitialized = false;
|
||||
|
||||
// Add ourselves to the global list of movie displays
|
||||
g_MovieDisplays.AddToTail( this );
|
||||
|
||||
m_bLastActiveState = IsActive();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Clean up the movie
|
||||
//-----------------------------------------------------------------------------
|
||||
CMovieDisplayScreen::~CMovieDisplayScreen( void )
|
||||
{
|
||||
if ( g_pVideo != NULL && m_VideoMaterial != NULL )
|
||||
{
|
||||
g_pVideo->DestroyVideoMaterial( m_VideoMaterial );
|
||||
m_VideoMaterial = NULL;
|
||||
}
|
||||
|
||||
// Clean up our texture reference
|
||||
g_pMatSystemSurface->DestroyTextureID( m_nTextureId );
|
||||
|
||||
// Remove ourselves from the global list of movie displays
|
||||
g_MovieDisplays.FindAndRemove( this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Setup our scheme
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMovieDisplayScreen::ApplySchemeSettings( IScheme *pScheme )
|
||||
{
|
||||
assert( pScheme );
|
||||
|
||||
m_cDefault = Color( 255, 255, 255, 255 );
|
||||
m_cInvisible = Color( 0, 0, 0, 0 );
|
||||
|
||||
m_pDisplayTextLabel->SetFgColor( m_cDefault );
|
||||
m_pDisplayTextLabel->SetText( "" );
|
||||
m_pDisplayTextLabel->SetVisible( false );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Initialization
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMovieDisplayScreen::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData )
|
||||
{
|
||||
// Make sure we get ticked...
|
||||
vgui::ivgui()->AddTickSignal( GetVPanel() );
|
||||
|
||||
if ( !BaseClass::Init( pKeyValues, pInitData ) )
|
||||
return false;
|
||||
|
||||
// Save this for simplicity later on
|
||||
m_hVGUIScreen = dynamic_cast<C_VGuiScreen *>( GetEntity() );
|
||||
if ( m_hVGUIScreen != NULL )
|
||||
{
|
||||
// Also get the associated entity
|
||||
m_hScreenEntity = dynamic_cast<C_MovieDisplay *>(m_hVGUIScreen->GetOwnerEntity());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Helper function to check our active state
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMovieDisplayScreen::IsActive( void )
|
||||
{
|
||||
bool bScreenActive = false;
|
||||
if ( m_hVGUIScreen != NULL )
|
||||
{
|
||||
bScreenActive = m_hVGUIScreen->IsActive();
|
||||
}
|
||||
|
||||
return bScreenActive;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Either become the master of a group of screens, or become a slave to another
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMovieDisplayScreen::SetupMovie( void )
|
||||
{
|
||||
// Only bother if we haven't been setup yet
|
||||
if ( m_bInitialized )
|
||||
return;
|
||||
|
||||
const char *szGroupName = m_hScreenEntity->GetGroupName();
|
||||
|
||||
CMovieDisplayScreen *pMasterScreen = NULL;
|
||||
for ( int i = 0; i < g_MovieDisplays.Count(); i++ )
|
||||
{
|
||||
// Must be valid and not us
|
||||
if ( g_MovieDisplays[i] == NULL || g_MovieDisplays[i] == this )
|
||||
continue;
|
||||
|
||||
// Must have an associated movie entity
|
||||
if ( g_MovieDisplays[i]->m_hScreenEntity == NULL )
|
||||
continue;
|
||||
|
||||
// Must have a group name to care
|
||||
if ( szGroupName[0] == NULL )
|
||||
continue;
|
||||
|
||||
// Group names must match!
|
||||
// FIXME: Use an ID instead?
|
||||
const char *szTestGroupName = g_MovieDisplays[i]->m_hScreenEntity->GetGroupName();
|
||||
if ( Q_strnicmp( szTestGroupName, szGroupName, 128 ) )
|
||||
continue;
|
||||
|
||||
// See if we've found a master display
|
||||
if ( g_MovieDisplays[i]->m_bInitialized && g_MovieDisplays[i]->m_bSlaved == false )
|
||||
{
|
||||
m_bSlaved = true;
|
||||
|
||||
// Share the info from the master
|
||||
m_playbackInfo = g_MovieDisplays[i]->m_playbackInfo;
|
||||
|
||||
// We need to calculate our own playback dimensions as we may be a different size than our parent
|
||||
CalculatePlaybackDimensions( m_playbackInfo.m_nSourceWidth, m_playbackInfo.m_nSourceHeight );
|
||||
|
||||
// Bind our texture
|
||||
m_nTextureId = surface()->CreateNewTextureID( true );
|
||||
g_pMatSystemSurface->DrawSetTextureMaterial( m_nTextureId, m_playbackInfo.m_pMaterial );
|
||||
|
||||
// Hold this as the master screen
|
||||
pMasterScreen = g_MovieDisplays[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// We need to try again, we have no screen entity!
|
||||
if ( m_hScreenEntity == NULL )
|
||||
return;
|
||||
|
||||
// No master found, become one
|
||||
if ( pMasterScreen == NULL )
|
||||
{
|
||||
const char *szFilename = m_hScreenEntity->GetMovieFilename();
|
||||
BeginPlayback( szFilename );
|
||||
m_bSlaved = false;
|
||||
}
|
||||
|
||||
// Done
|
||||
m_bInitialized = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Deal with the details of the video playback
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMovieDisplayScreen::UpdateMovie( void )
|
||||
{
|
||||
// Only the master in a group updates the bink file
|
||||
if ( m_bSlaved )
|
||||
return;
|
||||
|
||||
if ( m_VideoMaterial == NULL )
|
||||
return;
|
||||
|
||||
// Get the current activity state of the screen
|
||||
bool bScreenActive = IsActive();
|
||||
|
||||
// Pause if the game has paused
|
||||
if ( engine->IsPaused() || engine->Con_IsVisible() )
|
||||
{
|
||||
bScreenActive = false;
|
||||
}
|
||||
|
||||
// See if we've changed our activity state
|
||||
if ( bScreenActive != m_bLastActiveState )
|
||||
{
|
||||
m_VideoMaterial->SetPaused( !bScreenActive );
|
||||
}
|
||||
|
||||
// Updated
|
||||
m_bLastActiveState = bScreenActive;
|
||||
|
||||
// Update the frame if we're currently enabled
|
||||
if ( bScreenActive )
|
||||
{
|
||||
// Update our frame
|
||||
if ( m_VideoMaterial->Update() == false )
|
||||
{
|
||||
// Issue a close command
|
||||
// OnVideoOver();
|
||||
// StopPlayback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Update the display string
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMovieDisplayScreen::OnTick()
|
||||
{
|
||||
BaseClass::OnTick();
|
||||
|
||||
// Create our playback or slave to another screen already playing
|
||||
SetupMovie();
|
||||
|
||||
// Now update the movie
|
||||
UpdateMovie();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Adjust the playback dimensions to properly account for our screen dimensions
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMovieDisplayScreen::CalculatePlaybackDimensions( int nSrcWidth, int nSrcHeight )
|
||||
{
|
||||
float flFrameRatio = ( (float) GetWide() / (float) GetTall() );
|
||||
float flVideoRatio = ( (float) nSrcWidth / (float) nSrcHeight );
|
||||
|
||||
if ( flVideoRatio > flFrameRatio )
|
||||
{
|
||||
m_nPlaybackWidth = GetWide();
|
||||
m_nPlaybackHeight = ( GetWide() / flVideoRatio );
|
||||
}
|
||||
else if ( flVideoRatio < flFrameRatio )
|
||||
{
|
||||
m_nPlaybackWidth = ( GetTall() * flVideoRatio );
|
||||
m_nPlaybackHeight = GetTall();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nPlaybackWidth = GetWide();
|
||||
m_nPlaybackHeight = GetTall();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Begins playback of a movie
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMovieDisplayScreen::BeginPlayback( const char *pFilename )
|
||||
{
|
||||
// need working video services
|
||||
if ( g_pVideo == NULL )
|
||||
return false;
|
||||
|
||||
// Create a new video material
|
||||
if ( m_VideoMaterial != NULL )
|
||||
{
|
||||
g_pVideo->DestroyVideoMaterial( m_VideoMaterial );
|
||||
m_VideoMaterial = NULL;
|
||||
}
|
||||
|
||||
// Create a globally unique name for this material
|
||||
char szMaterialName[256];
|
||||
|
||||
// Append our group name if we have one
|
||||
const char *szGroupName = m_hScreenEntity->GetGroupName();
|
||||
if ( szGroupName[0] != NULL )
|
||||
{
|
||||
Q_snprintf( szMaterialName, sizeof(szMaterialName), "%s_%s", pFilename, szGroupName );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_strncpy( szMaterialName, pFilename, sizeof(szMaterialName) );
|
||||
}
|
||||
|
||||
const char *pszMaterialName = CFmtStrN<128>( "VideoMaterial_", m_hScreenEntity->GetEntityName() );
|
||||
m_VideoMaterial = g_pVideo->CreateVideoMaterial( pszMaterialName, pFilename, "GAME",
|
||||
VideoPlaybackFlags::DEFAULT_MATERIAL_OPTIONS,
|
||||
VideoSystem::DETERMINE_FROM_FILE_EXTENSION/*, m_bAllowAlternateMedia*/ );
|
||||
|
||||
if ( m_VideoMaterial == NULL )
|
||||
return false;
|
||||
|
||||
m_VideoMaterial->SetMuted( true ); // FIXME: Allow?
|
||||
|
||||
if ( m_hScreenEntity->IsLooping() )
|
||||
{
|
||||
m_VideoMaterial->SetLooping( true );
|
||||
}
|
||||
|
||||
if ( m_VideoMaterial->HasAudio() )
|
||||
{
|
||||
// We want to be the sole audio source
|
||||
enginesound->NotifyBeginMoviePlayback();
|
||||
}
|
||||
|
||||
// Get our basic info from the movie
|
||||
m_VideoMaterial->GetVideoImageSize( &m_playbackInfo.m_nSourceWidth, &m_playbackInfo.m_nSourceHeight );
|
||||
m_VideoMaterial->GetVideoTexCoordRange( &m_playbackInfo.m_flU, &m_playbackInfo.m_flV );
|
||||
m_playbackInfo.m_pMaterial = m_VideoMaterial->GetMaterial();
|
||||
|
||||
// Get our playback dimensions
|
||||
CalculatePlaybackDimensions( m_playbackInfo.m_nSourceWidth, m_playbackInfo.m_nSourceHeight );
|
||||
|
||||
// Bind our texture
|
||||
m_nTextureId = surface()->CreateNewTextureID( true );
|
||||
g_pMatSystemSurface->DrawSetTextureMaterial( m_nTextureId, m_playbackInfo.m_pMaterial );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Update and draw the frame
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMovieDisplayScreen::Paint( void )
|
||||
{
|
||||
// Masters must keep the video updated
|
||||
if ( m_bSlaved == false && m_VideoMaterial == NULL )
|
||||
{
|
||||
BaseClass::Paint();
|
||||
return;
|
||||
}
|
||||
|
||||
// Sit in the "center"
|
||||
int xpos, ypos;
|
||||
GetPanelPos( xpos, ypos );
|
||||
|
||||
// Black out the background (we could omit drawing under the video surface, but this is straight-forward)
|
||||
if ( m_bBlackBackground )
|
||||
{
|
||||
surface()->DrawSetColor( 0, 0, 0, 255 );
|
||||
surface()->DrawFilledRect( 0, 0, GetWide(), GetTall() );
|
||||
}
|
||||
|
||||
// Draw it
|
||||
surface()->DrawSetTexture( m_nTextureId );
|
||||
surface()->DrawSetColor( 255, 255, 255, 255 );
|
||||
surface()->DrawTexturedSubRect( xpos, ypos, xpos+m_nPlaybackWidth, ypos+m_nPlaybackHeight, 0.0f, 0.0f, m_playbackInfo.m_flU, m_playbackInfo.m_flV );
|
||||
|
||||
// Parent's turn
|
||||
BaseClass::Paint();
|
||||
}
|
@ -16,20 +16,59 @@
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
static CUtlVector< VideoPanel * > g_vecVideoPanels;
|
||||
|
||||
// Thiis is a hack due to the fact that the user can type quit with the video panel up, but it's parented to the GameUI dll root panel, which is already gone so
|
||||
// we would crash in the destructor
|
||||
void VGui_ClearVideoPanels()
|
||||
{
|
||||
for ( int i = g_vecVideoPanels.Count() - 1; i >= 0; --i )
|
||||
{
|
||||
if ( g_vecVideoPanels[ i ] )
|
||||
{
|
||||
delete g_vecVideoPanels[ i ];
|
||||
}
|
||||
}
|
||||
g_vecVideoPanels.RemoveAll();
|
||||
}
|
||||
|
||||
struct VideoPanelParms_t
|
||||
{
|
||||
VideoPanelParms_t( bool _interrupt = true, bool _loop = false, bool _mute = false )
|
||||
{
|
||||
bAllowInterrupt = _interrupt;
|
||||
bLoop = _loop;
|
||||
bMute = _mute;
|
||||
}
|
||||
|
||||
bool bAllowInterrupt;
|
||||
bool bLoop;
|
||||
bool bMute;
|
||||
|
||||
//float flFadeIn;
|
||||
//float flFadeOut;
|
||||
};
|
||||
|
||||
VideoPanel::VideoPanel( unsigned int nXPos, unsigned int nYPos, unsigned int nHeight, unsigned int nWidth, bool allowAlternateMedia ) :
|
||||
BaseClass( NULL, "VideoPanel" ),
|
||||
m_VideoMaterial( NULL ),
|
||||
m_nPlaybackWidth( 0 ),
|
||||
m_nPlaybackHeight( 0 ),
|
||||
m_bAllowAlternateMedia( allowAlternateMedia )
|
||||
m_nShutdownCount( 0 ),
|
||||
m_bLooping( false ),
|
||||
m_bStopAllSounds( true ),
|
||||
m_bAllowInterruption( true ),
|
||||
m_bAllowAlternateMedia( allowAlternateMedia ),
|
||||
m_bStarted( false )
|
||||
{
|
||||
|
||||
#ifdef MAPBASE
|
||||
vgui::VPANEL pParent = enginevgui->GetPanel( PANEL_ROOT );
|
||||
#else
|
||||
vgui::VPANEL pParent = enginevgui->GetPanel( PANEL_GAMEUIDLL );
|
||||
#endif
|
||||
|
||||
SetParent( pParent );
|
||||
SetVisible( false );
|
||||
|
||||
@ -53,6 +92,11 @@ VideoPanel::VideoPanel( unsigned int nXPos, unsigned int nYPos, unsigned int nHe
|
||||
|
||||
SetScheme(vgui::scheme()->LoadSchemeFromFile( "resource/VideoPanelScheme.res", "VideoPanelScheme"));
|
||||
LoadControlSettings("resource/UI/VideoPanel.res");
|
||||
|
||||
// Let us update
|
||||
vgui::ivgui()->AddTickSignal( GetVPanel() );
|
||||
|
||||
g_vecVideoPanels.AddToTail( this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -60,6 +104,8 @@ VideoPanel::VideoPanel( unsigned int nXPos, unsigned int nYPos, unsigned int nHe
|
||||
//-----------------------------------------------------------------------------
|
||||
VideoPanel::~VideoPanel( void )
|
||||
{
|
||||
g_vecVideoPanels.FindAndRemove( this );
|
||||
|
||||
SetParent( (vgui::Panel *) NULL );
|
||||
|
||||
// Shut down this video, destroy the video material
|
||||
@ -70,13 +116,39 @@ VideoPanel::~VideoPanel( void )
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Keeps a tab on when the movie is ending and allows a frame to pass to prevent threading issues
|
||||
//-----------------------------------------------------------------------------
|
||||
void VideoPanel::OnTick( void )
|
||||
{
|
||||
if ( m_nShutdownCount > 0 )
|
||||
{
|
||||
m_nShutdownCount++;
|
||||
|
||||
if ( m_nShutdownCount > 10 )
|
||||
{
|
||||
OnClose();
|
||||
m_nShutdownCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::OnTick();
|
||||
}
|
||||
|
||||
void VideoPanel::OnVideoOver()
|
||||
{
|
||||
StopPlayback();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Begins playback of a movie
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool VideoPanel::BeginPlayback( const char *pFilename )
|
||||
{
|
||||
// Who the heck hacked this in?
|
||||
if ( !pFilename || pFilename[ 0 ] == '\0' )
|
||||
return false;
|
||||
|
||||
#ifdef _X360
|
||||
XVIDEO_MODE videoMode;
|
||||
XGetVideoMode( &videoMode );
|
||||
@ -106,9 +178,25 @@ bool VideoPanel::BeginPlayback( const char *pFilename )
|
||||
if ( m_VideoMaterial == NULL )
|
||||
return false;
|
||||
|
||||
if ( m_bLooping )
|
||||
{
|
||||
m_VideoMaterial->SetLooping( true );
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
if ( m_bMuted )
|
||||
{
|
||||
m_VideoMaterial->SetMuted( true );
|
||||
}
|
||||
#endif
|
||||
|
||||
m_bStarted = true;
|
||||
|
||||
// We want to be the sole audio source
|
||||
// FIXME: This may not always be true!
|
||||
enginesound->NotifyBeginMoviePlayback();
|
||||
if ( m_bStopAllSounds )
|
||||
{
|
||||
enginesound->NotifyBeginMoviePlayback();
|
||||
}
|
||||
|
||||
int nWidth, nHeight;
|
||||
m_VideoMaterial->GetVideoImageSize( &nWidth, &nHeight );
|
||||
@ -168,9 +256,10 @@ void VideoPanel::DoModal( void )
|
||||
//-----------------------------------------------------------------------------
|
||||
void VideoPanel::OnKeyCodeTyped( vgui::KeyCode code )
|
||||
{
|
||||
if ( code == KEY_ESCAPE )
|
||||
bool bInterruptKeyPressed = ( code == KEY_ESCAPE );
|
||||
if ( m_bAllowInterruption && bInterruptKeyPressed )
|
||||
{
|
||||
OnClose();
|
||||
StopPlayback();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -181,34 +270,54 @@ void VideoPanel::OnKeyCodeTyped( vgui::KeyCode code )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handle keys that should cause us to close
|
||||
//-----------------------------------------------------------------------------
|
||||
void VideoPanel::OnKeyCodePressed( vgui::KeyCode code )
|
||||
void VideoPanel::OnKeyCodePressed( vgui::KeyCode keycode )
|
||||
{
|
||||
vgui::KeyCode code = GetBaseButtonCode( keycode );
|
||||
|
||||
// All these keys will interrupt playback
|
||||
bool bInterruptKeyPressed = ( code == KEY_ESCAPE ||
|
||||
code == KEY_BACKQUOTE ||
|
||||
code == KEY_SPACE ||
|
||||
code == KEY_ENTER ||
|
||||
code == KEY_XBUTTON_A ||
|
||||
code == KEY_XBUTTON_B ||
|
||||
code == KEY_XBUTTON_X ||
|
||||
code == KEY_XBUTTON_Y ||
|
||||
code == KEY_XBUTTON_START ||
|
||||
code == KEY_XBUTTON_BACK );
|
||||
|
||||
// These keys cause the panel to shutdown
|
||||
if ( code == KEY_ESCAPE ||
|
||||
code == KEY_BACKQUOTE ||
|
||||
code == KEY_SPACE ||
|
||||
code == KEY_ENTER ||
|
||||
code == KEY_XBUTTON_A ||
|
||||
code == KEY_XBUTTON_B ||
|
||||
code == KEY_XBUTTON_X ||
|
||||
code == KEY_XBUTTON_Y ||
|
||||
code == KEY_XBUTTON_START ||
|
||||
code == KEY_XBUTTON_BACK )
|
||||
if ( m_bAllowInterruption && bInterruptKeyPressed )
|
||||
{
|
||||
OnClose();
|
||||
StopPlayback();
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseClass::OnKeyCodePressed( code );
|
||||
BaseClass::OnKeyCodePressed( keycode );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void VideoPanel::StopPlayback( void )
|
||||
{
|
||||
SetVisible( false );
|
||||
|
||||
// Start the deferred shutdown process
|
||||
m_nShutdownCount = 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void VideoPanel::OnClose( void )
|
||||
{
|
||||
enginesound->NotifyEndMoviePlayback();
|
||||
if ( m_bStopAllSounds )
|
||||
{
|
||||
enginesound->NotifyEndMoviePlayback();
|
||||
}
|
||||
|
||||
BaseClass::OnClose();
|
||||
|
||||
if ( vgui::input()->GetAppModalSurface() == GetVPanel() )
|
||||
@ -224,7 +333,6 @@ void VideoPanel::OnClose( void )
|
||||
engine->ClientCmd( m_szExitCommand );
|
||||
}
|
||||
|
||||
SetVisible( false );
|
||||
MarkForDeletion();
|
||||
}
|
||||
|
||||
@ -247,26 +355,52 @@ void VideoPanel::Paint( void )
|
||||
if ( m_VideoMaterial == NULL )
|
||||
return;
|
||||
|
||||
float alpha = ((float)GetFgColor()[3]/255.0f);
|
||||
#ifdef MAPBASE
|
||||
if (m_flFadeIn != 0.0f || m_flFadeOut != 0.0f)
|
||||
{
|
||||
// GetCurrentVideoTime() and GetVideoDuration() are borked
|
||||
float flFrameCount = m_VideoMaterial->GetFrameCount();
|
||||
float flEnd = flFrameCount / m_VideoMaterial->GetVideoFrameRate().GetFPS();
|
||||
float flTime = ((float)(m_VideoMaterial->GetCurrentFrame()) / flFrameCount) * flEnd;
|
||||
float flFadeOutDelta = (flEnd - m_flFadeOut);
|
||||
|
||||
if (flTime <= m_flFadeIn)
|
||||
{
|
||||
alpha = (flTime / m_flFadeIn);
|
||||
}
|
||||
else if (flTime >= flFadeOutDelta)
|
||||
{
|
||||
alpha = (1.0f - ((flTime - flFadeOutDelta) / m_flFadeOut));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( m_VideoMaterial->Update() == false )
|
||||
{
|
||||
// Issue a close command
|
||||
OnVideoOver();
|
||||
OnClose();
|
||||
//OnClose();
|
||||
}
|
||||
|
||||
// Sit in the "center"
|
||||
int xpos, ypos;
|
||||
GetPanelPos( xpos, ypos );
|
||||
LocalToScreen( xpos, ypos );
|
||||
|
||||
// Black out the background (we could omit drawing under the video surface, but this is straight-forward)
|
||||
if ( m_bBlackBackground )
|
||||
{
|
||||
vgui::surface()->DrawSetColor( 0, 0, 0, 255 );
|
||||
vgui::surface()->DrawSetColor( 0, 0, 0, alpha * 255.0f );
|
||||
vgui::surface()->DrawFilledRect( 0, 0, GetWide(), GetTall() );
|
||||
}
|
||||
|
||||
// Draw the polys to draw this out
|
||||
CMatRenderContextPtr pRenderContext( materials );
|
||||
|
||||
#ifdef MAPBASE
|
||||
pRenderContext->ClearColor4ub( 255, 255, 255, alpha * 255.0f );
|
||||
#endif
|
||||
|
||||
pRenderContext->MatrixMode( MATERIAL_VIEW );
|
||||
pRenderContext->PushMatrix();
|
||||
@ -306,8 +440,6 @@ void VideoPanel::Paint( void )
|
||||
flTopY = FLerp( 1, -1, 0, vh ,flTopY );
|
||||
flBottomY = FLerp( 1, -1, 0, vh, flBottomY );
|
||||
|
||||
float alpha = ((float)GetFgColor()[3]/255.0f);
|
||||
|
||||
for ( int corner=0; corner<4; corner++ )
|
||||
{
|
||||
bool bLeft = (corner==0) || (corner==3);
|
||||
@ -340,16 +472,37 @@ void VideoPanel::Paint( void )
|
||||
bool VideoPanel_Create( unsigned int nXPos, unsigned int nYPos,
|
||||
unsigned int nWidth, unsigned int nHeight,
|
||||
const char *pVideoFilename,
|
||||
const char *pExitCommand /*= NULL*/)
|
||||
const char *pExitCommand /*= NULL*/,
|
||||
const VideoPanelParms_t &parms )
|
||||
{
|
||||
// Create the base video panel
|
||||
VideoPanel *pVideoPanel = new VideoPanel( nXPos, nYPos, nHeight, nWidth, false );
|
||||
VideoPanel *pVideoPanel = new VideoPanel( nXPos, nYPos, nHeight, nWidth );
|
||||
if ( pVideoPanel == NULL )
|
||||
return false;
|
||||
|
||||
// Toggle if we want the panel to allow interruption
|
||||
pVideoPanel->SetAllowInterrupt( parms.bAllowInterrupt );
|
||||
|
||||
// Set the command we'll call (if any) when the video is interrupted or completes
|
||||
pVideoPanel->SetExitCommand( pExitCommand );
|
||||
|
||||
#ifdef MAPBASE
|
||||
// Toggle if we want the panel to loop (inspired by Portal 2)
|
||||
pVideoPanel->SetLooping( parms.bLoop );
|
||||
|
||||
// Toggle if we want the panel to be muted
|
||||
pVideoPanel->SetMuted( parms.bMute );
|
||||
|
||||
// TODO: Unique "Stop All Sounds" parameter
|
||||
if (parms.bMute)
|
||||
{
|
||||
pVideoPanel->SetStopAllSounds( false );
|
||||
}
|
||||
|
||||
// Fade parameters (unfinished)
|
||||
//pVideoPanel->SetFade( parms.flFadeIn, parms.flFadeOut );
|
||||
#endif
|
||||
|
||||
// Start it going
|
||||
if ( pVideoPanel->BeginPlayback( pVideoFilename ) == false )
|
||||
{
|
||||
@ -364,8 +517,29 @@ bool VideoPanel_Create( unsigned int nXPos, unsigned int nYPos,
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Used to launch a video playback (Debug) -
|
||||
// user must include file extension
|
||||
// Purpose: Create a video panel with the supplied commands
|
||||
//-----------------------------------------------------------------------------
|
||||
void CreateVideoPanel( const char *lpszFilename, const char *lpszExitCommand, int nWidth, int nHeight, VideoPanelParms_t &parms )
|
||||
{
|
||||
char strFullpath[MAX_PATH];
|
||||
Q_strncpy( strFullpath, "media/", MAX_PATH ); // Assume we must play out of the media directory
|
||||
char strFilename[MAX_PATH];
|
||||
Q_StripExtension( lpszFilename, strFilename, MAX_PATH );
|
||||
Q_strncat( strFullpath, lpszFilename, MAX_PATH );
|
||||
|
||||
// Use the full screen size if they haven't specified an override
|
||||
unsigned int nScreenWidth = ( nWidth != 0 ) ? nWidth : ScreenWidth();
|
||||
unsigned int nScreenHeight = ( nHeight != 0 ) ? nHeight : ScreenHeight();
|
||||
|
||||
// Create the panel and go!
|
||||
if ( VideoPanel_Create( 0, 0, nScreenWidth, nScreenHeight, strFullpath, lpszExitCommand, parms ) == false )
|
||||
{
|
||||
Warning( "Unable to play video: %s\n", strFullpath );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Used to launch a video playback
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CON_COMMAND( playvideo, "Plays a video: <filename> [width height]" )
|
||||
@ -375,30 +549,32 @@ CON_COMMAND( playvideo, "Plays a video: <filename> [width height]" )
|
||||
|
||||
unsigned int nScreenWidth = Q_atoi( args[2] );
|
||||
unsigned int nScreenHeight = Q_atoi( args[3] );
|
||||
|
||||
char strFullpath[MAX_PATH];
|
||||
Q_strncpy( strFullpath, "media/", MAX_PATH ); // Assume we must play out of the media directory
|
||||
char strFilename[MAX_PATH];
|
||||
Q_StripExtension( args[1], strFilename, MAX_PATH );
|
||||
Q_strncat( strFullpath, args[1], MAX_PATH );
|
||||
|
||||
if ( nScreenWidth == 0 )
|
||||
{
|
||||
nScreenWidth = ScreenWidth();
|
||||
}
|
||||
|
||||
if ( nScreenHeight == 0 )
|
||||
{
|
||||
nScreenHeight = ScreenHeight();
|
||||
}
|
||||
|
||||
// Create the panel and go!
|
||||
if ( VideoPanel_Create( 0, 0, nScreenWidth, nScreenHeight, strFullpath ) == false )
|
||||
{
|
||||
Warning( "Unable to play video: %s\n", strFullpath );
|
||||
}
|
||||
// New struct; functionally identical
|
||||
VideoPanelParms_t parms;
|
||||
|
||||
CreateVideoPanel( args[1], NULL, nScreenWidth, nScreenHeight, parms );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Used to launch a video playback
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CON_COMMAND( playvideo_nointerrupt, "Plays a video without ability to skip: <filename> [width height]" )
|
||||
{
|
||||
if ( args.ArgC() < 2 )
|
||||
return;
|
||||
|
||||
unsigned int nScreenWidth = Q_atoi( args[2] );
|
||||
unsigned int nScreenHeight = Q_atoi( args[3] );
|
||||
|
||||
// New struct; functionally identical
|
||||
VideoPanelParms_t parms( false );
|
||||
|
||||
CreateVideoPanel( args[1], NULL, nScreenWidth, nScreenHeight, parms );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Used to launch a video playback and fire a command on completion
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -408,21 +584,78 @@ CON_COMMAND( playvideo_exitcommand, "Plays a video and fires and exit command wh
|
||||
if ( args.ArgC() < 2 )
|
||||
return;
|
||||
|
||||
unsigned int nScreenWidth = ScreenWidth();
|
||||
unsigned int nScreenHeight = ScreenHeight();
|
||||
|
||||
char strFullpath[MAX_PATH];
|
||||
Q_strncpy( strFullpath, "media/", MAX_PATH ); // Assume we must play out of the media directory
|
||||
char strFilename[MAX_PATH];
|
||||
Q_StripExtension( args[1], strFilename, MAX_PATH );
|
||||
Q_strncat( strFullpath, args[1], MAX_PATH );
|
||||
|
||||
// Pull out the exit command we want to use
|
||||
char *pExitCommand = Q_strstr( args.GetCommandString(), args[2] );
|
||||
|
||||
// Create the panel and go!
|
||||
if ( VideoPanel_Create( 0, 0, nScreenWidth, nScreenHeight, strFullpath, pExitCommand ) == false )
|
||||
// New struct; functionally identical
|
||||
VideoPanelParms_t parms;
|
||||
|
||||
CreateVideoPanel( args[1], pExitCommand, 0, 0, parms );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Used to launch a video playback and fire a command on completion
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CON_COMMAND( playvideo_exitcommand_nointerrupt, "Plays a video (without interruption) and fires and exit command when it is stopped or finishes: <filename> <exit command>" )
|
||||
{
|
||||
if ( args.ArgC() < 2 )
|
||||
return;
|
||||
|
||||
// Pull out the exit command we want to use
|
||||
char *pExitCommand = Q_strstr( args.GetCommandString(), args[2] );
|
||||
|
||||
// New struct; functionally identical
|
||||
VideoPanelParms_t parms( false );
|
||||
|
||||
CreateVideoPanel( args[1], pExitCommand, 0, 0, parms );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Cause all playback to stop
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CON_COMMAND( stopvideos, "Stops all videos playing to the screen" )
|
||||
{
|
||||
FOR_EACH_VEC( g_vecVideoPanels, itr )
|
||||
{
|
||||
Warning( "Unable to play video: %s\n", strFullpath );
|
||||
engine->ClientCmd( pExitCommand );
|
||||
g_vecVideoPanels[itr]->StopPlayback();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Used to launch a video playback and fire a command on completion
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CON_COMMAND( playvideo_complex, "Plays a video with various parameters to simplify logic_playmovie: <filename> <exit command> <no interrupt> <looping> <fade in> <fade out>" )
|
||||
{
|
||||
if ( args.ArgC() < 2 )
|
||||
return;
|
||||
|
||||
// Pull out the exit command we want to use
|
||||
char *pExitCommand = Q_strstr( args.GetCommandString(), args[2] );
|
||||
|
||||
// Parameters
|
||||
VideoPanelParms_t parms;
|
||||
|
||||
if (args.ArgC() >= 3)
|
||||
parms.bAllowInterrupt = atoi( args[3] ) != 0;
|
||||
if (args.ArgC() >= 4)
|
||||
parms.bLoop = atoi( args[4] ) != 0;
|
||||
if (args.ArgC() >= 5)
|
||||
parms.bMute = atoi( args[5] ) != 0;
|
||||
|
||||
//if (args.ArgC() >= 5)
|
||||
// parms.flFadeIn = atof( args[5] );
|
||||
//if (args.ArgC() >= 6)
|
||||
// parms.flFadeOut = atof( args[6] );
|
||||
|
||||
// Stop a softlock
|
||||
if (parms.bAllowInterrupt == false && parms.bLoop)
|
||||
{
|
||||
Warning( "WARNING: Tried to play video set to be uninterruptible and looping. This would cause a softlock because the video loops forever and there's no way to stop it.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
CreateVideoPanel( args[1], pExitCommand, 0, 0, parms );
|
||||
}
|
||||
|
@ -45,14 +45,22 @@ public:
|
||||
}
|
||||
|
||||
bool BeginPlayback( const char *pFilename );
|
||||
void StopPlayback( void );
|
||||
|
||||
void SetBlackBackground( bool bBlack ){ m_bBlackBackground = bBlack; }
|
||||
void SetAllowInterrupt( bool bAllowInterrupt ) { m_bAllowInterruption = bAllowInterrupt; }
|
||||
void SetStopAllSounds( bool bStopAllSounds ) { m_bStopAllSounds = bStopAllSounds; }
|
||||
#ifdef MAPBASE
|
||||
void SetLooping( bool bLooping ) { m_bLooping = bLooping; }
|
||||
void SetMuted( bool bMuted ) { m_bMuted = bMuted; }
|
||||
void SetFade( float flStartFade, float flEndFade ) { m_flFadeIn = flStartFade; m_flFadeOut = flEndFade; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
virtual void OnTick( void ) { BaseClass::OnTick(); }
|
||||
virtual void OnTick( void );
|
||||
virtual void OnCommand( const char *pcCommand ) { BaseClass::OnCommand( pcCommand ); }
|
||||
virtual void OnVideoOver(){}
|
||||
virtual void OnVideoOver();
|
||||
|
||||
protected:
|
||||
IVideoMaterial *m_VideoMaterial;
|
||||
@ -65,8 +73,19 @@ protected:
|
||||
float m_flU; // U,V ranges for video on its sheet
|
||||
float m_flV;
|
||||
|
||||
bool m_bLooping;
|
||||
#ifdef MAPBASE
|
||||
float m_flFadeIn;
|
||||
float m_flFadeOut;
|
||||
bool m_bMuted;
|
||||
#endif
|
||||
bool m_bStopAllSounds;
|
||||
bool m_bAllowInterruption;
|
||||
bool m_bBlackBackground;
|
||||
bool m_bAllowAlternateMedia;
|
||||
int m_nShutdownCount;
|
||||
|
||||
bool m_bStarted;
|
||||
};
|
||||
|
||||
|
||||
|
136
sp/src/game/server/logic_playmovie.cpp
Normal file
136
sp/src/game/server/logic_playmovie.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
//===== Copyright © 1996-2009, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose: Plays a movie and reports on finish
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CLogicPlayMovie : public CLogicalEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CLogicPlayMovie, CLogicalEntity );
|
||||
DECLARE_DATADESC();
|
||||
|
||||
CLogicPlayMovie( void ) { }
|
||||
~CLogicPlayMovie( void ) { }
|
||||
|
||||
virtual void Precache( void );
|
||||
virtual void Spawn( void );
|
||||
|
||||
private:
|
||||
|
||||
void InputPlayMovie( inputdata_t &data );
|
||||
#ifdef MAPBASE
|
||||
void InputStopMovie( inputdata_t &data );
|
||||
#endif
|
||||
void InputMovieFinished( inputdata_t &data );
|
||||
|
||||
string_t m_strMovieFilename;
|
||||
bool m_bAllowUserSkip;
|
||||
#ifdef MAPBASE
|
||||
bool m_bLooping;
|
||||
bool m_bMuted;
|
||||
|
||||
bool m_bPlayingVideo;
|
||||
#endif
|
||||
|
||||
COutputEvent m_OnPlaybackFinished;
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( logic_playmovie, CLogicPlayMovie );
|
||||
|
||||
BEGIN_DATADESC( CLogicPlayMovie )
|
||||
|
||||
DEFINE_KEYFIELD( m_strMovieFilename, FIELD_STRING, "MovieFilename" ),
|
||||
DEFINE_KEYFIELD( m_bAllowUserSkip, FIELD_BOOLEAN, "allowskip" ),
|
||||
#ifdef MAPBASE
|
||||
DEFINE_KEYFIELD( m_bLooping, FIELD_BOOLEAN, "loopvideo" ),
|
||||
DEFINE_KEYFIELD( m_bMuted, FIELD_BOOLEAN, "mute" ),
|
||||
|
||||
DEFINE_FIELD( m_bPlayingVideo, FIELD_BOOLEAN ),
|
||||
#endif
|
||||
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "PlayMovie", InputPlayMovie ),
|
||||
#ifdef MAPBASE
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "StopMovie", InputStopMovie ),
|
||||
#endif
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "__MovieFinished", InputMovieFinished ),
|
||||
|
||||
DEFINE_OUTPUT( m_OnPlaybackFinished, "OnPlaybackFinished" ),
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLogicPlayMovie::Precache( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLogicPlayMovie::Spawn( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLogicPlayMovie::InputPlayMovie( inputdata_t &data )
|
||||
{
|
||||
// Build the hacked string
|
||||
|
||||
char szClientCmd[256];
|
||||
Q_snprintf( szClientCmd, sizeof(szClientCmd),
|
||||
"playvideo_complex %s \"ent_fire %s __MovieFinished\" %d %d %d\n",
|
||||
STRING(m_strMovieFilename),
|
||||
GetEntityNameAsCStr(),
|
||||
m_bAllowUserSkip,
|
||||
#ifdef MAPBASE
|
||||
m_bLooping,
|
||||
m_bMuted
|
||||
#else
|
||||
0,
|
||||
0
|
||||
#endif
|
||||
);
|
||||
|
||||
// Send it on
|
||||
engine->ServerCommand( szClientCmd );
|
||||
|
||||
#ifdef MAPBASE
|
||||
m_bPlayingVideo = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLogicPlayMovie::InputStopMovie( inputdata_t &data )
|
||||
{
|
||||
if (m_bPlayingVideo)
|
||||
{
|
||||
// Send it on
|
||||
engine->ServerCommand( "stopvideos\n" );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLogicPlayMovie::InputMovieFinished( inputdata_t &data )
|
||||
{
|
||||
// Simply fire our output
|
||||
m_OnPlaybackFinished.FireOutput( this, this );
|
||||
|
||||
#ifdef MAPBASE
|
||||
m_bPlayingVideo = false;
|
||||
#endif
|
||||
}
|
372
sp/src/game/server/movie_display.cpp
Normal file
372
sp/src/game/server/movie_display.cpp
Normal file
@ -0,0 +1,372 @@
|
||||
//========= Copyright © 1996-2009, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Allows movies to be played as a VGUI screen in the world
|
||||
//
|
||||
//=====================================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "EnvMessage.h"
|
||||
#include "fmtstr.h"
|
||||
#include "vguiscreen.h"
|
||||
#include "filesystem.h"
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
class CMovieDisplay : public CBaseEntity
|
||||
{
|
||||
public:
|
||||
|
||||
DECLARE_CLASS( CMovieDisplay, CBaseEntity );
|
||||
DECLARE_DATADESC();
|
||||
DECLARE_SERVERCLASS();
|
||||
|
||||
virtual ~CMovieDisplay();
|
||||
|
||||
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 );
|
||||
|
||||
private:
|
||||
|
||||
// Control panel
|
||||
void GetControlPanelInfo( int nPanelIndex, const char *&pPanelName );
|
||||
void GetControlPanelClassName( int nPanelIndex, const char *&pPanelName );
|
||||
void SpawnControlPanels( void );
|
||||
void RestoreControlPanels( void );
|
||||
|
||||
private:
|
||||
CNetworkVar( bool, m_bEnabled );
|
||||
CNetworkVar( bool, m_bLooping );
|
||||
|
||||
CNetworkString( m_szDisplayText, 128 );
|
||||
|
||||
// Filename of the movie to play
|
||||
CNetworkString( m_szMovieFilename, 128 );
|
||||
string_t m_strMovieFilename;
|
||||
|
||||
// "Group" name. Screens of the same group name will play the same movie at the same time
|
||||
// Effectively this lets multiple screens tune to the same "channel" in the world
|
||||
CNetworkString( m_szGroupName, 128 );
|
||||
string_t m_strGroupName;
|
||||
|
||||
int m_iScreenWidth;
|
||||
int m_iScreenHeight;
|
||||
|
||||
bool m_bDoFullTransmit;
|
||||
|
||||
CHandle<CVGuiScreen> m_hScreen;
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( vgui_movie_display, CMovieDisplay );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Save/load
|
||||
//-----------------------------------------------------------------------------
|
||||
BEGIN_DATADESC( CMovieDisplay )
|
||||
|
||||
DEFINE_FIELD( m_bEnabled, FIELD_BOOLEAN ),
|
||||
|
||||
DEFINE_AUTO_ARRAY_KEYFIELD( m_szDisplayText, FIELD_CHARACTER, "displaytext" ),
|
||||
|
||||
DEFINE_AUTO_ARRAY( m_szMovieFilename, FIELD_CHARACTER ),
|
||||
DEFINE_KEYFIELD( m_strMovieFilename, FIELD_STRING, "moviefilename" ),
|
||||
|
||||
DEFINE_AUTO_ARRAY( m_szGroupName, FIELD_CHARACTER ),
|
||||
DEFINE_KEYFIELD( m_strGroupName, FIELD_STRING, "groupname" ),
|
||||
|
||||
DEFINE_KEYFIELD( m_iScreenWidth, FIELD_INTEGER, "width" ),
|
||||
DEFINE_KEYFIELD( m_iScreenHeight, FIELD_INTEGER, "height" ),
|
||||
DEFINE_KEYFIELD( m_bLooping, FIELD_BOOLEAN, "looping" ),
|
||||
|
||||
DEFINE_FIELD( m_bDoFullTransmit, FIELD_BOOLEAN ),
|
||||
|
||||
DEFINE_FIELD( m_hScreen, FIELD_EHANDLE ),
|
||||
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ),
|
||||
|
||||
DEFINE_INPUTFUNC( FIELD_STRING, "SetDisplayText", InputSetDisplayText ),
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
IMPLEMENT_SERVERCLASS_ST( CMovieDisplay, DT_MovieDisplay )
|
||||
SendPropBool( SENDINFO( m_bEnabled ) ),
|
||||
SendPropBool( SENDINFO( m_bLooping ) ),
|
||||
SendPropString( SENDINFO( m_szMovieFilename ) ),
|
||||
SendPropString( SENDINFO( m_szGroupName ) ),
|
||||
END_SEND_TABLE()
|
||||
|
||||
CMovieDisplay::~CMovieDisplay()
|
||||
{
|
||||
DestroyVGuiScreen( m_hScreen.Get() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Read in Hammer data
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMovieDisplay::KeyValue( const char *szKeyName, const char *szValue )
|
||||
{
|
||||
// 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 CMovieDisplay::UpdateTransmitState()
|
||||
{
|
||||
if ( m_bDoFullTransmit )
|
||||
{
|
||||
m_bDoFullTransmit = false;
|
||||
return SetTransmitState( FL_EDICT_ALWAYS );
|
||||
}
|
||||
|
||||
return SetTransmitState( FL_EDICT_FULLCHECK );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMovieDisplay::SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways )
|
||||
{
|
||||
// Are we already marked for transmission?
|
||||
if ( pInfo->m_pTransmitEdict->Get( entindex() ) )
|
||||
return;
|
||||
|
||||
BaseClass::SetTransmit( pInfo, bAlways );
|
||||
|
||||
// Force our screen to be sent too.
|
||||
m_hScreen->SetTransmit( pInfo, bAlways );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMovieDisplay::Spawn( void )
|
||||
{
|
||||
// Move the strings into a networkable form
|
||||
Q_strcpy( m_szMovieFilename.GetForModify(), m_strMovieFilename.ToCStr() );
|
||||
Q_strcpy( m_szGroupName.GetForModify(), m_strGroupName.ToCStr() );
|
||||
|
||||
Precache();
|
||||
|
||||
BaseClass::Spawn();
|
||||
|
||||
m_bEnabled = false;
|
||||
|
||||
SpawnControlPanels();
|
||||
|
||||
ScreenVisible( m_bEnabled );
|
||||
|
||||
m_bDoFullTransmit = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMovieDisplay::Precache( void )
|
||||
{
|
||||
BaseClass::Precache();
|
||||
|
||||
PrecacheVGuiScreen( "video_display_screen" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMovieDisplay::OnRestore( void )
|
||||
{
|
||||
BaseClass::OnRestore();
|
||||
|
||||
RestoreControlPanels();
|
||||
|
||||
ScreenVisible( m_bEnabled );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMovieDisplay::ScreenVisible( bool bVisible )
|
||||
{
|
||||
// Set its active state
|
||||
m_hScreen->SetActive( bVisible );
|
||||
|
||||
if ( bVisible )
|
||||
{
|
||||
m_hScreen->RemoveEffects( EF_NODRAW );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hScreen->AddEffects( EF_NODRAW );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMovieDisplay::Disable( void )
|
||||
{
|
||||
if ( !m_bEnabled )
|
||||
return;
|
||||
|
||||
m_bEnabled = false;
|
||||
|
||||
ScreenVisible( false );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMovieDisplay::Enable( void )
|
||||
{
|
||||
if ( m_bEnabled )
|
||||
return;
|
||||
|
||||
m_bEnabled = true;
|
||||
|
||||
ScreenVisible( true );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMovieDisplay::InputDisable( inputdata_t &inputdata )
|
||||
{
|
||||
Disable();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMovieDisplay::InputEnable( inputdata_t &inputdata )
|
||||
{
|
||||
Enable();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMovieDisplay::InputSetDisplayText( inputdata_t &inputdata )
|
||||
{
|
||||
Q_strcpy( m_szDisplayText.GetForModify(), inputdata.value.String() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMovieDisplay::GetControlPanelInfo( int nPanelIndex, const char *&pPanelName )
|
||||
{
|
||||
pPanelName = "movie_display_screen";
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMovieDisplay::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 CMovieDisplay::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, 0 );
|
||||
pScreen->ChangeTeam( GetTeamNumber() );
|
||||
pScreen->SetActualSize( flWidth, flHeight );
|
||||
pScreen->SetActive( true );
|
||||
pScreen->MakeVisibleOnlyToTeammates( false );
|
||||
pScreen->SetTransparency( true );
|
||||
m_hScreen = pScreen;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMovieDisplay::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 )
|
||||
{
|
||||
m_hScreen = pScreen;
|
||||
m_hScreen->SetActive( true );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
@ -27,6 +27,8 @@ $Project
|
||||
$File "postprocesscontroller.h"
|
||||
$File "env_dof_controller.cpp"
|
||||
$File "env_dof_controller.h"
|
||||
$File "logic_playmovie.cpp"
|
||||
$File "movie_display.cpp"
|
||||
|
||||
$Folder "Mapbase"
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user