You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
411 lines
11 KiB
411 lines
11 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
// |
|
//=============================================================================// |
|
#include <windows.h> |
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <assert.h> |
|
#include <eh.h> |
|
#include "isys.h" |
|
#include "console/conproc.h" |
|
#include "dedicated.h" |
|
#include "engine_hlds_api.h" |
|
#include "checksum_md5.h" |
|
#include "tier0/vcrmode.h" |
|
#include "tier0/dbg.h" |
|
#include "tier1/strtools.h" |
|
#include "tier0/icommandline.h" |
|
#include "inputsystem/iinputsystem.h" |
|
#include "SteamAppStartup.h" |
|
#include "console/textconsole.h" |
|
#include "vgui/vguihelpers.h" |
|
#include "appframework/appframework.h" |
|
#include "materialsystem/imaterialsystem.h" |
|
#include "istudiorender.h" |
|
#include "vgui/ivgui.h" |
|
#include "console/TextConsoleWin32.h" |
|
#include "icvar.h" |
|
#include "datacache/idatacache.h" |
|
#include "datacache/imdlcache.h" |
|
#include "vphysics_interface.h" |
|
#include "filesystem.h" |
|
#include "steam/steam_api.h" |
|
#include "filesystem/IQueuedLoader.h" |
|
|
|
extern CTextConsoleWin32 console; |
|
extern bool g_bVGui; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Implements OS Specific layer ( loosely ) |
|
//----------------------------------------------------------------------------- |
|
class CSys : public ISys |
|
{ |
|
public: |
|
virtual ~CSys( void ); |
|
|
|
virtual bool LoadModules( CDedicatedAppSystemGroup *pAppSystemGroup ); |
|
|
|
void Sleep( int msec ); |
|
bool GetExecutableName( char *out ); |
|
void ErrorMessage( int level, const char *msg ); |
|
|
|
void WriteStatusText( char *szText ); |
|
void UpdateStatus( int force ); |
|
|
|
long LoadLibrary( char *lib ); |
|
void FreeLibrary( long library ); |
|
|
|
bool CreateConsoleWindow( void ); |
|
void DestroyConsoleWindow( void ); |
|
|
|
void ConsoleOutput ( char *string ); |
|
char *ConsoleInput ( int index, char *buf, int buflen ); |
|
void Printf( PRINTF_FORMAT_STRING const char *fmt, ... ); |
|
}; |
|
|
|
static CSys g_Sys; |
|
ISys *sys = &g_Sys; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CSys::~CSys() |
|
{ |
|
sys = NULL; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : msec - |
|
//----------------------------------------------------------------------------- |
|
void CSys::Sleep( int msec ) |
|
{ |
|
// Call ThreadSleep because it has the necessary magic to set the system |
|
// timer resolution so that Sleep( 1 ) will sleep for one millisecond |
|
// instead of for 10-16 ms. |
|
ThreadSleep( msec ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *lib - |
|
// Output : long |
|
//----------------------------------------------------------------------------- |
|
long CSys::LoadLibrary( char *lib ) |
|
{ |
|
void *hDll = ::LoadLibrary( lib ); |
|
return (long)hDll; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : library - |
|
//----------------------------------------------------------------------------- |
|
void CSys::FreeLibrary( long library ) |
|
{ |
|
if ( !library ) |
|
return; |
|
|
|
::FreeLibrary( (HMODULE)library ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *out - |
|
// Output : Returns true on success, false on failure. |
|
//----------------------------------------------------------------------------- |
|
bool CSys::GetExecutableName( char *out ) |
|
{ |
|
if ( !::GetModuleFileName( ( HINSTANCE )GetModuleHandle( NULL ), out, 256 ) ) |
|
{ |
|
return false; |
|
} |
|
return true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : level - |
|
// *msg - |
|
//----------------------------------------------------------------------------- |
|
void CSys::ErrorMessage( int level, const char *msg ) |
|
{ |
|
MessageBox( NULL, msg, "Half-Life", MB_OK ); |
|
PostQuitMessage(0); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : force - |
|
//----------------------------------------------------------------------------- |
|
void CSys::UpdateStatus( int force ) |
|
{ |
|
static double tLast = 0.0; |
|
double tCurrent; |
|
char szPrompt[256]; |
|
int n, nMax; |
|
char szMap[64]; |
|
char szHostname[128]; |
|
float fps; |
|
|
|
if ( !engine ) |
|
return; |
|
|
|
tCurrent = Sys_FloatTime(); |
|
|
|
if ( !force ) |
|
{ |
|
if ( ( tCurrent - tLast ) < 0.5f ) |
|
return; |
|
} |
|
|
|
tLast = tCurrent; |
|
|
|
engine->UpdateStatus( &fps, &n, &nMax, szMap, sizeof( szMap ) ); |
|
engine->UpdateHostname( szHostname, sizeof( szHostname ) ); |
|
|
|
console.SetTitle( szHostname ); |
|
|
|
Q_snprintf( szPrompt, sizeof( szPrompt ), "%.1f fps %2i/%2i on map %16s", (float)fps, n, nMax, szMap); |
|
|
|
console.SetStatusLine(szPrompt); |
|
console.UpdateStatus(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *string - |
|
// Output : void CSys::ConsoleOutput |
|
//----------------------------------------------------------------------------- |
|
void CSys::ConsoleOutput (char *string) |
|
{ |
|
if ( g_bVGui ) |
|
{ |
|
VGUIPrintf( string ); |
|
} |
|
else |
|
{ |
|
console.Print(string); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *fmt - |
|
// ... - |
|
//----------------------------------------------------------------------------- |
|
void CSys::Printf( PRINTF_FORMAT_STRING const char *fmt, ... ) |
|
{ |
|
// Dump text to debugging console. |
|
va_list argptr; |
|
char szText[1024]; |
|
|
|
va_start (argptr, fmt); |
|
Q_vsnprintf (szText, sizeof( szText ), fmt, argptr); |
|
va_end (argptr); |
|
|
|
// Get Current text and append it. |
|
ConsoleOutput( szText ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Output : char * |
|
//----------------------------------------------------------------------------- |
|
char *CSys::ConsoleInput ( int index, char *buf, int buflen ) |
|
{ |
|
return console.GetLine( index, buf, buflen ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *szText - |
|
//----------------------------------------------------------------------------- |
|
void CSys::WriteStatusText( char *szText ) |
|
{ |
|
SetConsoleTitle( szText ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Output : Returns true on success, false on failure. |
|
//----------------------------------------------------------------------------- |
|
bool CSys::CreateConsoleWindow( void ) |
|
{ |
|
if ( !AllocConsole () ) |
|
{ |
|
return false; |
|
} |
|
|
|
InitConProc(); |
|
return true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CSys::DestroyConsoleWindow( void ) |
|
{ |
|
FreeConsole (); |
|
|
|
// shut down QHOST hooks if necessary |
|
DeinitConProc (); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Loading modules used by the dedicated server. |
|
//----------------------------------------------------------------------------- |
|
bool CSys::LoadModules( CDedicatedAppSystemGroup *pAppSystemGroup ) |
|
{ |
|
AppSystemInfo_t appSystems[] = |
|
{ |
|
{ "engine.dll", CVAR_QUERY_INTERFACE_VERSION }, // NOTE: This one must be first!! |
|
{ "inputsystem.dll", INPUTSYSTEM_INTERFACE_VERSION }, |
|
{ "materialsystem.dll", MATERIAL_SYSTEM_INTERFACE_VERSION }, |
|
{ "studiorender.dll", STUDIO_RENDER_INTERFACE_VERSION }, |
|
{ "vphysics.dll", VPHYSICS_INTERFACE_VERSION }, |
|
{ "datacache.dll", DATACACHE_INTERFACE_VERSION }, |
|
{ "datacache.dll", MDLCACHE_INTERFACE_VERSION }, |
|
{ "datacache.dll", STUDIO_DATA_CACHE_INTERFACE_VERSION }, |
|
{ "vgui2.dll", VGUI_IVGUI_INTERFACE_VERSION }, |
|
{ "engine.dll", VENGINE_HLDS_API_VERSION }, |
|
{ "dedicated.dll", QUEUEDLOADER_INTERFACE_VERSION }, |
|
{ "", "" } // Required to terminate the list |
|
}; |
|
|
|
if ( !pAppSystemGroup->AddSystems( appSystems ) ) |
|
return false; |
|
|
|
engine = (IDedicatedServerAPI *)pAppSystemGroup->FindSystem( VENGINE_HLDS_API_VERSION ); |
|
|
|
IMaterialSystem* pMaterialSystem = (IMaterialSystem*)pAppSystemGroup->FindSystem( MATERIAL_SYSTEM_INTERFACE_VERSION ); |
|
pMaterialSystem->SetShaderAPI( "shaderapiempty.dll" ); |
|
return true; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
bool NET_Init( void ) |
|
{ |
|
// Startup winock |
|
WORD version = MAKEWORD( 1, 1 ); |
|
WSADATA wsaData; |
|
|
|
int err = WSAStartup( version, &wsaData ); |
|
if ( err != 0 ) |
|
{ |
|
char msg[ 256 ]; |
|
Q_snprintf( msg, sizeof( msg ), "Winsock 1.1 unavailable...\n" ); |
|
sys->Printf( "%s", msg ); |
|
Plat_DebugString( msg ); |
|
return false; |
|
} |
|
return true; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void NET_Shutdown( void ) |
|
{ |
|
// Kill winsock |
|
WSACleanup(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : hInstance - |
|
// hPrevInstance - |
|
// lpszCmdLine - |
|
// nCmdShow - |
|
// Output : int PASCAL |
|
//----------------------------------------------------------------------------- |
|
int main(int argc, char **argv); // in sys_ded.cpp |
|
static char *GetBaseDir( const char *pszBuffer ) |
|
{ |
|
static char basedir[ MAX_PATH ]; |
|
char szBuffer[ MAX_PATH ]; |
|
int j; |
|
char *pBuffer = NULL; |
|
|
|
V_strcpy_safe( szBuffer, pszBuffer ); |
|
|
|
pBuffer = strrchr( szBuffer,'\\' ); |
|
if ( pBuffer ) |
|
{ |
|
*(pBuffer+1) = '\0'; |
|
} |
|
|
|
strcpy( basedir, szBuffer ); |
|
|
|
j = strlen( basedir ); |
|
if (j > 0) |
|
{ |
|
if ( ( basedir[ j-1 ] == '\\' ) || |
|
( basedir[ j-1 ] == '/' ) ) |
|
{ |
|
basedir[ j-1 ] = 0; |
|
} |
|
} |
|
|
|
return basedir; |
|
} |
|
|
|
void MiniDumpFunction( unsigned int nExceptionCode, EXCEPTION_POINTERS *pException ) |
|
{ |
|
SteamAPI_WriteMiniDump( nExceptionCode, pException, 0 ); |
|
} |
|
|
|
extern "C" __declspec(dllexport) int DedicatedMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) |
|
{ |
|
SetAppInstance( hInstance ); |
|
|
|
// Check that we are running on Win32 |
|
OSVERSIONINFO vinfo; |
|
vinfo.dwOSVersionInfoSize = sizeof(vinfo); |
|
|
|
if ( !GetVersionEx ( &vinfo ) ) |
|
return -1; |
|
|
|
if ( vinfo.dwPlatformId == VER_PLATFORM_WIN32s ) |
|
return -1; |
|
|
|
int argc, iret = -1; |
|
LPWSTR * argv= CommandLineToArgvW(GetCommandLineW(),&argc); |
|
CommandLine()->CreateCmdLine( VCRHook_GetCommandLine() ); |
|
|
|
if ( !Plat_IsInDebugSession() && !CommandLine()->FindParm( "-nominidumps") ) |
|
{ |
|
// This warning only applies if you want to catch structured exceptions (crashes) |
|
// using C++ exceptions. We do not want to do that so we can build with C++ exceptions |
|
// completely disabled, and just suppress this warning. |
|
// warning C4535: calling _set_se_translator() requires /EHa |
|
#pragma warning( suppress : 4535 ) |
|
_set_se_translator( MiniDumpFunction ); |
|
|
|
try // this try block allows the SE translator to work |
|
{ |
|
iret = main(argc,(char **)argv); |
|
} |
|
catch( ... ) |
|
{ |
|
return -1; |
|
} |
|
} |
|
else |
|
{ |
|
iret = main(argc,(char **)argv); |
|
} |
|
|
|
GlobalFree( argv ); |
|
return iret; |
|
} |
|
|
|
|