diff options
Diffstat (limited to 'gameui/matchmaking/sessionbrowserdialog.cpp')
| -rw-r--r-- | gameui/matchmaking/sessionbrowserdialog.cpp | 323 |
1 files changed, 323 insertions, 0 deletions
diff --git a/gameui/matchmaking/sessionbrowserdialog.cpp b/gameui/matchmaking/sessionbrowserdialog.cpp new file mode 100644 index 0000000..f29b177 --- /dev/null +++ b/gameui/matchmaking/sessionbrowserdialog.cpp @@ -0,0 +1,323 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Present a list of sessions from which the player can choose a game to join. +// +//=============================================================================// + +#include "sessionbrowserdialog.h" +#include "engine/imatchmaking.h" +#include "EngineInterface.h" +#include "vgui_controls/ImagePanel.h" +#include "vgui_controls/Label.h" +#include "KeyValues.h" +#include "vgui/ISurface.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +CSessionBrowserDialog *g_pBrowserDialog; + +//-------------------------------- +// CSessionBrowserDialog +//-------------------------------- +CSessionBrowserDialog::CSessionBrowserDialog( vgui::Panel *pParent, KeyValues *pDialogKeys ) : BaseClass( pParent, "" ) +{ + g_pBrowserDialog = this; + m_pDialogKeys = pDialogKeys; + + SetDeleteSelfOnClose( true ); +} + +CSessionBrowserDialog::~CSessionBrowserDialog() +{ + m_pScenarioInfos.PurgeAndDeleteElements(); +} + +//--------------------------------------------------------------------- +// Purpose: Center the dialog on the screen +//--------------------------------------------------------------------- +void CSessionBrowserDialog::PerformLayout() +{ + BaseClass::PerformLayout(); + + MoveToCenterOfScreen(); + UpdateScenarioDisplay(); +} + +//--------------------------------------------------------------------- +// Purpose: Parse session properties and contexts from the resource file +//--------------------------------------------------------------------- +void CSessionBrowserDialog::ApplySettings( KeyValues *pResourceData ) +{ + BaseClass::ApplySettings( pResourceData ); + + KeyValues *pScenarios = pResourceData->FindKey( "ScenarioInfoPanels" ); + if ( pScenarios ) + { + for ( KeyValues *pScenario = pScenarios->GetFirstSubKey(); pScenario != NULL; pScenario = pScenario->GetNextKey() ) + { + CScenarioInfoPanel *pScenarioInfo = new CScenarioInfoPanel( this, "ScenarioInfoPanel" ); + SETUP_PANEL( pScenarioInfo ); + pScenarioInfo->m_pTitle->SetText( pScenario->GetString( "title" ) ); + pScenarioInfo->m_pSubtitle->SetText( pScenario->GetString( "subtitle" ) ); + pScenarioInfo->m_pMapImage->SetImage( pScenario->GetString( "image" ) ); + + int nTall = pScenario->GetInt( "tall", -1 ); + if ( nTall > 0 ) + { + pScenarioInfo->SetTall( nTall ); + } + + int nXPos = pScenario->GetInt( "xpos", -1 ); + if ( nXPos >= 0 ) + { + int x, y; + pScenarioInfo->GetPos( x, y ); + pScenarioInfo->SetPos( nXPos, y ); + } + + int nDescOneYpos = pScenario->GetInt( "descOneY", -1 ); + if ( nDescOneYpos > 0 ) + { + int x, y; + pScenarioInfo->m_pDescOne->GetPos( x, y ); + pScenarioInfo->m_pDescOne->SetPos( x, nDescOneYpos ); + } + + int nDescTwoYpos = pScenario->GetInt( "descTwoY", -1 ); + if ( nDescTwoYpos > 0 ) + { + int x, y; + pScenarioInfo->m_pDescTwo->GetPos( x, y ); + pScenarioInfo->m_pDescTwo->SetPos( x, nDescTwoYpos ); + } + + m_pScenarioInfos.AddToTail( pScenarioInfo ); + } + } +} + +//--------------------------------------------------------------------- +// Purpose: Set up colors and other such stuff +//--------------------------------------------------------------------- +void CSessionBrowserDialog::ApplySchemeSettings( vgui::IScheme *pScheme ) +{ + BaseClass::ApplySchemeSettings( pScheme ); + + for ( int i = 0; i < m_pScenarioInfos.Count(); ++i ) + { + m_pScenarioInfos[i]->SetBgColor( pScheme->GetColor( "TanDark", Color( 0, 0, 0, 255 ) ) ); + } +} + +//--------------------------------------------------------------------- +// Purpose: Info about a session, sent from matchmaking +//--------------------------------------------------------------------- +void CSessionBrowserDialog::SessionSearchResult( int searchIdx, void *pHostData, XSESSION_SEARCHRESULT *pResult, int ping ) +{ + char *pPing; + switch ( ping ) + { + case 0: + pPing = "#TF_Icon_Ping_Green"; + break; + case 1: + pPing = "#TF_Icon_Ping_Yellow"; + break; + case 2: + default: + pPing = "#TF_Icon_Ping_Red"; + break; + } + + int nScenarioId = 0; + uint nContextId = m_pDialogKeys->GetInt( "scenario", -1 ); + for ( uint i = 0; i < pResult->cContexts; ++i ) + { + if ( pResult->pContexts[i].dwContextId == nContextId ) + { + nScenarioId = pResult->pContexts[i].dwValue; + break; + } + } + + hostData_s *pData = (hostData_s*)pHostData; + + int filledSlots = pResult->dwFilledPublicSlots + pResult->dwFilledPrivateSlots; + int totalSlots = filledSlots + pResult->dwOpenPublicSlots + pResult->dwOpenPrivateSlots; + + m_GameStates.AddToTail( pData->gameState ); + m_GameTimes.AddToTail( pData->gameTime ); + m_XUIDs.AddToTail( pData->xuid ); + + char szSlots[16] = {0}; + Q_snprintf( szSlots, sizeof( szSlots ), "%d/%d", filledSlots, totalSlots ); + + int ct = 0; + const char *ppStrings[4]; + ppStrings[ct++] = pData->hostName; + ppStrings[ct++] = szSlots; + ppStrings[ct++] = pData->scenario; + if ( ping != -1 ) + { + ppStrings[ct++] = pPing; + } + m_Menu.AddSectionedItem( ppStrings, ct ); + + m_ScenarioIndices.AddToTail( nScenarioId ); + m_SearchIndices.AddToTail( searchIdx ); + + if ( m_Menu.GetItemCount() == 1 ) + { + m_Menu.SetFocus( 0 ); + } + + UpdateScenarioDisplay(); +} + +//----------------------------------------------------------------- +// Purpose: Show the correct scenario image and text +//----------------------------------------------------------------- +void CSessionBrowserDialog::UpdateScenarioDisplay( void ) +{ + if ( !m_ScenarioIndices.Count() ) + return; + + // Check if the selected map has changed (first menu item) + int idx = m_Menu.GetActiveItemIndex(); + for ( int i = 0; i < m_pScenarioInfos.Count(); ++i ) + { + m_pScenarioInfos[i]->SetVisible( i == m_ScenarioIndices[idx] ); + } + + // Get the screen size + int wide, tall; + vgui::surface()->GetScreenSize(wide, tall); + bool bLodef = ( tall <= 480 ); + + const char *pState = ""; + switch( m_GameStates[idx] ) + { + case 0: + if ( bLodef ) + { + pState = "#TF_GameState_InLobby_lodef"; + } + else + { + pState = "#TF_GameState_InLobby"; + } + break; + + case 1: + if ( bLodef ) + { + pState = "#TF_GameState_GameInProgress_lodef"; + } + else + { + pState = "#TF_GameState_GameInProgress"; + } + break; + } + + char szTime[32] = {0}; + if ( m_GameTimes[idx] >= NO_TIME_LIMIT ) + { + Q_strncpy( szTime, "#TF_NoTimeLimit", sizeof( szTime) ); + } + else + { + Q_snprintf( szTime, sizeof( szTime), "%d:00", m_GameTimes[idx] ); + } + + if ( !m_pScenarioInfos.IsValidIndex( m_ScenarioIndices[idx] ) ) + return; + + CScenarioInfoPanel *pPanel = m_pScenarioInfos[ m_ScenarioIndices[idx] ]; + pPanel->m_pDescOne->SetText( pState ); + pPanel->m_pDescTwo->SetText( szTime ); +} + + +//----------------------------------------------------------------- +// helper to swap two ints in a utlvector +//----------------------------------------------------------------- +static void Swap( CUtlVector< int > &vec, int iOne, int iTwo ) +{ + int temp = vec[iOne]; + vec[iOne] = vec[iTwo]; + vec[iTwo] = temp; +} + +//----------------------------------------------------------------- +// Purpose: Swap the order of two menu items +//----------------------------------------------------------------- +void CSessionBrowserDialog::SwapMenuItems( int iOne, int iTwo ) +{ + Swap( m_ScenarioIndices, iOne, iTwo ); + Swap( m_SearchIndices, iOne, iTwo ); + Swap( m_GameStates, iOne, iTwo ); + Swap( m_GameTimes, iOne, iTwo ); + + // swap the XUIDs, too + XUID temp = m_XUIDs[iOne]; + m_XUIDs[iOne] = m_XUIDs[iTwo]; + m_XUIDs[iTwo] = temp; +} + +//----------------------------------------------------------------- +// Purpose: Handle commands from the dialog menu +//----------------------------------------------------------------- +void CSessionBrowserDialog::OnCommand( const char *pCommand ) +{ + if ( !Q_stricmp( pCommand, "SelectSession" ) ) + { + int idx = m_SearchIndices[ m_Menu.GetActiveItemIndex() ]; + matchmaking->SelectSession( idx ); + } + + m_pParent->OnCommand( pCommand ); +} + +//----------------------------------------------------------------- +// Purpose: Send key presses to the dialog's menu +//----------------------------------------------------------------- +void CSessionBrowserDialog::OnKeyCodePressed( vgui::KeyCode code ) +{ + switch( code ) + { + case KEY_XBUTTON_B: + matchmaking->KickPlayerFromSession( 0 ); + break; + case KEY_XBUTTON_X: +#ifdef _X360 + int idx = m_Menu.GetActiveItemIndex(); + if ( m_XUIDs.IsValidIndex( idx ) ) + { + XShowGamerCardUI( XBX_GetPrimaryUserId(), m_XUIDs[idx] ); + } +#endif + break; + } + + BaseClass::OnKeyCodePressed( code ); + + // Selected session may have been updated + UpdateScenarioDisplay(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSessionBrowserDialog::OnThink() +{ + vgui::KeyCode code = m_KeyRepeat.KeyRepeated(); + if ( code ) + { + m_Menu.HandleKeyCode( code ); + UpdateScenarioDisplay(); + } + + BaseClass::OnThink(); +} |