Skip to content

Instantly share code, notes, and snippets.

@GamerDude27 GamerDude27/menu_background.cpp Secret
Last active Sep 13, 2018

Embed
What would you like to do?
//========= Copyright © 1996-2008, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//====================================================================================//
#include "cbase.h"
#include "menu_background.h"
#include <cdll_client_int.h>
#include <ienginevgui.h>
#include <KeyValues.h>
#include "iclientmode.h"
#include <vgui/IScheme.h>
#include <vgui/ILocalize.h>
#include <vgui/ISurface.h>
#include <vgui/IVGui.h>
#include "clienteffectprecachesystem.h"
#include "tier0/icommandline.h"
#include "baseviewport.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// Basically this entire file was given to me by Tony Sergi from Project Valkyrie.
CLIENTEFFECT_REGISTER_BEGIN( PrecacheMainMenu )
CLIENTEFFECT_MATERIAL( "console/mainmenu" )
CLIENTEFFECT_REGISTER_END()
enum
{
MAINMENU_NONE, //start here
MAINMENU_STARTVIDEO, //start video
MAINMENU_STOPVIDEO, //stop video
};
CMainMenu::CMainMenu(vgui::Panel* parent, const char *pElementName ) : vgui::Panel( NULL, "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_VideoMaterial = NULL;
m_nPlaybackWidth = 0;
m_nPlaybackHeight = 0;
m_flActionThink = -1;
m_iAction = MAINMENU_NONE;
m_bToolsMode = false;
m_bLoaded = false;
m_MainMenuRef.Init( "console/mainmenu.vmt", TEXTURE_GROUP_OTHER );
}
CMainMenu::~CMainMenu()
{
ReleaseVideo();
MarkForDeletion();
}
bool CMainMenu::IsVideoPlaying()
{
return m_bPaintVideo;
}
void CMainMenu::StartVideo()
{
m_bToolsMode = (IsPC() && ( CommandLine()->CheckParm( "-tools" ) != NULL )) ? true : false;
SetVisible(true);
SetPaintEnabled(true);
SetNextThink( 0.1, MAINMENU_STARTVIDEO );
}
void CMainMenu::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 CMainMenu::OnThink()
{
SetPos(0,0);
SetSize(ScreenWidth(),ScreenHeight());
SetZPos(-1);
if ( m_flActionThink > 0 && m_flActionThink < gpGlobals->curtime )
{
if ( m_iAction == MAINMENU_STARTVIDEO )
{
bool isWide = false;
if ((ScreenWidth() / 4) != (ScreenHeight() / 3))
isWide = true;
m_bLoaded = false;
if (isWide)
{
//DevMsg("attempting to play widescreen video\n");
if (BeginPlayback( "media/mainmenu_wide.bik" ))
m_bLoaded = true;
else
{
if (BeginPlayback( "media/mainmenu.bik" ))
m_bLoaded = true;
}
}
else
{
if (BeginPlayback( "media/mainmenu.bik" ))
m_bLoaded = true;
}
}
else if ( m_iAction == MAINMENU_STOPVIDEO )
ReleaseVideo();
// reset our think
SetNextThink( -1, MAINMENU_NONE );
}
}
void CMainMenu::OnVideoOver()
{
SetNextThink( gpGlobals->curtime, MAINMENU_STARTVIDEO );
}
void CMainMenu::SetNextThink( float flActionThink, int iAction )
{
m_flActionThink = flActionThink;
m_iAction = iAction;
}
void CMainMenu::GetPanelPos( int &xpos, int &ypos )
{
vgui::ipanel()->GetAbsPos( GetVPanel(), xpos, ypos );
}
void CMainMenu::Paint( void )
{
if (m_bToolsMode)
return;
if (engine->IsConnected())
return;
if (!m_bLoaded)
return;
if (m_bPaintVideo)
{
// No video to play, so do nothing
if ( m_VideoMaterial == NULL )
return;
// Update our frame
if ( m_VideoMaterial->Update() == 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 CMainMenu::BeginPlayback( const char *pFilename )
{
// need working video services
if ( g_pVideo == NULL )
return false;
// Destroy any previously allocated video
if ( m_VideoMaterial != NULL )
{
g_pVideo->DestroyVideoMaterial( m_VideoMaterial );
m_VideoMaterial = NULL;
}
// Create new Video material
m_VideoMaterial = g_pVideo->CreateVideoMaterial( "VideoMaterial", pFilename, "GAME",
VideoPlaybackFlags::DEFAULT_MATERIAL_OPTIONS,
VideoSystem::DETERMINE_FROM_FILE_EXTENSION, m_bAllowAlternateMedia );
if ( m_VideoMaterial == NULL )
return false;
m_bPaintVideo = true;
int nWidth, nHeight;
m_VideoMaterial->GetVideoImageSize( &nWidth, &nHeight );
m_VideoMaterial->GetVideoTexCoordRange( &m_flU, &m_flV );
m_pMaterial = m_VideoMaterial->GetMaterial();
m_nPlaybackWidth = ScreenWidth();
m_nPlaybackHeight = ScreenHeight();
return true;
}
void CMainMenu::ReleaseVideo()
{
m_bPaintVideo = false;
//Tony; not touching the sound!!
// enginesound->NotifyEndMoviePlayback();
// Destroy any previously allocated video
// Shut down this video, destroy the video material
if ( g_pVideo != NULL && m_VideoMaterial != NULL )
{
g_pVideo->DestroyVideoMaterial( m_VideoMaterial );
m_VideoMaterial = NULL;
}
}
void CMainMenu::SetBlackBackground( bool bBlack )
{
m_bBlackBackground = bBlack;
}
void CMainMenu::DoModal( void )
{
vgui::surface()->RestrictPaintToSinglePanel( GetVPanel() );
}
//Tony; if we get disconnected, load the menu
void CMainMenu::OnDisconnectFromGame( void )
{
StartVideo();
}
CON_COMMAND( __disconnect, "Disconnect game from server." )
{
SDKViewport *pViewPort = dynamic_cast<SDKViewport*>(g_pClientMode->GetViewport());
if (pViewPort)
pViewPort->StartMainMenuVideo();
engine->ClientCmd_Unrestricted("__real_disconnect");
}
//Tony; find the disconnect command, and rename it..
void SwapDisconnectCommand()
{
// DevMsg("SwapDisconnectCommand\n");
ConCommand *_realDisconnectCommand = dynamic_cast< ConCommand* >( g_pCVar->FindCommand( "disconnect" ) );
ConCommand *_DisconnectCommand = dynamic_cast< ConCommand* >( g_pCVar->FindCommand( "__disconnect" ) );
if (!_realDisconnectCommand)
return;
if (!_DisconnectCommand)
return;
_realDisconnectCommand->Shutdown();
_realDisconnectCommand->Create("__real_disconnect", "" );
_realDisconnectCommand->Init();
_DisconnectCommand->Shutdown();
_DisconnectCommand->Create("disconnect", "Disconnect game from server." );
_DisconnectCommand->Init();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.