411 lines
12 KiB
C++
411 lines
12 KiB
C++
//=========== (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
|
|
|