This commit is contained in:
nephacks
2025-06-04 03:22:50 +02:00
parent f234f23848
commit f12416cffd
14243 changed files with 6446499 additions and 26 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,129 @@
//========= Copyright <20> 1996-2008, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=====================================================================================//
#ifndef _BASEMODFACTORYBASEPANEL_H__
#define _BASEMODFACTORYBASEPANEL_H__
#include "vgui_controls/Panel.h"
#include "vgui_controls/Frame.h"
#include "vgui_controls/Button.h"
#include "tier1/utllinkedlist.h"
#include "avi/ibik.h"
#include "ixboxsystem.h"
#include "matchmaking/imatchframework.h"
namespace BaseModUI
{
//=============================================================================
//
//=============================================================================
class CBaseModPanel : public vgui::EditablePanel, public IMatchEventsSink
{
DECLARE_CLASS_SIMPLE( CBaseModPanel, vgui::EditablePanel );
public:
CBaseModPanel();
~CBaseModPanel();
// IMatchEventSink implementation
public:
virtual void OnEvent( KeyValues *pEvent );
public:
static CBaseModPanel& GetSingleton();
static CBaseModPanel* GetSingletonPtr();
void ReloadScheme();
bool IsLevelLoading();
void OnGameUIActivated();
void OnGameUIHidden();
void OpenFrontScreen();
void RunFrame();
void OnLevelLoadingStarted( char const *levelName, bool bShowProgressDialog );
void OnLevelLoadingFinished( KeyValues *kvEvent );
bool UpdateProgressBar(float progress, const char *statusText);
void OnCreditsFinished(void);
bool IsReadyToWriteConfig( void );
void StartExitingProcess( bool bWarmRestart );
void SetLastActiveUserId( int userId );
int GetLastActiveUserId();
bool IsMenuBackgroundMovieValid( void );
bool IsBackgroundMusicPlaying();
bool StartBackgroundMusic( float fVol );
void UpdateBackgroundMusicVolume( float fVol );
void ReleaseBackgroundMusic();
void SafeNavigateTo( Panel *pExpectedFrom, Panel *pDesiredTo, bool bAllowStealFocus );
#if defined( _GAMECONSOLE ) && defined( _DEMO )
void OnDemoTimeout();
#endif
protected:
CBaseModPanel(const CBaseModPanel&);
CBaseModPanel& operator=(const CBaseModPanel&);
void ApplySchemeSettings(vgui::IScheme *pScheme);
void PaintBackground();
void OnCommand(const char *command);
void OnSetFocus();
virtual bool RequestInfo( KeyValues *data );
MESSAGE_FUNC( OnMovedPopupToFront, "OnMovedPopupToFront" );
private:
void DrawColoredText( vgui::HFont hFont, int x, int y, unsigned int color, const char *pAnsiText );
void DrawCopyStats();
void OnEngineLevelLoadingSession( KeyValues *pEvent );
bool ActivateBackgroundEffects();
// Background movie playback
bool InitBackgroundMovie( void );
void CalculateMovieParameters( void );
bool RenderBackgroundMovie( float *pflFadeDelta ); // Render and update our BIK movie in the background
void ShutdownBackgroundMovie( void );
BIKMaterial_t m_BIKHandle;
IMaterial *m_pMovieMaterial;
float m_flU0, m_flV0, m_flU1, m_flV1;
float m_flMovieFadeInTime; // Time to be fully faded in
bool m_bMovieFailed;
static CBaseModPanel* m_CFactoryBasePanel;
bool m_LevelLoading;
vgui::HScheme m_UIScheme;
int m_lastActiveUserId;
vgui::HFont m_hDefaultFont;
int m_iBackgroundImageID;
int m_iFadeToBackgroundImageID;
int m_iMovieTransitionImage;
int m_DelayActivation;
int m_ExitingFrameCount;
bool m_bWarmRestartMode;
bool m_bClosingAllWindows;
float m_flBlurScale;
float m_flLastBlurTime;
CUtlString m_backgroundMusic;
int m_nBackgroundMusicGUID;
bool m_bFadeMusicUp;
};
};
#endif

View File

@ -0,0 +1,27 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Includes all the headers/declarations necessary to access the
// engine interface
//
// $NoKeywords: $
//=============================================================================//
#ifndef ENGINEINTERFACE_H
#define ENGINEINTERFACE_H
#ifdef _WIN32
#pragma once
#endif
// engine interface
#include "steam/steam_api.h"
#include "cdll_client_int.h"
#include "tier2/tier2.h"
#include "matchmaking/imatchframework.h"
extern class IEngineVGui *enginevguifuncs;
#ifdef _GAMECONSOLE
extern class IXOnline *xonline;
#endif
#endif // ENGINEINTERFACE_H

View File

