Skip to content

Instantly share code, notes, and snippets.

@BSVino
Created November 12, 2013 04:09
Show Gist options
  • Select an option

  • Save BSVino/7425335 to your computer and use it in GitHub Desktop.

Select an option

Save BSVino/7425335 to your computer and use it in GitHub Desktop.
This code for background movies in Source SDK 2013 used to run with Bink but Bink support was removed for the SDK 2013 update is broken and I'm in no mood to fix the code.
enum
{
MAINMENU_NONE, //start here
MAINMENU_STARTVIDEO, //start video
MAINMENU_STOPVIDEO, //stop video
};
// The CDAMainMenu class graciously donated by Tony Sergi, from Project Valkyrie.
class CDAMainMenu : public vgui::Panel
{
public:
DECLARE_CLASS_SIMPLE( CDAMainMenu, vgui::Panel );
CDAMainMenu::CDAMainMenu(vgui::Panel* parent, const char *pElementName ) : vgui::Panel( NULL, "da_main_menu" )
{
vgui::VPANEL pParent = enginevgui->GetPanel( PANEL_GAMEUIDLL );
SetParent( pParent );
SetBuildModeEditable(false);
SetVisible(false);
SetPaintEnabled(false);
SetProportional( true );
SetKeyBoardInputEnabled( false );
SetBlackBackground( false );
SetPaintBorderEnabled( false );
m_AVIHandle = AVIHANDLE_INVALID;
m_nPlaybackWidth = 0;
m_nPlaybackHeight = 0;
m_flActionThink = -1;
m_iAction = MAINMENU_NONE;
m_bToolsMode = false;
m_MainMenuRef.Init( "console/mainmenu.vmt", TEXTURE_GROUP_OTHER );
}
~CDAMainMenu()
{
ReleaseVideo();
MarkForDeletion();
}
bool IsVideoPlaying()
{
return m_bPaintVideo;
}
void StartVideo()
{
m_bToolsMode = (IsPC() && ( CommandLine()->CheckParm( "-tools" ) != NULL )) ? true : false;
SetVisible(true);
SetPaintEnabled(true);
SetNextThink( 0.1, MAINMENU_STARTVIDEO );
}
void StopVideo()
{
//Tony; release the video when stopping
//Tony; modified; don't hide the panel anymore, because we draw the main menu logo thing for ingame
// SetVisible(false);
// SetPaintEnabled(false);
SetNextThink( 0.1, MAINMENU_STOPVIDEO );
}
void OnThink()
{
SetPos(0,0);
SetSize(ScreenWidth(),ScreenHeight());
SetZPos(500);
if ( m_flActionThink > 0 && m_flActionThink < gpGlobals->curtime )
{
if ( m_iAction == MAINMENU_STARTVIDEO )
{
bool isWide = false;
if ((ScreenWidth() / 4) != (ScreenHeight() / 3))
isWide = true;
if (isWide)
{
// DevMsg("attempting to play widescreen video\n");
if (!BeginPlayback( "media/mainmenu_wide.avi" ))
BeginPlayback( "media/mainmenu.avi" );
}
else
BeginPlayback( "media/mainmenu.avi" );
}
else if ( m_iAction == MAINMENU_STOPVIDEO )
ReleaseVideo();
// reset our think
SetNextThink( -1, MAINMENU_NONE );
}
}
void OnVideoOver()
{
SetNextThink( gpGlobals->curtime, MAINMENU_STARTVIDEO );
}
void SetNextThink( float flActionThink, int iAction )
{
m_flActionThink = flActionThink;
m_iAction = iAction;
}
void GetPanelPos( int &xpos, int &ypos )
{
vgui::ipanel()->GetAbsPos( GetVPanel(), xpos, ypos );
}
void Paint( void )
{
if (m_bToolsMode)
return;
if (m_bPaintVideo)
{
// No video to play, so do nothing
if ( m_AVIHandle == AVIHANDLE_INVALID )
return;
// Update our frame
if ( avi->Update( m_AVIHandle ) == false )
OnVideoOver();
// 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 )
{
vgui::surface()->DrawSetColor( 0, 0, 0, 255 );
vgui::surface()->DrawFilledRect( 0, 0, GetWide(), GetTall() );
}
// Draw the polys to draw this out
CMatRenderContextPtr pRenderContext( materials );
pRenderContext->MatrixMode( MATERIAL_VIEW );
pRenderContext->PushMatrix();
pRenderContext->LoadIdentity();
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
pRenderContext->PushMatrix();
pRenderContext->LoadIdentity();
pRenderContext->Bind( m_pMaterial, NULL );
CMeshBuilder meshBuilder;
IMesh* pMesh = pRenderContext->GetDynamicMesh( true );
meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
float flLeftX = xpos;
float flRightX = xpos + (m_nPlaybackWidth-1);
float flTopY = ypos;
float flBottomY = ypos + (m_nPlaybackHeight-1);
// Map our UVs to cut out just the portion of the video we're interested in
float flLeftU = 0.0f;
float flTopV = 0.0f;
// We need to subtract off a pixel to make sure we don't bleed
float flRightU = m_flU - ( 1.0f / (float) m_nPlaybackWidth );
float flBottomV = m_flV - ( 1.0f / (float) m_nPlaybackHeight );
// Get the current viewport size
int vx, vy, vw, vh;
pRenderContext->GetViewport( vx, vy, vw, vh );
// map from screen pixel coords to -1..1
flRightX = FLerp( -1, 1, 0, vw, flRightX );
flLeftX = FLerp( -1, 1, 0, vw, flLeftX );
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);
meshBuilder.Position3f( (bLeft) ? flLeftX : flRightX, (corner & 2) ? flBottomY : flTopY, 0.0f );
meshBuilder.Normal3f( 0.0f, 0.0f, 1.0f );
meshBuilder.TexCoord2f( 0, (bLeft) ? flLeftU : flRightU, (corner & 2) ? flBottomV : flTopV );
meshBuilder.TangentS3f( 0.0f, 1.0f, 0.0f );
meshBuilder.TangentT3f( 1.0f, 0.0f, 0.0f );
meshBuilder.Color4f( 1.0f, 1.0f, 1.0f, alpha );
meshBuilder.AdvanceVertex();
}
meshBuilder.End();
pMesh->Draw();
pRenderContext->MatrixMode( MATERIAL_VIEW );
pRenderContext->PopMatrix();
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
pRenderContext->PopMatrix();
}
//Tony; now draw the mainmenu.vmt overtop!
{
CMatRenderContextPtr pRenderContext( materials );
CMeshBuilder mb;
IMesh *mesh;
pRenderContext->Bind( m_MainMenuRef );
mesh = pRenderContext->GetDynamicMesh( true );
mb.Begin( mesh, MATERIAL_QUADS, 1 );
mb.Color4ub( 255, 255, 255, 255);
mb.TexCoord2f( 0,0,0 ); mb.Position3f( 0.0f, 0.0f, 0 ); mb.AdvanceVertex();
mb.Color4ub( 255, 255, 255, 255);
mb.TexCoord2f( 0,1,0 ); mb.Position3f( ScreenWidth(), 0.0f, 0 ); mb.AdvanceVertex();
mb.Color4ub( 255, 255, 255, 255);
mb.TexCoord2f( 0,1,1 ); mb.Position3f( ScreenWidth(), ScreenHeight(), 0 ); mb.AdvanceVertex();
mb.Color4ub( 255, 255, 255, 255);
mb.TexCoord2f( 0,0,1 ); mb.Position3f( 0.0f, ScreenHeight(), 0 ); mb.AdvanceVertex();
mb.End();
mesh->Draw();
}
}
bool BeginPlayback( const char *pFilename )
{
// Destroy any previously allocated video
if ( m_AVIHandle != AVIHANDLE_INVALID )
{
avi->DestroyMaterial( m_AVIHandle );
m_AVIHandle = AVIHANDLE_INVALID;
}
// Load and create our BINK video
m_AVIHandle = avi->CreateMaterial( "VideoAVIMaterial", pFilename, "GAME" );
if ( m_AVIHandle == AVIHANDLE_INVALID )
return false;
m_bPaintVideo = true;
int nWidth, nHeight;
avi->GetFrameSize( m_AVIHandle, &nWidth, &nHeight );
avi->GetTexCoordRange( m_AVIHandle, &m_flU, &m_flV );
m_pMaterial = avi->GetMaterial( m_AVIHandle );
// float flFrameRatio = ( (float) GetWide() / (float) GetTall() );
// float flVideoRatio = ( (float) nWidth / (float) nHeight );
// if ( flVideoRatio > flFrameRatio )
// {
// m_nPlaybackWidth = ScreenWidth();
// m_nPlaybackHeight = ( ScreenWidth() / flVideoRatio );
// }
// else if ( flVideoRatio < flFrameRatio )
// {
// m_nPlaybackWidth = ( ScreenHeight() * flVideoRatio );
// m_nPlaybackHeight = ScreenHeight();
// }
// else
{
m_nPlaybackWidth = ScreenWidth();
m_nPlaybackHeight = ScreenHeight();
}
return true;
}
void ReleaseVideo()
{
m_bPaintVideo = false;
//Tony; not touching the sound!!
// enginesound->NotifyEndMoviePlayback();
// Destroy any previously allocated video
if ( m_AVIHandle != AVIHANDLE_INVALID )
{
avi->DestroyMaterial( m_AVIHandle );
m_AVIHandle = AVIHANDLE_INVALID;
}
}
void SetBlackBackground( bool bBlack ){ m_bBlackBackground = bBlack; }
void DoModal( void )
{
vgui::surface()->RestrictPaintToSinglePanel( GetVPanel() );
}
MESSAGE_FUNC( OnDisconnectFromGame, "DisconnectedFromGame" );
private:
bool m_bToolsMode;
bool m_bPaintVideo;
float m_flActionThink;
int m_iAction;
CMaterialReference m_MainMenuRef;
protected:
AVIMaterial_t m_AVIHandle;
IMaterial *m_pMaterial;
int m_nPlaybackHeight; // Calculated to address ratio changes
int m_nPlaybackWidth;
char m_szExitCommand[MAX_PATH]; // This call is fired at the engine when the video finishes or is interrupted
float m_flU; // U,V ranges for video on its sheet
float m_flV;
bool m_bBlackBackground;
};
//Tony; if we get disconnected, load the menu
void CDAMainMenu::OnDisconnectFromGame( void )
{
StartVideo();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment