This repository has been archived on 2022-06-27. You can view files and clone it, but cannot push or open issues or pull requests.
Xash3DArchive/engine/host.c

408 lines
8.0 KiB
C
Raw Normal View History

2007-06-21 22:00:00 +02:00
//=======================================================================
// Copyright XashXT Group 2007 <20>
// host.c - dedicated and shared host
//=======================================================================
#include <setjmp.h>
#include "engine.h"
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);
HINSTANCE global_hInstance;
2007-11-08 22:00:00 +01:00
dll_info_t physic_dll = { "physic.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(physic_exp_t) };
2007-06-21 22:00:00 +02:00
cvar_t *timescale;
cvar_t *fixedtime;
2007-11-14 22:00:00 +01:00
cvar_t *dedicated;
cvar_t *host_serverstate;
cvar_t *host_frametime;
2007-06-21 22:00:00 +02:00
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-11-10 22:00:00 +01:00
io = std;
2007-10-22 22:00:00 +02:00
2007-11-10 22:00:00 +01:00
// overload some funcs
2007-11-14 22:00:00 +01:00
io.print = Host_Print;
io.printf = Host_Printf;
io.dprintf = Host_DPrintf;
io.wprintf = Host_DWarnf;
2007-10-22 22:00:00 +02:00
if(crash_on_error) io.error = Sys_Error;
else io.error = Host_Error;
2007-09-13 22:00:00 +02:00
2007-10-22 22:00:00 +02:00
return io;
}
2007-11-11 22:00:00 +01:00
void Host_InitCommon( uint funcname, int argc, char **argv )
2007-10-22 22:00:00 +02:00
{
2007-09-13 22:00:00 +02:00
// TODO: init basedir here
2007-11-10 22:00:00 +01:00
FS_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-11-11 22:00:00 +01:00
Mem_FreePool( &zonepool );
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;
2007-11-11 22:00:00 +01:00
launch_t CreatePhys;
stdlib_api_t io = Host_GetStdio( false );
2007-10-22 22:00:00 +02:00
2007-10-27 22:00:00 +02:00
// phys callback
2007-11-11 22:00:00 +01:00
pi.api_size = sizeof(physic_imp_t);
2007-10-27 22:00:00 +02:00
pi.Transform = SV_Transform;
2007-10-22 22:00:00 +02:00
Sys_LoadLibrary( &physic_dll );
CreatePhys = (void *)physic_dll.main;
2007-11-11 22:00:00 +01:00
Phys = CreatePhys( &io, &pi );
2007-10-22 22:00:00 +02:00
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-11-14 22:00:00 +01:00
/*
==================
Host_GetServerState
==================
*/
int Host_ServerState( void )
{
return host_serverstate->integer;
}
/*
==================
Host_SetServerState
==================
*/
void Host_SetServerState( int state )
{
Cvar_SetValue("host_serverstate", state );
}
2007-06-21 22:00:00 +02:00
/*
=================
Host_Init
=================
*/
2007-11-11 22:00:00 +01:00
void Host_Init (uint funcname, int argc, char **argv)
2007-06-21 22:00:00 +02:00
{
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-11-11 22:00:00 +01:00
host.type = funcname;
2007-06-21 22:00:00 +02:00
2007-11-08 22:00:00 +01:00
srand(time(NULL)); // init random generator
2007-06-21 22:00:00 +02:00
2007-11-08 22:00:00 +01:00
Host_InitCommon( funcname, argc, argv ); // loading common.dll
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-11 22:00:00 +01:00
#if 1
2007-11-04 22:00:00 +01:00
Cbuf_AddText("exec keys.rc\n");
Cbuf_AddText("exec vars.rc\n");
2007-11-11 22:00:00 +01:00
#else
Cbuf_AddText("exec default.cfg\n");
Cbuf_AddText("exec config.cfg\n");
#endif
2007-11-04 22:00:00 +01:00
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
2007-10-29 22:00:00 +01:00
host_frametime = Cvar_Get ("host_frametime", "0.01", 0);
2007-11-14 22:00:00 +01:00
host_serverstate = Cvar_Get ("host_serverstate", "0", 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
2007-11-14 22:00:00 +01:00
s = va("^1Xash %g ^3%s", XASH_VERSION, 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-11-11 22:00:00 +01:00
2007-10-22 22:00:00 +02:00
NET_Init();
Netchan_Init();
Host_InitPhysic();
2007-11-11 22:00:00 +01:00
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" );
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-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-11-14 22:00:00 +01:00
Sys_SendKeyEvents(); // get new key events
2007-10-29 22:00:00 +01:00
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-11-14 22:00:00 +01:00
} while( s );
2007-11-11 22:00:00 +01:00
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-06-21 22:00:00 +02:00
SV_Frame (time);
CL_Frame (time);
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
=================
*/
2007-11-14 22:00:00 +01:00
void Host_Free( void )
2007-06-21 22:00:00 +02:00
{
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
}
2007-11-14 22:00:00 +01:00
/*
================
Host_Print
Handles cursor positioning, line wrapping, etc
All console printing must go through this in order to be logged to disk
If no console is visible, the text will appear at the top of the game window
================
*/
void Host_Print( const char *txt )
{
if(host.rd.target)
{
if((strlen (txt) + strlen(host.rd.buffer)) > (host.rd.buffersize - 1))
{
if(host.rd.flush)
{
host.rd.flush(host.rd.target, host.rd.buffer);
*host.rd.buffer = 0;
}
}
strcat (host.rd.buffer, txt);
return;
}
Con_Print( txt ); // echo to client console
Sys_Print( txt ); // echo to system console
// sys print also stored messages into system log
}
/*
=============
Host_Printf
Both client and server can use this, and it will output
to the apropriate place.
=============
*/
void Host_Printf( const char *fmt, ... )
{
va_list argptr;
char msg[MAX_INPUTLINE];
va_start( argptr, fmt );
vsprintf( msg, fmt, argptr );
va_end( argptr );
Host_Print( msg );
}
/*
================
Host_DPrintf
A Msg that only shows up in developer mode
================
*/
void Host_DPrintf( int level, const char *fmt, ... )
{
va_list argptr;
char msg[MAX_INPUTLINE];
// don't confuse non-developers with techie stuff...
if(host.developer < level) return;
va_start( argptr, fmt );
vsprintf( msg, fmt, argptr );
va_end( argptr );
switch(level)
{
case D_INFO:
Host_Print( msg );
break;
case D_WARN:
Host_Print(va("^3Warning:^7 %s", msg));
break;
case D_ERROR:
Host_Print(va("^1Error:^7 %s", msg));
break;
case D_LOAD:
Host_Print(va("^2Loading: ^7%s", msg));
break;
case D_NOTE:
Host_Print( msg );
break;
case D_MEMORY:
Host_Print(va("^6Mem: ^7%s", msg));
break;
}
}
/*
================
Host_DWarnf
A Warning that only shows up in debug mode
================
*/
void Host_DWarnf( const char *fmt, ... )
{
va_list argptr;
char msg[MAX_INPUTLINE];
// don't confuse non-developers with techie stuff...
if (!host.debug) return;
va_start( argptr, fmt );
vsprintf( msg, fmt, argptr );
va_end( argptr );
Host_Print(va("^3Warning:^7 %s", msg));
}
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 );
2007-11-14 22:00:00 +01:00
else Host_Printf("Host_Error: %s", hosterror1);
2007-09-10 22:00:00 +02:00
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
}