mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-07 17:29:36 +00:00
1
This commit is contained in:
@@ -0,0 +1,573 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Defines a group of app systems that all have the same lifetime
|
||||
// that need to be connected/initialized, etc. in a well-defined order
|
||||
//
|
||||
// $Revision: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "appframework/IAppSystemGroup.h"
|
||||
#include "appframework/IAppSystem.h"
|
||||
#include "interface.h"
|
||||
#include "filesystem.h"
|
||||
#include "filesystem_init.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
//extern ILoggingListener *g_pDefaultLoggingListener;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CAppSystemGroup::CAppSystemGroup( CAppSystemGroup *pAppSystemParent ) : m_SystemDict(false, 0, 16)
|
||||
{
|
||||
m_pParentAppSystem = pAppSystemParent;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Actually loads a DLL
|
||||
//-----------------------------------------------------------------------------
|
||||
CSysModule *CAppSystemGroup::LoadModuleDLL( const char *pDLLName )
|
||||
{
|
||||
return Sys_LoadModule( pDLLName );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Methods to load + unload DLLs
|
||||
//-----------------------------------------------------------------------------
|
||||
AppModule_t CAppSystemGroup::LoadModule( const char *pDLLName )
|
||||
{
|
||||
// Remove the extension when creating the name.
|
||||
int nLen = Q_strlen( pDLLName ) + 1;
|
||||
char *pModuleName = (char*)stackalloc( nLen );
|
||||
Q_StripExtension( pDLLName, pModuleName, nLen );
|
||||
|
||||
// See if we already loaded it...
|
||||
for ( int i = m_Modules.Count(); --i >= 0; )
|
||||
{
|
||||
if ( m_Modules[i].m_pModuleName )
|
||||
{
|
||||
if ( !Q_stricmp( pModuleName, m_Modules[i].m_pModuleName ) )
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
CSysModule *pSysModule = LoadModuleDLL( pDLLName );
|
||||
if (!pSysModule)
|
||||
{
|
||||
Warning("AppFramework : Unable to load module %s!\n", pDLLName );
|
||||
return APP_MODULE_INVALID;
|
||||
}
|
||||
|
||||
int nIndex = m_Modules.AddToTail();
|
||||
m_Modules[nIndex].m_pModule = pSysModule;
|
||||
m_Modules[nIndex].m_Factory = 0;
|
||||
m_Modules[nIndex].m_pModuleName = (char*)malloc( nLen );
|
||||
Q_strncpy( m_Modules[nIndex].m_pModuleName, pModuleName, nLen );
|
||||
|
||||
return nIndex;
|
||||
}
|
||||
|
||||
AppModule_t CAppSystemGroup::LoadModule( CreateInterfaceFn factory )
|
||||
{
|
||||
if (!factory)
|
||||
{
|
||||
Warning("AppFramework : Unable to load module %p!\n", factory );
|
||||
return APP_MODULE_INVALID;
|
||||
}
|
||||
|
||||
// See if we already loaded it...
|
||||
for ( int i = m_Modules.Count(); --i >= 0; )
|
||||
{
|
||||
if ( m_Modules[i].m_Factory )
|
||||
{
|
||||
if ( m_Modules[i].m_Factory == factory )
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
int nIndex = m_Modules.AddToTail();
|
||||
m_Modules[nIndex].m_pModule = NULL;
|
||||
m_Modules[nIndex].m_Factory = factory;
|
||||
m_Modules[nIndex].m_pModuleName = NULL;
|
||||
return nIndex;
|
||||
}
|
||||
|
||||
void CAppSystemGroup::UnloadAllModules()
|
||||
{
|
||||
// NOTE: Iterate in reverse order so they are unloaded in opposite order
|
||||
// from loading
|
||||
for (int i = m_Modules.Count(); --i >= 0; )
|
||||
{
|
||||
if ( m_Modules[i].m_pModule )
|
||||
{
|
||||
Sys_UnloadModule( m_Modules[i].m_pModule );
|
||||
}
|
||||
if ( m_Modules[i].m_pModuleName )
|
||||
{
|
||||
free( m_Modules[i].m_pModuleName );
|
||||
}
|
||||
}
|
||||
m_Modules.RemoveAll();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Methods to add/remove various global singleton systems
|
||||
//-----------------------------------------------------------------------------
|
||||
IAppSystem *CAppSystemGroup::AddSystem( AppModule_t module, const char *pInterfaceName )
|
||||
{
|
||||
if (module == APP_MODULE_INVALID)
|
||||
return NULL;
|
||||
|
||||
Assert( (module >= 0) && (module < m_Modules.Count()) );
|
||||
CreateInterfaceFn pFactory = m_Modules[module].m_pModule ? Sys_GetFactory( m_Modules[module].m_pModule ) : m_Modules[module].m_Factory;
|
||||
|
||||
int retval;
|
||||
void *pSystem = pFactory( pInterfaceName, &retval );
|
||||
if ((retval != IFACE_OK) || (!pSystem))
|
||||
{
|
||||
Warning("AppFramework : Unable to create system %s!\n", pInterfaceName );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IAppSystem *pAppSystem = static_cast<IAppSystem*>(pSystem);
|
||||
|
||||
int sysIndex = m_Systems.AddToTail( pAppSystem );
|
||||
|
||||
// Inserting into the dict will help us do named lookup later
|
||||
MEM_ALLOC_CREDIT();
|
||||
m_SystemDict.Insert( pInterfaceName, sysIndex );
|
||||
return pAppSystem;
|
||||
}
|
||||
|
||||
static char const *g_StageLookup[] =
|
||||
{
|
||||
"CREATION",
|
||||
"CONNECTION",
|
||||
"PREINITIALIZATION",
|
||||
"INITIALIZATION",
|
||||
"SHUTDOWN",
|
||||
"POSTSHUTDOWN",
|
||||
"DISCONNECTION",
|
||||
"DESTRUCTION",
|
||||
"NONE",
|
||||
};
|
||||
|
||||
void CAppSystemGroup::ReportStartupFailure( int nErrorStage, int nSysIndex )
|
||||
{
|
||||
char const *pszStageDesc = "Unknown";
|
||||
if ( nErrorStage >= 0 && nErrorStage < ARRAYSIZE( g_StageLookup ) )
|
||||
{
|
||||
pszStageDesc = g_StageLookup[ nErrorStage ];
|
||||
}
|
||||
|
||||
char const *pszSystemName = "(Unknown)";
|
||||
for ( int i = m_SystemDict.First(); i != m_SystemDict.InvalidIndex(); i = m_SystemDict.Next( i ) )
|
||||
{
|
||||
if ( m_SystemDict[ i ] != nSysIndex )
|
||||
continue;
|
||||
|
||||
pszSystemName = m_SystemDict.GetElementName( i );
|
||||
break;
|
||||
}
|
||||
|
||||
// Walk the dictionary
|
||||
Warning( "System (%s) failed during stage %s\n", pszSystemName, pszStageDesc );
|
||||
}
|
||||
|
||||
void CAppSystemGroup::AddSystem( IAppSystem *pAppSystem, const char *pInterfaceName )
|
||||
{
|
||||
if ( !pAppSystem )
|
||||
return;
|
||||
|
||||
int sysIndex = m_Systems.AddToTail( pAppSystem );
|
||||
|
||||
// Inserting into the dict will help us do named lookup later
|
||||
MEM_ALLOC_CREDIT();
|
||||
m_SystemDict.Insert( pInterfaceName, sysIndex );
|
||||
}
|
||||
|
||||
void CAppSystemGroup::RemoveAllSystems()
|
||||
{
|
||||
// NOTE: There's no deallcation here since we don't really know
|
||||
// how the allocation has happened. We could add a deallocation method
|
||||
// to the code in interface.h; although when the modules are unloaded
|
||||
// the deallocation will happen anyways
|
||||
m_Systems.RemoveAll();
|
||||
m_SystemDict.RemoveAll();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Simpler method of doing the LoadModule/AddSystem thing.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CAppSystemGroup::AddSystems( AppSystemInfo_t *pSystemList )
|
||||
{
|
||||
while ( pSystemList->m_pModuleName[0] )
|
||||
{
|
||||
AppModule_t module = LoadModule( pSystemList->m_pModuleName );
|
||||
IAppSystem *pSystem = AddSystem( module, pSystemList->m_pInterfaceName );
|
||||
if ( !pSystem )
|
||||
{
|
||||
Warning( "Unable to load interface %s from %s\n", pSystemList->m_pInterfaceName, pSystemList->m_pModuleName );
|
||||
return false;
|
||||
}
|
||||
++pSystemList;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Methods to find various global singleton systems
|
||||
//-----------------------------------------------------------------------------
|
||||
void *CAppSystemGroup::FindSystem( const char *pSystemName )
|
||||
{
|
||||
unsigned short i = m_SystemDict.Find( pSystemName );
|
||||
if (i != m_SystemDict.InvalidIndex())
|
||||
return m_Systems[m_SystemDict[i]];
|
||||
|
||||
// If it's not an interface we know about, it could be an older
|
||||
// version of an interface, or maybe something implemented by
|
||||
// one of the instantiated interfaces...
|
||||
|
||||
// QUESTION: What order should we iterate this in?
|
||||
// It controls who wins if multiple ones implement the same interface
|
||||
for ( i = 0; i < m_Systems.Count(); ++i )
|
||||
{
|
||||
void *pInterface = m_Systems[i]->QueryInterface( pSystemName );
|
||||
if (pInterface)
|
||||
return pInterface;
|
||||
}
|
||||
|
||||
if ( m_pParentAppSystem )
|
||||
{
|
||||
void* pInterface = m_pParentAppSystem->FindSystem( pSystemName );
|
||||
if ( pInterface )
|
||||
return pInterface;
|
||||
}
|
||||
|
||||
// No dice..
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets at the parent appsystem group
|
||||
//-----------------------------------------------------------------------------
|
||||
CAppSystemGroup *CAppSystemGroup::GetParent()
|
||||
{
|
||||
return m_pParentAppSystem;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Method to connect/disconnect all systems
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CAppSystemGroup::ConnectSystems()
|
||||
{
|
||||
for (int i = 0; i < m_Systems.Count(); ++i )
|
||||
{
|
||||
IAppSystem *sys = m_Systems[i];
|
||||
|
||||
if (!sys->Connect( GetFactory() ))
|
||||
{
|
||||
ReportStartupFailure( CONNECTION, i );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CAppSystemGroup::DisconnectSystems()
|
||||
{
|
||||
// Disconnect in reverse order of connection
|
||||
for (int i = m_Systems.Count(); --i >= 0; )
|
||||
{
|
||||
m_Systems[i]->Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Method to initialize/shutdown all systems
|
||||
//-----------------------------------------------------------------------------
|
||||
InitReturnVal_t CAppSystemGroup::InitSystems()
|
||||
{
|
||||
for (int i = 0; i < m_Systems.Count(); ++i )
|
||||
{
|
||||
InitReturnVal_t nRetVal = m_Systems[i]->Init();
|
||||
if ( nRetVal != INIT_OK )
|
||||
{
|
||||
ReportStartupFailure( INITIALIZATION, i );
|
||||
return nRetVal;
|
||||
}
|
||||
}
|
||||
return INIT_OK;
|
||||
}
|
||||
|
||||
void CAppSystemGroup::ShutdownSystems()
|
||||
{
|
||||
// Shutdown in reverse order of initialization
|
||||
for (int i = m_Systems.Count(); --i >= 0; )
|
||||
{
|
||||
m_Systems[i]->Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the stage at which the app system group ran into an error
|
||||
//-----------------------------------------------------------------------------
|
||||
CAppSystemGroup::AppSystemGroupStage_t CAppSystemGroup::GetErrorStage() const
|
||||
{
|
||||
return m_nErrorStage;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets at a factory that works just like FindSystem
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function is used to make this system appear to the outside world to
|
||||
// function exactly like the currently existing factory system
|
||||
CAppSystemGroup *s_pCurrentAppSystem;
|
||||
void *AppSystemCreateInterfaceFn(const char *pName, int *pReturnCode)
|
||||
{
|
||||
void *pInterface = s_pCurrentAppSystem->FindSystem( pName );
|
||||
if ( pReturnCode )
|
||||
{
|
||||
*pReturnCode = pInterface ? IFACE_OK : IFACE_FAILED;
|
||||
}
|
||||
return pInterface;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets at a class factory for the topmost appsystem group in an appsystem stack
|
||||
//-----------------------------------------------------------------------------
|
||||
CreateInterfaceFn CAppSystemGroup::GetFactory()
|
||||
{
|
||||
return AppSystemCreateInterfaceFn;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main application loop
|
||||
//-----------------------------------------------------------------------------
|
||||
int CAppSystemGroup::Run()
|
||||
{
|
||||
// The factory now uses this app system group
|
||||
s_pCurrentAppSystem = this;
|
||||
|
||||
// Load, connect, init
|
||||
int nRetVal = OnStartup();
|
||||
if ( m_nErrorStage != NONE )
|
||||
return nRetVal;
|
||||
|
||||
// Main loop implemented by the application
|
||||
// FIXME: HACK workaround to avoid vgui porting
|
||||
nRetVal = Main();
|
||||
|
||||
// Shutdown, disconnect, unload
|
||||
OnShutdown();
|
||||
|
||||
// The factory now uses the parent's app system group
|
||||
s_pCurrentAppSystem = GetParent();
|
||||
|
||||
return nRetVal;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Virtual methods for override
|
||||
//-----------------------------------------------------------------------------
|
||||
int CAppSystemGroup::Startup()
|
||||
{
|
||||
return OnStartup();
|
||||
}
|
||||
|
||||
void CAppSystemGroup::Shutdown()
|
||||
{
|
||||
return OnShutdown();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Use this version in cases where you can't control the main loop and
|
||||
// expect to be ticked
|
||||
//-----------------------------------------------------------------------------
|
||||
int CAppSystemGroup::OnStartup()
|
||||
{
|
||||
// The factory now uses this app system group
|
||||
s_pCurrentAppSystem = this;
|
||||
|
||||
m_nErrorStage = NONE;
|
||||
|
||||
// Call an installed application creation function
|
||||
if ( !Create() )
|
||||
{
|
||||
m_nErrorStage = CREATION;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Let all systems know about each other
|
||||
if ( !ConnectSystems() )
|
||||
{
|
||||
m_nErrorStage = CONNECTION;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Allow the application to do some work before init
|
||||
if ( !PreInit() )
|
||||
{
|
||||
m_nErrorStage = PREINITIALIZATION;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Call Init on all App Systems
|
||||
int nRetVal = InitSystems();
|
||||
if ( nRetVal != INIT_OK )
|
||||
{
|
||||
m_nErrorStage = INITIALIZATION;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return nRetVal;
|
||||
}
|
||||
|
||||
void CAppSystemGroup::OnShutdown()
|
||||
{
|
||||
// The factory now uses this app system group
|
||||
s_pCurrentAppSystem = this;
|
||||
|
||||
switch( m_nErrorStage )
|
||||
{
|
||||
case NONE:
|
||||
break;
|
||||
|
||||
case PREINITIALIZATION:
|
||||
case INITIALIZATION:
|
||||
goto disconnect;
|
||||
|
||||
case CREATION:
|
||||
case CONNECTION:
|
||||
goto destroy;
|
||||
}
|
||||
|
||||
// Cal Shutdown on all App Systems
|
||||
ShutdownSystems();
|
||||
|
||||
// Allow the application to do some work after shutdown
|
||||
PostShutdown();
|
||||
|
||||
disconnect:
|
||||
// Systems should disconnect from each other
|
||||
DisconnectSystems();
|
||||
|
||||
destroy:
|
||||
// Unload all DLLs loaded in the AppCreate block
|
||||
RemoveAllSystems();
|
||||
|
||||
// Have to do this because the logging listeners & response policies may live in modules which are being unloaded
|
||||
// @TODO: this seems like a bad legacy practice... app systems should unload their spew handlers gracefully.
|
||||
// LoggingSystem_ResetCurrentLoggingState();
|
||||
// Assert( g_pDefaultLoggingListener != NULL );
|
||||
// LoggingSystem_RegisterLoggingListener( g_pDefaultLoggingListener );
|
||||
|
||||
UnloadAllModules();
|
||||
|
||||
// Call an installed application destroy function
|
||||
Destroy();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// This class represents a group of app systems that are loaded through steam
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CSteamAppSystemGroup::CSteamAppSystemGroup( IFileSystem *pFileSystem, CAppSystemGroup *pAppSystemParent )
|
||||
{
|
||||
m_pFileSystem = pFileSystem;
|
||||
m_pGameInfoPath[0] = 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Used by CSteamApplication to set up necessary pointers if we can't do it in the constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSteamAppSystemGroup::Setup( IFileSystem *pFileSystem, CAppSystemGroup *pParentAppSystem )
|
||||
{
|
||||
m_pFileSystem = pFileSystem;
|
||||
m_pParentAppSystem = pParentAppSystem;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Loads the module from Steam
|
||||
//-----------------------------------------------------------------------------
|
||||
CSysModule *CSteamAppSystemGroup::LoadModuleDLL( const char *pDLLName )
|
||||
{
|
||||
return m_pFileSystem->LoadModule( pDLLName );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the game info path
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CSteamAppSystemGroup::GetGameInfoPath() const
|
||||
{
|
||||
return m_pGameInfoPath;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets up the search paths
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSteamAppSystemGroup::SetupSearchPaths( const char *pStartingDir, bool bOnlyUseStartingDir, bool bIsTool )
|
||||
{
|
||||
CFSSteamSetupInfo steamInfo;
|
||||
steamInfo.m_pDirectoryName = pStartingDir;
|
||||
steamInfo.m_bOnlyUseDirectoryName = bOnlyUseStartingDir;
|
||||
steamInfo.m_bToolsMode = bIsTool;
|
||||
steamInfo.m_bSetSteamDLLPath = true;
|
||||
steamInfo.m_bSteam = m_pFileSystem->IsSteam();
|
||||
if ( FileSystem_SetupSteamEnvironment( steamInfo ) != FS_OK )
|
||||
return false;
|
||||
|
||||
CFSMountContentInfo fsInfo;
|
||||
fsInfo.m_pFileSystem = m_pFileSystem;
|
||||
fsInfo.m_bToolsMode = bIsTool;
|
||||
fsInfo.m_pDirectoryName = steamInfo.m_GameInfoPath;
|
||||
|
||||
if ( FileSystem_MountContent( fsInfo ) != FS_OK )
|
||||
return false;
|
||||
|
||||
// Finally, load the search paths for the "GAME" path.
|
||||
CFSSearchPathsInit searchPathsInit;
|
||||
searchPathsInit.m_pDirectoryName = steamInfo.m_GameInfoPath;
|
||||
searchPathsInit.m_pFileSystem = fsInfo.m_pFileSystem;
|
||||
if ( FileSystem_LoadSearchPaths( searchPathsInit ) != FS_OK )
|
||||
return false;
|
||||
|
||||
FileSystem_AddSearchPath_Platform( fsInfo.m_pFileSystem, steamInfo.m_GameInfoPath );
|
||||
Q_strncpy( m_pGameInfoPath, steamInfo.m_GameInfoPath, sizeof(m_pGameInfoPath) );
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// The copyright to the contents herein is the property of Valve, L.L.C.
|
||||
// The contents may be used and/or copied only with the written permission of
|
||||
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
|
||||
// the agreement/contract under which the contents have been supplied.
|
||||
//
|
||||
//=============================================================================
|
||||
#ifdef _WIN32
|
||||
|
||||
#if defined( _WIN32 ) && !defined( _X360 )
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include "appframework/vguimatsysapp.h"
|
||||
#include "filesystem.h"
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include "vgui/ivgui.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui_controls/controls.h"
|
||||
#include "vgui/ischeme.h"
|
||||
#include "vgui/ilocalize.h"
|
||||
#include "tier0/dbg.h"
|
||||
#include "tier0/icommandline.h"
|
||||
#include "materialsystem/materialsystem_config.h"
|
||||
#include "filesystem_init.h"
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
#include "inputsystem/iinputsystem.h"
|
||||
#include "tier3/tier3.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CVguiMatSysApp::CVguiMatSysApp()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Create all singleton systems
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVguiMatSysApp::Create()
|
||||
{
|
||||
AppSystemInfo_t appSystems[] =
|
||||
{
|
||||
{ "inputsystem.dll", INPUTSYSTEM_INTERFACE_VERSION },
|
||||
{ "materialsystem.dll", MATERIAL_SYSTEM_INTERFACE_VERSION },
|
||||
|
||||
// NOTE: This has to occur before vgui2.dll so it replaces vgui2's surface implementation
|
||||
{ "vguimatsurface.dll", VGUI_SURFACE_INTERFACE_VERSION },
|
||||
{ "vgui2.dll", VGUI_IVGUI_INTERFACE_VERSION },
|
||||
|
||||
// Required to terminate the list
|
||||
{ "", "" }
|
||||
};
|
||||
|
||||
if ( !AddSystems( appSystems ) )
|
||||
return false;
|
||||
|
||||
IMaterialSystem *pMaterialSystem = (IMaterialSystem*)FindSystem( MATERIAL_SYSTEM_INTERFACE_VERSION );
|
||||
|
||||
if ( !pMaterialSystem )
|
||||
{
|
||||
Warning( "CVguiMatSysApp::Create: Unable to connect to necessary interface!\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
pMaterialSystem->SetShaderAPI( "shaderapidx9.dll" );
|
||||
return true;
|
||||
}
|
||||
|
||||
void CVguiMatSysApp::Destroy()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Window management
|
||||
//-----------------------------------------------------------------------------
|
||||
void*CVguiMatSysApp::CreateAppWindow( char const *pTitle, bool bWindowed, int w, int h )
|
||||
{
|
||||
WNDCLASSEX wc;
|
||||
memset( &wc, 0, sizeof( wc ) );
|
||||
wc.cbSize = sizeof( wc );
|
||||
wc.style = CS_OWNDC | CS_DBLCLKS;
|
||||
wc.lpfnWndProc = DefWindowProc;
|
||||
wc.hInstance = (HINSTANCE)GetAppInstance();
|
||||
wc.lpszClassName = "Valve001";
|
||||
wc.hIcon = NULL; //LoadIcon( s_HInstance, MAKEINTRESOURCE( IDI_LAUNCHER ) );
|
||||
wc.hIconSm = wc.hIcon;
|
||||
|
||||
RegisterClassEx( &wc );
|
||||
|
||||
// Note, it's hidden
|
||||
DWORD style = WS_POPUP | WS_CLIPSIBLINGS;
|
||||
|
||||
if ( bWindowed )
|
||||
{
|
||||
// Give it a frame
|
||||
style |= WS_OVERLAPPEDWINDOW;
|
||||
style &= ~WS_THICKFRAME;
|
||||
}
|
||||
|
||||
// Never a max box
|
||||
style &= ~WS_MAXIMIZEBOX;
|
||||
|
||||
RECT windowRect;
|
||||
windowRect.top = 0;
|
||||
windowRect.left = 0;
|
||||
windowRect.right = w;
|
||||
windowRect.bottom = h;
|
||||
|
||||
// Compute rect needed for that size client area based on window style
|
||||
AdjustWindowRectEx(&windowRect, style, FALSE, 0);
|
||||
|
||||
// Create the window
|
||||
void *hWnd = CreateWindow( wc.lpszClassName, pTitle, style, 0, 0,
|
||||
windowRect.right - windowRect.left, windowRect.bottom - windowRect.top,
|
||||
NULL, NULL, (HINSTANCE)GetAppInstance(), NULL );
|
||||
|
||||
if (!hWnd)
|
||||
return NULL;
|
||||
|
||||
int CenterX, CenterY;
|
||||
|
||||
CenterX = (GetSystemMetrics(SM_CXSCREEN) - w) / 2;
|
||||
CenterY = (GetSystemMetrics(SM_CYSCREEN) - h) / 2;
|
||||
CenterX = (CenterX < 0) ? 0: CenterX;
|
||||
CenterY = (CenterY < 0) ? 0: CenterY;
|
||||
|
||||
// In VCR modes, keep it in the upper left so mouse coordinates are always relative to the window.
|
||||
SetWindowPos( (HWND)hWnd, NULL, CenterX, CenterY, 0, 0,
|
||||
SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_DRAWFRAME);
|
||||
|
||||
return hWnd;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Pump messages
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVguiMatSysApp::AppPumpMessages()
|
||||
{
|
||||
g_pInputSystem->PollInputState();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets up the game path
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVguiMatSysApp::SetupSearchPaths( const char *pStartingDir, bool bOnlyUseStartingDir, bool bIsTool )
|
||||
{
|
||||
if ( !BaseClass::SetupSearchPaths( pStartingDir, bOnlyUseStartingDir, bIsTool ) )
|
||||
return false;
|
||||
|
||||
g_pFullFileSystem->AddSearchPath( GetGameInfoPath(), "SKIN", PATH_ADD_TO_HEAD );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Init, shutdown
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVguiMatSysApp::PreInit( )
|
||||
{
|
||||
if ( !BaseClass::PreInit() )
|
||||
return false;
|
||||
|
||||
if ( !g_pFullFileSystem || !g_pMaterialSystem || !g_pInputSystem || !g_pMatSystemSurface )
|
||||
{
|
||||
Warning( "CVguiMatSysApp::PreInit: Unable to connect to necessary interface!\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add paths...
|
||||
if ( !SetupSearchPaths( NULL, false, true ) )
|
||||
return false;
|
||||
|
||||
const char *pArg;
|
||||
int iWidth = 1024;
|
||||
int iHeight = 768;
|
||||
bool bWindowed = (CommandLine()->CheckParm( "-fullscreen" ) == NULL);
|
||||
if (CommandLine()->CheckParm( "-width", &pArg ))
|
||||
{
|
||||
iWidth = atoi( pArg );
|
||||
}
|
||||
if (CommandLine()->CheckParm( "-height", &pArg ))
|
||||
{
|
||||
iHeight = atoi( pArg );
|
||||
}
|
||||
|
||||
m_nWidth = iWidth;
|
||||
m_nHeight = iHeight;
|
||||
m_HWnd = CreateAppWindow( GetAppName(), bWindowed, iWidth, iHeight );
|
||||
if ( !m_HWnd )
|
||||
return false;
|
||||
|
||||
g_pInputSystem->AttachToWindow( m_HWnd );
|
||||
g_pMatSystemSurface->AttachToWindow( m_HWnd );
|
||||
|
||||
// NOTE: If we specifically wanted to use a particular shader DLL, we set it here...
|
||||
//m_pMaterialSystem->SetShaderAPI( "shaderapidx8" );
|
||||
|
||||
// Get the adapter from the command line....
|
||||
const char *pAdapterString;
|
||||
int adapter = 0;
|
||||
if (CommandLine()->CheckParm( "-adapter", &pAdapterString ))
|
||||
{
|
||||
adapter = atoi( pAdapterString );
|
||||
}
|
||||
|
||||
int adapterFlags = 0;
|
||||
if ( CommandLine()->CheckParm( "-ref" ) )
|
||||
{
|
||||
adapterFlags |= MATERIAL_INIT_REFERENCE_RASTERIZER;
|
||||
}
|
||||
if ( AppUsesReadPixels() )
|
||||
{
|
||||
adapterFlags |= MATERIAL_INIT_ALLOCATE_FULLSCREEN_TEXTURE;
|
||||
}
|
||||
|
||||
g_pMaterialSystem->SetAdapter( adapter, adapterFlags );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CVguiMatSysApp::PostShutdown()
|
||||
{
|
||||
if ( g_pMatSystemSurface && g_pInputSystem )
|
||||
{
|
||||
g_pMatSystemSurface->AttachToWindow( NULL );
|
||||
g_pInputSystem->DetachFromWindow( );
|
||||
}
|
||||
|
||||
BaseClass::PostShutdown();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the window size
|
||||
//-----------------------------------------------------------------------------
|
||||
int CVguiMatSysApp::GetWindowWidth() const
|
||||
{
|
||||
return m_nWidth;
|
||||
}
|
||||
|
||||
int CVguiMatSysApp::GetWindowHeight() const
|
||||
{
|
||||
return m_nHeight;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the window
|
||||
//-----------------------------------------------------------------------------
|
||||
void* CVguiMatSysApp::GetAppWindow()
|
||||
{
|
||||
return m_HWnd;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the video mode
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVguiMatSysApp::SetVideoMode( )
|
||||
{
|
||||
MaterialSystem_Config_t config;
|
||||
if ( CommandLine()->CheckParm( "-fullscreen" ) )
|
||||
{
|
||||
config.SetFlag( MATSYS_VIDCFG_FLAGS_WINDOWED, false );
|
||||
}
|
||||
else
|
||||
{
|
||||
config.SetFlag( MATSYS_VIDCFG_FLAGS_WINDOWED, true );
|
||||
}
|
||||
|
||||
if ( CommandLine()->CheckParm( "-resizing" ) )
|
||||
{
|
||||
config.SetFlag( MATSYS_VIDCFG_FLAGS_RESIZING, true );
|
||||
}
|
||||
|
||||
if ( CommandLine()->CheckParm( "-mat_vsync" ) )
|
||||
{
|
||||
config.SetFlag( MATSYS_VIDCFG_FLAGS_NO_WAIT_FOR_VSYNC, false );
|
||||
}
|
||||
|
||||
config.m_nAASamples = CommandLine()->ParmValue( "-mat_antialias", 1 );
|
||||
config.m_nAAQuality = CommandLine()->ParmValue( "-mat_aaquality", 0 );
|
||||
|
||||
config.m_VideoMode.m_Width = config.m_VideoMode.m_Height = 0;
|
||||
config.m_VideoMode.m_Format = IMAGE_FORMAT_BGRX8888;
|
||||
config.m_VideoMode.m_RefreshRate = 0;
|
||||
config.SetFlag( MATSYS_VIDCFG_FLAGS_STENCIL, true );
|
||||
|
||||
bool modeSet = g_pMaterialSystem->SetMode( m_HWnd, config );
|
||||
if (!modeSet)
|
||||
{
|
||||
Error( "Unable to set mode\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
g_pMaterialSystem->OverrideConfig( config, false );
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: An application framework
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifdef POSIX
|
||||
#error
|
||||
#else
|
||||
#if defined( _WIN32 ) && !defined( _X360 )
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include "appframework/appframework.h"
|
||||
#include "tier0/dbg.h"
|
||||
#include "tier0/icommandline.h"
|
||||
#include "interface.h"
|
||||
#include "filesystem.h"
|
||||
#include "appframework/iappsystemgroup.h"
|
||||
#include "filesystem_init.h"
|
||||
#include "vstdlib/cvar.h"
|
||||
#include "xbox/xbox_console.h"
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Globals...
|
||||
//-----------------------------------------------------------------------------
|
||||
HINSTANCE s_HInstance;
|
||||
|
||||
//static CSimpleWindowsLoggingListener s_SimpleWindowsLoggingListener;
|
||||
//static CSimpleLoggingListener s_SimpleLoggingListener;
|
||||
//ILoggingListener *g_pDefaultLoggingListener = &s_SimpleLoggingListener;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// HACK: Since I don't want to refit vgui yet...
|
||||
//-----------------------------------------------------------------------------
|
||||
void *GetAppInstance()
|
||||
{
|
||||
return s_HInstance;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the application instance, should only be used if you're not calling AppMain.
|
||||
//-----------------------------------------------------------------------------
|
||||
void SetAppInstance( void* hInstance )
|
||||
{
|
||||
s_HInstance = (HINSTANCE)hInstance;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Specific 360 environment setup.
|
||||
//-----------------------------------------------------------------------------
|
||||
#if defined( _X360 )
|
||||
bool SetupEnvironment360()
|
||||
{
|
||||
CommandLine()->CreateCmdLine( GetCommandLine() );
|
||||
|
||||
if ( !CommandLine()->FindParm( "-game" ) && !CommandLine()->FindParm( "-vproject" ) )
|
||||
{
|
||||
// add the default game name due to lack of vproject environment
|
||||
CommandLine()->AppendParm( "-game", "hl2" );
|
||||
}
|
||||
|
||||
// success
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Version of AppMain used by windows applications
|
||||
//-----------------------------------------------------------------------------
|
||||
int AppMain( void* hInstance, void* hPrevInstance, const char* lpCmdLine, int nCmdShow, CAppSystemGroup *pAppSystemGroup )
|
||||
{
|
||||
Assert( pAppSystemGroup );
|
||||
|
||||
// g_pDefaultLoggingListener = &s_SimpleWindowsLoggingListener;
|
||||
s_HInstance = (HINSTANCE)hInstance;
|
||||
#if !defined( _X360 )
|
||||
CommandLine()->CreateCmdLine( ::GetCommandLine() );
|
||||
#else
|
||||
SetupEnvironment360();
|
||||
#endif
|
||||
|
||||
return pAppSystemGroup->Run();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Version of AppMain used by console applications
|
||||
//-----------------------------------------------------------------------------
|
||||
int AppMain( int argc, char **argv, CAppSystemGroup *pAppSystemGroup )
|
||||
{
|
||||
Assert( pAppSystemGroup );
|
||||
|
||||
// g_pDefaultLoggingListener = &s_SimpleLoggingListener;
|
||||
s_HInstance = NULL;
|
||||
#if !defined( _X360 )
|
||||
CommandLine()->CreateCmdLine( argc, argv );
|
||||
#else
|
||||
SetupEnvironment360();
|
||||
#endif
|
||||
|
||||
return pAppSystemGroup->Run();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Used to startup/shutdown the application
|
||||
//-----------------------------------------------------------------------------
|
||||
int AppStartup( void* hInstance, void* hPrevInstance, const char* lpCmdLine, int nCmdShow, CAppSystemGroup *pAppSystemGroup )
|
||||
{
|
||||
Assert( pAppSystemGroup );
|
||||
|
||||
// g_pDefaultLoggingListener = &s_SimpleWindowsLoggingListener;
|
||||
s_HInstance = (HINSTANCE)hInstance;
|
||||
#if !defined( _X360 )
|
||||
CommandLine()->CreateCmdLine( ::GetCommandLine() );
|
||||
#else
|
||||
SetupEnvironment360();
|
||||
#endif
|
||||
|
||||
return pAppSystemGroup->Startup();
|
||||
}
|
||||
|
||||
int AppStartup( int argc, char **argv, CAppSystemGroup *pAppSystemGroup )
|
||||
{
|
||||
Assert( pAppSystemGroup );
|
||||
|
||||
// g_pDefaultLoggingListener = &s_SimpleLoggingListener;
|
||||
s_HInstance = NULL;
|
||||
#if !defined( _X360 )
|
||||
CommandLine()->CreateCmdLine( argc, argv );
|
||||
#else
|
||||
SetupEnvironment360();
|
||||
#endif
|
||||
|
||||
return pAppSystemGroup->Startup();
|
||||
}
|
||||
|
||||
void AppShutdown( CAppSystemGroup *pAppSystemGroup )
|
||||
{
|
||||
Assert( pAppSystemGroup );
|
||||
pAppSystemGroup->Shutdown();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Default implementation of an application meant to be run using Steam
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CSteamApplication::CSteamApplication( CSteamAppSystemGroup *pAppSystemGroup )
|
||||
{
|
||||
m_pChildAppSystemGroup = pAppSystemGroup;
|
||||
m_pFileSystem = NULL;
|
||||
m_bSteam = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Create necessary interfaces
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSteamApplication::Create()
|
||||
{
|
||||
FileSystem_SetErrorMode( FS_ERRORMODE_AUTO );
|
||||
|
||||
char pFileSystemDLL[MAX_PATH];
|
||||
if ( FileSystem_GetFileSystemDLLName( pFileSystemDLL, MAX_PATH, m_bSteam ) != FS_OK )
|
||||
return false;
|
||||
|
||||
// Add in the cvar factory
|
||||
AppModule_t cvarModule = LoadModule( VStdLib_GetICVarFactory() );
|
||||
AddSystem( cvarModule, CVAR_INTERFACE_VERSION );
|
||||
|
||||
AppModule_t fileSystemModule = LoadModule( pFileSystemDLL );
|
||||
m_pFileSystem = (IFileSystem*)AddSystem( fileSystemModule, FILESYSTEM_INTERFACE_VERSION );
|
||||
if ( !m_pFileSystem )
|
||||
{
|
||||
Error( "Unable to load %s", pFileSystemDLL );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// The file system pointer is invalid at this point
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSteamApplication::Destroy()
|
||||
{
|
||||
m_pFileSystem = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Pre-init, shutdown
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSteamApplication::PreInit()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void CSteamApplication::PostShutdown()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Run steam main loop
|
||||
//-----------------------------------------------------------------------------
|
||||
int CSteamApplication::Main()
|
||||
{
|
||||
// Now that Steam is loaded, we can load up main libraries through steam
|
||||
if ( FileSystem_SetBasePaths( m_pFileSystem ) != FS_OK )
|
||||
return 0;
|
||||
|
||||
m_pChildAppSystemGroup->Setup( m_pFileSystem, this );
|
||||
return m_pChildAppSystemGroup->Run();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Use this version in cases where you can't control the main loop and
|
||||
// expect to be ticked
|
||||
//-----------------------------------------------------------------------------
|
||||
int CSteamApplication::Startup()
|
||||
{
|
||||
int nRetVal = BaseClass::Startup();
|
||||
if ( GetErrorStage() != NONE )
|
||||
return nRetVal;
|
||||
|
||||
if ( FileSystem_SetBasePaths( m_pFileSystem ) != FS_OK )
|
||||
return 0;
|
||||
|
||||
// Now that Steam is loaded, we can load up main libraries through steam
|
||||
m_pChildAppSystemGroup->Setup( m_pFileSystem, this );
|
||||
return m_pChildAppSystemGroup->Startup();
|
||||
}
|
||||
|
||||
void CSteamApplication::Shutdown()
|
||||
{
|
||||
m_pChildAppSystemGroup->Shutdown();
|
||||
BaseClass::Shutdown();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// APPFRAMEWORK.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$macro SRCDIR ".."
|
||||
|
||||
$include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$General
|
||||
{
|
||||
$AdditionalProjectDependencies "$BASE;togl" [!$IS_LIB_PROJECT && $GL]
|
||||
}
|
||||
|
||||
$Linker [$OSXALL]
|
||||
{
|
||||
$SystemFrameworks "Carbon;OpenGL;Quartz;Cocoa;IOKit"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "appframework"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "AppSystemGroup.cpp"
|
||||
$File "$SRCDIR\public\filesystem_init.cpp"
|
||||
$File "vguimatsysapp.cpp" [$WIN32]
|
||||
$File "winapp.cpp" [$WIN32]
|
||||
$File "posixapp.cpp" [$POSIX]
|
||||
$File "sdlmgr.cpp" [$SDL]
|
||||
$File "glmrendererinfo_osx.mm" [$OSXALL]
|
||||
}
|
||||
|
||||
$Folder "Interface"
|
||||
{
|
||||
$File "$SRCDIR\public\appframework\AppFramework.h"
|
||||
$File "$SRCDIR\public\appframework\IAppSystem.h"
|
||||
$File "$SRCDIR\public\appframework\IAppSystemGroup.h"
|
||||
$File "$SRCDIR\public\appframework\tier2app.h"
|
||||
$File "$SRCDIR\public\appframework\tier3app.h"
|
||||
$File "$SRCDIR\public\appframework\VguiMatSysApp.h"
|
||||
$File "$SRCDIR\public\appframework\ilaunchermgr.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$ImpLib togl [!$IS_LIB_PROJECT && $GL]
|
||||
$ImpLib SDL2 [!$IS_LIB_PROJECT && $SDL]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,630 @@
|
||||
//========= Copyright 1996-2009, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Defines a group of app systems that all have the same lifetime
|
||||
// that need to be connected/initialized, etc. in a well-defined order
|
||||
//
|
||||
// $Revision: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
//===============================================================================
|
||||
|
||||
GLMRendererInfo::GLMRendererInfo( void )
|
||||
{
|
||||
m_display = NULL;
|
||||
Q_memset( &m_info, 0, sizeof( m_info ) );
|
||||
}
|
||||
|
||||
GLMRendererInfo::~GLMRendererInfo( void )
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
|
||||
if (m_display)
|
||||
{
|
||||
delete m_display;
|
||||
m_display = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// !!! FIXME: sync this function with the Mac version in case anything important has changed.
|
||||
void GLMRendererInfo::Init( GLMRendererInfoFields *info )
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
|
||||
m_info = *info;
|
||||
m_display = NULL;
|
||||
|
||||
m_info.m_fullscreen = 0;
|
||||
m_info.m_accelerated = 1;
|
||||
m_info.m_windowed = 1;
|
||||
|
||||
m_info.m_ati = true;
|
||||
m_info.m_atiNewer = true;
|
||||
|
||||
m_info.m_hasGammaWrites = true;
|
||||
|
||||
// If you haven't created a GL context by now (and initialized gGL), you're about to crash.
|
||||
|
||||
m_info.m_hasMixedAttachmentSizes = gGL->m_bHave_GL_ARB_framebuffer_object;
|
||||
m_info.m_hasBGRA = gGL->m_bHave_GL_EXT_vertex_array_bgra;
|
||||
|
||||
// !!! FIXME: what do these do on the Mac?
|
||||
m_info.m_hasNewFullscreenMode = false;
|
||||
m_info.m_hasNativeClipVertexMode = true;
|
||||
|
||||
// if user disabled them
|
||||
if (CommandLine()->FindParm("-glmdisableclipplanes"))
|
||||
{
|
||||
m_info.m_hasNativeClipVertexMode = false;
|
||||
}
|
||||
|
||||
// or maybe enabled them..
|
||||
if (CommandLine()->FindParm("-glmenableclipplanes"))
|
||||
{
|
||||
m_info.m_hasNativeClipVertexMode = true;
|
||||
}
|
||||
|
||||
m_info.m_hasOcclusionQuery = gGL->m_bHave_GL_ARB_occlusion_query;
|
||||
m_info.m_hasFramebufferBlit = gGL->m_bHave_GL_EXT_framebuffer_blit || gGL->m_bHave_GL_ARB_framebuffer_object;
|
||||
|
||||
GLint nMaxAniso = 0;
|
||||
gGL->glGetIntegerv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &nMaxAniso );
|
||||
m_info.m_maxAniso = clamp<int>( nMaxAniso, 0, 16 );
|
||||
|
||||
// We don't currently used bindable uniforms, but I've been experimenting with them so I might as well check this in just in case they turn out to be useful.
|
||||
m_info.m_hasBindableUniforms = gGL->m_bHave_GL_EXT_bindable_uniform;
|
||||
m_info.m_hasBindableUniforms = false; // !!! FIXME hardwiring this path to false until we see how to accelerate it properly
|
||||
m_info.m_maxVertexBindableUniforms = 0;
|
||||
m_info.m_maxFragmentBindableUniforms = 0;
|
||||
m_info.m_maxBindableUniformSize = 0;
|
||||
|
||||
if (m_info.m_hasBindableUniforms)
|
||||
{
|
||||
gGL->glGetIntegerv(GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT, &m_info.m_maxVertexBindableUniforms);
|
||||
gGL->glGetIntegerv(GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT, &m_info.m_maxFragmentBindableUniforms);
|
||||
gGL->glGetIntegerv(GL_MAX_BINDABLE_UNIFORM_SIZE_EXT, &m_info.m_maxBindableUniformSize);
|
||||
if ( ( m_info.m_maxVertexBindableUniforms < 1 ) || ( m_info.m_maxFragmentBindableUniforms < 1 ) || ( m_info.m_maxBindableUniformSize < ( sizeof( float ) * 4 * 256 ) ) )
|
||||
{
|
||||
m_info.m_hasBindableUniforms = false;
|
||||
}
|
||||
}
|
||||
|
||||
m_info.m_hasUniformBuffers = gGL->m_bHave_GL_ARB_uniform_buffer;
|
||||
m_info.m_hasPerfPackage1 = true; // this flag is Mac-specific. We do slower things if you don't have Mac OS X 10.x.y or later. Linux always does the fast path!
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// runtime options that aren't negotiable once set
|
||||
|
||||
m_info.m_hasDualShaders = CommandLine()->FindParm("-glmdualshaders") != 0;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// "can'ts "
|
||||
|
||||
#if defined( OSX )
|
||||
m_info.m_cantBlitReliably = m_info.m_intel; //FIXME X3100&10.6.3 has problems blitting.. adjust this if bug fixed in 10.6.4
|
||||
#else
|
||||
// m_cantBlitReliably path doesn't work right now, and the Intel path is different for us on Linux/Win7 anyway
|
||||
m_info.m_cantBlitReliably = false;
|
||||
#endif
|
||||
|
||||
if (CommandLine()->FindParm("-glmenabletrustblit"))
|
||||
{
|
||||
m_info.m_cantBlitReliably = false; // we trust the blit, so set the cant-blit cap to false
|
||||
}
|
||||
if (CommandLine()->FindParm("-glmdisabletrustblit"))
|
||||
{
|
||||
m_info.m_cantBlitReliably = true; // we do not trust the blit, so set the cant-blit cap to true
|
||||
}
|
||||
|
||||
// MSAA resolve issues
|
||||
m_info.m_cantResolveFlipped = false;
|
||||
|
||||
|
||||
#if defined( OSX )
|
||||
m_info.m_cantResolveScaled = true; // generally true until new extension ships
|
||||
#else
|
||||
// DON'T just slam this to false and run without first testing with -gl_debug enabled on NVidia/AMD/etc.
|
||||
// This path needs the m_bHave_GL_EXT_framebuffer_multisample_blit_scaled extension.
|
||||
m_info.m_cantResolveScaled = true;
|
||||
|
||||
if ( gGL->m_bHave_GL_EXT_framebuffer_multisample_blit_scaled )
|
||||
{
|
||||
m_info.m_cantResolveScaled = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// gamma decode impacting shader codegen
|
||||
m_info.m_costlyGammaFlips = false;
|
||||
}
|
||||
|
||||
void GLMRendererInfo::PopulateDisplays()
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
|
||||
Assert( !m_display );
|
||||
m_display = new GLMDisplayInfo;
|
||||
|
||||
// Populate display mode table.
|
||||
m_display->PopulateModes();
|
||||
}
|
||||
|
||||
|
||||
void GLMRendererInfo::Dump( int which )
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
|
||||
GLMPRINTF(("\n #%d: GLMRendererInfo @ %p, renderer-id=(%08x) display-mask=%08x vram=%dMB",
|
||||
which, this,
|
||||
m_info.m_rendererID,
|
||||
m_info.m_displayMask,
|
||||
m_info.m_vidMemory >> 20
|
||||
));
|
||||
GLMPRINTF(("\n VendorID=%04x DeviceID=%04x Model=%s",
|
||||
m_info.m_pciVendorID,
|
||||
m_info.m_pciDeviceID,
|
||||
m_info.m_pciModelString
|
||||
));
|
||||
|
||||
m_display->Dump( which );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
GLMDisplayDB::GLMDisplayDB ()
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
|
||||
m_renderer.m_display = NULL;
|
||||
}
|
||||
|
||||
GLMDisplayDB::~GLMDisplayDB ( void )
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
|
||||
if ( m_renderer.m_display )
|
||||
{
|
||||
delete m_renderer.m_display;
|
||||
m_renderer.m_display = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX
|
||||
#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047
|
||||
#endif
|
||||
|
||||
#ifndef GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX
|
||||
#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048
|
||||
#endif
|
||||
|
||||
#ifndef GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX
|
||||
#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049
|
||||
#endif
|
||||
|
||||
#ifndef GL_VBO_FREE_MEMORY_ATI
|
||||
#define GL_VBO_FREE_MEMORY_ATI 0x87FB
|
||||
#endif
|
||||
|
||||
#ifndef GL_TEXTURE_FREE_MEMORY_ATI
|
||||
#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC
|
||||
#endif
|
||||
|
||||
#ifndef GL_RENDERBUFFER_FREE_MEMORY_ATI
|
||||
#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD
|
||||
#endif
|
||||
|
||||
void GLMDisplayDB::PopulateRenderers( void )
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
|
||||
Assert( !m_renderer.m_display );
|
||||
|
||||
GLMRendererInfoFields fields;
|
||||
memset( &fields, 0, sizeof(fields) );
|
||||
|
||||
// Assume 512MB of available video memory
|
||||
fields.m_vidMemory = 512 * 1024 * 1024;
|
||||
|
||||
DebugPrintf( "GL_NVX_gpu_memory_info: %s\n", gGL->m_bHave_GL_NVX_gpu_memory_info ? "AVAILABLE" : "UNAVAILABLE" );
|
||||
DebugPrintf( "GL_ATI_meminfo: %s\n", gGL->m_bHave_GL_ATI_meminfo ? "AVAILABLE" : "UNAVAILABLE" );
|
||||
|
||||
if ( gGL->m_bHave_GL_NVX_gpu_memory_info )
|
||||
{
|
||||
gGL->glGetError();
|
||||
|
||||
GLint nTotalDedicated = 0, nTotalAvail = 0, nCurrentAvail = 0;
|
||||
gGL->glGetIntegerv( GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &nTotalDedicated );
|
||||
gGL->glGetIntegerv( GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &nTotalAvail );
|
||||
gGL->glGetIntegerv( GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &nCurrentAvail );
|
||||
|
||||
if ( gGL->glGetError() )
|
||||
{
|
||||
DebugPrintf( "GL_NVX_gpu_memory_info: Failed retrieving available GPU memory\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugPrintf( "GL_NVX_gpu_memory_info: Total Dedicated: %u, Total Avail: %u, Current Avail: %u\n", nTotalDedicated, nTotalAvail, nCurrentAvail );
|
||||
|
||||
// Try to do something reasonable. Should we report dedicated or total available to the engine here?
|
||||
// For now, just take the MAX of both.
|
||||
uint64 nActualAvail = static_cast<uint64>( MAX( nTotalAvail, nTotalDedicated ) ) * 1024;
|
||||
fields.m_vidMemory = static_cast< GLint >( MIN( nActualAvail, 0x7FFFFFFF ) );
|
||||
}
|
||||
}
|
||||
else if ( gGL->m_bHave_GL_ATI_meminfo )
|
||||
{
|
||||
// As of 10/8/12 this extension is only available under Linux and Windows FireGL parts.
|
||||
gGL->glGetError();
|
||||
|
||||
GLint nAvail[4] = { 0, 0, 0, 0 };
|
||||
gGL->glGetIntegerv( GL_TEXTURE_FREE_MEMORY_ATI, nAvail );
|
||||
|
||||
if ( gGL->glGetError() )
|
||||
{
|
||||
DebugPrintf( "GL_ATI_meminfo: Failed retrieving available GPU memory\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
// param[0] - total memory free in the pool
|
||||
// param[1] - largest available free block in the pool
|
||||
// param[2] - total auxiliary memory free
|
||||
// param[3] - largest auxiliary free block
|
||||
|
||||
DebugPrintf( "GL_ATI_meminfo: GL_TEXTURE_FREE_MEMORY_ATI: Total Free: %i, Largest Avail: %i, Total Aux: %i, Largest Aux Avail: %i\n",
|
||||
nAvail[0], nAvail[1], nAvail[2], nAvail[3] );
|
||||
|
||||
uint64 nActualAvail = static_cast<uint64>( nAvail[0] ) * 1024;
|
||||
fields.m_vidMemory = static_cast< GLint >( MIN( nActualAvail, 0x7FFFFFFF ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Clamp the min amount of video memory to 256MB in case a query returned something bogus, or we interpreted it badly.
|
||||
fields.m_vidMemory = MAX( fields.m_vidMemory, 128 * 1024 * 1024 );
|
||||
fields.m_texMemory = fields.m_vidMemory;
|
||||
|
||||
fields.m_pciVendorID = GLM_OPENGL_VENDOR_ID;
|
||||
fields.m_pciDeviceID = GLM_OPENGL_DEFAULT_DEVICE_ID;
|
||||
if ( ( gGL->m_nDriverProvider == cGLDriverProviderIntel ) || ( gGL->m_nDriverProvider == cGLDriverProviderIntelOpenSource ) )
|
||||
{
|
||||
fields.m_pciDeviceID = GLM_OPENGL_LOW_PERF_DEVICE_ID;
|
||||
}
|
||||
|
||||
/* fields.m_colorModes = (uint)-1;
|
||||
fields.m_bufferModes = (uint)-1;
|
||||
fields.m_depthModes = (uint)-1;
|
||||
fields.m_stencilModes = (uint)-1;
|
||||
fields.m_maxAuxBuffers = (uint)128;
|
||||
fields.m_maxSampleBuffers = (uint)128;
|
||||
fields.m_maxSamples = (uint)2048;
|
||||
fields.m_sampleModes = (uint)128;
|
||||
fields.m_sampleAlpha = (uint)32;
|
||||
*/
|
||||
|
||||
GLint nMaxMultiSamples = 0;
|
||||
gGL->glGetIntegerv( GL_MAX_SAMPLES_EXT, &nMaxMultiSamples );
|
||||
fields.m_maxSamples = clamp<int>( nMaxMultiSamples, 0, 8 );
|
||||
DebugPrintf( "GL_MAX_SAMPLES_EXT: %i\n", nMaxMultiSamples );
|
||||
|
||||
// We only have one GLMRendererInfo on Linux, unlike Mac OS X. Whatever libGL.so wants to do, we go with it.
|
||||
m_renderer.Init( &fields );
|
||||
|
||||
// then go back and ask each renderer to populate its display info table.
|
||||
m_renderer.PopulateDisplays();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GLMDisplayDB::PopulateFakeAdapters( uint realRendererIndex ) // fake adapters = one real adapter times however many displays are on it
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
|
||||
Assert( realRendererIndex == 0 );
|
||||
}
|
||||
|
||||
void GLMDisplayDB::Populate(void)
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
|
||||
this->PopulateRenderers();
|
||||
|
||||
this->PopulateFakeAdapters( 0 );
|
||||
|
||||
#if GLMDEBUG
|
||||
this->Dump();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
int GLMDisplayDB::GetFakeAdapterCount( void )
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool GLMDisplayDB::GetFakeAdapterInfo( int fakeAdapterIndex, int *rendererOut, int *displayOut, GLMRendererInfoFields *rendererInfoOut, GLMDisplayInfoFields *displayInfoOut )
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
|
||||
if (fakeAdapterIndex >= GetFakeAdapterCount() )
|
||||
{
|
||||
*rendererOut = 0;
|
||||
*displayOut = 0;
|
||||
return true; // fail
|
||||
}
|
||||
|
||||
*rendererOut = 0;
|
||||
*displayOut = 0;
|
||||
|
||||
bool rendResult = GetRendererInfo( *rendererOut, rendererInfoOut );
|
||||
bool dispResult = GetDisplayInfo( *rendererOut, *displayOut, displayInfoOut );
|
||||
|
||||
return rendResult || dispResult;
|
||||
}
|
||||
|
||||
|
||||
int GLMDisplayDB::GetRendererCount( void )
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool GLMDisplayDB::GetRendererInfo( int rendererIndex, GLMRendererInfoFields *infoOut )
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
|
||||
memset( infoOut, 0, sizeof( GLMRendererInfoFields ) );
|
||||
|
||||
if (rendererIndex >= GetRendererCount())
|
||||
return true; // fail
|
||||
|
||||
*infoOut = m_renderer.m_info;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int GLMDisplayDB::GetDisplayCount( int rendererIndex )
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
|
||||
if (rendererIndex >= GetRendererCount())
|
||||
{
|
||||
Assert( 0 );
|
||||
return 0; // fail
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool GLMDisplayDB::GetDisplayInfo( int rendererIndex, int displayIndex, GLMDisplayInfoFields *infoOut )
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
|
||||
memset( infoOut, 0, sizeof( GLMDisplayInfoFields ) );
|
||||
|
||||
if (rendererIndex >= GetRendererCount())
|
||||
return true; // fail
|
||||
|
||||
if (displayIndex >= GetDisplayCount(rendererIndex))
|
||||
return true; // fail
|
||||
|
||||
*infoOut = m_renderer.m_display->m_info;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int GLMDisplayDB::GetModeCount( int rendererIndex, int displayIndex )
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
|
||||
if (rendererIndex >= GetRendererCount())
|
||||
return 0; // fail
|
||||
|
||||
if (displayIndex >= GetDisplayCount(rendererIndex))
|
||||
return 0; // fail
|
||||
|
||||
return m_renderer.m_display->m_modes->Count();
|
||||
}
|
||||
|
||||
bool GLMDisplayDB::GetModeInfo( int rendererIndex, int displayIndex, int modeIndex, GLMDisplayModeInfoFields *infoOut )
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
|
||||
memset( infoOut, 0, sizeof( GLMDisplayModeInfoFields ) );
|
||||
|
||||
if ( rendererIndex >= GetRendererCount())
|
||||
return true; // fail
|
||||
|
||||
if (displayIndex >= GetDisplayCount( rendererIndex ) )
|
||||
return true; // fail
|
||||
|
||||
if ( modeIndex >= GetModeCount( rendererIndex, displayIndex ) )
|
||||
return true; // fail
|
||||
|
||||
if ( modeIndex >= 0 )
|
||||
{
|
||||
GLMDisplayMode *displayModeInfo = m_renderer.m_display->m_modes->Element( modeIndex );
|
||||
|
||||
*infoOut = displayModeInfo->m_info;
|
||||
}
|
||||
else
|
||||
{
|
||||
const GLMDisplayInfoFields &info = m_renderer.m_display->m_info;
|
||||
|
||||
infoOut->m_modePixelWidth = info.m_displayPixelWidth;
|
||||
infoOut->m_modePixelHeight = info.m_displayPixelHeight;
|
||||
infoOut->m_modeRefreshHz = 0;
|
||||
|
||||
//return true; // fail
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void GLMDisplayDB::Dump( void )
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
|
||||
GLMPRINTF(("\n GLMDisplayDB @ %p ",this ));
|
||||
|
||||
m_renderer.Dump( 0 );
|
||||
}
|
||||
|
||||
//===============================================================================
|
||||
|
||||
GLMDisplayInfo::GLMDisplayInfo()
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
|
||||
m_modes = NULL;
|
||||
|
||||
int Width, Height;
|
||||
GetLargestDisplaySize( Width, Height );
|
||||
|
||||
m_info.m_displayPixelWidth = ( uint )Width;
|
||||
m_info.m_displayPixelHeight = ( uint )Height;
|
||||
}
|
||||
|
||||
GLMDisplayInfo::~GLMDisplayInfo( void )
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
}
|
||||
|
||||
extern "C" int DisplayModeSortFunction( GLMDisplayMode * const *A, GLMDisplayMode * const *B )
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
|
||||
int bigger = -1;
|
||||
int smaller = 1; // adjust these for desired ordering
|
||||
|
||||
// check refreshrate - higher should win
|
||||
if ( (*A)->m_info.m_modeRefreshHz > (*B)->m_info.m_modeRefreshHz )
|
||||
{
|
||||
return bigger;
|
||||
}
|
||||
else if ( (*A)->m_info.m_modeRefreshHz < (*B)->m_info.m_modeRefreshHz )
|
||||
{
|
||||
return smaller;
|
||||
}
|
||||
|
||||
// check area - larger mode should win
|
||||
int areaa = (*A)->m_info.m_modePixelWidth * (*A)->m_info.m_modePixelHeight;
|
||||
int areab = (*B)->m_info.m_modePixelWidth * (*B)->m_info.m_modePixelHeight;
|
||||
|
||||
if ( areaa > areab )
|
||||
{
|
||||
return bigger;
|
||||
}
|
||||
else if ( areaa < areab )
|
||||
{
|
||||
return smaller;
|
||||
}
|
||||
|
||||
return 0; // equal rank
|
||||
}
|
||||
|
||||
|
||||
void GLMDisplayInfo::PopulateModes( void )
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
|
||||
Assert( !m_modes );
|
||||
m_modes = new CUtlVector< GLMDisplayMode* >;
|
||||
|
||||
int nummodes = SDL_GetNumVideoDisplays();
|
||||
|
||||
for ( int i = 0; i < nummodes; i++ )
|
||||
{
|
||||
SDL_Rect rect = { 0, 0, 0, 0 };
|
||||
|
||||
if ( !SDL_GetDisplayBounds( i, &rect ) && rect.w && rect.h )
|
||||
{
|
||||
m_modes->AddToTail( new GLMDisplayMode( rect.w, rect.h, 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Add a big pile of window resolutions.
|
||||
static const struct
|
||||
{
|
||||
uint w;
|
||||
uint h;
|
||||
} s_Resolutions[] =
|
||||
{
|
||||
{ 640, 480 }, // 4x3
|
||||
{ 800, 600 },
|
||||
{ 1024, 768 },
|
||||
{ 1152, 864 },
|
||||
{ 1280, 960 },
|
||||
{ 1600, 1200 },
|
||||
{ 1920, 1440 },
|
||||
{ 2048, 1536 },
|
||||
|
||||
{ 1280, 720 }, // 16x9
|
||||
{ 1366, 768 },
|
||||
{ 1600, 900 },
|
||||
{ 1920, 1080 },
|
||||
|
||||
{ 720, 480 }, // 16x10
|
||||
{ 1280, 800 },
|
||||
{ 1680, 1050 },
|
||||
{ 1920, 1200 },
|
||||
{ 2560, 1600 },
|
||||
};
|
||||
|
||||
for ( int i = 0; i < ARRAYSIZE( s_Resolutions ); i++ )
|
||||
{
|
||||
uint w = s_Resolutions[ i ].w;
|
||||
uint h = s_Resolutions[ i ].h;
|
||||
|
||||
if ( ( w <= m_info.m_displayPixelWidth ) && ( h <= m_info.m_displayPixelHeight ) )
|
||||
{
|
||||
m_modes->AddToTail( new GLMDisplayMode( w, h, 0 ) );
|
||||
|
||||
if ( ( w * 2 <= m_info.m_displayPixelWidth ) && ( h * 2 < m_info.m_displayPixelHeight ) )
|
||||
{
|
||||
// Add double of everything also - Retina proofing hopefully.
|
||||
m_modes->AddToTail( new GLMDisplayMode( w * 2, h * 2, 0 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_modes->Sort( DisplayModeSortFunction );
|
||||
|
||||
// remove dupes.
|
||||
nummodes = m_modes->Count();
|
||||
int i = 1; // not zero!
|
||||
while (i < nummodes)
|
||||
{
|
||||
GLMDisplayModeInfoFields& info0 = m_modes->Element( i - 1 )->m_info;
|
||||
GLMDisplayModeInfoFields& info1 = m_modes->Element( i )->m_info;
|
||||
|
||||
if ( ( info0.m_modePixelWidth == info1.m_modePixelWidth ) &&
|
||||
( info0.m_modePixelHeight == info1.m_modePixelHeight ) &&
|
||||
( info0.m_modeRefreshHz == info1.m_modeRefreshHz ) )
|
||||
{
|
||||
m_modes->Remove(i);
|
||||
nummodes--;
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GLMDisplayInfo::Dump( int which )
|
||||
{
|
||||
SDLAPP_FUNC;
|
||||
|
||||
GLMPRINTF(("\n #%d: GLMDisplayInfo @ %08x, pixwidth=%d pixheight=%d",
|
||||
which, (int)this, m_info.m_displayPixelWidth, m_info.m_displayPixelHeight ));
|
||||
|
||||
FOR_EACH_VEC( *m_modes, i )
|
||||
{
|
||||
( *m_modes )[i]->Dump(i);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,182 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Pieces of the application framework, shared between POSIX systems (Mac OS X, Linux, etc)
|
||||
//
|
||||
// $Revision: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "appframework/AppFramework.h"
|
||||
#include "tier0/dbg.h"
|
||||
#include "tier0/icommandline.h"
|
||||
#include "interface.h"
|
||||
#include "filesystem.h"
|
||||
#include "appframework/IAppSystemGroup.h"
|
||||
#include "filesystem_init.h"
|
||||
#include "tier1/convar.h"
|
||||
#include "vstdlib/cvar.h"
|
||||
#include "togl/rendermechanism.h"
|
||||
|
||||
// NOTE: This has to be the last file included! (turned off below, since this is included like a header)
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Globals...
|
||||
//-----------------------------------------------------------------------------
|
||||
HINSTANCE s_HInstance;
|
||||
|
||||
//#if !defined(LINUX)
|
||||
//static CSimpleLoggingListener s_SimpleLoggingListener;
|
||||
//ILoggingListener *g_pDefaultLoggingListener = &s_SimpleLoggingListener;
|
||||
//#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// HACK: Since I don't want to refit vgui yet...
|
||||
//-----------------------------------------------------------------------------
|
||||
void *GetAppInstance()
|
||||
{
|
||||
return s_HInstance;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the application instance, should only be used if you're not calling AppMain.
|
||||
//-----------------------------------------------------------------------------
|
||||
void SetAppInstance( void* hInstance )
|
||||
{
|
||||
s_HInstance = (HINSTANCE)hInstance;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Version of AppMain used by windows applications
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int AppMain( void* hInstance, void* hPrevInstance, const char* lpCmdLine, int nCmdShow, CAppSystemGroup *pAppSystemGroup )
|
||||
{
|
||||
Assert( 0 );
|
||||
return -1;
|
||||
}
|
||||
|
||||
//#if !defined(LINUX)
|
||||
//static CNonFatalLoggingResponsePolicy s_NonFatalLoggingResponsePolicy;
|
||||
//#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Version of AppMain used by console applications
|
||||
//-----------------------------------------------------------------------------
|
||||
int AppMain( int argc, char **argv, CAppSystemGroup *pAppSystemGroup )
|
||||
{
|
||||
Assert( pAppSystemGroup );
|
||||
|
||||
//#if !defined(LINUX)
|
||||
// LoggingSystem_SetLoggingResponsePolicy( &s_NonFatalLoggingResponsePolicy );
|
||||
//#endif
|
||||
s_HInstance = NULL;
|
||||
CommandLine()->CreateCmdLine( argc, argv );
|
||||
|
||||
return pAppSystemGroup->Run( );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Default implementation of an application meant to be run using Steam
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CSteamApplication::CSteamApplication( CSteamAppSystemGroup *pAppSystemGroup )
|
||||
{
|
||||
m_pChildAppSystemGroup = pAppSystemGroup;
|
||||
m_pFileSystem = NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Create necessary interfaces
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSteamApplication::Create( )
|
||||
{
|
||||
FileSystem_SetErrorMode( FS_ERRORMODE_NONE );
|
||||
|
||||
char pFileSystemDLL[MAX_PATH];
|
||||
if ( FileSystem_GetFileSystemDLLName( pFileSystemDLL, MAX_PATH, m_bSteam ) != FS_OK )
|
||||
return false;
|
||||
|
||||
// Add in the cvar factory
|
||||
AppModule_t cvarModule = LoadModule( VStdLib_GetICVarFactory() );
|
||||
AddSystem( cvarModule, CVAR_INTERFACE_VERSION );
|
||||
|
||||
AppModule_t fileSystemModule = LoadModule( pFileSystemDLL );
|
||||
m_pFileSystem = (IFileSystem*)AddSystem( fileSystemModule, FILESYSTEM_INTERFACE_VERSION );
|
||||
if ( !m_pFileSystem )
|
||||
{
|
||||
Error( "Unable to load %s", pFileSystemDLL );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// The file system pointer is invalid at this point
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSteamApplication::Destroy()
|
||||
{
|
||||
m_pFileSystem = NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Pre-init, shutdown
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSteamApplication::PreInit( )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void CSteamApplication::PostShutdown( )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Run steam main loop
|
||||
//-----------------------------------------------------------------------------
|
||||
int CSteamApplication::Main( )
|
||||
{
|
||||
// Now that Steam is loaded, we can load up main libraries through steam
|
||||
m_pChildAppSystemGroup->Setup( m_pFileSystem, this );
|
||||
return m_pChildAppSystemGroup->Run( );
|
||||
}
|
||||
|
||||
|
||||
int CSteamApplication::Startup()
|
||||
{
|
||||
int nRetVal = BaseClass::Startup();
|
||||
if ( GetErrorStage() != NONE )
|
||||
return nRetVal;
|
||||
|
||||
if ( FileSystem_SetBasePaths( m_pFileSystem ) != FS_OK )
|
||||
return 0;
|
||||
|
||||
// Now that Steam is loaded, we can load up main libraries through steam
|
||||
m_pChildAppSystemGroup->Setup( m_pFileSystem, this );
|
||||
return m_pChildAppSystemGroup->Startup();
|
||||
}
|
||||
|
||||
|
||||
void CSteamApplication::Shutdown()
|
||||
{
|
||||
m_pChildAppSystemGroup->Shutdown();
|
||||
BaseClass::Shutdown();
|
||||
}
|
||||
|
||||
// Turn off memdbg macros (turned on up top) since this is included like a header
|
||||
#include "tier0/memdbgoff.h"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user