From c4abb0b07fb287aac20bf508b6d2c4f890cfdf40 Mon Sep 17 00:00:00 2001 From: Blixibon Date: Sun, 7 Mar 2021 11:39:50 -0600 Subject: [PATCH] Made HUD movie parameters more flexible; Added WIP movie fade effects for replicating the Portal 2 keyvalues --- sp/src/game/client/vgui_video.cpp | 116 +++++++++++++++++++++---- sp/src/game/client/vgui_video.h | 5 ++ sp/src/game/server/logic_playmovie.cpp | 9 +- 3 files changed, 109 insertions(+), 21 deletions(-) diff --git a/sp/src/game/client/vgui_video.cpp b/sp/src/game/client/vgui_video.cpp index 39ab6b6c..2fa66cf7 100644 --- a/sp/src/game/client/vgui_video.cpp +++ b/sp/src/game/client/vgui_video.cpp @@ -34,6 +34,22 @@ void VGui_ClearVideoPanels() g_vecVideoPanels.RemoveAll(); } +struct VideoPanelParms_t +{ + VideoPanelParms_t( bool _interrupt = true, bool _loop = false, float _fadein = 0.0f, float _fadeout = 0.0f ) + { + bAllowInterrupt = _interrupt; + bLoop = _loop; + flFadeIn = _fadein; + flFadeOut = _fadeout; + } + + bool bAllowInterrupt; + bool bLoop; + 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 ), @@ -331,6 +347,27 @@ 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 @@ -346,12 +383,16 @@ void VideoPanel::Paint( void ) // 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(); @@ -391,8 +432,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); @@ -426,8 +465,7 @@ bool VideoPanel_Create( unsigned int nXPos, unsigned int nYPos, unsigned int nWidth, unsigned int nHeight, const char *pVideoFilename, const char *pExitCommand /*= NULL*/, - bool bAllowInterruption /*= true*/, - bool bLooping = false ) + const VideoPanelParms_t &parms ) { // Create the base video panel VideoPanel *pVideoPanel = new VideoPanel( nXPos, nYPos, nHeight, nWidth ); @@ -435,14 +473,17 @@ bool VideoPanel_Create( unsigned int nXPos, unsigned int nYPos, return false; // Toggle if we want the panel to allow interruption - pVideoPanel->SetAllowInterrupt( bAllowInterruption ); + 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( bLooping ); + pVideoPanel->SetLooping( parms.bLoop ); + + // Fade parameters + pVideoPanel->SetFade( parms.flFadeIn, parms.flFadeOut ); #endif // Start it going @@ -461,7 +502,7 @@ bool VideoPanel_Create( unsigned int nXPos, unsigned int nYPos, //----------------------------------------------------------------------------- // Purpose: Create a video panel with the supplied commands //----------------------------------------------------------------------------- -void CreateVideoPanel( const char *lpszFilename, const char *lpszExitCommand, int nWidth, int nHeight, bool bAllowInterruption, bool bLooping = false ) +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 @@ -474,7 +515,7 @@ void CreateVideoPanel( const char *lpszFilename, const char *lpszExitCommand, in unsigned int nScreenHeight = ( nHeight != 0 ) ? nHeight : ScreenHeight(); // Create the panel and go! - if ( VideoPanel_Create( 0, 0, nScreenWidth, nScreenHeight, strFullpath, lpszExitCommand, bAllowInterruption, bLooping ) == false ) + if ( VideoPanel_Create( 0, 0, nScreenWidth, nScreenHeight, strFullpath, lpszExitCommand, parms ) == false ) { Warning( "Unable to play video: %s\n", strFullpath ); } @@ -491,8 +532,11 @@ CON_COMMAND( playvideo, "Plays a video: [width height]" ) unsigned int nScreenWidth = Q_atoi( args[2] ); unsigned int nScreenHeight = Q_atoi( args[3] ); + + // New struct; functionally identical + VideoPanelParms_t parms; - CreateVideoPanel( args[1], NULL, nScreenWidth, nScreenHeight, true ); + CreateVideoPanel( args[1], NULL, nScreenWidth, nScreenHeight, parms ); } //----------------------------------------------------------------------------- @@ -507,7 +551,10 @@ CON_COMMAND( playvideo_nointerrupt, "Plays a video without ability to skip: " ) +CON_COMMAND( playvideo_exitcommand, "Plays a video and fires and exit command when it is stopped or finishes: " ) { if ( args.ArgC() < 2 ) return; @@ -523,10 +570,10 @@ CON_COMMAND( playvideo_exitcommand, "Plays a video and fires and exit command wh // Pull out the exit command we want to use char *pExitCommand = Q_strstr( args.GetCommandString(), args[2] ); - // Check if we should loop - bool bLoop = atoi(args.Arg(3)) != 0; + // New struct; functionally identical + VideoPanelParms_t parms; - CreateVideoPanel( args[1], pExitCommand, 0, 0, true, bLoop ); + CreateVideoPanel( args[1], pExitCommand, 0, 0, parms ); } //----------------------------------------------------------------------------- @@ -541,7 +588,10 @@ CON_COMMAND( playvideo_exitcommand_nointerrupt, "Plays a video (without interrup // Pull out the exit command we want to use char *pExitCommand = Q_strstr( args.GetCommandString(), args[2] ); - CreateVideoPanel( args[1], pExitCommand, 0, 0, false, false ); + // New struct; functionally identical + VideoPanelParms_t parms( false ); + + CreateVideoPanel( args[1], pExitCommand, 0, 0, parms ); } //----------------------------------------------------------------------------- @@ -555,3 +605,37 @@ CON_COMMAND( stopvideos, "Stops all videos playing to the screen" ) 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: " ) +{ + 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] ) != 1; + if (args.ArgC() >= 4) + parms.bLoop = atoi( args[4] ) != 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 ); +} diff --git a/sp/src/game/client/vgui_video.h b/sp/src/game/client/vgui_video.h index f31cae24..9e76ace0 100644 --- a/sp/src/game/client/vgui_video.h +++ b/sp/src/game/client/vgui_video.h @@ -51,6 +51,7 @@ public: void SetAllowInterrupt( bool bAllowInterrupt ) { m_bAllowInterruption = bAllowInterrupt; } #ifdef MAPBASE void SetLooping( bool bLooping ) { m_bLooping = bLooping; } + void SetFade( float flStartFade, float flEndFade ) { m_flFadeIn = flStartFade; m_flFadeOut = flEndFade; } #endif protected: @@ -71,6 +72,10 @@ protected: float m_flV; bool m_bLooping; +#ifdef MAPBASE + float m_flFadeIn; + float m_flFadeOut; +#endif bool m_bStopAllSounds; bool m_bAllowInterruption; bool m_bBlackBackground; diff --git a/sp/src/game/server/logic_playmovie.cpp b/sp/src/game/server/logic_playmovie.cpp index 1ea25fee..41ce74e9 100644 --- a/sp/src/game/server/logic_playmovie.cpp +++ b/sp/src/game/server/logic_playmovie.cpp @@ -71,19 +71,18 @@ void CLogicPlayMovie::Spawn( void ) //----------------------------------------------------------------------------- void CLogicPlayMovie::InputPlayMovie( inputdata_t &data ) { - const char *szVideoCommand = ( m_bAllowUserSkip ) ? "playvideo_exitcommand" : "playvideo_exitcommand_nointerrupt"; // Build the hacked string char szClientCmd[256]; Q_snprintf( szClientCmd, sizeof(szClientCmd), - "%s %s \"ent_fire %s __MovieFinished\" %s\n", - szVideoCommand, + "playvideo_complex %s \"ent_fire %s __MovieFinished\" %d %d\n", STRING(m_strMovieFilename), GetEntityNameAsCStr(), + m_bAllowUserSkip, #ifdef MAPBASE - m_bLooping ? "1" : "0" + m_bLooping #else - "0" + 0 #endif );