@ -0,0 +1,147 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "GameConsole.h"
#include "GameConsoleDialog.h"
#include "vgui/ISurface.h"
#include "KeyValues.h"
#include "vgui/VGUI.h"
#include "vgui/IVGUI.h"
#include "vgui_controls/Panel.h"
#include "convar.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
static CGameConsole g_GameConsole;
//-----------------------------------------------------------------------------
// Purpose: singleton accessor
//-----------------------------------------------------------------------------
CGameConsole &GameConsole()
{
return g_GameConsole;
}
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CGameConsole, IGameConsole, GAMECONSOLE_INTERFACE_VERSION, g_GameConsole);
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CGameConsole::CGameConsole()
{
m_bInitialized = false;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CGameConsole::~CGameConsole()
{
m_bInitialized = false;
}
//-----------------------------------------------------------------------------
// Purpose: sets up the console for use
//-----------------------------------------------------------------------------
void CGameConsole::Initialize()
{
m_pConsole = vgui::SETUP_PANEL( new CGameConsoleDialog() ); // we add text before displaying this so set it up now!
// set the console to taking up most of the right-half of the screen
int swide, stall;
vgui::surface()->GetScreenSize(swide, stall);
int offset = vgui::scheme()->GetProportionalScaledValue(16);
m_pConsole->SetBounds(
swide / 2 - (offset * 4),
offset,
(swide / 2) + (offset * 3),
stall - (offset * 8));
m_bInitialized = true;
}
//-----------------------------------------------------------------------------
// Purpose: activates the console, makes it visible and brings it to the foreground
//-----------------------------------------------------------------------------
void CGameConsole::Activate()
{
if (!m_bInitialized)
return;
vgui::surface()->RestrictPaintToSinglePanel(NULL);
m_pConsole->Activate();
}
//-----------------------------------------------------------------------------
// Purpose: hides the console
//-----------------------------------------------------------------------------
void CGameConsole::Hide()
{
if (!m_bInitialized)
return;
m_pConsole->Hide();
}
//-----------------------------------------------------------------------------
// Purpose: clears the console
//-----------------------------------------------------------------------------
void CGameConsole::Clear()
{
if (!m_bInitialized)
return;
m_pConsole->Clear();
}
//-----------------------------------------------------------------------------
// Purpose: returns true if the console is currently in focus
//-----------------------------------------------------------------------------
bool CGameConsole::IsConsoleVisible()
{
if (!m_bInitialized)
return false;
return m_pConsole->IsVisible();
}
//-----------------------------------------------------------------------------
// Purpose: activates the console after a delay
//-----------------------------------------------------------------------------
void CGameConsole::ActivateDelayed(float time)
{
if (!m_bInitialized)
return;
m_pConsole->PostMessage(m_pConsole, new KeyValues("Activate"), time);
}
void CGameConsole::SetParent( int parent )
{
if (!m_bInitialized)
return;
m_pConsole->SetParent( static_cast<vgui::VPANEL>( parent ));
}
//-----------------------------------------------------------------------------
// Purpose: static command handler
//-----------------------------------------------------------------------------
void CGameConsole::OnCmdCondump()
{
g_GameConsole.m_pConsole->DumpConsoleTextToFile();
}
CON_COMMAND( condump, "dump the text currently in the console to condumpXX.log" )
{
g_GameConsole.OnCmdCondump();
}

View File

@ -0,0 +1,54 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef GAMECONSOLE_H
#define GAMECONSOLE_H
#ifdef _WIN32
#pragma once
#endif
#include "GameUI/IGameConsole.h"
class CGameConsoleDialog;
//-----------------------------------------------------------------------------
// Purpose: VGui implementation of the game/dev console
//-----------------------------------------------------------------------------
class CGameConsole : public IGameConsole
{
public:
CGameConsole();
~CGameConsole();
// sets up the console for use
void Initialize();
// activates the console, makes it visible and brings it to the foreground
virtual void Activate();
// hides the console
virtual void Hide();
// clears the console
virtual void Clear();
// returns true if the console is currently in focus
virtual bool IsConsoleVisible();
// activates the console after a delay
void ActivateDelayed(float time);
void SetParent( int parent );
static void OnCmdCondump();
private:
bool m_bInitialized;
CGameConsoleDialog *m_pConsole;
};
extern CGameConsole &GameConsole();
#endif // GAMECONSOLE_H

View File

@ -0,0 +1,106 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#include "cbase.h"
#include "GameConsoleDialog.h"
#include "GameUI_Interface.h"
#include "vgui/iinput.h"
#include "vgui/isurface.h"
#include "vgui/keycode.h"
#ifdef GAMEUI_LEGACY_SUPPORT_LOADING_DIALOG
#include "LoadingDialog.h"
#endif
#include "igameuifuncs.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CGameConsoleDialog::CGameConsoleDialog() : BaseClass( NULL, "GameConsole", false )
{
AddActionSignalTarget( this );
}
//-----------------------------------------------------------------------------
// Purpose: generic vgui command handler
//-----------------------------------------------------------------------------
void CGameConsoleDialog::OnCommand(const char *command)
{
if ( !Q_stricmp( command, "Close" ) )
{
if ( GameUI().IsInBackgroundLevel() )
{
// Tell the engine we've hid the console, so that it unpauses the game
// even though we're still sitting at the menu.
engine->ClientCmd_Unrestricted( "unpause" );
}
}
BaseClass::OnCommand(command);
}
//-----------------------------------------------------------------------------
// HACK: Allow F key bindings to operate even when typing in the text entry field
//-----------------------------------------------------------------------------
void CGameConsoleDialog::OnKeyCodeTyped(KeyCode code)
{
BaseClass::OnKeyCodeTyped(code);
// check for processing
if ( m_pConsolePanel->TextEntryHasFocus() )
{
// HACK: Allow F key bindings to operate even here
if ( code >= KEY_F1 && code <= KEY_F12 )
{
// See if there is a binding for the FKey
const char *binding = gameuifuncs->GetBindingForButtonCode( code );
if ( binding && binding[0] )
{
// submit the entry as a console commmand
char szCommand[256];
Q_strncpy( szCommand, binding, sizeof( szCommand ) );
engine->ClientCmd_Unrestricted( szCommand, true );
}
}
}
}
//-----------------------------------------------------------------------------
// Submits a command
//-----------------------------------------------------------------------------
void CGameConsoleDialog::OnCommandSubmitted( const char *pCommand )
{
engine->ClientCmd_Unrestricted( pCommand, true );
}
//-----------------------------------------------------------------------------
// Submits a command
//-----------------------------------------------------------------------------
void CGameConsoleDialog::OnClosedByHittingTilde()
{
#ifdef GAMEUI_LEGACY_SUPPORT_LOADING_DIALOG
if ( !LoadingDialog() )
{
GameUI().HideGameUI();
}
else
{
vgui::surface()->RestrictPaintToSinglePanel( LoadingDialog()->GetVPanel() );
}
#else
GameUI().HideGameUI();
#endif
}

View File

@ -0,0 +1,40 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#ifndef GAMECONSOLEDIALOG_H
#define GAMECONSOLEDIALOG_H
#ifdef _WIN32
#pragma once
#endif
#include "vgui_controls/consoledialog.h"
#include <Color.h>
#include "UtlVector.h"
#include "EngineInterface.h"
#include "vgui_controls/Frame.h"
//-----------------------------------------------------------------------------
// Purpose: Game/dev console dialog
//-----------------------------------------------------------------------------
class CGameConsoleDialog : public vgui::CConsoleDialog
{
DECLARE_CLASS_SIMPLE( CGameConsoleDialog, vgui::CConsoleDialog );
public:
CGameConsoleDialog();
private:
MESSAGE_FUNC( OnClosedByHittingTilde, "ClosedByHittingTilde" );
MESSAGE_FUNC_CHARPTR( OnCommandSubmitted, "CommandSubmitted", command );
virtual void OnKeyCodeTyped( vgui::KeyCode code );
virtual void OnCommand( const char *command );
};
#endif // GAMECONSOLEDIALOG_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,137 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Defines the interface that the GameUI dll exports
//
// $NoKeywords: $
//=============================================================================//
#ifndef GAMEUI_INTERFACE_H
#define GAMEUI_INTERFACE_H
#pragma once
#include "GameUI/IGameUI.h"
#include "vgui_controls/Panel.h"
#include "vgui_controls/PHandle.h"
#include "convar.h"
#if defined ( CSTRIKE15 )
#error "DEPRICIATED: Use the gameui_interface in the cstrike15 folder"
#endif
class IGameClientExports;
class CCommand;
int GetGameUIActiveSplitScreenPlayerSlot();
void SetGameUIActiveSplitScreenPlayerSlot( int nSlot );
//-----------------------------------------------------------------------------
// Purpose: Implementation of GameUI's exposed interface
//-----------------------------------------------------------------------------
class CGameUI : public IGameUI
{
public:
CGameUI();
~CGameUI();
virtual void Initialize( CreateInterfaceFn appFactory );
virtual void Connect( CreateInterfaceFn gameFactory );
virtual void Start();
virtual void Shutdown();
virtual void RunFrame();
virtual void PostInit();
// plays the startup mp3 when GameUI starts
void PlayGameStartupSound();
// Engine wrappers for activating / hiding the gameUI
void ActivateGameUI();
void HideGameUI();
// Toggle allowing the engine to hide the game UI with the escape key
void PreventEngineHideGameUI();
void AllowEngineHideGameUI();
virtual void SetLoadingBackgroundDialog( vgui::VPANEL panel );
// notifications
virtual void OnGameUIActivated();
virtual void OnGameUIHidden();
virtual void OLD_OnConnectToServer( const char *game, int IP, int port ); // OLD: use OnConnectToServer2
virtual void OnConnectToServer2( const char *game, int IP, int connectionPort, int queryPort );
virtual void OnDisconnectFromServer( uint8 eSteamLoginFailure );
virtual void OnLevelLoadingStarted( const char *levelName, bool bShowProgressDialog );
virtual void OnLevelLoadingFinished( bool bError, const char *failureReason, const char *extendedReason );
virtual void OnDisconnectFromServer_OLD( uint8 eSteamLoginFailure, const char *username ) { OnDisconnectFromServer( eSteamLoginFailure ); }
// progress
virtual bool UpdateProgressBar(float progress, const char *statusText);
// Shows progress desc, returns previous setting... (used with custom progress bars )
virtual bool SetShowProgressText( bool show );
// Allows the level loading progress to show map-specific info
virtual void SetProgressLevelName( const char *levelName );
virtual void NeedConnectionProblemWaitScreen();
virtual void ShowPasswordUI( char const *pchCurrentPW );
virtual void SetProgressOnStart();
#if defined( _GAMECONSOLE ) && defined( _DEMO )
virtual void OnDemoTimeout();
#endif
// state
bool IsInLevel();
bool IsInBackgroundLevel();
bool IsInMultiplayer();
bool HasSavedThisMenuSession();
void SetSavedThisMenuSession( bool bState );
void ShowLoadingBackgroundDialog();
void HideLoadingBackgroundDialog();
bool HasLoadingBackgroundDialog();
private:
void SendConnectedToGameMessage();
virtual void StartProgressBar();
virtual bool ContinueProgressBar(float progressFraction);
virtual void StopProgressBar(bool bError, const char *failureReason, const char *extendedReason = NULL);
virtual bool SetProgressBarStatusText(const char *statusText);
//!! these functions currently not implemented
virtual void SetSecondaryProgressBar(float progress /* range [0..1] */);
virtual void SetSecondaryProgressBarText(const char *statusText);
bool FindPlatformDirectory(char *platformDir, int bufferSize);
void GetUpdateVersion( char *pszProd, char *pszVer);
void ValidateCDKey();
CreateInterfaceFn m_GameFactory;
bool m_bTryingToLoadFriends : 1;
bool m_bActivatedUI : 1;
bool m_bHasSavedThisMenuSession : 1;
bool m_bOpenProgressOnStart : 1;
int m_iGameIP;
int m_iGameConnectionPort;
int m_iGameQueryPort;
int m_iFriendsLoadPauseFrames;
int m_iPlayGameStartupSound;
char m_szPreviousStatusText[128];
char m_szPlatformDir[MAX_PATH];
vgui::DHANDLE<class CCDKeyEntryDialog> m_hCDKeyEntryDialog;
};
// Purpose: singleton accessor
extern CGameUI &GameUI();
// expose client interface
extern IGameClientExports *GameClientExports();
#endif // GAMEUI_INTERFACE_H

View File

@ -0,0 +1,72 @@
//=========== (C) Copyright Valve, L.L.C. All rights reserved. ===========
#include "cbase.h"
#include "ui_nugget.h"
#include "vstdlib/iprocessutils.h"
#include "../uigamedata.h"
class CUiNuggetApplication : public CUiNuggetBase
{
DECLARE_NUGGET_FN_MAP( CUiNuggetApplication, CUiNuggetBase );
NUGGET_FN( Quit )
{
// We need to quit the app
if ( IsPC() )
{
engine->ClientCmd( "quit" );
}
// X360 can quit in demo mode
if ( IsGameConsole() )
{
engine->ExecuteClientCmd( "demo_exit" );
}
return NULL;
}
NUGGET_FN( ResumeGame )
{
engine->ClientCmd("gameui_hide");
return NULL;
}
NUGGET_FN( ExitToMainMenu )
{
engine->ExecuteClientCmd( "gameui_hide" );
if ( IMatchSession *pMatchSession = g_pMatchFramework->GetMatchSession() )
{
// Closing an active session results in disconnecting from the game.
g_pMatchFramework->CloseSession();
}
else
{
// On PC people can be playing via console bypassing matchmaking
// and required session settings, so to leave game duplicate
// session closure with an extra "disconnect" command.
engine->ExecuteClientCmd( "disconnect" );
}
engine->ExecuteClientCmd( "gameui_activate" );
return NULL;
}
NUGGET_FN( SteamOverlayCommand )
{
#ifndef _GAMECONSOLE
BaseModUI::CUIGameData::Get()->ExecuteOverlayCommand( args->GetString( "command" ) );
#endif
return NULL;
}
NUGGET_FN( LaunchExternalApp )
{
int nExitCode = g_pProcessUtils ? g_pProcessUtils->SimpleRunProcess( args->GetString( "command" ) ) : -1;
return new KeyValues( "", "code", nExitCode );
}
};
UI_NUGGET_FACTORY_SINGLETON( CUiNuggetApplication, "app" );

View File

@ -0,0 +1,31 @@
//=========== (C) Copyright Valve, L.L.C. All rights reserved. ===========
#include "cbase.h"
#include "ui_nugget.h"
class CUiNuggetLoadingProgress : public CUiNuggetBase
{
public:
CUiNuggetLoadingProgress()
{
m_pUiNuggetData->SetString( "map", "" );
m_pUiNuggetData->SetFloat( "progress", 0.0f );
}
DECLARE_NUGGET_FN_MAP( CUiNuggetLoadingProgress, CUiNuggetBase );
NUGGET_BROADCAST_FN( OnLevelLoadingProgress )
{
m_pUiNuggetData->MergeFrom( args, KeyValues::MERGE_KV_BORROW );
return true;
}
virtual bool ShouldDeleteOnLastScreenDisconnect()
{
// bad to try to delete a static.
return false;
}
};
static CUiNuggetLoadingProgress g_nugget_loadingprogress;
UI_NUGGET_FACTORY_GLOBAL_INSTANCE( CUiNuggetLoadingProgress, &g_nugget_loadingprogress, "loadingprogress" );

View File

@ -0,0 +1,63 @@
//=========== (C) Copyright Valve, L.L.C. All rights reserved. ===========
#include "cbase.h"
#include "ui_nugget.h"
#include "matchmaking/imatchframework.h"
class CUiNuggetMatchEvents : public CUiNuggetBase, IMatchEventsSink
{
DECLARE_NUGGET_FN_MAP( CUiNuggetMatchEvents, CUiNuggetBase );
virtual void OnEvent( KeyValues *pEvent )
{
BroadcastEventToScreens( pEvent );
return;
#if SCRIPTS_NEED_EVENT_NAMES_WITH_BASIC_CHARSET
// In case scripts cannot define function names
// associations with any characters, then we'll
// need to do some work to make event names conform
// with those scripts.
//
// In lua we can easily do any member function names:
/*
mainmenu["Command::Game::SampleCmd"] = function(self, params)
print( "Command::Game::SampleCmd" )
print( self.extraPieceOfData )
end
*/
//
// Fix the event name for scripting:
char chEventName[256] = {0}, *pch = chEventName;
Q_snprintf( chEventName, ARRAYSIZE( chEventName ), "%s", pEvent->GetName() );
for ( ; *pch; ++ pch )
{
bool bValidChar = (
( *pch >= 'a' && *pch <= 'z' ) ||
( *pch >= 'A' && *pch <= 'Z' ) ||
( *pch >= '0' && *pch <= '9' )
);
if ( !bValidChar )
*pch = '_';
}
// New event for scripting
KeyValues *pEventCopy = pEvent->MakeCopy();
KeyValues::AutoDelete autodelete_pEventCopy( pEventCopy );
pEventCopy->SetName( chEventName );
BroadcastEventToScreens( pEventCopy );
#endif
}
public:
CUiNuggetMatchEvents()
{
g_pMatchFramework->GetEventsSubscription()->Subscribe( this );
}
~CUiNuggetMatchEvents()
{
g_pMatchFramework->GetEventsSubscription()->Unsubscribe( this );
}
};
UI_NUGGET_FACTORY_SINGLETON( CUiNuggetMatchEvents, "matchevents" );

View File

@ -0,0 +1,275 @@
//=========== (C) Copyright Valve, L.L.C. All rights reserved. ===========
#include "cbase.h"
#include "ui_nugget.h"
#include "vstdlib/ikeyvaluessystem.h"
//////////////////////////////////////////////////////////////////////////
//
// CUiNuggetReference implementation
//
class CUiNuggetReference
{
public:
virtual void OnNuggetReleased( CUiNuggetBase *pNugget ) = 0;
};
//////////////////////////////////////////////////////////////////////////
//
// CUiNuggetBase implementation
//
CUiNuggetBase::CUiNuggetBase() :
m_pUiNuggetData( new KeyValues( "" ) ),
m_autodelete_m_pUiNuggetData( m_pUiNuggetData )
{
}
CUiNuggetBase::~CUiNuggetBase()
{
while ( m_arrReferences.Count() )
{
CUiNuggetReference *pSink = m_arrReferences.Head();
m_arrReferences.RemoveMultipleFromHead( 1 );
pSink->OnNuggetReleased( this );
}
}
int CUiNuggetBase::OnScreenConnected( IGameUISystem *pScreenView )
{
ConnectionInfo_t ci( pScreenView );
int idx = m_arrConnectedScreens.Find( ci );
if ( idx != m_arrConnectedScreens.InvalidIndex() )
{
++ m_arrConnectedScreens[idx].m_nRefCount;
}
else
{
ci.m_nRefCount = 1;
m_arrConnectedScreens.AddToTail( ci );
}
return m_arrConnectedScreens.Count();
}
int CUiNuggetBase::OnScreenDisconnected( IGameUISystem *pScreenView )
{
ConnectionInfo_t ci( pScreenView );
int idx = m_arrConnectedScreens.Find( ci );
if ( idx != m_arrConnectedScreens.InvalidIndex() )
{
if ( -- m_arrConnectedScreens[idx].m_nRefCount )
return m_arrConnectedScreens.Count();
// Otherwise this screen must be released
m_arrConnectedScreens.Remove( idx );
// Assert that screen is not disconnecting in the middle of
// event broadcast (otherwise need to implement index adjustment
// so that broadcast could succeed)
Assert( !m_arrBroadcastEventIdxArray.Count() );
// Check if we need to delete us
int numRemaining = m_arrConnectedScreens.Count();
if ( !numRemaining && ShouldDeleteOnLastScreenDisconnect() )
{
delete this;
}
return numRemaining;
}
else
{
Warning( "CUiNuggetBase::OnScreenDisconnected %p for not connected screen!\n", pScreenView );
Assert( !"OnScreenDisconnected" );
return m_arrConnectedScreens.Count();
}
}
KeyValues * CUiNuggetBase::OnScreenEvent( IGameUISystem *pScreenView, KeyValues *kvEvent )
{
int nEvent = kvEvent->GetNameSymbol();
static int const s_nGetData = KeyValuesSystem()->GetSymbolForString( "GetData" );
if ( nEvent == s_nGetData )
{
return m_pUiNuggetData->MakeCopy();
}
static int const s_nEnableEvents = KeyValuesSystem()->GetSymbolForString( "EnableEvents" );
if ( nEvent == s_nEnableEvents )
{
int nScriptHandle = kvEvent->GetInt( "scripthandle" );
bool bEnabled = kvEvent->GetBool( "enable", true );
m_arrEventsDisabledScreenHandles.FindAndFastRemove( nScriptHandle );
if ( !bEnabled )
m_arrEventsDisabledScreenHandles.AddToTail( nScriptHandle );
return NULL;
}
DevWarning( "CUiNuggetBase(%p)::OnScreenEvent for unknown command %s!\n", this, kvEvent->GetName() );
return NULL;
}
void CUiNuggetBase::BroadcastEventToScreens( KeyValues *kvEvent )
{
int idx = 0;
m_arrBroadcastEventIdxArray.AddToTail( &idx );
for ( ; idx < m_arrConnectedScreens.Count(); ++ idx )
{
IGameUISystem *pUI = m_arrConnectedScreens[idx].m_pScreen;
int iScriptHandle = pUI->GetScriptHandle();
if ( m_arrEventsDisabledScreenHandles.Find( iScriptHandle ) != m_arrEventsDisabledScreenHandles.InvalidIndex() )
continue;
pUI->ExecuteScript( kvEvent );
}
m_arrBroadcastEventIdxArray.RemoveMultipleFromTail( 1 );
}
//////////////////////////////////////////////////////////////////////////
//
// CUiNuggetFactoryRegistrarBase implementation
//
static CUiNuggetFactoryRegistrarBase *g_pUiNuggetFactoriesCircularList = NULL;
CUiNuggetFactoryRegistrarBase::CUiNuggetFactoryRegistrarBase()
{
// Add us to list
CUiNuggetFactoryRegistrarBase *pLeft = this;
CUiNuggetFactoryRegistrarBase *pRight = this;
if ( g_pUiNuggetFactoriesCircularList )
{
pLeft = g_pUiNuggetFactoriesCircularList;
pRight = g_pUiNuggetFactoriesCircularList->m_pNext;
pLeft->m_pNext = this;
pRight->m_pPrev = this;
}
g_pUiNuggetFactoriesCircularList = this;
m_pNext = pRight;
m_pPrev = pLeft;
}
CUiNuggetFactoryRegistrarBase::~CUiNuggetFactoryRegistrarBase()
{
// Remove us from list
if ( m_pPrev == this || m_pNext == this )
{
Assert( m_pPrev == this && m_pNext == this && g_pUiNuggetFactoriesCircularList == this );
g_pUiNuggetFactoriesCircularList = NULL;
}
else
{
m_pPrev->m_pNext = m_pNext;
m_pNext->m_pPrev = m_pPrev;
if ( g_pUiNuggetFactoriesCircularList == this )
g_pUiNuggetFactoriesCircularList = m_pPrev;
}
}
void CUiNuggetFactoryRegistrarBase::Register()
{
Assert( g_pGameUISystemMgr );
g_pGameUISystemMgr->RegisterScreenControllerFactory( GetName(), this );
}
void CUiNuggetFactoryRegistrarBase::RegisterAll()
{
CUiNuggetFactoryRegistrarBase *p = g_pUiNuggetFactoriesCircularList;
if ( !p )
return;
do
{
p->Register();
p = p->m_pNext;
}
while ( p != g_pUiNuggetFactoriesCircularList );
}
//////////////////////////////////////////////////////////////////////////
//
// factories implementation
//
CUiNuggetFactoryRegistrarBaseSingleton::CUiNuggetFactoryRegistrarBaseSingleton() :
m_pSingleton( NULL )
{
}
class CUiNuggetFactoryRegistrarBaseSingletonReferenceTracker : public CUiNuggetReference
{
public:
CUiNuggetFactoryRegistrarBaseSingletonReferenceTracker( CUiNuggetBase *pNugget, CUiNuggetFactoryRegistrarBaseSingleton *pFactory )
{
m_pFactory = pFactory;
m_pFactory->m_pSingleton = pNugget;
pNugget->AddReferenceSink( this );
}
private:
virtual void OnNuggetReleased( CUiNuggetBase *pNugget )
{
m_pFactory->m_pSingleton = NULL;
delete this;
}
private:
CUiNuggetFactoryRegistrarBaseSingleton *m_pFactory;
};
IGameUIScreenController * CUiNuggetFactoryRegistrarBaseSingleton::GetController( KeyValues *kvRequest )
{
if ( Q_stricmp( GetName(), kvRequest->GetName() ) )
return NULL;
if ( !m_pSingleton )
{
m_pSingleton = CreateNewController();
new CUiNuggetFactoryRegistrarBaseSingletonReferenceTracker( m_pSingleton, this );
}
return m_pSingleton;
}
class CUiNuggetFactoryRegistrarBaseInstancesReferenceTracker : public CUiNuggetReference
{
public:
CUiNuggetFactoryRegistrarBaseInstancesReferenceTracker( CUiNuggetBase *pNugget, CUiNuggetFactoryRegistrarBaseInstances *pFactory )
{
m_pFactory = pFactory;
m_pFactory->m_arrInstances.AddToTail( pNugget );
pNugget->AddReferenceSink( this );
}
private:
virtual void OnNuggetReleased( CUiNuggetBase *pNugget )
{
m_pFactory->m_arrInstances.FindAndRemove( pNugget );
delete this;
}
private:
CUiNuggetFactoryRegistrarBaseInstances *m_pFactory;
};
IGameUIScreenController * CUiNuggetFactoryRegistrarBaseInstances::GetController( KeyValues *kvRequest )
{
if ( Q_stricmp( GetName(), kvRequest->GetName() ) )
return NULL;
CUiNuggetBase *pInstance = CreateNewController();
if ( !pInstance )
return NULL;
new CUiNuggetFactoryRegistrarBaseInstancesReferenceTracker( pInstance, this );
return pInstance;
}

View File

@ -0,0 +1,252 @@
//=========== (C) Copyright Valve, L.L.C. All rights reserved. ===========
#ifndef UI_NUGGET_H
#define UI_NUGGET_H
#include "game_controls/igameuisystemmgr.h"
#include "matchmaking/imatchframework.h"
#include "fmtstr.h"
#include "utlstringmap.h"
class CUiNuggetBase;
class CUiNuggetReference;
class CUiNuggetFactoryRegistrarBase;
class CUiNuggetFactoryRegistrarBaseInstances;
class CUiNuggetFactoryRegistrarBaseSingleton;
//////////////////////////////////////////////////////////////////////////
//
// Base class for implementing UI nuggets
//
class CUiNuggetBase : public IGameUIScreenController
{
public:
CUiNuggetBase();
virtual ~CUiNuggetBase();
// IGameUIScreenController
public:
// Connects a screen to the controller, returns number of
// remaining connected screens (or 1 for the first connection)
virtual int OnScreenConnected( IGameUISystem *pScreenView );
// Releases the screen from controller, returns number of
// remaining connected screens (returns 0 if no screens are
// connected - new object must be reacquired from factory
// in this case)
virtual int OnScreenDisconnected( IGameUISystem *pScreenView );
// Callback for screen events handling
virtual KeyValues * OnScreenEvent( IGameUISystem *pScreenView, KeyValues *kvEvent );
// Broadcast an event to all connected screens (caller retains ownership of keyvalues)
virtual void BroadcastEventToScreens( KeyValues *kvEvent );
public:
// Add a reference to the nugget to be notified upon release
virtual void AddReferenceSink( CUiNuggetReference *pSink ) { m_arrReferences.AddToTail( pSink ); }
protected:
// Policy for whether the object should be deleted when no screen references remain
virtual bool ShouldDeleteOnLastScreenDisconnect() { return true; }
protected:
struct ConnectionInfo_t
{
IGameUISystem *m_pScreen;
int m_nRefCount;
explicit ConnectionInfo_t( IGameUISystem *pScreen = NULL ) : m_pScreen( pScreen ), m_nRefCount( 0 ) {}
bool operator == ( ConnectionInfo_t const &other ) const { return m_pScreen == other.m_pScreen; }
};
typedef CUtlVector< ConnectionInfo_t > ConnectedScreens;
ConnectedScreens m_arrConnectedScreens;
CUtlVector< int > m_arrEventsDisabledScreenHandles;
KeyValues *m_pUiNuggetData;
KeyValues::AutoDelete m_autodelete_m_pUiNuggetData;
private:
CUtlVector< int * > m_arrBroadcastEventIdxArray;
CUtlVector< CUiNuggetReference * > m_arrReferences;
};
//////////////////////////////////////////////////////////////////////////
//
// Declaration of UI nuggets factories
//
class CUiNuggetFactoryRegistrarBase : public IGameUIScreenControllerFactory
{
public:
CUiNuggetFactoryRegistrarBase();
~CUiNuggetFactoryRegistrarBase();
virtual void Register();
virtual char const *GetName() = 0;
public:
static void RegisterAll();
private:
CUiNuggetFactoryRegistrarBase *m_pPrev, *m_pNext;
};
class CUiNuggetFactoryRegistrarBaseGlobalInstance : public CUiNuggetFactoryRegistrarBase
{
public:
// Returns an instance of a controller interface
virtual IGameUIScreenController * GetController( KeyValues *kvRequest ) = 0;
// Access controller instances
virtual int GetControllerInstancesCount() { return 1; }
virtual IGameUIScreenController * GetControllerInstance( int iIndex ) = 0;
};
class CUiNuggetFactoryRegistrarBaseSingleton : public CUiNuggetFactoryRegistrarBase
{
friend class CUiNuggetFactoryRegistrarBaseSingletonReferenceTracker;
public:
CUiNuggetFactoryRegistrarBaseSingleton();
public:
// Returns an instance of a controller interface
virtual IGameUIScreenController * GetController( KeyValues *kvRequest );
// Access controller instances
virtual int GetControllerInstancesCount() { return !!m_pSingleton; }
virtual IGameUIScreenController * GetControllerInstance( int iIndex ) { return m_pSingleton; }
public:
// Creates an instance of a controller interface
virtual CUiNuggetBase * CreateNewController() = 0;
protected:
CUiNuggetBase *m_pSingleton;
};
class CUiNuggetFactoryRegistrarBaseInstances : public CUiNuggetFactoryRegistrarBase
{
friend class CUiNuggetFactoryRegistrarBaseInstancesReferenceTracker;
public:
// Returns an instance of a controller interface
virtual IGameUIScreenController * GetController( KeyValues *kvRequest );
// Access controller instances
virtual int GetControllerInstancesCount() { return m_arrInstances.Count(); }
virtual IGameUIScreenController * GetControllerInstance( int iIndex ) { return m_arrInstances.IsValidIndex( iIndex ) ? m_arrInstances[iIndex] : NULL; }
public:
// Creates an instance of a controller interface
virtual CUiNuggetBase * CreateNewController() = 0;
protected:
// Nugget instances
CUtlVector< CUiNuggetBase * > m_arrInstances;
};
//////////////////////////////////////////////////////////////////////////
//
// Macros to be used to declare UI nuggets factories
//
// Global instance factory - a nugget instance always exists in a global variable
// and is always shared with all screens.
#define UI_NUGGET_FACTORY_GLOBAL_INSTANCE( nuggetclassname, instanceptr, scriptname ) \
namespace { \
class Factory_##nuggetclassname##_Class : public CUiNuggetFactoryRegistrarBaseGlobalInstance \
{ \
virtual IGameUIScreenController * GetController( KeyValues *kvRequest ) { return static_cast< nuggetclassname * >( instanceptr ); } \
virtual IGameUIScreenController * GetControllerInstance( int iIndex ) { return static_cast< nuggetclassname * >( instanceptr ); } \
virtual char const * GetName() { return scriptname; } \
} \
g_factory_##nuggetclassname##_globalinstance; \
};
// Singleton factory - create a new nugget instance and share it with all screens
// until all references to the nugget are released and nugget is destroyed.
// If nugget policy is not deleting the nugget upon last release, then a single nugget
// instance will be created once and shared with all screens.
#define UI_NUGGET_FACTORY_SINGLETON( nuggetclassname, scriptname ) \
namespace { \
class Factory_##nuggetclassname##_Class : public CUiNuggetFactoryRegistrarBaseSingleton \
{ \
virtual CUiNuggetBase * CreateNewController() { return new nuggetclassname; } \
virtual char const * GetName() { return scriptname; } \
} \
g_factory_##nuggetclassname##_singleton; \
};
// Instances factory - create a new nugget instance per each request.
// Screens need to implement own methods of sharing data from a single nugget
// instance. Nugget instance must be marked for delete upon last release.
#define UI_NUGGET_FACTORY_INSTANCES( nuggetclassname, scriptname ) \
namespace { \
class Factory_##nuggetclassname##_Class : public CUiNuggetFactoryRegistrarBaseInstances \
{ \
virtual CUiNuggetBase * CreateNewController() { return new nuggetclassname; } \
virtual char const * GetName() { return scriptname; } \
} \
g_factory_##nuggetclassname##_instances; \
};
//////////////////////////////////////////////////////////////////////////
//
// Macros to be used to declare nuggets functions
//
#define DECLARE_NUGGET_FN_MAP( classname, baseclass ) \
typedef classname NuggetEventMapClass; \
typedef baseclass NuggetEventMapBaseClass; \
class NuggetEventMap : \
public CUtlStringMap< KeyValues * (classname::*)( IGameUISystem *pScreenView, KeyValues *args ) > \
{} \
m_NuggetEventMap; \
class NuggetPreBroadcastMap : \
public CUtlStringMap< bool (classname::*)( KeyValues *args ) > \
{} \
m_NuggetPreBroadcastMap; \
virtual KeyValues * OnScreenEvent( IGameUISystem *pScreenView, KeyValues *args ) { \
char const *szEvent = args->GetName(); \
UtlSymId_t sym = m_NuggetEventMap.Find( szEvent ); \
if ( sym != m_NuggetEventMap.InvalidIndex() ) { \
return (this->* (m_NuggetEventMap[sym]) )( pScreenView, args ); \
} \
return NuggetEventMapBaseClass::OnScreenEvent( pScreenView, args ); \
} \
virtual void BroadcastEventToScreens( KeyValues *args ) { \
char const *szEvent = args->GetName(); \
UtlSymId_t sym = m_NuggetPreBroadcastMap.Find( szEvent ); \
if ( sym != m_NuggetPreBroadcastMap.InvalidIndex() ) { \
if ( ! (this->* (m_NuggetPreBroadcastMap[sym]) )( args ) ) return; \
} \
return NuggetEventMapBaseClass::BroadcastEventToScreens( args ); \
}
#define NUGGET_FN( eventname ) \
class eventname##_EventRegistrar { \
public: typedef eventname##_EventRegistrar ThisClass; \
eventname##_EventRegistrar() { \
NuggetEventMapClass *pNugget = reinterpret_cast< NuggetEventMapClass * >( reinterpret_cast< size_t >( this ) - offsetof( NuggetEventMapClass, m_##eventname##_EventRegistrar ) ); \
pNugget->m_NuggetEventMap[ #eventname ] = &NuggetEventMapClass::Event_##eventname; \
COMPILE_TIME_ASSERT( offsetof( NuggetEventMapClass, m_##eventname##_EventRegistrar ) > offsetof( NuggetEventMapClass, m_NuggetEventMap ) ); \
} } m_##eventname##_EventRegistrar; \
KeyValues * Event_##eventname( IGameUISystem *pScreenView, KeyValues *args )
#define NUGGET_BROADCAST_FN( eventname ) \
class eventname##_BroadcastRegistrar { \
public: typedef eventname##_BroadcastRegistrar ThisClass; \
eventname##_BroadcastRegistrar() { \
NuggetEventMapClass *pNugget = reinterpret_cast< NuggetEventMapClass * >( reinterpret_cast< size_t >( this ) - offsetof( NuggetEventMapClass, m_##eventname##_BroadcastRegistrar ) ); \
pNugget->m_NuggetPreBroadcastMap[ #eventname ] = &NuggetEventMapClass::Broadcast_##eventname; \
COMPILE_TIME_ASSERT( offsetof( NuggetEventMapClass, m_##eventname##_BroadcastRegistrar ) > offsetof( NuggetEventMapClass, m_NuggetPreBroadcastMap ) ); \
} } m_##eventname##_BroadcastRegistrar; \
bool Broadcast_##eventname( KeyValues *args )
#endif // UI_NUGGET_H

View File

@ -0,0 +1,44 @@
//=========== (C) Copyright Valve, L.L.C. All rights reserved. ===========
#include "cbase.h"
#include "ui_nugget.h"
class CUiNuggetPlayerManager : public CUiNuggetBase
{
DECLARE_NUGGET_FN_MAP( CUiNuggetPlayerManager, CUiNuggetBase );
NUGGET_FN( GetLocalPlayer )
{
// Request for local player info
int iController = args->GetInt( "index" );
IPlayerLocal *pLocalPlayer = g_pMatchFramework->GetMatchSystem()->GetPlayerManager()->GetLocalPlayer( iController );
if ( !pLocalPlayer )
return NULL;
return PlayerAsKeyValues( pLocalPlayer, CFmtStr( "localplayer%d", iController ) );
}
NUGGET_FN( JoinFriend )
{
// Request to join a friend
XUID xuid = args->GetUint64( "xuid" );
IPlayerFriend *pFriend = g_pMatchFramework->GetMatchSystem()->GetPlayerManager()->GetFriendByXUID( xuid );
if ( !pFriend )
return NULL;
pFriend->Join();
return NULL;
}
KeyValues * PlayerAsKeyValues( IPlayer *pPlayer, char const *szResultTitle = "" )
{
KeyValues *kv = new KeyValues( szResultTitle );
kv->SetString( "name", pPlayer->GetName() );
kv->SetString( "xuid", CFmtStr( "%llu", pPlayer->GetXUID() ) );
kv->SetInt( "index", pPlayer->GetPlayerIndex() );
kv->SetInt( "state", pPlayer->GetOnlineState() );
return kv;
}
};
UI_NUGGET_FACTORY_SINGLETON( CUiNuggetPlayerManager, "playermanager" );

View File

@ -0,0 +1,51 @@
//=========== (C) Copyright Valve, L.L.C. All rights reserved. ===========
#include "cbase.h"
#include "ui_nugget.h"
class CUiNuggetSemaphore : public CUiNuggetBase
{
DECLARE_NUGGET_FN_MAP( CUiNuggetSemaphore, CUiNuggetBase );
NUGGET_FN( Configure )
{
m_pUiNuggetData->MergeFrom( args, KeyValues::MERGE_KV_UPDATE );
return NULL;
}
NUGGET_FN( Signal )
{
char const *szSemaphoreSignal = m_pUiNuggetData->GetString( "signal" );
if ( !*szSemaphoreSignal )
return NULL;
KeyValues *pEvent = m_pUiNuggetData->MakeCopy();
pEvent->SetName( szSemaphoreSignal );
KeyValues::AutoDelete autodelete_pEvent( pEvent );
char const *szEventData = m_pUiNuggetData->GetString( "eventdata" );
if ( *szEventData )
{
if ( KeyValues *pSub = pEvent->FindKey( szEventData ) )
{
pEvent->RemoveSubKey( pSub );
pSub->deleteThis();
}
KeyValues *pParams = args->MakeCopy();
pParams->SetName( szEventData );
pEvent->AddSubKey( pParams );
}
BroadcastEventToScreens( pEvent );
return NULL;
}
public:
CUiNuggetSemaphore()
{
m_pUiNuggetData->SetString( "signal", "OnSemaphore" );
m_pUiNuggetData->SetString( "eventdata", "eventdata" );
}
};
UI_NUGGET_FACTORY_INSTANCES( CUiNuggetSemaphore, "semaphore" );

View File

@ -0,0 +1,70 @@
//=========== (C) Copyright Valve, L.L.C. All rights reserved. ===========
#include "cbase.h"
#include "ui_nugget.h"
class CUiNuggetSessions : public CUiNuggetBase
{
DECLARE_NUGGET_FN_MAP( CUiNuggetSessions, CUiNuggetBase );
NUGGET_FN( CloseSession )
{
g_pMatchFramework->CloseSession();
return NULL;
}
NUGGET_FN( CreateSession )
{
args->SetName( "settings" );
g_pMatchFramework->CreateSession( args );
return NULL;
}
NUGGET_FN( MatchSession )
{
args->SetName( "settings" );
g_pMatchFramework->MatchSession( args );
return NULL;
}
NUGGET_FN( SessionSystemData )
{
if ( IMatchSession *p = g_pMatchFramework->GetMatchSession() )
{
KeyValues *kv = p->GetSessionSystemData();
return kv ? kv->MakeCopy() : NULL;
}
return NULL;
}
NUGGET_FN( SessionSettings )
{
if ( IMatchSession *p = g_pMatchFramework->GetMatchSession() )
{
KeyValues *kv = p->GetSessionSettings();
return kv ? kv->MakeCopy() : NULL;
}
return NULL;
}
NUGGET_FN( SessionUpdateSettings )
{
if ( IMatchSession *p = g_pMatchFramework->GetMatchSession() )
{
args->SetName( "settings" );
p->UpdateSessionSettings( args );
}
return NULL;
}
NUGGET_FN( SessionCommand )
{
if ( IMatchSession *p = g_pMatchFramework->GetMatchSession() )
{
p->Command( args->GetFirstSubKey() );
}
return NULL;
}
};
UI_NUGGET_FACTORY_SINGLETON( CUiNuggetSessions, "sessions" );

View File

@ -0,0 +1,204 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#include "cbase.h"
#include "IRunGameEngine.h"
#include "EngineInterface.h"
#include "tier1/strtools.h"
#include "igameuifuncs.h"
#include "tier1/convar.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Purpose: Interface to running the engine from the UI dlls
//-----------------------------------------------------------------------------
class CRunGameEngine : public IRunGameEngine
{
public:
// Returns true if the engine is running, false otherwise.
virtual bool IsRunning()
{
return true;
}
// Adds text to the engine command buffer. Only works if IsRunning()
// returns true on success, false on failure
virtual bool AddTextCommand(const char *text)
{
engine->ClientCmd_Unrestricted((char *)text);
return true;
}
// runs the engine with the specified command line parameters. Only works if !IsRunning()
// returns true on success, false on failure
virtual bool RunEngine(const char *gameName, const char *commandLineParams)
{
return false;
}
virtual bool RunEngine2(const char *gameDir, const char *commandLineParams, bool isSourceGame)
{
return false;
}
virtual ERunResult RunEngine( int iAppID, const char *gameDir, const char *commandLineParams )
{
return k_ERunResultOkay;
}
// returns true if the player is currently connected to a game server
virtual bool IsInGame()
{
return engine->GetLevelName() && strlen(engine->GetLevelName()) > 0;
}
// gets information about the server the engine is currently connected to
// returns true on success, false on failure
virtual bool GetGameInfo(char *infoBuffer, int bufferSize)
{
//!! need to implement
return false;
}
virtual void SetTrackerUserID(int trackerID, const char *trackerName)
{
gameuifuncs->SetFriendsID(trackerID, trackerName);
// update the player's name if necessary
ConVarRef name( "name" );
if ( name.IsValid() && trackerName && *trackerName && !Q_strcmp( name.GetString(), "unnamed" ) )
{
name.SetValue(trackerName);
}
}
// iterates users
// returns the number of user
virtual int GetPlayerCount()
{
return engine->GetMaxClients();
}
// returns a playerID for a player
// playerIndex is in the range [0, GetPlayerCount)
virtual unsigned int GetPlayerFriendsID(int playerIndex)
{
player_info_t pi;
if ( engine->GetPlayerInfo(playerIndex, &pi ) )
return pi.friendsID;
return 0;
}
// gets the in-game name of another user, returns NULL if that user doesn't exists
virtual const char *GetPlayerName(int trackerID)
{
// find the player by their friendsID
player_info_t pi;
for (int i = 0; i < engine->GetMaxClients(); i++)
{
if (engine->GetPlayerInfo(i, &pi ))
{
if (pi.friendsID == (uint)trackerID)
{
return pi.name;
}
}
}
return NULL;
}
virtual const char *GetPlayerFriendsName(int trackerID)
{
// find the player by their friendsID
player_info_t pi;
for (int i = 0; i < engine->GetMaxClients(); i++)
{
if (engine->GetPlayerInfo(i, &pi ))
{
if (pi.friendsID == (uint)trackerID)
{
return pi.friendsName;
}
}
}
return NULL;
}
// return the build number of the engine
virtual unsigned int GetEngineBuildNumber()
{
return engine->GetEngineBuildNumber();
}
// return the product version of the mod being played (comes from steam.inf)
virtual const char *GetProductVersionString()
{
return engine->GetProductVersionString();
}
};
EXPOSE_SINGLE_INTERFACE(CRunGameEngine, IRunGameEngine, RUNGAMEENGINE_INTERFACE_VERSION);
//namespace
//{
////-----------------------------------------------------------------------------
//// Purpose: Interface to running the game engine
////-----------------------------------------------------------------------------
//abstract_class IRunGameEngine_Old : public IBaseInterface
//{
//public:
// // Returns true if the engine is running, false otherwise.
// virtual bool IsRunning() = 0;
//
// // Adds text to the engine command buffer. Only works if IsRunning()
// // returns true on success, false on failure
// virtual bool AddTextCommand(const char *text) = 0;
//
// // runs the engine with the specified command line parameters. Only works if !IsRunning()
// // returns true on success, false on failure
// virtual bool RunEngine(const char *gameDir, const char *commandLineParams) = 0;
//
// // returns true if the player is currently connected to a game server
// virtual bool IsInGame() = 0;
//
// // gets information about the server the engine is currently ctrue on success, false on failure
// virtual bool GetGameInfo(char *infoBuffer, int bufferSize) = 0;
//
// // tells the engine our userID
// virtual void SetTrackerUserID(int trackerID, const char *trackerName) = 0;
//
// // this next section could probably moved to another interface
// // iterates users
// // returns the number of user
// virtual int GetPlayerCount() = 0;
//
// // returns a playerID for a player
// // playerIndex is in the range [0, GetPlayerCount)
// virtual unsigned int GetPlayerFriendsID(int playerIndex) = 0;
//
// // gets the in-game name of another user, returns NULL if that user doesn't exists
// virtual const char *GetPlayerName(int friendsID) = 0;
//
// // gets the friends name of a player
// virtual const char *GetPlayerFriendsName(int friendsID) = 0;
//};
//
//#define RUNGAMEENGINE_INTERFACE_VERSION_OLD "RunGameEngine004"
//
//#ifndef _XBOX
//EXPOSE_SINGLE_INTERFACE(CRunGameEngine, IRunGameEngine_Old, RUNGAMEENGINE_INTERFACE_VERSION_OLD);
//#endif
//}

View File

View File

@ -0,0 +1,116 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "winlite.h"
#include "Sys_Utils.h"
#include "EngineInterface.h"
#if defined( _GAMECONSOLE )
#include "xbox/xbox_win32stubs.h"
#endif
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
const unsigned int SYS_NO_ERROR = NO_ERROR;
const unsigned int SYS_ERROR_INVALID_HANDLE = ERROR_INVALID_HANDLE;
void Sys_SetLastError(unsigned long error)
{
::SetLastError(error);
}
unsigned long Sys_GetLastError()
{
return ::GetLastError();
}
WHANDLE Sys_CreateMutex(const char *mutexName)
{
return (WHANDLE)::CreateMutex(NULL, FALSE, TEXT(mutexName));
}
void Sys_ReleaseMutex(WHANDLE mutexHandle)
{
::ReleaseMutex((HANDLE)mutexHandle);
}
const unsigned int SYS_WAIT_OBJECT_0 = WAIT_OBJECT_0;
const unsigned int SYS_WAIT_ABANDONED = WAIT_ABANDONED;
unsigned int Sys_WaitForSingleObject(WHANDLE mutexHandle, int milliseconds)
{
return WaitForSingleObject((HANDLE)mutexHandle, milliseconds);
}
unsigned int Sys_RegisterWindowMessage(const char *msgName)
{
return ::RegisterWindowMessage(msgName);
}
WHANDLE Sys_FindWindow(const char *className, const char *windowName)
{
return (WHANDLE)::FindWindow(className, windowName);
}
void Sys_EnumWindows(void *callbackFunction, int lparam)
{
::EnumWindows((WNDENUMPROC)callbackFunction, lparam);
}
void Sys_GetWindowText(WHANDLE wnd, char *buffer, int bufferSize)
{
::GetWindowText((HWND)wnd, buffer, bufferSize - 1);
}
void Sys_PostMessage(WHANDLE wnd, unsigned int msg, unsigned int wParam, unsigned int lParam)
{
::PostMessageA((HWND)wnd, msg, wParam, lParam);
}
void Sys_SetCursorPos(int x, int y)
{
::SetCursorPos(x, y);
// engine->SetCursorPos(x,y); // SRC version
}
static ATOM staticWndclassAtom = 0;
static WNDCLASS staticWndclass = { NULL };
static LRESULT CALLBACK staticProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
return DefWindowProc(hwnd,msg,wparam,lparam);
}
WHANDLE Sys_CreateWindowEx(const char *windowName)
{
/*
if (!staticWndclassAtom)
{
memset( &staticWndclass,0,sizeof(staticWndclass) );
staticWndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
staticWndclass.lpfnWndProc = staticProc;
staticWndclass.hInstance = GetModuleHandle(NULL);
staticWndclass.hIcon = 0;
staticWndclass.lpszClassName = windowName;
staticWndclassAtom = ::RegisterClass( &staticWndclass );
DWORD error = ::GetLastError();
}
return (WHANDLE)::CreateWindow(windowName, windowName, 0, 0, 0, 0, 0, 0, 0, GetModuleHandle(NULL), 0);
*/
return (WHANDLE)1;
}
void Sys_DestroyWindow(WHANDLE wnd)
{
//::DestroyWindow((HWND)wnd);
}

View File

@ -0,0 +1,49 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef SYS_UTILS_H
#define SYS_UTILS_H
#ifdef _WIN32
#pragma once
#endif
typedef int WHANDLE;
// ERROR HANDLING
extern const unsigned int SYS_NO_ERROR;
extern const unsigned int SYS_ERROR_INVALID_HANDLE;
void Sys_SetLastError(unsigned long error);
unsigned long Sys_GetLastError();
// MUTEX HANDLING
WHANDLE Sys_CreateMutex(const char *mutexName);
void Sys_ReleaseMutex(WHANDLE mutexHandle);
// MUTEX SYNCHRONIZATION
extern const unsigned int SYS_WAIT_OBJECT_0;
extern const unsigned int SYS_WAIT_ABANDONED;
unsigned int Sys_WaitForSingleObject(WHANDLE mutexHandle, int milliseconds);
// window handling
unsigned int Sys_RegisterWindowMessage(const char *msgName);
WHANDLE Sys_FindWindow(const char *className, const char *windowName);
void Sys_EnumWindows(void *callbackFunction, int lparam);
void Sys_GetWindowText(WHANDLE wnd, char *buffer, int bufferSize);
void Sys_PostMessage(WHANDLE wnd, unsigned int msg, unsigned int wParam, unsigned int lParam);
WHANDLE Sys_CreateWindowEx(const char *windowName);
void Sys_DestroyWindow(WHANDLE wnd);
// mouse
void Sys_SetCursorPos(int x, int y);
#endif // SYS_UTILS_H

View File

@ -0,0 +1,116 @@
//========= Copyright <20> 1996-2008, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=====================================================================================//
#include "cbase.h"
#include "UIGameData.h"
#include "UIAvatarImage.h"
#include "EngineInterface.h"
#include "vgui/ISurface.h"
#ifndef _GAMECONSOLE
#include "steam/steam_api.h"
#endif
#ifndef _GAMECONSOLE
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CGameUiAvatarImage::CGameUiAvatarImage( void )
{
m_bValid = false;
m_flFetchedTime = 0.0f;
m_iTextureID = ( -1 );
}
void CGameUiAvatarImage::ClearAvatarSteamID( void )
{
m_bValid = false;
m_flFetchedTime = 0.0f;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CGameUiAvatarImage::SetAvatarSteamID( CSteamID steamIDUser )
{
ClearAvatarSteamID();
if ( steamapicontext->SteamFriends() && steamapicontext->SteamUtils() )
{
int iAvatar = steamapicontext->SteamFriends()->GetFriendAvatar( steamIDUser, k_EAvatarSize64x64 );
/*
// See if it's in our list already
*/
uint32 wide, tall;
if ( steamapicontext->SteamUtils()->GetImageSize( iAvatar, &wide, &tall ) )
{
bool bUseSteamImage = true;
if ( wide == 0 || tall == 0 )
{
// attempt to handle rare data integrity issue, avatar got lost
bUseSteamImage = false;
// mock up solid white as 64x64
wide = tall = 64;
}
int cubImage = wide * tall * 4;
byte *rgubDest = (byte*)_alloca( cubImage );
if ( bUseSteamImage )
{
steamapicontext->SteamUtils()->GetImageRGBA( iAvatar, rgubDest, cubImage );
}
else
{
// solid white, avoids any issue with where the alpha channel is
memset( rgubDest, 0xFF, cubImage );
}
InitFromRGBA( rgubDest, wide, tall );
m_flFetchedTime = Plat_FloatTime();
}
}
return m_bValid;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CGameUiAvatarImage::InitFromRGBA( const byte *rgba, int width, int height )
{
if ( m_iTextureID == -1 )
{
m_iTextureID = vgui::surface()->CreateNewTextureID( true );
}
vgui::surface()->DrawSetTextureRGBA( m_iTextureID, rgba, width, height );
int screenWide, screenTall;
vgui::surface()->GetScreenSize( screenWide, screenTall );
m_nWide = width * ( ( (float) screenWide ) / 640.0f );
m_nTall = height * ( ( (float) screenTall ) / 480.0f );
m_Color = Color( 255, 255, 255, 255 );
m_bValid = true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CGameUiAvatarImage::Paint( void )
{
if ( m_bValid )
{
vgui::surface()->DrawSetColor( m_Color );
vgui::surface()->DrawSetTexture( m_iTextureID );
vgui::surface()->DrawTexturedRect( m_nX, m_nY, m_nX + m_nWide, m_nY + m_nTall );
}
}
#endif // !_GAMECONSOLE

View File

@ -0,0 +1,100 @@
//========= Copyright <20> 1996-2009, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=====================================================================================//
#ifndef __UIAVATARIMAGE_H__
#define __UIAVATARIMAGE_H__
#include "vgui/IImage.h"
#ifdef _GAMECONSOLE
typedef vgui::IImage CGameUiAvatarImage;
#else
#include "steam/steam_api.h"
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CGameUiAvatarImage : public vgui::IImage
{
public:
CGameUiAvatarImage( void );
// Call this to set the steam ID associated with the avatar
bool SetAvatarSteamID( CSteamID steamIDUser );
void ClearAvatarSteamID( void );
// Call to Paint the image
// Image will draw within the current panel context at the specified position
virtual void Paint( void );
// Set the position of the image
virtual void SetPos(int x, int y)
{
m_nX = x;
m_nY = y;
}
// Gets the size of the content
virtual void GetContentSize(int &wide, int &tall)
{
wide = m_nWide;
tall = m_nTall;
}
// Get the size the image will actually draw in (usually defaults to the content size)
virtual void GetSize(int &wide, int &tall)
{
GetContentSize( wide, tall );
}
// Sets the size of the image
virtual void SetSize(int wide, int tall)
{
m_nWide = wide;
m_nTall = tall;
}
// Set the draw color
virtual void SetColor(Color col)
{
m_Color = col;
}
virtual void SetRotation( int )
{
( void ) 0; // Not implemented
}
virtual bool Evict() { return false; }
virtual int GetNumFrames() { return 0; }
virtual void SetFrame( int nFrame ) {}
virtual vgui::HTexture GetID() { return m_iTextureID; }
bool IsValid( void ) { return m_bValid; }
float GetFetchedTime() const { return m_flFetchedTime; }
protected:
void InitFromRGBA( const byte *rgba, int width, int height );
private:
Color m_Color;
int m_iTextureID;
int m_nX, m_nY, m_nWide, m_nTall;
bool m_bValid;
float m_flFetchedTime;
};
#endif // !_GAMECONSOLE
#endif // __UIAVATARIMAGE_H__

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,294 @@
//========= Copyright <20> 1996-2008, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=====================================================================================//
#ifndef __UIGAMEDATA_H__
#define __UIGAMEDATA_H__
#undef XBX_GetPrimaryUserId
#include "vgui_controls/Panel.h"
#include "vgui_controls/Frame.h"
#include "vgui_controls/Button.h"
#include "tier1/utllinkedlist.h"
#include "tier1/UtlMap.h"
#include "tier1/keyvalues.h"
#include "tier1/fmtstr.h"
#ifndef _GAMECONSOLE
#include "steam/steam_api.h"
#endif // _GAMECONSOLE
#include "matchmaking/imatchframework.h"
#include "matchmaking/imatchsystem.h"
#include "matchmaking/iplayer.h"
#include "matchmaking/iplayermanager.h"
#include "matchmaking/iservermanager.h"
#include "ixboxsystem.h"
#include "basemodpanel.h"
#include "UIAvatarImage.h"
#include "tokenset.h"
#include "EngineInterface.h"
#include "matchmaking/mm_helpers.h"
namespace BaseModUI {
class CAsyncCtxUIOnDeviceAttached;
extern const tokenset_t< const char * > s_characterPortraits[];
//=============================================================================
//
//=============================================================================
//
// ISelectStorageDeviceClient
//
// Client interface for device selector:
// async flow is as follows:
// client calls into SelectStorageDevice with its parameters established:
// GetCtrlrIndex, ForceSelector, AllowDeclined
// XUI blade shows up (or implicitly determines which device should be picked based on settings).
// if OnSelectError callback fires, then the process failed.
// if OnDeviceNotSelected fires, then the process is over, device not picked
// if OnDeviceFull fires, then device has insufficient capacity and cannot be used
// if OnDeviceSelected fires, then device has been picked and async operations on containers started
// should wait for AfterDeviceMounted callback
// when AfterDeviceMounted callback fires the device is fully mounted and ready
//
class ISelectStorageDeviceClient
{
public:
virtual int GetCtrlrIndex() = 0; // Controller index (0, 1, 2 or 3)
virtual bool ForceSelector() = 0; // Whether device selector should be forcefully shown
virtual bool AllowDeclined() = 0; // Whether declining storage device is allowed
virtual bool AllowAnyController() = 0; // Whether any connected controller can be selecting storage or only game-committed
enum FailReason_t
{
FAIL_ERROR,
FAIL_NOT_SELECTED,
FAIL_FULL,
FAIL_CORRUPT
};
virtual void OnDeviceFail( FailReason_t eReason ) = 0; // Storage device has not been set
virtual void OnDeviceSelected() = 0; // After device has been picked in XUI blade, but before mounting symbolic roots and opening containers
virtual void AfterDeviceMounted() = 0; // After device has been successfully mounted, configs processed, etc.
};
//
// CChangeStorageDevice
//
// Should be used when user wants to change storage device
//
class CChangeStorageDevice : public ISelectStorageDeviceClient
{
public:
explicit CChangeStorageDevice( int iCtrlr );
virtual ~CChangeStorageDevice() {}
public:
virtual int GetCtrlrIndex() { return m_iCtrlr; }
virtual bool ForceSelector() { return m_bForce; }
virtual bool AllowDeclined() { return m_bAllowDeclined; }
virtual bool AllowAnyController() { return m_bAnyController; }
virtual void OnDeviceFail( FailReason_t eReason ); // Storage device has not been set
virtual void OnDeviceSelected(); // After device has been picked in XUI blade, but before mounting symbolic roots and opening containers
virtual void AfterDeviceMounted(); // After device has been successfully mounted, configs processed, etc.
public:
// Fired as a follow-up after all async operations finish and
// all confirmation boxes are closed down by user
virtual void DeviceChangeCompleted( bool bChanged );
public:
int m_iCtrlr;
bool m_bForce;
bool m_bAllowDeclined;
bool m_bAnyController;
int m_nConfirmationData;
};
//
// UI game data
//
class CUIGameData : public IMatchEventsSink
{
public:
CUIGameData();
~CUIGameData();
static CUIGameData* Get();
static void Shutdown();
void RunFrame();
void RunFrame_Storage();
void RunFrame_Invite();
void Invite_Confirm();
void Invite_Connecting();
bool Invite_IsStorageDeviceValid();
void OnGameUIPostInit();
void OpenFriendRequestPanel(int index, uint64 playerXuid);
void OpenInviteUI( char const *szInviteUiType );
void ExecuteOverlayCommand( char const *szCommand );
// Listening for match events
virtual void OnEvent( KeyValues *pEvent );
bool SignedInToLive();
bool AnyUserSignedInToLiveWithMultiplayerDisabled();
const char *GetLocalPlayerName( int iController );
bool SelectStorageDevice( ISelectStorageDeviceClient *pSelectClient );
void OnDeviceAttached();
void OnCompletedAsyncDeviceAttached( CAsyncCtxUIOnDeviceAttached * job );
void OnGameUIHidden();
bool IsXUIOpen();
void NeedConnectionProblemWaitScreen( void );
void ShowPasswordUI( char const *pchCurrentPW );
vgui::IImage * GetAvatarImage( XUID playerID );
char const * GetPlayerName( XUID playerID, char const *szPlayerNameSpeculative );
#if !defined( _GAMECONSOLE ) && !defined( NO_STEAM )
STEAM_CALLBACK( CUIGameData, Steam_OnPersonaStateChanged, PersonaStateChange_t, m_CallbackPersonaStateChanged );
#endif
void ReloadScheme();
//
// Implementation of async jobs
// An async job is enqueued by calling "ExecuteAsync" with the proper job context.
// Job's function "ExecuteAsync" is called on a separate thread.
// After the job finishes the "Completed" function is called on the
// main thread.
//
class CAsyncJobContext
{
public:
CAsyncJobContext( float flLeastExecuteTime = 0.0f ) : m_flLeastExecuteTime( flLeastExecuteTime ), m_hThreadHandle( NULL ) {}
virtual ~CAsyncJobContext() {}
virtual void ExecuteAsync() = 0; // Executed on the secondary thread
virtual void Completed() = 0; // Executed on the main thread
public:
void * volatile m_hThreadHandle; // Handle to an async job thread waiting for
float m_flLeastExecuteTime; // Least amount of time this job should keep executing
};
CAsyncJobContext *m_pAsyncJob;
void ExecuteAsync( CAsyncJobContext *pAsync );
private:
bool IsActiveSplitScreenPlayerSpectating( void );
protected:
static CUIGameData* m_Instance;
static bool m_bModuleShutDown;
bool m_CGameUIPostInit;
float m_flShowConnectionProblemTimer;
float m_flTimeLastFrame;
bool m_bShowConnectionProblemActive;
CUtlMap< XUID, CGameUiAvatarImage * > m_mapUserXuidToAvatar;
CUtlMap< XUID, CUtlString > m_mapUserXuidToName;
//XUI info
bool m_bXUIOpen;
//storage device info
bool m_bWaitingForStorageDeviceHandle;
AsyncHandle_t m_hStorageDeviceChangeHandle;
uint m_iStorageID;
int m_iStorageController;
ISelectStorageDeviceClient *m_pSelectStorageClient;
void OnSetStorageDeviceId( int iController, uint nDeviceId );
};
}
extern ConVar demo_ui_enable;
extern ConVar demo_connect_string;
uint64 GetDlcInstalledMask();
//
// RemapText_t arrText[] = {
// { "", "#SessionError_Unknown", RemapText_t::MATCH_FULL },
// { "n/a", "#SessionError_NotAvailable", RemapText_t::MATCH_FULL },
// { "create", "#SessionError_Create", RemapText_t::MATCH_FULL },
// { "connect", "#SessionError_Connect", RemapText_t::MATCH_FULL },
// { "full", "#SessionError_Full", RemapText_t::MATCH_FULL },
// { "lock", "#SessionError_Lock", RemapText_t::MATCH_FULL },
// { "kicked", "#SessionError_Kicked", RemapText_t::MATCH_FULL },
// { "migrate", "#SessionError_Migrate", RemapText_t::MATCH_FULL },
// { "SteamServersDisconnected", "#SessionError_SteamServersDisconnected", RemapText_t::MATCH_FULL },
// { NULL, NULL, RemapText_t::MATCH_FULL }
// };
// szReason = RemapText_t::RemapRawText( arrText, szReason );
//
struct RemapText_t
{
char const *m_szRawText;
char const *m_szRemapText;
enum MatchPolicy_t
{
MATCH_FULL,
MATCH_SUBSTR,
MATCH_START
};
MatchPolicy_t m_eMatchPolicy;
inline bool Match( char const *szRawText )
{
switch( m_eMatchPolicy )
{
case MATCH_FULL:
return !Q_stricmp( szRawText, m_szRawText );
case MATCH_SUBSTR:
return Q_stristr( szRawText, m_szRawText ) != NULL;
case MATCH_START:
return StringHasPrefix( szRawText, m_szRawText );
default:
return false;
}
}
inline static char const * RemapRawText( RemapText_t *pRemapTable, char const *szRawText )
{
for ( ; pRemapTable && pRemapTable->m_szRawText; ++ pRemapTable )
{
if ( pRemapTable->Match( szRawText ) )
{
return pRemapTable->m_szRemapText;
}
}
return szRawText;
}
};
#endif // __UIGAMEDATA_H__

View File

@ -0,0 +1,243 @@
//========= Copyright <20> 1996-2008, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=====================================================================================//
#include "cbase.h"
#include "basemodpanel.h"
#include "UIGameData.h"
// vgui controls
#include "vgui/ILocalize.h"
// matchsystem
#include "matchmaking/imatchframework.h"
#ifndef _GAMECONSOLE
#include "steam/steam_api.h"
#endif
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
using namespace BaseModUI;
using namespace vgui;
//
// Invite approval
//
static int s_nInviteApprovalConf = 0;
static ISelectStorageDeviceClient *s_pPendingInviteStorageSelector = NULL;
enum InviteUserMapping_t
{
INVITE_USER_BLOCK_INPUT,
INVITE_USER_ALLOW_INPUT
};
static void Invite_MapUserForUiInput( InviteUserMapping_t eUi )
{
// Check invited user if it was the active user
#ifdef _GAMECONSOLE
if ( XBX_GetInvitedUserId() == XBX_INVALID_USER_ID )
return;
for ( DWORD k = 0; k < XBX_GetNumGameUsers(); ++ k )
{
if ( XBX_GetInvitedUserId() == (DWORD) XBX_GetUserId( k ) )
return;
}
// Invited user artificial mapping
switch ( eUi )
{
case INVITE_USER_BLOCK_INPUT:
XBX_ClearUserId( XBX_GetInvitedUserId() );
break;
case INVITE_USER_ALLOW_INPUT:
XBX_SetUserId( XBX_GetNumGameUsers(), XBX_GetInvitedUserId() );
break;
}
#endif
}
static void Invite_NotifyAction( char const *szNotifyAction )
{
s_nInviteApprovalConf = 0;
Invite_MapUserForUiInput( INVITE_USER_BLOCK_INPUT );
g_pMatchFramework->GetEventsSubscription()->BroadcastEvent( new KeyValues(
"OnInvite", "action", szNotifyAction ) );
}
static void Invite_Approved()
{
CUIGameData::Get()->Invite_Connecting();
Invite_NotifyAction( "join" );
}
static void Invite_Declined()
{
Invite_NotifyAction( "deny" );
}
void CUIGameData::RunFrame_Invite()
{
if ( s_nInviteApprovalConf )
{
#if 0 // TODO: UI: // Check that the confirmation wasn't dismissed without notifying the invite system
// Check that the confirmation wasn't dismissed without notifying the invite system
GenericConfirmation* confirmation =
static_cast<GenericConfirmation*>( CBaseModPanel::GetSingleton().GetWindow( WT_GENERICCONFIRMATION ) );
if ( !confirmation ||
confirmation->GetUsageId() != s_nInviteApprovalConf )
{
// Well, pretend like user declined the prompt
Invite_Declined();
}
#endif
}
if ( s_pPendingInviteStorageSelector && !IsXUIOpen() )
{
SelectStorageDevice( s_pPendingInviteStorageSelector );
s_pPendingInviteStorageSelector = NULL;
}
}
//=============================================================================
#ifdef _GAMECONSOLE
class CInviteSelectStorageDevice : public CChangeStorageDevice
{
public:
explicit CInviteSelectStorageDevice();
public:
virtual void DeviceChangeCompleted( bool bChanged );
};
CInviteSelectStorageDevice::CInviteSelectStorageDevice() :
CChangeStorageDevice( XBX_GetInvitedUserId() )
{
// Get UI panel
CBaseModPanel &ui = CBaseModPanel::GetSingleton();
ui.OnGameUIActivated();
// Allow non-involved controller
m_bAnyController = true;
// Don't force to re-select, just reload configs
m_bForce = false;
Invite_MapUserForUiInput( INVITE_USER_ALLOW_INPUT );
}
void CInviteSelectStorageDevice::DeviceChangeCompleted( bool bChanged )
{
CChangeStorageDevice::DeviceChangeCompleted( bChanged );
// Proceed with joining the invite session
Invite_NotifyAction( "join" );
}
#endif
//=============================================================================
bool CUIGameData::Invite_IsStorageDeviceValid()
{
#ifdef _GAMECONSOLE
//
// Note: the only code path that should lead to this routine is
// from invite accepting code.
// XBX_GetInvitedUserId() is set to the user id of who accepted the invite
// For that user the storage device has to be validated.
//
// If this function returns "true" it means that the user has a valid device
// selected and it is safe to proceed with the invite.
//
// If this function returns "false" it will send the "join" action OnInvite event
// after storage device selection process is over.
//
int iCtrlr = XBX_GetInvitedUserId();
if ( iCtrlr < 0 || iCtrlr >= XUSER_MAX_COUNT )
return true;
// Check what device the guy currently has mapped
DWORD dwDevice = XBX_GetStorageDeviceId( iCtrlr );
if ( XBX_DescribeStorageDevice( dwDevice ) ||
XBX_STORAGE_DECLINED == dwDevice )
// The guy has a valid device selected
// or allow the guy to play because we already
// told him earlier that his settings will not
// be saved
return true;
//
// Need to show device selector
//
s_pPendingInviteStorageSelector = new CInviteSelectStorageDevice;
return false;
#endif
return true;
}
void CUIGameData::Invite_Confirm()
{
// Activate game ui
CBaseModPanel &ui = CBaseModPanel::GetSingleton();
if ( !ui.IsVisible() )
{
// Activate game ui to see the dialog
engine->ExecuteClientCmd( "gameui_activate" );
}
#if 0 // TODO: UI: // Show a prompt
// Get current window
CBaseModFrame *pFrame = NULL;
WINDOW_TYPE wt = ui.GetActiveWindowType();
if ( wt != WT_NONE &&
wt != WT_GENERICCONFIRMATION )
pFrame = ui.GetWindow( wt );
// Show a prompt
GenericConfirmation* confirmation =
static_cast<GenericConfirmation*>( ui.
OpenWindow( WT_GENERICCONFIRMATION, pFrame, false ) );
GenericConfirmation::Data_t data;
data.pWindowTitle = "#L4D360UI_LeaveInviteConf";
data.pMessageText = "#L4D360UI_LeaveInviteConfTxt";
data.bOkButtonEnabled = true;
data.bCancelButtonEnabled = true;
data.pfnOkCallback = Invite_Approved;
data.pfnCancelCallback = Invite_Declined;
s_nInviteApprovalConf = confirmation->SetUsageData(data);
#endif
Invite_MapUserForUiInput( INVITE_USER_ALLOW_INPUT );
}
void CUIGameData::Invite_Connecting()
{
// Close any session that we might have outstanding
g_pMatchFramework->CloseSession();
#if 0 // TODO: UI: // Navigate to attract screen which might take a frame
// Navigate to attract screen which might take a frame
CBaseModPanel::GetSingleton().CloseAllWindows( CBaseModPanel::CLOSE_POLICY_EVEN_MSGS );
CAttractScreen::SetAttractMode( CAttractScreen::ATTRACT_ACCEPTINVITE );
CBaseModPanel::GetSingleton().OpenWindow( WT_ATTRACTSCREEN, NULL, true );
#endif
}

View File

@ -0,0 +1,751 @@
//========= Copyright <20> 1996-2008, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=====================================================================================//
#include "cbase.h"
#include "basemodpanel.h"
#include "UIGameData.h"
#include "EngineInterface.h"
#include "vgui/ILocalize.h"
#include "matchmaking/imatchframework.h"
#include "filesystem.h"
#include "fmtstr.h"
#ifndef _GAMECONSOLE
#include "steam/steam_api.h"
#endif
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
using namespace BaseModUI;
using namespace vgui;
#ifndef ERROR_SUCCESS
#define ERROR_SUCCESS 0
#endif
#ifndef ERROR_IO_INCOMPLETE
#define ERROR_IO_INCOMPLETE 996L
#endif
//
// Storage device selection
//
//-----------------------------------------------------------------------------
// Purpose: A storage device has been connected, update our settings and anything else
//-----------------------------------------------------------------------------
namespace BaseModUI {
class CAsyncCtxUIOnDeviceAttached : public CUIGameData::CAsyncJobContext
{
public:
explicit CAsyncCtxUIOnDeviceAttached( int iController );
~CAsyncCtxUIOnDeviceAttached();
virtual void ExecuteAsync();
virtual void Completed();
uint GetContainerOpenResult( void ) { return m_ContainerOpenResult; }
int GetController() const { return m_iController; }
private:
uint m_ContainerOpenResult;
int m_iController;
};
CAsyncCtxUIOnDeviceAttached::CAsyncCtxUIOnDeviceAttached( int iController ) :
CUIGameData::CAsyncJobContext( 3.0f ), // Storage device info for at least 3 seconds
m_ContainerOpenResult( ERROR_SUCCESS ),
m_iController( iController )
{
//CUIGameData::Get()->ShowMessageDialog( MD_CHECKING_STORAGE_DEVICE );
}
CAsyncCtxUIOnDeviceAttached::~CAsyncCtxUIOnDeviceAttached()
{
//CUIGameData::Get()->CloseMessageDialog( 0 );
}
void CAsyncCtxUIOnDeviceAttached::ExecuteAsync()
{
// Asynchronously do the tasks that don't interact with the command buffer
g_pFullFileSystem->DiscoverDLC( GetController() );
// Open user settings and save game container here
m_ContainerOpenResult = engine->OnStorageDeviceAttached( GetController() );
if ( m_ContainerOpenResult != ERROR_SUCCESS )
return;
}
ConVar ui_start_dlc_time_pump( "ui_start_dlc_time_pump", "30" );
ConVar ui_start_dlc_time_loaded( "ui_start_dlc_time_loaded", "150" );
ConVar ui_start_dlc_time_corrupt( "ui_start_dlc_time_corrupt", "300" );
CON_COMMAND_F( ui_pump_dlc_mount_corrupt, "", FCVAR_DEVELOPMENTONLY )
{
int nStage = -1;
if ( args.ArgC() > 1 )
{
nStage = Q_atoi( args.Arg( 1 ) );
}
DevMsg( 2, "ui_pump_dlc_mount_corrupt %d\n", nStage );
int nCorruptDLCs = g_pFullFileSystem->IsAnyCorruptDLC();
while ( nStage >= 0 && nStage < nCorruptDLCs )
{
static wchar_t wszDlcInfo[ 3 * MAX_PATH ] = {0};
if ( !g_pFullFileSystem->GetAnyCorruptDLCInfo( nStage, wszDlcInfo, sizeof( wszDlcInfo ) ) )
{
++ nStage;
continue;
}
// information text
if ( wchar_t *wszExplanation = g_pVGuiLocalize->Find( "#L4D360UI_MsgBx_DlcCorruptTxt" ) )
{
int wlen = Q_wcslen( wszDlcInfo );
Q_wcsncpy( wszDlcInfo + wlen, wszExplanation, sizeof( wszDlcInfo ) - 2 * wlen );
}
#if 0 // TODO: UI: // We've got a corrupt DLC, put it up on the spinner
// We've got a corrupt DLC, put it up on the spinner
CUIGameData::Get()->UpdateWaitPanel( wszDlcInfo, 0.0f );
#endif
engine->ClientCmd( CFmtStr( "echo corruptdlc%d; wait %d; ui_pump_dlc_mount_corrupt %d;",
nStage + 1, ui_start_dlc_time_corrupt.GetInt(), nStage + 1 ) );
return;
}
// end of dlc mounting phases
CUIGameData::Get()->OnCompletedAsyncDeviceAttached( NULL );
}
CON_COMMAND_F( ui_pump_dlc_mount_content, "", FCVAR_DEVELOPMENTONLY )
{
int nStage = -1;
if ( args.ArgC() > 1 )
{
nStage = Q_atoi( args.Arg( 1 ) );
}
DevMsg( 2, "ui_pump_dlc_mount_content %d\n", nStage );
bool bSearchPathMounted = false;
int numDlcsContent = g_pFullFileSystem->IsAnyDLCPresent( &bSearchPathMounted );
while ( nStage >= 0 && nStage < numDlcsContent )
{
static wchar_t wszDlcInfo[ 3 * MAX_PATH ] = {0};
unsigned int ulMask;
if ( !g_pFullFileSystem->GetAnyDLCInfo( nStage, &ulMask, wszDlcInfo, sizeof( wszDlcInfo ) ) )
{
++ nStage;
continue;
}
// information text
if ( wchar_t *wszExplanation = g_pVGuiLocalize->Find( "#L4D360UI_MsgBx_DlcMountedTxt" ) )
{
int wlen = Q_wcslen( wszDlcInfo );
Q_wcsncpy( wszDlcInfo + wlen, wszExplanation, sizeof( wszDlcInfo ) - 2 * wlen );
}
#if 0 // TODO: UI: // We've got a corrupt DLC, put it up on the spinner
// We've got a corrupt DLC, put it up on the spinner
CUIGameData::Get()->UpdateWaitPanel( wszDlcInfo, 0.0f );
#endif
engine->ClientCmd( CFmtStr( "echo mounteddlc%d (0x%08X); wait %d; ui_pump_dlc_mount_content %d;",
nStage + 1, ulMask, ui_start_dlc_time_loaded.GetInt(), nStage + 1 ) );
return;
}
// Done displaying found content, show corrupt
engine->ClientCmd( "ui_pump_dlc_mount_corrupt 0" );
}
CON_COMMAND_F( ui_pump_dlc_mount_stage, "", FCVAR_DEVELOPMENTONLY )
{
// execute in order
int nStage = -1;
if ( args.ArgC() > 1 )
{
nStage = Q_atoi( args.Arg( 1 ) );
}
DevMsg( 2, "ui_pump_dlc_mount_stage %d\n", nStage );
static char const *s_arrClientCmdsDlcMount[] =
{
"net_reloadgameevents",
"hud_reloadscheme",
"gameinstructor_reload_lessons",
"scenefilecache_reload",
"cc_reload",
"rr_reloadresponsesystems",
"cl_soundemitter_reload",
"sv_soundemitter_reload",
};
if ( nStage >= 0 && nStage < ARRAYSIZE( s_arrClientCmdsDlcMount ) )
{
// execute in phases, each command deferred occurs on main thread as required
// adding a wait <frames> to let spinner clock a little
// no way to solve any one phase that blocks for too long...this is good enough
engine->ClientCmd( CFmtStr( "wait %d; %s; ui_pump_dlc_mount_stage %d;",
ui_start_dlc_time_pump.GetInt(),
s_arrClientCmdsDlcMount[ nStage ],
nStage + 1 ) );
return;
}
// Done mounting
engine->ClientCmd( "ui_pump_dlc_mount_content 0" );
}
void CAsyncCtxUIOnDeviceAttached::Completed()
{
bool bDLCSearchPathMounted = false;
if ( GetContainerOpenResult() == ERROR_SUCCESS &&
g_pFullFileSystem->IsAnyDLCPresent( &bDLCSearchPathMounted ) )
{
if ( !bDLCSearchPathMounted )
{
// add the DLC search paths if they exist
// this must be done on the main thread
// the DLC search path mount will incur a quick synchronous hit due to zip mounting
g_pFullFileSystem->AddDLCSearchPaths();
// new DLC data may trump prior data, so need to signal isolated system reloads
engine->ClientCmd( "ui_pump_dlc_mount_stage 0" );
return;
}
}
// No valid DLC was discovered, check if we discovered some corrupt DLC
if ( g_pFullFileSystem->IsAnyCorruptDLC() )
{
// need to show just corrupt DLC information
engine->ClientCmd( CFmtStr( "ui_pump_dlc_mount_corrupt %d", 0 ) );
return;
}
// Otherwise we are done attaching storage right now
CUIGameData::Get()->OnCompletedAsyncDeviceAttached( this );
}
}
//
// CChangeStorageDevice
//
// Should be used when user wants to change storage device
//
static CChangeStorageDevice *s_pChangeStorageDeviceCallback = NULL;
static void CChangeStorageDevice_Continue()
{
s_pChangeStorageDeviceCallback->DeviceChangeCompleted( true );
delete s_pChangeStorageDeviceCallback;
s_pChangeStorageDeviceCallback = NULL;
}
static void CChangeStorageDevice_SelectAgain()
{
CUIGameData::Get()->SelectStorageDevice( s_pChangeStorageDeviceCallback );
s_pChangeStorageDeviceCallback = NULL;
}
CChangeStorageDevice::CChangeStorageDevice( int iCtrlr ) :
m_iCtrlr( iCtrlr ),
m_bAllowDeclined( true ),
m_bForce( true ),
m_nConfirmationData( 0 )
{
// Just in case clean up (if dialogs were cancelled due to user sign out or such)
delete s_pChangeStorageDeviceCallback;
s_pChangeStorageDeviceCallback = NULL;
}
void CChangeStorageDevice::OnDeviceFail( FailReason_t eReason )
{
// Depending if the user had storage device by this moment
// or not we will take different actions:
DWORD dwDevice = XBX_GetStorageDeviceId( GetCtrlrIndex() );
switch ( eReason )
{
case FAIL_ERROR:
case FAIL_NOT_SELECTED:
if ( XBX_DescribeStorageDevice( dwDevice ) )
{
// That's fine user has a valid storage device, didn't want to change
DeviceChangeCompleted( false );
delete this;
return;
}
// otherwise, proceed with the ui msg
}
XBX_SetStorageDeviceId( GetCtrlrIndex(), XBX_STORAGE_DECLINED );
// We don't want to fire notification because there might be unsaved
// preferences changes that were done without a storage device
// no: g_pMatchFramework->GetEventsSubscription()->BroadcastEvent( new KeyValues( "OnProfileStorageAvailable", "iController", GetCtrlrIndex() ) );
m_bAllowDeclined = false;
#if 0 // TODO: UI: CChangeStorageDevice::OnDeviceFail
GenericConfirmation* confirmation =
static_cast<GenericConfirmation*>( CBaseModPanel::GetSingleton().
OpenWindow( WT_GENERICCONFIRMATION, CUIGameData::Get()->GetParentWindowForSystemMessageBox(), false ) );
GenericConfirmation::Data_t data;
switch ( eReason )
{
case FAIL_ERROR:
case FAIL_NOT_SELECTED:
data.pWindowTitle = "#L4D360UI_MsgBx_AttractDeviceNoneC";
data.pMessageText = "#L4D360UI_MsgBx_AttractDeviceNoneTxt";
break;
case FAIL_FULL:
data.pWindowTitle = "#L4D360UI_MsgBx_AttractDeviceFullC";
data.pMessageText = "#L4D360UI_MsgBx_AttractDeviceFullTxt";
break;
case FAIL_CORRUPT:
default:
data.pWindowTitle = "#L4D360UI_MsgBx_AttractDeviceCorruptC";
data.pMessageText = "#L4D360UI_MsgBx_AttractDeviceCorruptTxt";
break;
}
data.bOkButtonEnabled = true;
data.bCancelButtonEnabled = true;
s_pChangeStorageDeviceCallback = this;
data.pfnOkCallback = CChangeStorageDevice_Continue;
data.pfnCancelCallback = CChangeStorageDevice_SelectAgain;
// WARNING! WARNING! WARNING!
// The nature of Generic Confirmation is that it will be silently replaced
// with another Generic Confirmation if a system event occurs
// e.g. user unplugs controller, user changes storage device, etc.
// If that happens neither OK nor CANCEL callbacks WILL NOT BE CALLED
// The state machine cannot depend on either callback advancing the
// state because in some situations neither callback can fire and the
// confirmation dismissed/closed/replaced.
// State machine must implement OnThink and check if the required
// confirmation box is still present!
// This code implements some sort of fallback - it deletes the static
// confirmation data when a new storage device change is requested.
// Vitaliy -- 9/26/2009
//
m_nConfirmationData = confirmation->SetUsageData(data);
#endif
}
void CChangeStorageDevice::OnDeviceSelected()
{
DevMsg( "[GAMEUI] CChangeStorageDevice::OnDeviceSelected( 0x%08X )\n",
XBX_GetStorageDeviceId( GetCtrlrIndex() ) );
#if 0 // TODO: UI: CChangeStorageDevice::OnDeviceSelected
CUIGameData::Get()->UpdateWaitPanel( "#L4D360UI_WaitScreen_SignOnSucceded" );
#endif
}
void CChangeStorageDevice::AfterDeviceMounted()
{
DeviceChangeCompleted( true );
g_pMatchFramework->GetEventsSubscription()->BroadcastEvent( new KeyValues( "OnProfileStorageAvailable", "iController", GetCtrlrIndex() ) );
delete this;
}
void CChangeStorageDevice::DeviceChangeCompleted( bool bChanged )
{
if ( bChanged )
{
Msg( "CChangeStorageDevice::DeviceChangeCompleted for ctrlr%d device 0x%08X\n",
GetCtrlrIndex(), XBX_GetStorageDeviceId( GetCtrlrIndex() ) );
}
else
{
Msg( "CChangeStorageDevice::DeviceChangeCompleted - ctrlr%d is keeping device 0x%08X\n",
GetCtrlrIndex(), XBX_GetStorageDeviceId( GetCtrlrIndex() ) );
}
}
//=============================================================================
//
//=============================================================================
class CChangeStorageDeviceChained : public CChangeStorageDevice
{
public:
typedef CChangeStorageDevice BaseClass;
explicit CChangeStorageDeviceChained( int iCtrlrs[2] ) :
BaseClass( iCtrlrs[0] ), m_nChainCtrlr( iCtrlrs[1] ) {}
virtual void DeviceChangeCompleted( bool bChanged )
{
// Defer to the base class
BaseClass::DeviceChangeCompleted( bChanged );
// If we have a chain target, then call this off again
if ( m_nChainCtrlr >= 0 )
{
CUIGameData::Get()->SelectStorageDevice( new CChangeStorageDevice( m_nChainCtrlr ) );
}
}
private:
int m_nChainCtrlr;
};
void OnStorageDevicesChangedSelectNewDevice()
{
#ifdef _GAMECONSOLE
int numChangedCtrlrs = 0;
int nChangedCtrlrs[2] = { -1, -1 }; // We can only have two users (split-screen)
for ( DWORD i = 0; i < XBX_GetNumGameUsers(); ++ i )
{
int iController = XBX_GetUserId( i );
// Guests can't choose a storage device!
if ( XBX_GetUserIsGuest( iController ) )
continue;
int nStorageID = XBX_GetStorageDeviceId( iController );
if ( nStorageID == XBX_INVALID_STORAGE_ID )
{
// A controller's device has changed, and we'll need to prompt them to replace it
nChangedCtrlrs[numChangedCtrlrs] = iController;
numChangedCtrlrs++;
}
}
// If a controller changed, then start off our device change dialogs
if ( numChangedCtrlrs )
{
CUIGameData::Get()->SelectStorageDevice( new CChangeStorageDeviceChained( nChangedCtrlrs ) );
}
#endif // _GAMECONSOLE
}
void CUIGameData::RunFrame_Storage()
{
// Check to see if a pending async task has already finished
if ( m_pAsyncJob && !m_pAsyncJob->m_hThreadHandle )
{
m_pAsyncJob->Completed();
delete m_pAsyncJob;
m_pAsyncJob = NULL;
}
if( m_bWaitingForStorageDeviceHandle )
{
//the select device blade just closed, get the selected device
DWORD ret = xboxsystem->GetOverlappedResult( m_hStorageDeviceChangeHandle, NULL, true );
if ( ret != ERROR_IO_INCOMPLETE )
{
// Done waiting
xboxsystem->ReleaseAsyncHandle( m_hStorageDeviceChangeHandle );
m_bWaitingForStorageDeviceHandle = false;
// If we selected something, validate it
if ( m_iStorageID != XBX_INVALID_STORAGE_ID )
{
OnSetStorageDeviceId( m_iStorageController, m_iStorageID );
}
else
{
#if 0 // TODO: UI: CloseWaitScreen( NULL, "ReportNoDeviceSelected" );
CloseWaitScreen( NULL, "ReportNoDeviceSelected" );
#endif
if ( m_pSelectStorageClient )
{
m_pSelectStorageClient->OnDeviceFail( ISelectStorageDeviceClient::FAIL_NOT_SELECTED );
m_pSelectStorageClient = NULL;
}
}
}
}
}
void StorageDevice_SelectAllNow()
{
#ifdef _GAMECONSOLE
int numChangedCtrlrs = 0;
int nChangedCtrlrs[2] = { -1, -1 }; // We can only have two users (split-screen)
for ( DWORD i = 0; i < XBX_GetNumGameUsers(); ++ i )
{
int iController = XBX_GetUserId( i );
// Guests can't choose a storage device!
if ( XBX_GetUserIsGuest( iController ) )
continue;
int nStorageID = XBX_GetStorageDeviceId( iController );
if ( nStorageID == XBX_INVALID_STORAGE_ID )
{
// A controller's device has changed, and we'll need to prompt them to replace it
nChangedCtrlrs[numChangedCtrlrs] = iController;
numChangedCtrlrs++;
}
}
// If a controller changed, then start off our device change dialogs
if ( numChangedCtrlrs )
{
CUIGameData::Get()->SelectStorageDevice( new CChangeStorageDeviceChained( nChangedCtrlrs ) );
}
#endif // _GAMECONSOLE
}
//=============================================================================
//This is where we open the XUI pannel to let the user select the current storage device.
bool CUIGameData::SelectStorageDevice( ISelectStorageDeviceClient *pSelectClient )
{
#ifdef _GAMECONSOLE
if ( !pSelectClient )
return false;
int iController = pSelectClient->GetCtrlrIndex();
bool bAllowDeclined = pSelectClient->AllowDeclined();
bool bForceDisplay = pSelectClient->ForceSelector();
bool bCheckCtrlr = !pSelectClient->AllowAnyController();
DevMsg( 2, "[GAMEUI] SelectStorageDevice( ctrlr=%d; %d, %d ), waiting=%d\n",
iController, bAllowDeclined, bForceDisplay, m_bWaitingForStorageDeviceHandle );
if ( bCheckCtrlr )
{
// Check if the game is in guest mode
if ( XBX_GetPrimaryUserIsGuest() )
{
Warning( "[GAMEUI] SelectStorageDevice for guest!\n" );
pSelectClient->OnDeviceFail( ISelectStorageDeviceClient::FAIL_ERROR );
return false; // go away, no storage for guests
}
int nSlot = -1;
for ( DWORD k = 0; k < XBX_GetNumGameUsers(); ++ k )
{
int iCtrlr = XBX_GetUserId( k );
if ( iCtrlr != iController )
continue;
else if ( XBX_GetUserIsGuest( k ) )
{
Warning( "[GAMEUI] SelectStorageDevice for guest!\n" );
pSelectClient->OnDeviceFail( ISelectStorageDeviceClient::FAIL_ERROR );
return false; // go away, game thinks you are a guest
}
else
nSlot = k;
}
if ( nSlot < 0 )
{
Warning( "[GAMEUI] SelectStorageDevice for not active ctrlr!\n" );
pSelectClient->OnDeviceFail( ISelectStorageDeviceClient::FAIL_ERROR );
return false; // this controller is not involved in the game, go away
}
}
// Is the controller signed in?
if( XUserGetSigninState( iController ) == eXUserSigninState_NotSignedIn )
{
Warning( "[GAMEUI] SelectStorageDevice for not signed in user!\n" );
pSelectClient->OnDeviceFail( ISelectStorageDeviceClient::FAIL_ERROR );
return false; // not signed in, no device selector
}
// Maybe a guest buddy?
XUSER_SIGNIN_INFO xsi;
if ( ERROR_SUCCESS == XUserGetSigninInfo( iController, XUSER_GET_SIGNIN_INFO_ONLINE_XUID_ONLY, &xsi ) &&
(xsi.dwInfoFlags & XUSER_INFO_FLAG_GUEST) != 0 )
{
Warning( "[GAMEUI] SelectStorageDevice for LIVE-guest!\n" );
pSelectClient->OnDeviceFail( ISelectStorageDeviceClient::FAIL_ERROR );
return false; // guests don't have device selectors, go away
}
if ( ERROR_SUCCESS != XUserGetSigninInfo( iController, XUSER_GET_SIGNIN_INFO_OFFLINE_XUID_ONLY, &xsi ) )
{
Warning( "[GAMEUI] SelectStorageDevice failed to obtain XUID!\n" );
pSelectClient->OnDeviceFail( ISelectStorageDeviceClient::FAIL_ERROR );
return false; // failed to obtain XUID?
}
//
// Prevent reentry
//
if( m_bWaitingForStorageDeviceHandle )
{
Warning( "[GAMEUI] SelectStorageDevice is already busy selecting storage device! Cannot re-enter!\n" );
pSelectClient->OnDeviceFail( ISelectStorageDeviceClient::FAIL_ERROR );
return false; // Somebody already selecting a device
}
#if defined( _DEMO ) && defined( _GAMECONSOLE )
// Demo mode cannot have access to storage devices anyway
if ( IsGameConsole() )
{
m_iStorageID = XBX_STORAGE_DECLINED;
m_iStorageController = iController;
m_pSelectStorageClient = pSelectClient;
m_pSelectStorageClient->OnDeviceSelected();
OnCompletedAsyncDeviceAttached( NULL );
return true;
}
#endif
// Check if we already have a valid storage device
if ( XBX_GetStorageDeviceId( iController ) != XBX_INVALID_STORAGE_ID &&
( bAllowDeclined || XBX_GetStorageDeviceId( iController ) != XBX_STORAGE_DECLINED ) &&
! bForceDisplay )
{
DevMsg( 2, "[GAMEUI] SelectStorageDevice - storage id = 0x%08X\n",
XBX_GetStorageDeviceId( iController ) );
// Put up a progress that we are loading profile...
// TODO: UI: OpenWaitScreen( "#L4D360UI_WaitScreen_SigningOn" );
// - OpenWaitScreen( "#L4D360UI_WaitScreen_SigningOn" );
m_iStorageID = XBX_GetStorageDeviceId( iController );
m_iStorageController = iController;
m_pSelectStorageClient = pSelectClient;
OnSetStorageDeviceId( iController, XBX_GetStorageDeviceId( iController ) );
// Already have a storage device
return true;
}
// Put up a progress that we are loading profile...
// TODO: UI: OpenWaitScreen( "#L4D360UI_WaitScreen_SigningOn", 0.0f );
// - OpenWaitScreen( "#L4D360UI_WaitScreen_SigningOn", 0.0f );
// NOTE: this shouldn't have a 3 sec time-out as a new wait message is taking over
// the progress when container starts mounting
//open the dialog
m_bWaitingForStorageDeviceHandle = true;
m_hStorageDeviceChangeHandle = xboxsystem->CreateAsyncHandle();
m_iStorageID = XBX_INVALID_STORAGE_ID;
m_iStorageController = iController;
m_pSelectStorageClient = pSelectClient;
xboxsystem->ShowDeviceSelector( iController, bForceDisplay, &m_iStorageID, &m_hStorageDeviceChangeHandle );
#endif
return false;
}
//=============================================================================
void CUIGameData::OnDeviceAttached()
{
//This is straight from CBasePanel
ExecuteAsync( new CAsyncCtxUIOnDeviceAttached( m_iStorageController ) );
}
//=============================================================================
void CUIGameData::OnCompletedAsyncDeviceAttached( CAsyncCtxUIOnDeviceAttached * job )
{
ISelectStorageDeviceClient *pStorageDeviceClient = m_pSelectStorageClient;
m_pSelectStorageClient = NULL;
static ConVarRef mm_dlcs_mask_extras( "mm_dlcs_mask_extras" );
if ( mm_dlcs_mask_extras.IsValid() )
{
#ifdef _GAMECONSOLE
int iDLCmask = mm_dlcs_mask_extras.GetInt();
if ( engine->IsLowViolence() && XGetGameRegion() == XC_GAME_REGION_EUROPE_REST )
{
// iDLCmask |= ( 1 << ? );
}
mm_dlcs_mask_extras.SetValue( iDLCmask );
#endif
}
uint nRet = job ? job->GetContainerOpenResult() : ERROR_SUCCESS;
if ( nRet != ERROR_SUCCESS )
{
#if 0 // TODO: UI: CloseWaitScreen( NULL, "ReportDeviceCorrupt" );
CloseWaitScreen( NULL, "ReportDeviceCorrupt" );
#endif
pStorageDeviceClient->OnDeviceFail( ISelectStorageDeviceClient::FAIL_CORRUPT );
}
else
{
// Notify that data has loaded
pStorageDeviceClient->AfterDeviceMounted();
// Check for opening a new storage device immediately
if ( m_pSelectStorageClient == NULL )
{
// Close down the waiting screen
#if 0 // TODO: UI: CloseWaitScreen( NULL, "OnCompletedAsyncDeviceAttached" );
CloseWaitScreen( NULL, "OnCompletedAsyncDeviceAttached" );
#endif
}
}
}
#ifdef _WIN32
//-------------------------
// Purpose: Job wrapper
//-------------------------
static unsigned UIGameDataJobWrapperFn( void *pvContext )
{
CUIGameData::CAsyncJobContext *pAsync = reinterpret_cast< CUIGameData::CAsyncJobContext * >( pvContext );
float const flTimeStart = Plat_FloatTime();
pAsync->ExecuteAsync();
float const flElapsedTime = Plat_FloatTime() - flTimeStart;
if ( flElapsedTime < pAsync->m_flLeastExecuteTime )
{
ThreadSleep( ( pAsync->m_flLeastExecuteTime - flElapsedTime ) * 1000 );
}
ReleaseThreadHandle( ( ThreadHandle_t ) pAsync->m_hThreadHandle );
pAsync->m_hThreadHandle = NULL;
return 0;
}
#endif
//-----------------------------------------------------------------------------
// Purpose: Enqueues a job function to be called on a separate thread
//-----------------------------------------------------------------------------
void CUIGameData::ExecuteAsync( CAsyncJobContext *pAsync )
{
Assert( !m_pAsyncJob );
Assert( pAsync && !pAsync->m_hThreadHandle );
m_pAsyncJob = pAsync;
#ifdef _WIN32
ThreadHandle_t hHandle = CreateSimpleThread( UIGameDataJobWrapperFn, reinterpret_cast< void * >( pAsync ) );
pAsync->m_hThreadHandle = hHandle;
#ifdef _GAMECONSOLE
ThreadSetAffinity( hHandle, XBOX_PROCESSOR_3 );
#endif
#else
pAsync->ExecuteAsync();
#endif
}

View File

@ -0,0 +1,362 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "VGuiSystemModuleLoader.h"
#include "Sys_Utils.h"
#include "IVGuiModule.h"
#include "ServerBrowser/IServerBrowser.h"
#include <vgui/IPanel.h>
#include <vgui/ISystem.h>
#include <vgui/IVGui.h>
#include <vgui/ILocalize.h>
#include <KeyValues.h>
#include <vgui_controls/Controls.h>
#include <vgui_controls/Panel.h>
#include "FileSystem.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// instance of class
CVGuiSystemModuleLoader g_VModuleLoader;
extern vgui::VPANEL GetGameUIBasePanel();
bool bSteamCommunityFriendsVersion = false;
#include <tier0/dbg.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CVGuiSystemModuleLoader, IVGuiModuleLoader, VGUIMODULELOADER_INTERFACE_VERSION, g_VModuleLoader);
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CVGuiSystemModuleLoader::CVGuiSystemModuleLoader()
{
m_bModulesInitialized = false;
m_bPlatformShouldRestartAfterExit = false;
m_pPlatformModuleData = NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CVGuiSystemModuleLoader::~CVGuiSystemModuleLoader()
{
}
//-----------------------------------------------------------------------------
// Purpose: returns true if the module loader has acquired the platform mutex and loaded the modules
//-----------------------------------------------------------------------------
bool CVGuiSystemModuleLoader::IsPlatformReady()
{
return m_bModulesInitialized;
}
//-----------------------------------------------------------------------------
// Purpose: sets up all the modules for use
//-----------------------------------------------------------------------------
bool CVGuiSystemModuleLoader::InitializeAllModules(CreateInterfaceFn *factorylist, int factorycount)
{
if ( IsGameConsole() )
{
// not valid for 360
return false;
}
bool bSuccess = true;
// Init vgui in the modules
int i;
for ( i = 0; i < m_Modules.Count(); i++ )
{
if (!m_Modules[i].moduleInterface->Initialize(factorylist, factorycount))
{
bSuccess = false;
Error("Platform Error: module failed to initialize\n");
}
}
// create a table of all the loaded modules
CreateInterfaceFn *moduleFactories = (CreateInterfaceFn *)_alloca(sizeof(CreateInterfaceFn) * m_Modules.Count());
for ( i = 0; i < m_Modules.Count(); i++ )
{
moduleFactories[i] = Sys_GetFactory(m_Modules[i].module);
}
// give the modules a chance to link themselves together
for (i = 0; i < m_Modules.Count(); i++)
{
if (!m_Modules[i].moduleInterface->PostInitialize(moduleFactories, m_Modules.Count()))
{
bSuccess = false;
Error("Platform Error: module failed to initialize\n");
}
m_Modules[i].moduleInterface->SetParent(GetGameUIBasePanel());
}
m_bModulesInitialized = true;
return bSuccess;
}
//-----------------------------------------------------------------------------
// Purpose: Loads and initializes all the modules specified in the platform file
//-----------------------------------------------------------------------------
bool CVGuiSystemModuleLoader::LoadPlatformModules(CreateInterfaceFn *factorylist, int factorycount, bool useSteamModules)
{
if ( IsGameConsole() )
{
// not valid for 360
return false;
}
bool bSuccess = true;
// load platform menu
KeyValues *kv = new KeyValues("Platform");
if (!kv->LoadFromFile(g_pFullFileSystem, "steam/games/PlatformMenu.vdf", "PLATFORM"))
{
kv->deleteThis();
return false;
}
// walk the platform menu loading all the interfaces
KeyValues *menuKeys = kv->FindKey("Menu", true);
for (KeyValues *it = menuKeys->GetFirstSubKey(); it != NULL; it = it->GetNextKey())
{
// see if we should skip steam modules
if (!useSteamModules && it->GetInt("SteamApp"))
continue;
const char *pchInterface = it->GetString("interface");
// don't load friends if we are using Steam Community
if ( !Q_stricmp( pchInterface, "VGuiModuleTracker001" ) && bSteamCommunityFriendsVersion )
continue;
// get copy out of steam cache
const char *dllPath = it->GetString("dll");
// load the module (LoadModule calls GetLocalCopy() under steam)
CSysModule *mod = g_pFullFileSystem->LoadModule(dllPath, "EXECUTABLE_PATH");
if (!mod)
{
Error("Platform Error: bad module '%s', not loading\n", it->GetString("dll"));
bSuccess = false;
continue;
}
// make sure we get the right version
IVGuiModule *moduleInterface = (IVGuiModule *)Sys_GetFactory(mod)(pchInterface, NULL);
if (!moduleInterface)
{
Warning("Platform Error: module version ('%s, %s) invalid, not loading\n", it->GetString("dll"), it->GetString("interface"));
bSuccess = false;
continue;
}
// store off the module
int newIndex = m_Modules.AddToTail();
m_Modules[newIndex].module = mod;
m_Modules[newIndex].moduleInterface = moduleInterface;
m_Modules[newIndex].data = it;
}
m_pPlatformModuleData = kv;
return InitializeAllModules(factorylist, factorycount) && bSuccess;
}
//-----------------------------------------------------------------------------
// Purpose: gives all platform modules a chance to Shutdown gracefully
//-----------------------------------------------------------------------------
void CVGuiSystemModuleLoader::ShutdownPlatformModules()
{
if ( IsGameConsole() )
{
// not valid for 360
return;
}
// static include guard to prevent recursive calls
static bool runningFunction = false;
if (runningFunction)
return;
runningFunction = true;
// deactivate all the modules first
DeactivatePlatformModules();
// give all the modules notice of quit
int i;
for ( i = 0; i < m_Modules.Count(); i++ )
{
vgui::ivgui()->PostMessage(m_Modules[i].moduleInterface->GetPanel(), new KeyValues("Command", "command", "Quit"), NULL);
}
for ( i = 0; i < m_Modules.Count(); i++ )
{
m_Modules[i].moduleInterface->Shutdown();
}
runningFunction = false;
}
//-----------------------------------------------------------------------------
// Purpose: Deactivates all the modules (puts them into in inactive but recoverable state)
//-----------------------------------------------------------------------------
void CVGuiSystemModuleLoader::DeactivatePlatformModules()
{
for (int i = 0; i < m_Modules.Count(); i++)
{
m_Modules[i].moduleInterface->Deactivate();
}
}
//-----------------------------------------------------------------------------
// Purpose: Reenables all the deactivated platform modules
//-----------------------------------------------------------------------------
void CVGuiSystemModuleLoader::ReactivatePlatformModules()
{
for (int i = 0; i < m_Modules.Count(); i++)
{
m_Modules[i].moduleInterface->Reactivate();
}
}
//-----------------------------------------------------------------------------
// Purpose: Disables and unloads platform
//-----------------------------------------------------------------------------
void CVGuiSystemModuleLoader::UnloadPlatformModules()
{
for (int i = 0; i < m_Modules.Count(); i++)
{
g_pFullFileSystem->UnloadModule(m_Modules[i].module);
}
m_Modules.RemoveAll();
if (m_pPlatformModuleData)
{
m_pPlatformModuleData->deleteThis();
m_pPlatformModuleData = NULL;
}
}
//-----------------------------------------------------------------------------
// Purpose: Called every frame
//-----------------------------------------------------------------------------
void CVGuiSystemModuleLoader::RunFrame()
{
}
//-----------------------------------------------------------------------------
// Purpose: returns number of modules loaded
//-----------------------------------------------------------------------------
int CVGuiSystemModuleLoader::GetModuleCount()
{
return m_Modules.Count();
}
//-----------------------------------------------------------------------------
// Purpose: returns the string menu name (unlocalized) of a module
// moduleIndex is of the range [0, GetModuleCount())
//-----------------------------------------------------------------------------
const char *CVGuiSystemModuleLoader::GetModuleLabel(int moduleIndex)
{
return m_Modules[moduleIndex].data->GetString("MenuName", "< unknown >");
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CVGuiSystemModuleLoader::IsModuleVisible(int moduleIndex)
{
return vgui::ipanel()->IsVisible( m_Modules[moduleIndex].moduleInterface->GetPanel() );
}
//-----------------------------------------------------------------------------
// Purpose: brings the specified module to the foreground
//-----------------------------------------------------------------------------
bool CVGuiSystemModuleLoader::IsModuleHidden(int moduleIndex)
{
return m_Modules[moduleIndex].data->GetBool("Hidden", false);
}
//-----------------------------------------------------------------------------
// Purpose: brings the specified module to the foreground
//-----------------------------------------------------------------------------
bool CVGuiSystemModuleLoader::ActivateModule(int moduleIndex)
{
if (!m_Modules.IsValidIndex(moduleIndex))
return false;
m_Modules[moduleIndex].moduleInterface->Activate();
return true;
}
//-----------------------------------------------------------------------------
// Purpose: activates a module by name
//-----------------------------------------------------------------------------
bool CVGuiSystemModuleLoader::ActivateModule(const char *moduleName)
{
for (int i = 0; i < GetModuleCount(); i++)
{
if (!stricmp(GetModuleLabel(i), moduleName) || !stricmp(m_Modules[i].data->GetName(), moduleName))
{
ActivateModule(i);
return true;
}
}
return false;
}
//-----------------------------------------------------------------------------
// Purpose: returns a modules interface factory
//-----------------------------------------------------------------------------
CreateInterfaceFn CVGuiSystemModuleLoader::GetModuleFactory(int moduleIndex)
{
return Sys_GetFactory(m_Modules[moduleIndex].module);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CVGuiSystemModuleLoader::PostMessageToAllModules(KeyValues *message)
{
for (int i = 0; i < m_Modules.Count(); i++)
{
vgui::ivgui()->PostMessage(m_Modules[i].moduleInterface->GetPanel(), message->MakeCopy(), NULL);
}
message->deleteThis();
}
//-----------------------------------------------------------------------------
// Purpose: sets the the platform should update and restart when it quits
//-----------------------------------------------------------------------------
void CVGuiSystemModuleLoader::SetPlatformToRestart()
{
m_bPlatformShouldRestartAfterExit = true;
}
//-----------------------------------------------------------------------------
// Purpose: data accessor
//-----------------------------------------------------------------------------
bool CVGuiSystemModuleLoader::ShouldPlatformRestart()
{
return m_bPlatformShouldRestartAfterExit;
}

View File

@ -0,0 +1,97 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Handles loading/unloading of different vgui modules into a shared context
//
//=============================================================================//
#ifndef VGUISYSTEMMODULELOADER_H
#define VGUISYSTEMMODULELOADER_H
#ifdef _WIN32
#pragma once
#endif
#include "vgui_controls/PHandle.h"
#include "UtlVector.h"
#include "IVGuiModuleLoader.h"
class IVGuiModule;
class KeyValues;
//-----------------------------------------------------------------------------
// Purpose: Handles loading/unloading of different vgui modules into a shared context
//-----------------------------------------------------------------------------
class CVGuiSystemModuleLoader : public IVGuiModuleLoader
{
public:
CVGuiSystemModuleLoader();
~CVGuiSystemModuleLoader();
// loads all the modules in the platform
bool LoadPlatformModules(CreateInterfaceFn *factorylist, int factorycount, bool useSteamModules);
// returns true if the module loader has loaded the modules
bool IsPlatformReady();
// needs to be called every frame - updates all the modules states
void RunFrame();
// returns number of modules loaded
int GetModuleCount();
// returns the string menu name (unlocalized) of a module
// moduleIndex is of the range [0, GetModuleCount())
const char *GetModuleLabel(int moduleIndex);
bool IsModuleHidden(int moduleIndex);
bool IsModuleVisible(int moduleIndex);
// returns a modules interface factory
CreateInterfaceFn GetModuleFactory(int moduleIndex);
// brings the specified module to the foreground
bool ActivateModule(int moduleIndex);
bool ActivateModule(const char *moduleName);
// Deactivates all the modules (puts them into in inactive but recoverable state)
void DeactivatePlatformModules();
// Reenables all the deactivated platform modules
void ReactivatePlatformModules();
// shuts down all the platform modules
void ShutdownPlatformModules();
// unload all active platform modules/dlls from memory
void UnloadPlatformModules();
// posts a message to all active modules
void PostMessageToAllModules(KeyValues *message);
// sets the the platform should update and restart when it quits
void SetPlatformToRestart();
// returns true if the platform should restart after exit
bool ShouldPlatformRestart();
private:
// sets up all the modules for use
bool InitializeAllModules(CreateInterfaceFn *factorylist, int factorycount);
bool m_bModulesInitialized;
bool m_bPlatformShouldRestartAfterExit;
struct module_t
{
CSysModule *module;
IVGuiModule *moduleInterface;
KeyValues *data;
};
CUtlVector<module_t> m_Modules;
KeyValues *m_pPlatformModuleData;
};
extern CVGuiSystemModuleLoader g_VModuleLoader;
#endif // VGUISYSTEMMODULELOADER_H