initial
This commit is contained in:
@@ -0,0 +1,982 @@
|
||||
//========= Copyright 1996-2005, 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 "tier0/platform.h"
|
||||
|
||||
#include "appframework/ilaunchermgr.h"
|
||||
#if defined( PLATFORM_PS3)
|
||||
#include "ps3/ps3_helpers.h"
|
||||
#endif
|
||||
|
||||
#include "tier0/platwindow.h"
|
||||
#include "appframework/IAppSystemGroup.h"
|
||||
#include "appframework/iappsystem.h"
|
||||
#include "interface.h"
|
||||
#include "filesystem.h"
|
||||
#include "filesystem_init.h"
|
||||
#include <algorithm>
|
||||
|
||||
// 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)
|
||||
{
|
||||
#ifdef _X360
|
||||
Warning("AppFramework : Unable to load module %s! (err #%d)\n", pDLLName, GetLastError() );
|
||||
#else
|
||||
Warning("AppFramework : Unable to load module %s!\n", pDLLName );
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
int CAppSystemGroup::ReloadModule( 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; )
|
||||
{
|
||||
Module_t &module = m_Modules[i];
|
||||
if ( module.m_pModuleName && !Q_stricmp( pModuleName, module.m_pModuleName ) )
|
||||
{
|
||||
// found the module, reload
|
||||
Msg("Unloading module %s, dll %s\n", pModuleName, pDLLName );
|
||||
Sys_UnloadModule( m_Modules[i].m_pModule );
|
||||
Msg("Module %s unloaded, reloading\n", pModuleName );
|
||||
CSysModule *pSysModule = NULL;
|
||||
CreateInterfaceFn fnFactory = NULL;
|
||||
while( !pSysModule )
|
||||
{
|
||||
pSysModule = LoadModuleDLL( pDLLName );
|
||||
if( !pSysModule )
|
||||
{
|
||||
Warning("Cannot load, retrying in 5 seconds..\n");
|
||||
ThreadSleep( 5000 );
|
||||
}
|
||||
fnFactory = Sys_GetFactory( pSysModule ) ;
|
||||
if( !fnFactory )
|
||||
{
|
||||
Error( "Could not get factory from %s\n", pModuleName );
|
||||
}
|
||||
( *fnFactory )( "Reload Interface", NULL ); // let the CreateInterface function work and do after-reload stuff
|
||||
}
|
||||
|
||||
Msg( "Reload complete, module %p->%p, factory %llx->%llx\n", module.m_pModule, pSysModule, (uint64)(uintp)module.m_Factory, (uint64)(uintp)fnFactory );
|
||||
module.m_pModule = pSysModule;
|
||||
if( module.m_Factory )
|
||||
{ // don't reload factory pointer unless it was initialized to non-NULL
|
||||
module.m_Factory = fnFactory;
|
||||
}
|
||||
|
||||
return 0; // no error
|
||||
}
|
||||
}
|
||||
|
||||
Warning( "No such module: '%s' in appsystem @%p. Dumping available modules:\n", pModuleName, this );
|
||||
for ( int i = 0; i < m_Modules.Count(); ++i )
|
||||
{
|
||||
Module_t &module = m_Modules[i];
|
||||
#ifdef _PS3
|
||||
Msg( "%25s %llx %p %6d %6d bytes\n", module.m_pModuleName, (uint64)module.m_Factory, module.m_pModule, ( ( PS3_PrxLoadParametersBase_t *)module.m_pModule )->sysPrxId, ( ( PS3_PrxLoadParametersBase_t *)module.m_pModule )->cbSize );
|
||||
#else
|
||||
Msg("%25s %p %p\n", module.m_pModuleName, (void*)module.m_Factory, module.m_pModule );
|
||||
#endif
|
||||
}
|
||||
|
||||
return m_pParentAppSystem ? m_pParentAppSystem->ReloadModule( pDLLName ) : -1;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
int nFoundIndex = m_SystemDict.Find( pInterfaceName );
|
||||
if ( nFoundIndex != m_SystemDict.InvalidIndex() )
|
||||
{
|
||||
Warning("AppFramework : Attempted to add two systems with the same interface name %s!\n", pInterfaceName );
|
||||
return m_Systems[ m_SystemDict[nFoundIndex] ];
|
||||
}
|
||||
|
||||
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 const char *g_StageLookup[] =
|
||||
{
|
||||
"CREATION",
|
||||
"LOADING DEPENDENCIES",
|
||||
"CONNECTION",
|
||||
"PREINITIALIZATION",
|
||||
"INITIALIZATION",
|
||||
"POSTINITIALIZATION",
|
||||
"RUNNING",
|
||||
"PRESHUTDOWN",
|
||||
"SHUTDOWN",
|
||||
"POSTSHUTDOWN",
|
||||
"DISCONNECTION",
|
||||
"DESTRUCTION",
|
||||
};
|
||||
|
||||
void CAppSystemGroup::ReportStartupFailure( int nErrorStage, int nSysIndex )
|
||||
{
|
||||
COMPILE_TIME_ASSERT( APPSYSTEM_GROUP_STAGE_COUNT == ARRAYSIZE( g_StageLookup ) );
|
||||
|
||||
const char *pszStageDesc = "Unknown";
|
||||
if ( nErrorStage >= 0 && nErrorStage < ( int )ARRAYSIZE( g_StageLookup ) )
|
||||
{
|
||||
pszStageDesc = g_StageLookup[ nErrorStage ];
|
||||
}
|
||||
|
||||
const char *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, requested from EXE.\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;
|
||||
}
|
||||
|
||||
int nExternalCount = m_NonAppSystemFactories.Count();
|
||||
for ( i = 0; i < nExternalCount; ++i )
|
||||
{
|
||||
void *pInterface = m_NonAppSystemFactories[i]( pSystemName, NULL );
|
||||
if (pInterface)
|
||||
return pInterface;
|
||||
}
|
||||
|
||||
if ( m_pParentAppSystem )
|
||||
{
|
||||
void* pInterface = m_pParentAppSystem->FindSystem( pSystemName );
|
||||
if ( pInterface )
|
||||
return pInterface;
|
||||
}
|
||||
|
||||
// No dice..
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Adds a factory to the system so other stuff can query it. Triggers a connect systems
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAppSystemGroup::AddNonAppSystemFactory( CreateInterfaceFn fn )
|
||||
{
|
||||
m_NonAppSystemFactories.AddToTail( fn );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Removes a factory, triggers a disconnect call if it succeeds
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAppSystemGroup::RemoveNonAppSystemFactory( CreateInterfaceFn fn )
|
||||
{
|
||||
m_NonAppSystemFactories.FindAndRemove( fn );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Causes the systems to reconnect to an interface
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAppSystemGroup::ReconnectSystems( const char *pInterfaceName )
|
||||
{
|
||||
// Let the libraries regrab the specified interface
|
||||
for (int i = 0; i < m_Systems.Count(); ++i )
|
||||
{
|
||||
IAppSystem *pSystem = m_Systems[i];
|
||||
pSystem->Reconnect( GetFactory(), pInterfaceName );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets at the parent appsystem group
|
||||
//-----------------------------------------------------------------------------
|
||||
CAppSystemGroup *CAppSystemGroup::GetParent()
|
||||
{
|
||||
return m_pParentAppSystem;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Deals with sorting dependencies and finding circular dependencies
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAppSystemGroup::ComputeDependencies( LibraryDependencies_t &depend )
|
||||
{
|
||||
bool bDone = false;
|
||||
while ( !bDone )
|
||||
{
|
||||
bDone = true;
|
||||
|
||||
// If i depends on j, then i depends on what j depends on
|
||||
// Add secondary dependencies to i. We stop when no dependencies are added
|
||||
int nCount = depend.GetNumStrings();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
int nDependentCount = depend[i].GetNumStrings();
|
||||
for ( int j = 0; j < nDependentCount; ++j )
|
||||
{
|
||||
int nIndex = depend.Find( depend[i].String( j ) );
|
||||
if ( nIndex == UTL_INVAL_SYMBOL )
|
||||
continue;
|
||||
|
||||
int nSecondaryDepCount = depend[nIndex].GetNumStrings();
|
||||
for ( int k = 0; k < nSecondaryDepCount; ++k )
|
||||
{
|
||||
// Don't bother if we already contain the secondary dependency
|
||||
const char *pSecondaryDependency = depend[nIndex].String( k );
|
||||
if ( depend[i].Find( pSecondaryDependency ) != UTL_INVAL_SYMBOL )
|
||||
continue;
|
||||
|
||||
// Check for circular dependency
|
||||
if ( !Q_stricmp( pSecondaryDependency, depend.String( i ) ) )
|
||||
{
|
||||
Warning( "Encountered a circular dependency with library %s!\n", pSecondaryDependency );
|
||||
continue;
|
||||
}
|
||||
|
||||
bDone = false;
|
||||
depend[i].AddString( pSecondaryDependency );
|
||||
nDependentCount = depend[i].GetNumStrings();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sorts dependencies
|
||||
//-----------------------------------------------------------------------------
|
||||
CAppSystemGroup::LibraryDependencies_t *CAppSystemGroup::sm_pSortDependencies;
|
||||
bool CAppSystemGroup::SortLessFunc( const int &left, const int &right )
|
||||
{
|
||||
const char *pLeftInterface = sm_pSortDependencies->String( left );
|
||||
const char *pRightInterface = sm_pSortDependencies->String( right );
|
||||
bool bRightDependsOnLeft = ( (*sm_pSortDependencies)[pRightInterface].Find( pLeftInterface ) != UTL_INVAL_SYMBOL );
|
||||
return ( bRightDependsOnLeft );
|
||||
}
|
||||
|
||||
void CAppSystemGroup::SortDependentLibraries( LibraryDependencies_t &depend )
|
||||
{
|
||||
int nCount = depend.GetNumStrings();
|
||||
|
||||
int *pIndices = (int*)stackalloc( depend.GetNumStrings() * sizeof(int) );
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
pIndices[i] = i;
|
||||
}
|
||||
|
||||
// Sort by dependency. Can't use fancy stl algorithms here because the sort func isn't strongly transitive.
|
||||
// Using lame bubble sort instead. We could speed this up using a proper depth-first graph walk, but it's not worth the effort.
|
||||
sm_pSortDependencies = &depend;
|
||||
bool bChanged = true;
|
||||
while ( bChanged )
|
||||
{
|
||||
bChanged = false;
|
||||
for ( int i = 1; i < nCount; i++ )
|
||||
{
|
||||
for ( int j = 0; j < i; j++ )
|
||||
{
|
||||
if ( SortLessFunc( pIndices[i], pIndices[j] ) )
|
||||
{
|
||||
int nTmp = pIndices[i];
|
||||
pIndices[i] = pIndices[j];
|
||||
pIndices[j] = nTmp;
|
||||
bChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sm_pSortDependencies = NULL;
|
||||
|
||||
|
||||
// This logic will make it so it respects the specified initialization order
|
||||
// in the face of no dependencies telling the system otherwise.
|
||||
// Doing this just for safety to reduce the amount of changed code
|
||||
bool bDone = false;
|
||||
while ( !bDone )
|
||||
{
|
||||
bDone = true;
|
||||
for ( int i = 1; i < nCount; ++i )
|
||||
{
|
||||
int nLeft = pIndices[i-1];
|
||||
int nRight = pIndices[i];
|
||||
if ( nRight > nLeft )
|
||||
continue;
|
||||
|
||||
const char *pLeftInterface = depend.String( nLeft );
|
||||
const char *pRightInterface = depend.String( nRight );
|
||||
bool bRightDependsOnLeft = ( depend[pRightInterface].Find( pLeftInterface ) != UTL_INVAL_SYMBOL );
|
||||
if ( bRightDependsOnLeft )
|
||||
continue;
|
||||
Assert ( UTL_INVAL_SYMBOL == depend[pRightInterface].Find( pLeftInterface ) );
|
||||
V_swap( pIndices[i], pIndices[i-1] );
|
||||
bDone = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Reorder appsystem list + dictionary indexing
|
||||
Assert( m_Systems.Count() == nCount );
|
||||
int nTempSize = nCount * sizeof(IAppSystem*);
|
||||
IAppSystem **pTemp = (IAppSystem**)stackalloc( nTempSize );
|
||||
memcpy( pTemp, m_Systems.Base(), nTempSize );
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
m_Systems[i] = pTemp[ pIndices[i] ];
|
||||
}
|
||||
|
||||
// Remap system indices
|
||||
for ( uint16 i = m_SystemDict.First(); i != m_SystemDict.InvalidIndex(); i = m_SystemDict.Next( i ) )
|
||||
{
|
||||
int j = 0;
|
||||
for ( ; j < nCount; ++j )
|
||||
{
|
||||
if ( pIndices[j] == m_SystemDict[i] )
|
||||
{
|
||||
m_SystemDict[i] = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Assert( j != nCount );
|
||||
}
|
||||
|
||||
( void )stackfree( pTemp );
|
||||
( void )stackfree( pIndices );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Finds appsystem names
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CAppSystemGroup::FindSystemName( int nIndex )
|
||||
{
|
||||
for ( uint16 i = m_SystemDict.First(); i != m_SystemDict.InvalidIndex(); i = m_SystemDict.Next( i ) )
|
||||
{
|
||||
if ( m_SystemDict[i] == nIndex )
|
||||
return m_SystemDict.GetElementName( i );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Method to load all dependent systems
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CAppSystemGroup::LoadDependentSystems()
|
||||
{
|
||||
LibraryDependencies_t dependencies;
|
||||
|
||||
// First, load dependencies.
|
||||
for ( int i = 0; i < m_Systems.Count(); ++i )
|
||||
{
|
||||
IAppSystem *pSystem = m_Systems[i];
|
||||
const char *pInterfaceName = FindSystemName( i );
|
||||
dependencies.AddString( pInterfaceName );
|
||||
|
||||
const AppSystemInfo_t *pDependencies = pSystem->GetDependencies();
|
||||
if ( !pDependencies )
|
||||
continue;
|
||||
|
||||
for ( ; pDependencies->m_pInterfaceName && pDependencies->m_pInterfaceName[0]; ++pDependencies )
|
||||
{
|
||||
dependencies[ pInterfaceName ].AddString( pDependencies->m_pInterfaceName );
|
||||
|
||||
CreateInterfaceFn factory = GetFactory();
|
||||
if ( factory( pDependencies->m_pInterfaceName, NULL ) )
|
||||
continue;
|
||||
|
||||
AppModule_t module = LoadModule( pDependencies->m_pModuleName );
|
||||
IAppSystem *pSystem = AddSystem( module, pDependencies->m_pInterfaceName );
|
||||
if ( !pSystem )
|
||||
{
|
||||
Warning( "Unable to load interface %s from %s (Dependency of %s)\n", pDependencies->m_pInterfaceName, pDependencies->m_pModuleName, pInterfaceName );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ComputeDependencies( dependencies );
|
||||
SortDependentLibraries( dependencies );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Method to connect/disconnect all systems
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CAppSystemGroup::ConnectSystems()
|
||||
{
|
||||
// Let the libraries grab any other interfaces they may need
|
||||
for (int i = 0; i < m_Systems.Count(); ++i )
|
||||
{
|
||||
IAppSystem *pSystem = m_Systems[i];
|
||||
if ( !pSystem->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 nSystemsInitialized = 0; nSystemsInitialized < m_Systems.Count(); ++nSystemsInitialized )
|
||||
{
|
||||
InitReturnVal_t nRetVal = m_Systems[nSystemsInitialized]->Init();
|
||||
if ( nRetVal != INIT_OK )
|
||||
{
|
||||
for( int nSystemsRewind = nSystemsInitialized; nSystemsRewind-->0; )
|
||||
{
|
||||
m_Systems[nSystemsRewind]->Shutdown();
|
||||
}
|
||||
|
||||
ReportStartupFailure( INITIALIZATION, nSystemsInitialized );
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Window management
|
||||
//-----------------------------------------------------------------------------
|
||||
void* CAppSystemGroup::CreateAppWindow( void *hInstance, const char *pTitle, bool bWindowed, int w, int h, bool bResizing )
|
||||
{
|
||||
#if defined( PLATFORM_WINDOWS ) || defined( PLATFORM_OSX )
|
||||
int nFlags = 0;
|
||||
if ( !bWindowed )
|
||||
{
|
||||
nFlags |= WINDOW_CREATE_FULLSCREEN;
|
||||
}
|
||||
if ( bResizing )
|
||||
{
|
||||
nFlags |= WINDOW_CREATE_RESIZING;
|
||||
}
|
||||
|
||||
PlatWindow_t hWnd = Plat_CreateWindow( hInstance, pTitle, w, h, nFlags );
|
||||
if ( hWnd == PLAT_WINDOW_INVALID )
|
||||
return NULL;
|
||||
|
||||
int CenterX, CenterY;
|
||||
Plat_GetDesktopResolution( &CenterX, &CenterY );
|
||||
CenterX = ( CenterX - w ) / 2;
|
||||
CenterY = ( CenterY - 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.
|
||||
Plat_SetWindowPos( hWnd, CenterX, CenterY );
|
||||
|
||||
return hWnd;
|
||||
#elif defined( PLATFORM_OSX )
|
||||
extern ICocoaMgr *g_pCocoaMgr;
|
||||
g_pCocoaMgr->CreateGameWindow( pTitle, bWindowed, w, h );
|
||||
return (void*)Sys_GetFactoryThis(); // Other stuff will query for ICocoaBridge out of this.
|
||||
#elif defined( PLATFORM_LINUX )
|
||||
#ifndef DEDICATED
|
||||
|
||||
// PBTODO
|
||||
// extern IGLXMgr *g_pGLXMgr;
|
||||
// g_pGLXMgr->CreateWindow( pTitle, bWindowed, w, h );
|
||||
return (void*)Sys_GetFactoryThis(); // Other stuff will query for ICocoaBridge out of this.
|
||||
#endif
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CAppSystemGroup::SetAppWindowTitle( void* hWnd, const char *pTitle )
|
||||
{
|
||||
Plat_SetWindowTitle( (PlatWindow_t)hWnd, pTitle );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the stage at which the app system group ran into an error
|
||||
//-----------------------------------------------------------------------------
|
||||
CAppSystemGroup::AppSystemGroupStage_t CAppSystemGroup::GetCurrentStage() const
|
||||
{
|
||||
return m_nCurrentStage;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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();
|
||||
|
||||
// NOTE: In case of OnStartup Failure
|
||||
// On PS/3, not unloading the PRXes in order will cause crashes on quit, which is a TRC failure
|
||||
// We probably should, but don't have to do this on all platforms, since it's not required to clean-up crash-free.
|
||||
|
||||
if ( m_nCurrentStage == RUNNING )
|
||||
{
|
||||
// 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;
|
||||
|
||||
// Call an installed application creation function
|
||||
m_nCurrentStage = CREATION;
|
||||
if ( !Create() )
|
||||
return -1;
|
||||
|
||||
// Load dependent libraries
|
||||
m_nCurrentStage = DEPENDENCIES;
|
||||
if ( !LoadDependentSystems() )
|
||||
return -1;
|
||||
|
||||
// Let all systems know about each other
|
||||
m_nCurrentStage = CONNECTION;
|
||||
if ( !ConnectSystems() )
|
||||
return -1;
|
||||
|
||||
// Allow the application to do some work before init
|
||||
m_nCurrentStage = PREINITIALIZATION;
|
||||
if ( !PreInit() )
|
||||
return -1;
|
||||
|
||||
// Call Init on all App Systems
|
||||
m_nCurrentStage = INITIALIZATION;
|
||||
int nRetVal = InitSystems();
|
||||
if ( nRetVal != INIT_OK )
|
||||
return -1;
|
||||
|
||||
m_nCurrentStage = POSTINITIALIZATION;
|
||||
if ( !PostInit() )
|
||||
return -1;
|
||||
|
||||
m_nCurrentStage = RUNNING;
|
||||
return nRetVal;
|
||||
}
|
||||
|
||||
void CAppSystemGroup::OnShutdown()
|
||||
{
|
||||
// The factory now uses this app system group
|
||||
s_pCurrentAppSystem = this;
|
||||
|
||||
switch( m_nCurrentStage )
|
||||
{
|
||||
case RUNNING:
|
||||
case POSTINITIALIZATION:
|
||||
break;
|
||||
|
||||
case PREINITIALIZATION:
|
||||
case INITIALIZATION:
|
||||
goto disconnect;
|
||||
|
||||
case CREATION:
|
||||
case DEPENDENCIES:
|
||||
case CONNECTION:
|
||||
goto destroy;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Allow the application to do some work before shutdown
|
||||
m_nCurrentStage = PRESHUTDOWN;
|
||||
PreShutdown();
|
||||
|
||||
// Cal Shutdown on all App Systems
|
||||
m_nCurrentStage = SHUTDOWN;
|
||||
ShutdownSystems();
|
||||
|
||||
// Allow the application to do some work after shutdown
|
||||
m_nCurrentStage = POSTSHUTDOWN;
|
||||
PostShutdown();
|
||||
|
||||
disconnect:
|
||||
// Systems should disconnect from each other
|
||||
m_nCurrentStage = DISCONNECTION;
|
||||
DisconnectSystems();
|
||||
|
||||
destroy:
|
||||
// Unload all DLLs loaded in the AppCreate block
|
||||
m_nCurrentStage = DESTRUCTION;
|
||||
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,119 @@
|
||||
//=========== (C) Copyright 1999 Valve, L.L.C. 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
|
||||
|
||||
#include "appframework/vguimatsysapp.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 "VGuiMatSurface/IMatSystemSurface.h"
|
||||
#include "tier3/tier3.h"
|
||||
#include "inputsystem/iinputstacksystem.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CVguiMatSysApp::CVguiMatSysApp()
|
||||
{
|
||||
m_hAppInputContext = INPUT_CONTEXT_HANDLE_INVALID;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Create all singleton systems
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVguiMatSysApp::Create()
|
||||
{
|
||||
if ( !BaseClass::Create() )
|
||||
return false;
|
||||
|
||||
AppSystemInfo_t appSystems[] =
|
||||
{
|
||||
{ "inputsystem.dll", INPUTSTACKSYSTEM_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
|
||||
{ "", "" }
|
||||
};
|
||||
|
||||
return AddSystems( appSystems );
|
||||
}
|
||||
|
||||
void CVguiMatSysApp::Destroy()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Init, shutdown
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVguiMatSysApp::PreInit( )
|
||||
{
|
||||
if ( !BaseClass::PreInit() )
|
||||
return false;
|
||||
|
||||
CreateInterfaceFn factory = GetFactory();
|
||||
ConnectTier3Libraries( &factory, 1 );
|
||||
if ( !vgui::VGui_InitInterfacesList( "CVguiSteamApp", &factory, 1 ) )
|
||||
return false;
|
||||
|
||||
if ( !g_pMatSystemSurface )
|
||||
{
|
||||
Warning( "CVguiMatSysApp::PreInit: Unable to connect to necessary interface!\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
g_pMatSystemSurface->EnableWindowsMessages( true );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CVguiMatSysApp::PostInit()
|
||||
{
|
||||
if ( !BaseClass::PostInit() )
|
||||
return false;
|
||||
|
||||
m_hAppInputContext = g_pInputStackSystem->PushInputContext();
|
||||
InputContextHandle_t hVGuiInputContext = g_pInputStackSystem->PushInputContext();
|
||||
g_pMatSystemSurface->SetInputContext( hVGuiInputContext );
|
||||
g_pMatSystemSurface->EnableWindowsMessages( true );
|
||||
return true;
|
||||
}
|
||||
|
||||
void CVguiMatSysApp::PreShutdown()
|
||||
{
|
||||
g_pMatSystemSurface->EnableWindowsMessages( false );
|
||||
g_pMatSystemSurface->SetInputContext( NULL );
|
||||
if ( m_hAppInputContext != INPUT_CONTEXT_HANDLE_INVALID )
|
||||
{
|
||||
g_pInputStackSystem->PopInputContext(); // Vgui
|
||||
g_pInputStackSystem->PopInputContext(); // App
|
||||
}
|
||||
|
||||
BaseClass::PreShutdown();
|
||||
}
|
||||
|
||||
void CVguiMatSysApp::PostShutdown()
|
||||
{
|
||||
DisconnectTier3Libraries();
|
||||
BaseClass::PostShutdown();
|
||||
}
|
||||
|
||||
InputContextHandle_t CVguiMatSysApp::GetAppInputContext()
|
||||
{
|
||||
return m_hAppInputContext;
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
//====== Copyright (c) 1996-2005, Valve Corporation, All rights reserved. =======//
|
||||
//
|
||||
// Purpose: An application framework
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#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 "tier2/tier2.h"
|
||||
|
||||
#ifdef _X360
|
||||
#include "xbox/xbox_win32stubs.h"
|
||||
#include "xbox/xbox_console.h"
|
||||
#include "xbox/xbox_launch.h"
|
||||
#endif
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Globals...
|
||||
//-----------------------------------------------------------------------------
|
||||
void* 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;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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;
|
||||
|
||||
#ifdef WIN32
|
||||
// Prepend the module filename since most apps expect arg 0 to be that.
|
||||
char szModuleFilename[MAX_PATH];
|
||||
Plat_GetModuleFilename( szModuleFilename, sizeof( szModuleFilename ) );
|
||||
int nAllocLen = strlen( lpCmdLine ) + strlen( szModuleFilename ) + 4;
|
||||
char *pNewCmdLine = new char[nAllocLen]; // 2 for quotes, 1 for a space, and 1 for a null-terminator.
|
||||
_snprintf( pNewCmdLine, nAllocLen, "\"%s\" %s", szModuleFilename, lpCmdLine );
|
||||
|
||||
// Setup ICommandLine.
|
||||
CommandLine()->CreateCmdLine( pNewCmdLine );
|
||||
delete [] pNewCmdLine;
|
||||
#else
|
||||
CommandLine()->CreateCmdLine( lpCmdLine );
|
||||
#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;
|
||||
CommandLine()->CreateCmdLine( argc, argv );
|
||||
|
||||
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;
|
||||
CommandLine()->CreateCmdLine( lpCmdLine );
|
||||
|
||||
return pAppSystemGroup->Startup();
|
||||
}
|
||||
|
||||
int AppStartup( int argc, char **argv, CAppSystemGroup *pAppSystemGroup )
|
||||
{
|
||||
Assert( pAppSystemGroup );
|
||||
|
||||
g_pDefaultLoggingListener = &s_SimpleLoggingListener;
|
||||
s_HInstance = NULL;
|
||||
CommandLine()->CreateCmdLine( argc, argv );
|
||||
|
||||
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 ( !GetFileSystemDLLName( pFileSystemDLL, MAX_PATH, m_bSteam ) )
|
||||
return false;
|
||||
|
||||
FileSystem_SetupSteamInstallPath();
|
||||
|
||||
// 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 )
|
||||
{
|
||||
if( !IsPS3() )
|
||||
Error( "Unable to load %s", pFileSystemDLL );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSteamApplication::GetFileSystemDLLName( char *pOut, int nMaxBytes, bool &bIsSteam )
|
||||
{
|
||||
return FileSystem_GetFileSystemDLLName( pOut, nMaxBytes, bIsSteam ) == FS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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 ( GetCurrentStage() != RUNNING )
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// ----------------------------------------- //
|
||||
// File generated by VPC //
|
||||
// ----------------------------------------- //
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\appframework\AppSystemGroup.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\appframework\AppSystemGroup.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\appframework\AppSystemGroup.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\common\debug_lib_check.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\common\debug_lib_check.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\common\debug_lib_check.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\public\filesystem_init.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\public\filesystem_init.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\public\filesystem_init.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\appframework\matsysapp.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\appframework\matsysapp.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\appframework\matsysapp.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\appframework\VguiMatSysApp.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\appframework\VguiMatSysApp.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\appframework\VguiMatSysApp.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\appframework\WinApp.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\appframework\WinApp.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\appframework\WinApp.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// APPFRAMEWORK.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$macro SRCDIR ".."
|
||||
|
||||
$include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$General
|
||||
{
|
||||
$AdditionalProjectDependencies "$BASE;togl" [!$IS_LIB_PROJECT && $GL]
|
||||
}
|
||||
$Compiler
|
||||
{
|
||||
$PreprocessorDefinitions "$BASE;VERSION_SAFE_STEAM_API_INTERFACES" [($WINDOWS && $GL) || $LINUXALL]
|
||||
$PreprocessorDefinitions "$BASE;ALLOW_TEXT_MODE=1" [$CSTRIKE_TRUNK_BUILD||$CSTRIKE_STAGING_BUILD]
|
||||
}
|
||||
|
||||
$Linker [$OSXALL && !$IS_LIB_PROJECT]
|
||||
{
|
||||
$SystemFrameworks "Carbon;OpenGL;Quartz;Cocoa;IOKit"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "appframework"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "AppSystemGroup.cpp"
|
||||
$File "$SRCDIR\public\filesystem_init.cpp"
|
||||
$File "VguiMatSysApp.cpp" [$WINDOWS]
|
||||
$File "matsysapp.cpp" [$WINDOWS]
|
||||
$File "WinApp.cpp" [$WINDOWS]
|
||||
$File "posixapp.cpp" [$POSIX]
|
||||
$File "sdlmgr.cpp" [$SDL]
|
||||
$File "cocoamgr.mm" [!$SDL && $OSXALL]
|
||||
$File "glmrendererinfo_osx.mm" [$SDL && $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\matsysapp.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,13 @@
|
||||
"vpc_cache"
|
||||
{
|
||||
"CacheVersion" "1"
|
||||
"win32"
|
||||
{
|
||||
"CRCFile" "appframework.vcxproj.vpc_crc"
|
||||
"OutputFiles"
|
||||
{
|
||||
"0" "appframework.vcxproj"
|
||||
"1" "appframework.vcxproj.filters"
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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,410 @@
|
||||
//=========== (C) Copyright 1999 Valve, L.L.C. 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
|
||||
|
||||
#include "appframework/materialsystem2app.h"
|
||||
#include "FileSystem.h"
|
||||
#include "materialsystem2/IMaterialSystem2.h"
|
||||
#include "tier0/dbg.h"
|
||||
#include "tier0/icommandline.h"
|
||||
#include "filesystem_init.h"
|
||||
#include "inputsystem/iinputsystem.h"
|
||||
#include "tier2/tier2.h"
|
||||
#include "rendersystem/irenderdevice.h"
|
||||
#include "rendersystem/irenderhardwareconfig.h"
|
||||
#include "vstdlib/jobthread.h"
|
||||
//#include "videocfg/videocfg.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CMaterialSystem2App::CMaterialSystem2App()
|
||||
{
|
||||
m_RenderFactory = NULL;
|
||||
m_hSwapChain = SWAP_CHAIN_HANDLE_INVALID;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Creates render system
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMaterialSystem2App::AddRenderSystem()
|
||||
{
|
||||
bool bIsVistaOrHigher = IsPlatformWindowsPC() && ( Plat_GetOSVersion() >= PLAT_OS_VERSION_VISTA );
|
||||
const char *pShaderDLL = !IsPlatformX360() ? CommandLine()->ParmValue( "-rendersystemdll" ) : NULL;
|
||||
if ( !pShaderDLL )
|
||||
{
|
||||
if ( IsPlatformWindowsPC() )
|
||||
{
|
||||
pShaderDLL = "rendersystemdx11.dll";
|
||||
}
|
||||
else if ( IsPlatformX360() )
|
||||
{
|
||||
pShaderDLL = "rendersystemdx9_360.dll";
|
||||
}
|
||||
else
|
||||
{
|
||||
pShaderDLL = "rendersystemgl.dll";
|
||||
}
|
||||
}
|
||||
|
||||
// Disallow dx11 on XP machines
|
||||
if ( !bIsVistaOrHigher && !Q_stricmp( pShaderDLL, "rendersystemdx11.dll" ) )
|
||||
{
|
||||
pShaderDLL = "rendersystemdx9.dll";
|
||||
}
|
||||
|
||||
AppModule_t module = LoadModule( pShaderDLL );
|
||||
if ( module == APP_MODULE_INVALID )
|
||||
{
|
||||
if ( IsPlatformWindowsPC() )
|
||||
{
|
||||
pShaderDLL = "rendersystemdx9.dll";
|
||||
module = LoadModule( pShaderDLL );
|
||||
}
|
||||
if ( module == APP_MODULE_INVALID )
|
||||
{
|
||||
pShaderDLL = "rendersystemempty.dll";
|
||||
module = LoadModule( pShaderDLL );
|
||||
if ( module == APP_MODULE_INVALID )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
AddSystem( module, RENDER_DEVICE_MGR_INTERFACE_VERSION );
|
||||
|
||||
if ( IsPlatformX360() )
|
||||
{
|
||||
m_nRenderSystem = RENDER_SYSTEM_X360;
|
||||
}
|
||||
else if ( V_stristr( pShaderDLL, "rendersystemgl" ) != NULL )
|
||||
{
|
||||
m_nRenderSystem = RENDER_SYSTEM_GL;
|
||||
}
|
||||
else if ( V_stristr( pShaderDLL, "rendersystemdx11" ) != NULL )
|
||||
{
|
||||
m_nRenderSystem = RENDER_SYSTEM_DX11;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nRenderSystem = RENDER_SYSTEM_DX9;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Create all singleton systems
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMaterialSystem2App::Create()
|
||||
{
|
||||
if ( !AddRenderSystem() )
|
||||
return false;
|
||||
|
||||
AppSystemInfo_t appSystems[] =
|
||||
{
|
||||
{ "inputsystem.dll", INPUTSYSTEM_INTERFACE_VERSION },
|
||||
{ "materialsystem2.dll", MATERIAL_SYSTEM2_INTERFACE_VERSION },
|
||||
|
||||
// Required to terminate the list
|
||||
{ "", "" }
|
||||
};
|
||||
|
||||
if ( !AddSystems( appSystems ) )
|
||||
return false;
|
||||
|
||||
const char *pNumThreadsString = CommandLine()->ParmValue( "-threads" );
|
||||
if ( pNumThreadsString )
|
||||
{
|
||||
m_nThreadCount = atoi( pNumThreadsString );
|
||||
}
|
||||
else
|
||||
{
|
||||
const CPUInformation &cpuInfo = GetCPUInformation();
|
||||
m_nThreadCount = cpuInfo.m_nLogicalProcessors - 1; // one core for main thread
|
||||
}
|
||||
|
||||
if ( m_nThreadCount > 0 )
|
||||
{
|
||||
ThreadPoolStartParams_t sparms( false, m_nThreadCount );
|
||||
g_pThreadPool->Start( sparms );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMaterialSystem2App::Destroy()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Pump messages
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMaterialSystem2App::AppPumpMessages()
|
||||
{
|
||||
g_pInputSystem->PollInputState();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets up the game path
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMaterialSystem2App::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 CMaterialSystem2App::PreInit( )
|
||||
{
|
||||
if ( !BaseClass::PreInit() )
|
||||
return false;
|
||||
|
||||
if ( !g_pFullFileSystem || !g_pMaterialSystem2 || !g_pRenderDeviceMgr || !g_pInputSystem )
|
||||
{
|
||||
Warning( "CMaterialSystem2App::PreInit: Unable to connect to necessary interface!\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Needed to set up the device prior to Init() of other systems
|
||||
g_pRenderDeviceMgr->InstallRenderDeviceSetup( this );
|
||||
|
||||
// Add paths...
|
||||
// NOTE: Not sure if I should have this here or not. For now, my test
|
||||
// is rendersystem test, which wants to do it itself.
|
||||
// if ( !SetupSearchPaths( NULL, false, true ) )
|
||||
// return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Replace first underscore (if any) with \0 and return
|
||||
// This handles special mods like tf_movies, l4d_movies, tf_comics
|
||||
// As a result, such mods will use the gpu_level settings etc from the base mod
|
||||
//-----------------------------------------------------------------------------
|
||||
static void StripModSuffix( char *pModName )
|
||||
{
|
||||
int i = 0;
|
||||
while ( pModName[i] != '\0' ) // Walk to the end of the string
|
||||
{
|
||||
if ( pModName[i] == '_') // If we hit an underscore
|
||||
{
|
||||
pModName[i] = '\0'; // Terminate the string here and bail out
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Configures the application for the specific mod we're running
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMaterialSystem2App::ApplyModSettings( )
|
||||
{
|
||||
/* PORTFIXME
|
||||
char pModPath[MAX_PATH];
|
||||
V_snprintf( pModPath, sizeof(pModPath), "" );
|
||||
g_pFullFileSystem->GetSearchPath( "MOD", false, pModPath, sizeof( pModPath ) );
|
||||
|
||||
// Construct the mod name so we can use the mod-specific encrypted config files
|
||||
char pModName[32];
|
||||
V_StripTrailingSlash( pModPath );
|
||||
V_FileBase( pModPath, pModName, sizeof( pModName ) );
|
||||
StripModSuffix( pModName );
|
||||
|
||||
// Just use the highest levels in non-game apps
|
||||
UpdateSystemLevel( CPU_LEVEL_HIGH, GPU_LEVEL_VERYHIGH, MEM_LEVEL_HIGH, GPU_MEM_LEVEL_HIGH, false, pModName );
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Create our device + window
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMaterialSystem2App::CreateRenderDevice()
|
||||
{
|
||||
// Create a device for this adapter
|
||||
int nAdapterCount = g_pRenderDeviceMgr->GetAdapterCount();
|
||||
int nAdapter = CommandLine()->ParmValue( "-adapter", 0 );
|
||||
if ( nAdapter >= nAdapterCount )
|
||||
{
|
||||
Warning( "Specified too high an adapter number on the commandline (%d/%d)!\n", nAdapter, nAdapterCount );
|
||||
return false;
|
||||
}
|
||||
|
||||
int nFlags = 0;
|
||||
bool bResizing = !IsConsoleApp() && ( CommandLine()->CheckParm( "-resizing" ) != NULL );
|
||||
if ( bResizing )
|
||||
{
|
||||
nFlags |= RENDER_CREATE_DEVICE_RESIZE_WINDOWS;
|
||||
}
|
||||
|
||||
m_RenderFactory = g_pRenderDeviceMgr->CreateDevice( nAdapter, nFlags );
|
||||
if ( !m_RenderFactory )
|
||||
{
|
||||
Warning( "Unable to set mode!\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Let other systems see the render device
|
||||
AddNonAppSystemFactory( m_RenderFactory );
|
||||
ReconnectSystems( RENDER_DEVICE_INTERFACE_VERSION );
|
||||
ReconnectSystems( RENDER_HARDWARECONFIG_INTERFACE_VERSION );
|
||||
|
||||
g_pRenderDevice = (IRenderDevice*)m_RenderFactory( RENDER_DEVICE_INTERFACE_VERSION, NULL );
|
||||
g_pRenderHardwareConfig = (IRenderHardwareConfig*)m_RenderFactory( RENDER_HARDWARECONFIG_INTERFACE_VERSION, NULL );
|
||||
|
||||
// Fixup the platform level
|
||||
if ( m_nRenderSystem == RENDER_SYSTEM_DX11 )
|
||||
{
|
||||
if ( g_pRenderHardwareConfig->GetDXSupportLevel() < 100 )
|
||||
{
|
||||
m_nRenderSystem = RENDER_SYSTEM_DX9;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !IsConsoleApp() )
|
||||
return CreateMainWindow( bResizing );
|
||||
return CreateMainConsoleWindow();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Create our window
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMaterialSystem2App::PostInit( )
|
||||
{
|
||||
if ( !BaseClass::PostInit() )
|
||||
return false;
|
||||
|
||||
// Set up mod settings
|
||||
ApplyModSettings();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CMaterialSystem2App::PreShutdown()
|
||||
{
|
||||
if ( g_pInputSystem )
|
||||
{
|
||||
g_pInputSystem->DetachFromWindow( );
|
||||
}
|
||||
|
||||
if ( g_pRenderDevice )
|
||||
{
|
||||
g_pRenderDevice->DestroySwapChain( m_hSwapChain );
|
||||
m_hSwapChain = SWAP_CHAIN_HANDLE_INVALID;
|
||||
}
|
||||
|
||||
BaseClass::PreShutdown();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Creates the main 3d window
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMaterialSystem2App::CreateMainWindow( bool bResizing )
|
||||
{
|
||||
// NOTE: This could be placed into a separate function
|
||||
// Create a main 3d-capable window
|
||||
int nWidth = 1280;
|
||||
int nHeight = IsPlatformX360() ? 720 : 960;
|
||||
bool bFullscreen = ( CommandLine()->CheckParm( "-fullscreen" ) != NULL );
|
||||
|
||||
const char *pArg;
|
||||
if ( CommandLine()->CheckParm( "-width", &pArg ) )
|
||||
{
|
||||
nWidth = atoi( pArg );
|
||||
}
|
||||
if ( CommandLine()->CheckParm( "-height", &pArg ) )
|
||||
{
|
||||
nHeight = atoi( pArg );
|
||||
}
|
||||
|
||||
m_hSwapChain = Create3DWindow( GetAppName(), nWidth, nHeight, bResizing, bFullscreen, true );
|
||||
return ( m_hSwapChain != SWAP_CHAIN_HANDLE_INVALID );
|
||||
}
|
||||
|
||||
bool CMaterialSystem2App::CreateMainConsoleWindow()
|
||||
{
|
||||
RenderDeviceInfo_t mode;
|
||||
mode.m_DisplayMode.m_nWidth = 512;
|
||||
mode.m_DisplayMode.m_nHeight = 512;
|
||||
mode.m_DisplayMode.m_Format = IMAGE_FORMAT_RGBA8888;
|
||||
mode.m_DisplayMode.m_nRefreshRateNumerator = 60;
|
||||
mode.m_DisplayMode.m_nRefreshRateDenominator = 1;
|
||||
mode.m_bFullscreen = false;
|
||||
mode.m_nBackBufferCount = 1;
|
||||
mode.m_bWaitForVSync = false;
|
||||
|
||||
#ifdef PLATFORM_WINDOWS_PC
|
||||
m_hSwapChain = g_pRenderDevice->CreateSwapChain( Plat_GetShellWindow(), mode );
|
||||
return ( m_hSwapChain != SWAP_CHAIN_HANDLE_INVALID );
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Creates a 3d-capable window
|
||||
//-----------------------------------------------------------------------------
|
||||
SwapChainHandle_t CMaterialSystem2App::Create3DWindow( const char *pTitle, int nWidth, int nHeight, bool bResizing, bool bFullscreen, bool bAcceptsInput )
|
||||
{
|
||||
PlatWindow_t hWnd = (PlatWindow_t)CreateAppWindow( GetAppInstance(), pTitle, !bFullscreen, nWidth, nHeight, bResizing );
|
||||
if ( !hWnd )
|
||||
return SWAP_CHAIN_HANDLE_INVALID;
|
||||
|
||||
// By default, everything will just use this one swap chain.
|
||||
RenderDeviceInfo_t mode;
|
||||
mode.m_DisplayMode.m_nWidth = nWidth;
|
||||
mode.m_DisplayMode.m_nHeight = nHeight;
|
||||
mode.m_DisplayMode.m_Format = IMAGE_FORMAT_RGBA8888;
|
||||
mode.m_DisplayMode.m_nRefreshRateNumerator = 60;
|
||||
mode.m_DisplayMode.m_nRefreshRateDenominator = 1;
|
||||
mode.m_bFullscreen = bFullscreen;
|
||||
mode.m_nBackBufferCount = bFullscreen ? 2 : 1;
|
||||
mode.m_bWaitForVSync = ( CommandLine()->CheckParm( "-vsync" ) != NULL );
|
||||
SwapChainHandle_t hSwapChain = g_pRenderDevice->CreateSwapChain( hWnd, mode );
|
||||
|
||||
if ( bAcceptsInput )
|
||||
{
|
||||
g_pInputSystem->AttachToWindow( (void*)hWnd );
|
||||
}
|
||||
|
||||
return hSwapChain;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the window associated with a swap chain
|
||||
//-----------------------------------------------------------------------------
|
||||
PlatWindow_t CMaterialSystem2App::GetAppWindow()
|
||||
{
|
||||
if ( !m_hSwapChain || !g_pRenderDevice )
|
||||
return PLAT_WINDOW_INVALID;
|
||||
return g_pRenderDevice->GetSwapChainWindow( m_hSwapChain );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
@@ -0,0 +1,267 @@
|
||||
//=========== (C) Copyright 1999 Valve, L.L.C. 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
|
||||
|
||||
#include "appframework/matsysapp.h"
|
||||
#include "FileSystem.h"
|
||||
#include "materialsystem/IMaterialSystem.h"
|
||||
#include "tier0/dbg.h"
|
||||
#include "tier0/icommandline.h"
|
||||
#include "materialsystem/MaterialSystem_Config.h"
|
||||
#include "filesystem_init.h"
|
||||
#include "inputsystem/iinputsystem.h"
|
||||
#include "tier2/tier2.h"
|
||||
#include "videocfg/videocfg.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CMatSysApp::CMatSysApp()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Create all singleton systems
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMatSysApp::Create()
|
||||
{
|
||||
AppSystemInfo_t appSystems[] =
|
||||
{
|
||||
{ "inputsystem.dll", INPUTSYSTEM_INTERFACE_VERSION },
|
||||
{ "materialsystem.dll", MATERIAL_SYSTEM_INTERFACE_VERSION },
|
||||
|
||||
// Required to terminate the list
|
||||
{ "", "" }
|
||||
};
|
||||
|
||||
if ( !AddSystems( appSystems ) )
|
||||
return false;
|
||||
|
||||
IMaterialSystem *pMaterialSystem = (IMaterialSystem*)FindSystem( MATERIAL_SYSTEM_INTERFACE_VERSION );
|
||||
|
||||
if ( !pMaterialSystem )
|
||||
{
|
||||
Warning( "CMatSysApp::Create: Unable to connect to necessary interface!\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
pMaterialSystem->SetShaderAPI( "shaderapidx9.dll" );
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMatSysApp::Destroy()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Pump messages
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMatSysApp::AppPumpMessages()
|
||||
{
|
||||
g_pInputSystem->PollInputState();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets up the game path
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMatSysApp::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 CMatSysApp::PreInit( )
|
||||
{
|
||||
if ( !BaseClass::PreInit() )
|
||||
return false;
|
||||
|
||||
if ( !g_pFullFileSystem || !g_pMaterialSystem || !g_pInputSystem )
|
||||
{
|
||||
Warning( "CMatSysApp::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( GetAppInstance(), GetAppName(), bWindowed, iWidth, iHeight, false );
|
||||
if ( !m_HWnd )
|
||||
return false;
|
||||
|
||||
g_pInputSystem->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 CMatSysApp::PostShutdown()
|
||||
{
|
||||
if ( g_pInputSystem )
|
||||
{
|
||||
g_pInputSystem->DetachFromWindow( );
|
||||
}
|
||||
|
||||
BaseClass::PostShutdown();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the window size
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMatSysApp::GetWindowWidth() const
|
||||
{
|
||||
return m_nWidth;
|
||||
}
|
||||
|
||||
int CMatSysApp::GetWindowHeight() const
|
||||
{
|
||||
return m_nHeight;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the window
|
||||
//-----------------------------------------------------------------------------
|
||||
void* CMatSysApp::GetAppWindow()
|
||||
{
|
||||
return m_HWnd;
|
||||
}
|
||||
|
||||
// Replace first underscore (if any) with \0 and return
|
||||
// This handles special mods like tf_movies, l4d_movies, tf_comics
|
||||
// As a result, such mods will use the gpu_level settings etc from the base mod
|
||||
void StripModSuffix( char *pModName )
|
||||
{
|
||||
int i = 0;
|
||||
while ( pModName[i] != '\0' ) // Walk to the end of the string
|
||||
{
|
||||
if ( pModName[i] == '_') // If we hit an underscore
|
||||
{
|
||||
pModName[i] = '\0'; // Terminate the string here and bail out
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the video mode
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMatSysApp::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 );
|
||||
|
||||
if ( CommandLine()->FindParm( "-csm_quality_level" ) )
|
||||
{
|
||||
int nCSMQuality = CommandLine()->ParmValue( "-csm_quality_level", CSMQUALITY_VERY_LOW );
|
||||
config.m_nCSMQuality = (CSMQualityMode_t)clamp( nCSMQuality, CSMQUALITY_VERY_LOW, CSMQUALITY_TOTAL_MODES - 1 );
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
char pModPath[MAX_PATH];
|
||||
V_snprintf( pModPath, sizeof(pModPath), "" );
|
||||
g_pFullFileSystem->GetSearchPath( "MOD", false, pModPath, sizeof( pModPath ) );
|
||||
|
||||
// Construct the mod name so we can use the mod-specific encrypted config files
|
||||
char pModName[32];
|
||||
V_StripTrailingSlash( pModPath );
|
||||
V_FileBase( pModPath, pModName, sizeof( pModName ) );
|
||||
StripModSuffix( pModName );
|
||||
|
||||
// Just use the highest levels in non-game apps
|
||||
UpdateSystemLevel( CPU_LEVEL_HIGH, GPU_LEVEL_VERYHIGH, MEM_LEVEL_HIGH, GPU_MEM_LEVEL_HIGH, false, pModName );
|
||||
|
||||
g_pMaterialSystem->OverrideConfig( config, false );
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
//====== Copyright 1996-2005, 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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Version of AppMain used by windows applications
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int AppMain( void* hInstance, void* hPrevInstance, const char* lpCmdLine, int nCmdShow, CAppSystemGroup *pAppSystemGroup )
|
||||
{
|
||||
Assert( 0 );
|
||||
return -1;
|
||||
}
|
||||
|
||||
static CNonFatalLoggingResponsePolicy s_NonFatalLoggingResponsePolicy;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Version of AppMain used by console applications
|
||||
//-----------------------------------------------------------------------------
|
||||
int AppMain( int argc, char **argv, CAppSystemGroup *pAppSystemGroup )
|
||||
{
|
||||
Assert( pAppSystemGroup );
|
||||
|
||||
LoggingSystem_SetLoggingResponsePolicy( &s_NonFatalLoggingResponsePolicy );
|
||||
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;
|
||||
}
|
||||
|
||||
bool CSteamApplication::GetFileSystemDLLName( char *pOut, int nMaxBytes, bool &bIsSteam )
|
||||
{
|
||||
return FileSystem_GetFileSystemDLLName( pOut, nMaxBytes, bIsSteam ) == FS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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 ( GetCurrentStage() != 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
@@ -0,0 +1,120 @@
|
||||
//=========== (C) Copyright 1999 Valve, L.L.C. 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
|
||||
|
||||
#include "appframework/vguimaterialsystem2app.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 "vguirendersurface/ivguirendersurface.h"
|
||||
#include "tier3/tier3.h"
|
||||
#include "interfaces/interfaces.h"
|
||||
#include "inputsystem/iinputstacksystem.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CVGuiMaterialSystem2App::CVGuiMaterialSystem2App()
|
||||
{
|
||||
m_hAppInputContext = INPUT_CONTEXT_HANDLE_INVALID;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Create all singleton systems
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVGuiMaterialSystem2App::Create()
|
||||
{
|
||||
if ( !BaseClass::Create() )
|
||||
return false;
|
||||
|
||||
AppSystemInfo_t appSystems[] =
|
||||
{
|
||||
{ "inputsystem.dll", INPUTSTACKSYSTEM_INTERFACE_VERSION },
|
||||
// NOTE: This has to occur before vgui2.dll so it replaces vgui2's surface implementation
|
||||
{ "vguirendersurface.dll", VGUI_SURFACE_INTERFACE_VERSION },
|
||||
{ "vgui2.dll", VGUI_IVGUI_INTERFACE_VERSION },
|
||||
|
||||
// Required to terminate the list
|
||||
{ "", "" }
|
||||
};
|
||||
|
||||
return AddSystems( appSystems );
|
||||
}
|
||||
|
||||
void CVGuiMaterialSystem2App::Destroy()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Init, shutdown
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVGuiMaterialSystem2App::PreInit( )
|
||||
{
|
||||
if ( !BaseClass::PreInit() )
|
||||
return false;
|
||||
|
||||
CreateInterfaceFn factory = GetFactory();
|
||||
ConnectTier3Libraries( &factory, 1 );
|
||||
if ( !vgui::VGui_InitInterfacesList( "CVGuiMaterialSystem2App", &factory, 1 ) )
|
||||
return false;
|
||||
|
||||
if ( !g_pVGuiRenderSurface )
|
||||
{
|
||||
Warning( "CVGuiMaterialSystem2App::PreInit: Unable to connect to necessary interface!\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CVGuiMaterialSystem2App::PostInit()
|
||||
{
|
||||
if ( !BaseClass::PostInit() )
|
||||
return false;
|
||||
|
||||
m_hAppInputContext = g_pInputStackSystem->PushInputContext();
|
||||
InputContextHandle_t hVGuiInputContext = g_pInputStackSystem->PushInputContext();
|
||||
g_pVGuiRenderSurface->SetInputContext( hVGuiInputContext );
|
||||
g_pVGuiRenderSurface->EnableWindowsMessages( true );
|
||||
return true;
|
||||
}
|
||||
|
||||
void CVGuiMaterialSystem2App::PreShutdown()
|
||||
{
|
||||
g_pVGuiRenderSurface->EnableWindowsMessages( false );
|
||||
g_pVGuiRenderSurface->SetInputContext( NULL );
|
||||
if ( m_hAppInputContext != INPUT_CONTEXT_HANDLE_INVALID )
|
||||
{
|
||||
g_pInputStackSystem->PopInputContext(); // Vgui
|
||||
g_pInputStackSystem->PopInputContext(); // App
|
||||
}
|
||||
|
||||
BaseClass::PreShutdown();
|
||||
}
|
||||
|
||||
void CVGuiMaterialSystem2App::PostShutdown()
|
||||
{
|
||||
DisconnectTier3Libraries();
|
||||
BaseClass::PostShutdown();
|
||||
}
|
||||
|
||||
InputContextHandle_t CVGuiMaterialSystem2App::GetAppInputContext()
|
||||
{
|
||||
return m_hAppInputContext;
|
||||
}
|
||||
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
IMPORTANT: Do not remove the custom build step for this file
|
||||
Reference in New Issue
Block a user