2007-06-21 22:00:00 +02:00
|
|
|
|
//=======================================================================
|
|
|
|
|
// Copyright XashXT Group 2007 <20>
|
|
|
|
|
// host.c - dedicated and shared host
|
|
|
|
|
//=======================================================================
|
|
|
|
|
|
|
|
|
|
#include <setjmp.h>
|
|
|
|
|
#include <windows.h>
|
|
|
|
|
#include <dsound.h>
|
|
|
|
|
#include "engine.h"
|
|
|
|
|
|
2007-09-13 22:00:00 +02:00
|
|
|
|
common_exp_t *Com; // fundamental callbacks
|
2007-10-22 22:00:00 +02:00
|
|
|
|
physic_exp_t *Phys;
|
2007-09-03 22:00:00 +02:00
|
|
|
|
host_parm_t host; // host parms
|
2007-09-13 22:00:00 +02:00
|
|
|
|
stdlib_api_t std;
|
2007-06-21 22:00:00 +02:00
|
|
|
|
|
|
|
|
|
byte *zonepool;
|
|
|
|
|
int ActiveApp;
|
2007-09-06 22:00:00 +02:00
|
|
|
|
bool Minimized;
|
2007-09-11 22:00:00 +02:00
|
|
|
|
char *buildstring = __TIME__ " " __DATE__;
|
2007-09-02 22:00:00 +02:00
|
|
|
|
|
2007-06-21 22:00:00 +02:00
|
|
|
|
void Key_Init (void);
|
|
|
|
|
void SCR_EndLoadingPlaque (void);
|
|
|
|
|
|
|
|
|
|
HINSTANCE global_hInstance;
|
2007-09-13 22:00:00 +02:00
|
|
|
|
dll_info_t common_dll = { "common.dll", NULL, "CreateAPI", NULL, NULL, true, COMMON_API_VERSION, sizeof(common_exp_t) };
|
2007-10-22 22:00:00 +02:00
|
|
|
|
dll_info_t physic_dll = { "physic.dll", NULL, "CreateAPI", NULL, NULL, true, PHYSIC_API_VERSION, sizeof(physic_exp_t) };
|
2007-06-21 22:00:00 +02:00
|
|
|
|
|
|
|
|
|
cvar_t *timescale;
|
|
|
|
|
cvar_t *fixedtime;
|
|
|
|
|
|
2007-10-22 22:00:00 +02:00
|
|
|
|
stdlib_api_t Host_GetStdio( bool crash_on_error )
|
2007-06-21 22:00:00 +02:00
|
|
|
|
{
|
2007-09-13 22:00:00 +02:00
|
|
|
|
static stdlib_api_t io;
|
2007-06-21 22:00:00 +02:00
|
|
|
|
|
2007-10-22 22:00:00 +02:00
|
|
|
|
io.api_size = sizeof(stdlib_api_t);
|
|
|
|
|
|
2007-11-04 22:00:00 +01:00
|
|
|
|
io.print = Com_Print;
|
|
|
|
|
io.printf = Com_Printf;
|
|
|
|
|
io.dprintf = Com_DPrintf;
|
|
|
|
|
io.wprintf = Com_DWarnf;
|
2007-10-22 22:00:00 +02:00
|
|
|
|
io.exit = Sys_Quit;
|
|
|
|
|
io.input = Sys_ConsoleInput;
|
|
|
|
|
io.sleep = Sys_Sleep;
|
|
|
|
|
|
|
|
|
|
if(crash_on_error) io.error = Sys_Error;
|
|
|
|
|
else io.error = Host_Error;
|
2007-09-13 22:00:00 +02:00
|
|
|
|
|
|
|
|
|
io.LoadLibrary = Sys_LoadLibrary;
|
|
|
|
|
io.FreeLibrary = Sys_FreeLibrary;
|
2007-10-22 22:00:00 +02:00
|
|
|
|
io.GetProcAddress = std.GetProcAddress;
|
|
|
|
|
|
|
|
|
|
return io;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Host_InitCommon( char *funcname, int argc, char **argv )
|
|
|
|
|
{
|
|
|
|
|
common_t CreateCom;
|
|
|
|
|
stdlib_api_t io = Host_GetStdio( true );
|
|
|
|
|
|
2007-09-13 22:00:00 +02:00
|
|
|
|
Sys_LoadLibrary( &common_dll );
|
2007-06-21 22:00:00 +02:00
|
|
|
|
|
2007-09-13 22:00:00 +02:00
|
|
|
|
CreateCom = (void *)common_dll.main;
|
|
|
|
|
Com = CreateCom( &io );
|
2007-06-21 22:00:00 +02:00
|
|
|
|
|
2007-09-13 22:00:00 +02:00
|
|
|
|
Com->Init( argc, argv );
|
2007-06-21 22:00:00 +02:00
|
|
|
|
|
2007-09-13 22:00:00 +02:00
|
|
|
|
// TODO: init basedir here
|
|
|
|
|
Com->LoadGameInfo("gameinfo.txt");
|
2007-06-21 22:00:00 +02:00
|
|
|
|
zonepool = Mem_AllocPool("Zone Engine");
|
|
|
|
|
}
|
|
|
|
|
|
2007-09-13 22:00:00 +02:00
|
|
|
|
void Host_FreeCommon( void )
|
2007-06-21 22:00:00 +02:00
|
|
|
|
{
|
2007-09-13 22:00:00 +02:00
|
|
|
|
if(common_dll.link)
|
2007-06-21 22:00:00 +02:00
|
|
|
|
{
|
|
|
|
|
Mem_FreePool( &zonepool );
|
2007-09-13 22:00:00 +02:00
|
|
|
|
Com->Shutdown();
|
2007-06-21 22:00:00 +02:00
|
|
|
|
}
|
2007-09-13 22:00:00 +02:00
|
|
|
|
Sys_FreeLibrary( &common_dll );
|
2007-06-21 22:00:00 +02:00
|
|
|
|
}
|
|
|
|
|
|
2007-10-22 22:00:00 +02:00
|
|
|
|
void Host_InitPhysic( void )
|
|
|
|
|
{
|
|
|
|
|
static physic_imp_t pi;
|
|
|
|
|
physic_t CreatePhys;
|
|
|
|
|
|
|
|
|
|
pi.Fs = Com->Fs;
|
|
|
|
|
pi.VFs = Com->VFs;
|
|
|
|
|
pi.Mem = Com->Mem;
|
|
|
|
|
pi.Script = Com->Script;
|
|
|
|
|
pi.Compile = Com->Compile;
|
|
|
|
|
pi.Stdio = Host_GetStdio( false );
|
|
|
|
|
|
2007-10-27 22:00:00 +02:00
|
|
|
|
// phys callback
|
|
|
|
|
pi.Transform = SV_Transform;
|
|
|
|
|
|
2007-10-22 22:00:00 +02:00
|
|
|
|
Sys_LoadLibrary( &physic_dll );
|
|
|
|
|
|
|
|
|
|
CreatePhys = (void *)physic_dll.main;
|
|
|
|
|
Phys = CreatePhys( &pi );
|
|
|
|
|
|
|
|
|
|
Phys->Init();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Host_FreePhysic( void )
|
|
|
|
|
{
|
|
|
|
|
if(physic_dll.link)
|
|
|
|
|
{
|
|
|
|
|
Phys->Shutdown();
|
|
|
|
|
}
|
|
|
|
|
Sys_FreeLibrary( &physic_dll );
|
|
|
|
|
}
|
|
|
|
|
|
2007-09-10 22:00:00 +02:00
|
|
|
|
/*
|
|
|
|
|
================
|
|
|
|
|
Host_AbortCurrentFrame
|
|
|
|
|
|
|
|
|
|
aborts the current host frame and goes on with the next one
|
|
|
|
|
================
|
|
|
|
|
*/
|
|
|
|
|
void Host_AbortCurrentFrame( void )
|
|
|
|
|
{
|
|
|
|
|
longjmp(host.abortframe, 1);
|
|
|
|
|
}
|
|
|
|
|
|
2007-06-21 22:00:00 +02:00
|
|
|
|
/*
|
|
|
|
|
=================
|
|
|
|
|
Host_Init
|
|
|
|
|
=================
|
|
|
|
|
*/
|
|
|
|
|
void Host_Init (char *funcname, int argc, char **argv)
|
|
|
|
|
{
|
|
|
|
|
char *s;
|
|
|
|
|
|
2007-09-03 22:00:00 +02:00
|
|
|
|
host.state = HOST_INIT; //initialzation started
|
|
|
|
|
|
2007-06-21 22:00:00 +02:00
|
|
|
|
global_hInstance = (HINSTANCE)GetModuleHandle( NULL );
|
2007-08-13 22:00:00 +02:00
|
|
|
|
|
2007-09-03 22:00:00 +02:00
|
|
|
|
if(!strcmp(funcname, "host_dedicated")) host.type = HOST_DEDICATED;
|
|
|
|
|
else if(!strcmp(funcname, "host_shared")) host.type = HOST_NORMAL;
|
|
|
|
|
else host.type = HOST_OFFLINE; // launcher can loading engine for some reasons
|
2007-06-21 22:00:00 +02:00
|
|
|
|
|
2007-09-03 22:00:00 +02:00
|
|
|
|
COM_InitArgv (argc, argv); // init host.debug & host.developer here
|
2007-09-13 22:00:00 +02:00
|
|
|
|
Host_InitCommon( funcname, argc, argv );
|
2007-06-21 22:00:00 +02:00
|
|
|
|
|
2007-11-04 22:00:00 +01:00
|
|
|
|
Cmd_Init( argc, argv );
|
|
|
|
|
Cvar_Init();
|
|
|
|
|
Key_Init();
|
2007-09-16 22:00:00 +02:00
|
|
|
|
PRVM_Init();
|
2007-09-02 22:00:00 +02:00
|
|
|
|
|
2007-11-05 22:00:00 +01:00
|
|
|
|
// get default configuration
|
2007-11-04 22:00:00 +01:00
|
|
|
|
Cbuf_AddText("exec keys.rc\n");
|
|
|
|
|
Cbuf_AddText("exec vars.rc\n");
|
|
|
|
|
Cbuf_Execute();
|
2007-06-21 22:00:00 +02:00
|
|
|
|
|
|
|
|
|
// init commands and vars
|
2007-09-10 22:00:00 +02:00
|
|
|
|
Cmd_AddCommand ("error", Host_Error_f);
|
2007-06-21 22:00:00 +02:00
|
|
|
|
|
|
|
|
|
host_speeds = Cvar_Get ("host_speeds", "0", 0);
|
2007-10-29 22:00:00 +01:00
|
|
|
|
host_frametime = Cvar_Get ("host_frametime", "0.01", 0);
|
2007-06-21 22:00:00 +02:00
|
|
|
|
timescale = Cvar_Get ("timescale", "1", 0);
|
|
|
|
|
fixedtime = Cvar_Get ("fixedtime", "0", 0);
|
2007-11-04 22:00:00 +01:00
|
|
|
|
if(host.type == HOST_DEDICATED) dedicated = Cvar_Get ("dedicated", "1", CVAR_INIT);
|
|
|
|
|
else dedicated = Cvar_Get ("dedicated", "0", CVAR_INIT);
|
2007-06-21 22:00:00 +02:00
|
|
|
|
|
|
|
|
|
s = va("%4.2f %s %s %s", VERSION, "x86", __DATE__, BUILDSTRING);
|
2007-11-04 22:00:00 +01:00
|
|
|
|
Cvar_Get ("version", s, CVAR_SERVERINFO|CVAR_INIT);
|
2007-06-21 22:00:00 +02:00
|
|
|
|
|
2007-09-12 22:00:00 +02:00
|
|
|
|
if (dedicated->value) Cmd_AddCommand ("quit", Sys_Quit);
|
2007-09-10 22:00:00 +02:00
|
|
|
|
|
2007-10-22 22:00:00 +02:00
|
|
|
|
NET_Init();
|
|
|
|
|
Netchan_Init();
|
|
|
|
|
Host_InitPhysic();
|
2007-06-21 22:00:00 +02:00
|
|
|
|
|
|
|
|
|
SV_Init();
|
|
|
|
|
CL_Init();
|
|
|
|
|
|
2007-11-05 22:00:00 +01:00
|
|
|
|
Cbuf_AddText("exec init.rc\n");
|
|
|
|
|
Cbuf_Execute();
|
|
|
|
|
|
|
|
|
|
// if stuffcmds wasn't run, then init.rc is probably missing, use default
|
|
|
|
|
if(!host.stuffcmdsrun) Cbuf_ExecuteText( EXEC_NOW, "stuffcmds\n" );
|
|
|
|
|
|
|
|
|
|
SCR_EndLoadingPlaque ();
|
2007-09-09 22:00:00 +02:00
|
|
|
|
Sys_DoubleTime(); // initialize timer
|
2007-06-21 22:00:00 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
=================
|
|
|
|
|
Host_Frame
|
|
|
|
|
=================
|
|
|
|
|
*/
|
|
|
|
|
void Host_Frame (double time)
|
|
|
|
|
{
|
2007-09-10 22:00:00 +02:00
|
|
|
|
char *s;
|
2007-09-06 22:00:00 +02:00
|
|
|
|
static double time_before, time_between, time_after;
|
2007-06-21 22:00:00 +02:00
|
|
|
|
|
2007-09-10 22:00:00 +02:00
|
|
|
|
if (setjmp(host.abortframe)) return;
|
2007-06-21 22:00:00 +02:00
|
|
|
|
|
2007-09-11 22:00:00 +02:00
|
|
|
|
rand(); // keep the random time dependent
|
|
|
|
|
|
2007-10-29 22:00:00 +01:00
|
|
|
|
// get new key events
|
|
|
|
|
Sys_SendKeyEvents();
|
|
|
|
|
|
2007-06-21 22:00:00 +02:00
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
s = Sys_ConsoleInput ();
|
2007-09-11 22:00:00 +02:00
|
|
|
|
if(s) Cbuf_AddText (va("%s\n",s));
|
2007-06-21 22:00:00 +02:00
|
|
|
|
} while (s);
|
|
|
|
|
Cbuf_Execute ();
|
2007-09-06 22:00:00 +02:00
|
|
|
|
|
2007-10-29 22:00:00 +01:00
|
|
|
|
// if at a full screen console, don't update unless needed
|
|
|
|
|
if (Minimized || host.type == HOST_DEDICATED )
|
|
|
|
|
{
|
|
|
|
|
Sys_Sleep (1);
|
|
|
|
|
}
|
|
|
|
|
|
2007-09-06 22:00:00 +02:00
|
|
|
|
if (host_speeds->value) time_before = Sys_DoubleTime();
|
|
|
|
|
|
2007-06-21 22:00:00 +02:00
|
|
|
|
SV_Frame (time);
|
2007-09-06 22:00:00 +02:00
|
|
|
|
|
|
|
|
|
if (host_speeds->value) time_between = Sys_DoubleTime();
|
|
|
|
|
|
2007-06-21 22:00:00 +02:00
|
|
|
|
CL_Frame (time);
|
|
|
|
|
|
2007-09-06 22:00:00 +02:00
|
|
|
|
if (host_speeds->value) time_after = Sys_DoubleTime();
|
|
|
|
|
if (host_speeds->value)
|
|
|
|
|
{
|
|
|
|
|
double all, sv, gm, cl, rf;
|
|
|
|
|
|
|
|
|
|
all = time_after - time_before;
|
|
|
|
|
sv = time_between - time_before;
|
|
|
|
|
cl = time_after - time_between;
|
|
|
|
|
gm = time_after_game - time_before_game;
|
|
|
|
|
rf = time_after_ref - time_before_ref;
|
|
|
|
|
sv -= gm;
|
|
|
|
|
cl -= rf;
|
|
|
|
|
Msg ("all:%.3f sv:%.3f gm:%.3f cl:%.3f rf:%.3f\n", all, sv, gm, cl, rf);
|
|
|
|
|
}
|
2007-09-07 22:00:00 +02:00
|
|
|
|
host.framecount++;
|
2007-06-21 22:00:00 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
=================
|
|
|
|
|
Host_Main
|
|
|
|
|
=================
|
|
|
|
|
*/
|
|
|
|
|
void Host_Main( void )
|
|
|
|
|
{
|
2007-09-09 22:00:00 +02:00
|
|
|
|
static double time, oldtime, newtime;
|
2007-06-21 22:00:00 +02:00
|
|
|
|
|
2007-09-09 22:00:00 +02:00
|
|
|
|
oldtime = host.realtime;
|
2007-06-21 22:00:00 +02:00
|
|
|
|
|
|
|
|
|
// main window message loop
|
2007-09-22 22:00:00 +02:00
|
|
|
|
while (host.type != HOST_OFFLINE)
|
2007-06-21 22:00:00 +02:00
|
|
|
|
{
|
2007-10-29 22:00:00 +01:00
|
|
|
|
oldtime = newtime;
|
|
|
|
|
newtime = Sys_DoubleTime();
|
|
|
|
|
time = newtime - oldtime;
|
2007-06-21 22:00:00 +02:00
|
|
|
|
|
2007-09-09 22:00:00 +02:00
|
|
|
|
Host_Frame (time); // engine frame
|
2007-06-21 22:00:00 +02:00
|
|
|
|
}
|
2007-09-12 22:00:00 +02:00
|
|
|
|
host.state = HOST_SHUTDOWN;
|
2007-06-21 22:00:00 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
=================
|
|
|
|
|
Host_Shutdown
|
|
|
|
|
=================
|
|
|
|
|
*/
|
|
|
|
|
void Host_Free (void)
|
|
|
|
|
{
|
2007-10-29 22:00:00 +01:00
|
|
|
|
SV_Shutdown ("Server shutdown\n", false);
|
|
|
|
|
CL_Shutdown ();
|
2007-09-17 22:00:00 +02:00
|
|
|
|
NET_Shutdown();
|
2007-10-22 22:00:00 +02:00
|
|
|
|
Host_FreePhysic();
|
2007-10-24 22:00:00 +02:00
|
|
|
|
Host_FreeCommon();
|
2007-09-10 22:00:00 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
=================
|
|
|
|
|
Host_Error
|
|
|
|
|
=================
|
|
|
|
|
*/
|
|
|
|
|
void Host_Error( const char *error, ... )
|
|
|
|
|
{
|
|
|
|
|
static char hosterror1[MAX_INPUTLINE];
|
|
|
|
|
static char hosterror2[MAX_INPUTLINE];
|
|
|
|
|
static bool recursive = false;
|
|
|
|
|
va_list argptr;
|
|
|
|
|
|
|
|
|
|
va_start( argptr, error );
|
|
|
|
|
vsprintf( hosterror1, error, argptr );
|
|
|
|
|
va_end( argptr );
|
|
|
|
|
|
|
|
|
|
if (host.framecount < 3 || host.state == HOST_SHUTDOWN)
|
|
|
|
|
Sys_Error ("%s", hosterror1 );
|
|
|
|
|
else Msg("Host_Error: %s", hosterror1);
|
|
|
|
|
|
|
|
|
|
if(recursive)
|
|
|
|
|
{
|
|
|
|
|
Msg("Host_Error: recursive %s", hosterror2);
|
|
|
|
|
Sys_Error ("%s", hosterror1);
|
|
|
|
|
}
|
|
|
|
|
recursive = true;
|
2007-09-13 22:00:00 +02:00
|
|
|
|
strncpy(hosterror2, hosterror1, sizeof(hosterror2));
|
2007-09-10 22:00:00 +02:00
|
|
|
|
|
|
|
|
|
SV_Shutdown (va("Server crashed: %s", hosterror1), false);
|
|
|
|
|
CL_Drop(); // drop clients
|
|
|
|
|
|
|
|
|
|
recursive = false;
|
|
|
|
|
Host_AbortCurrentFrame();
|
2007-09-22 22:00:00 +02:00
|
|
|
|
host.state = HOST_ERROR;
|
2007-09-10 22:00:00 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Host_Error_f( void )
|
|
|
|
|
{
|
|
|
|
|
Host_Error( "%s\n", Cmd_Argv(1));
|
2007-06-21 22:00:00 +02:00
|
|
|
|
}
|