double oldrealtime; // last frame run
int host_framecount;
+double sv_frametime;
+
int host_hunklevel;
int minimum_memory;
jmp_buf host_abortserver;
-byte *host_basepal;
-byte *host_colormap;
-
cvar_t host_framerate = {"host_framerate","0"}; // set for slow motion
cvar_t host_speeds = {"host_speeds","0"}; // set for running times
cvar_t slowmo = {"slowmo", "1.0"}; // LordHavoc: framerate independent slowmo
cvar_t temp1 = {"temp1","0"};
+cvar_t timestamps = {"timestamps", "0", true};
+cvar_t timeformat = {"timeformat", "[%b %e %X] ", true};
/*
================
This shuts down both the client and server
================
*/
+char hosterrorstring[1024];
void Host_Error (char *error, ...)
{
va_list argptr;
- char string[1024];
static qboolean inerror = false;
if (inerror)
- Sys_Error ("Host_Error: recursively entered");
+ {
+ char string[1024];
+ va_start (argptr,error);
+ vsprintf (string,error,argptr);
+ va_end (argptr);
+ Sys_Error ("Host_Error: recursively entered (original error was: %s new error is: %s)", hosterrorstring, string);
+ }
inerror = true;
SCR_EndLoadingPlaque (); // reenable screen updates
va_start (argptr,error);
- vsprintf (string,error,argptr);
+ vsprintf (hosterrorstring,error,argptr);
va_end (argptr);
- Con_Printf ("Host_Error: %s\n",string);
+ Con_Printf ("Host_Error: %s\n",hosterrorstring);
if (sv.active)
Host_ShutdownServer (false);
if (cls.state == ca_dedicated)
- Sys_Error ("Host_Error: %s\n",string); // dedicated servers exit
+ Sys_Error ("Host_Error: %s\n",hosterrorstring); // dedicated servers exit
CL_Disconnect ();
cls.demonum = -1;
Cvar_RegisterVariable (&temp1);
+ Cvar_RegisterVariable (×tamps);
+ Cvar_RegisterVariable (&timeformat);
+
Host_FindMaxClients ();
host_time = 1.0; // so a think at time 0 won't get called
NET_SendMessage (host_client->netconnection, &host_client->message);
}
- if (host_client->edict && host_client->spawned)
+ if (sv.active && host_client->edict && host_client->spawned) // LordHavoc: don't call QC if server is dead (avoids recursive Host_Error in some mods when they run out of edicts)
{
// call the prog function for removing a client
// this will set the body to a dead frame, among other things
void Host_ClearMemory (void)
{
Con_DPrintf ("Clearing memory\n");
- D_FlushCaches ();
Mod_ClearAll ();
if (host_hunklevel)
Hunk_FreeToLowMark (host_hunklevel);
//============================================================================
-extern cvar_t maxfps;
-
/*
===================
Host_FilterTime
{
realtime += time;
- if (maxfps.value < 5) // LordHavoc: sanity checking
- maxfps.value = 5;
- if (maxfps.value > 1000) // LordHavoc: sanity checking
- maxfps.value = 1000;
- if (!cls.timedemo && realtime - oldrealtime < (1.0 / maxfps.value))
- return false; // framerate is too high
+// if (!cls.timedemo && realtime - oldrealtime < (1.0 / 72.0))
+// return false; // framerate is too high
host_frametime = (realtime - oldrealtime) * slowmo.value; // LordHavoc: slowmo cvar
oldrealtime = realtime;
==================
*/
-#ifdef FPS_20
-
-void _Host_ServerFrame (void)
-{
-// run the world state
- pr_global_struct->frametime = host_frametime;
-
-// read client messages
- SV_RunClients ();
-
-// move things around and think
-// always pause in single player if in console or menus
- if (!sv.paused && (svs.maxclients > 1 || key_dest == key_game) )
- SV_Physics ();
-}
-
-void Host_ServerFrame (void)
-{
- float save_host_frametime;
- float temp_host_frametime;
- static float host_serverframe_timevalue;
-
-// run the world state
- pr_global_struct->frametime = host_frametime;
-
-// set the time and clear the general datagram
- SV_ClearDatagram ();
-
-// check for new clients
- SV_CheckForNewClients ();
-
- temp_host_frametime = save_host_frametime = host_frametime;
- // LordHavoc: the results of my attempts to mangle this code to process no more than sys_ticrate,
- // when I found that was too choppy, I changed it back to processing at least 20fps,
- // I consider it a bit of a failure... because I felt a little out of control in singleplayer
- // (sliding around)
- //if (host_serverframe_timevalue < -0.2) // don't let it get way out of range
- // host_serverframe_timevalue = -0.2;
- //host_serverframe_timevalue += host_frametime;
- // process frames (several if rendering is too slow to run well as a server)
- while(temp_host_frametime > 0.0)
- {
- host_frametime = temp_host_frametime;
- if (host_frametime > 0.05)
- host_frametime = 0.05;
- temp_host_frametime -= host_frametime;
- // host_serverframe_timevalue -= host_frametime;
- _Host_ServerFrame ();
- }
- host_frametime = save_host_frametime;
-
-// send all messages to the clients
- SV_SendClientMessages ();
-// LordHavoc: sadly, this didn't look good to the person running the server in listen mode
- /*
-// wait until enough time has built up when the framerate exceeds sys_ticrate
- if (host_serverframe_timevalue >= sys_ticrate.value)
- //{
- // while(host_serverframe_timevalue >= sys_ticrate.value)
- // host_serverframe_timevalue -= sys_ticrate.value;
-// send all messages to the clients
- SV_SendClientMessages ();
- }
- */
-}
-
-#else
-
+double frametimetotal = 0, lastservertime = 0;
void Host_ServerFrame (void)
{
-// run the world state
- pr_global_struct->frametime = host_frametime;
+ frametimetotal += host_frametime;
+ // LordHavoc: cap server at sys_ticrate in listen games
+ if (!isDedicated && svs.maxclients > 1 && ((realtime - lastservertime) < sys_ticrate.value))
+ return;
+// run the world state
+ sv_frametime = pr_global_struct->frametime = frametimetotal;
+ frametimetotal = 0;
+// pr_global_struct->frametime = host_frametime;
// set the time and clear the general datagram
SV_ClearDatagram ();
SV_SendClientMessages ();
}
-#endif
-
/*
==================
#define VCR_SIGNATURE 0x56435231
// "VCR1"
-void Host_InitVCR (quakeparms_t *parms)
+void Host_InitVCR ()
{
int i, len, n;
char *p;
Sys_FileRead (vcrFile, &com_argc, sizeof(int));
com_argv = malloc(com_argc * sizeof(char *));
- com_argv[0] = parms->argv[0];
+ com_argv[0] = host_parms.argv[0];
for (i = 0; i < com_argc; i++)
{
Sys_FileRead (vcrFile, &len, sizeof(int));
com_argv[i+1] = p;
}
com_argc++; /* add one for arg[0] */
- parms->argc = com_argc;
- parms->argv = com_argv;
+ host_parms.argc = com_argc;
+ host_parms.argv = com_argv;
}
if ( (n = COM_CheckParm("-record")) != 0)
}
+void Render_Init();
+
/*
====================
Host_Init
====================
*/
-void Host_Init (quakeparms_t *parms)
+void Host_Init ()
{
if (standard_quake)
minimum_memory = MINIMUM_MEMORY_LEVELPAK;
if (COM_CheckParm ("-minmemory"))
- parms->memsize = minimum_memory;
-
- host_parms = *parms;
+ host_parms.memsize = minimum_memory;
- if (parms->memsize < minimum_memory)
- Sys_Error ("Only %4.1f megs of memory available, can't execute game", parms->memsize / (float)0x100000);
+ if (host_parms.memsize < minimum_memory)
+ Sys_Error ("Only %4.1f megs of memory available, can't execute game", host_parms.memsize / (float)0x100000);
- com_argc = parms->argc;
- com_argv = parms->argv;
+ com_argc = host_parms.argc;
+ com_argv = host_parms.argv;
- Memory_Init (parms->membase, parms->memsize);
+ Memory_Init (host_parms.membase, host_parms.memsize);
Cbuf_Init ();
Cmd_Init ();
V_Init ();
Chase_Init ();
- Host_InitVCR (parms);
- COM_Init (parms->basedir);
+ Host_InitVCR ();
+ COM_Init (host_parms.basedir);
Host_InitLocal ();
W_LoadWadFile ("gfx.wad");
Key_Init ();
SV_Init ();
Con_Printf ("Exe: "__TIME__" "__DATE__"\n");
- Con_Printf ("%4.1f megabyte heap\n",parms->memsize/ (1024*1024.0));
+ Con_Printf ("%4.1f megabyte heap\n",host_parms.memsize/(1024*1024.0));
R_InitTextures (); // needed even for dedicated servers
if (cls.state != ca_dedicated)
{
- host_basepal = (byte *)COM_LoadHunkFile ("gfx/palette.lmp", false);
- if (!host_basepal)
- Sys_Error ("Couldn't load gfx/palette.lmp");
- host_colormap = (byte *)COM_LoadHunkFile ("gfx/colormap.lmp", false);
- if (!host_colormap)
- Sys_Error ("Couldn't load gfx/colormap.lmp");
+ Palette_Init("gfx/palette.lmp");
#ifndef _WIN32 // on non win32, mouse comes before video for security reasons
IN_Init ();
#endif
- VID_Init (host_basepal);
-
- Draw_Init ();
- SCR_Init ();
- R_Init ();
-#ifndef _WIN32
- // on Win32, sound initialization has to come before video initialization, so we
- // can put up a popup if the sound hardware is in use
- S_Init ();
-#else
+ VID_Init ();
- // FIXME: doesn't use the new one-window approach yet
+ Render_Init();
S_Init ();
-
-#endif // _WIN32
CDAudio_Init ();
Sbar_Init ();
CL_Init ();
if (cls.state != ca_dedicated)
{
+ R_ShutdownModules();
VID_Shutdown();
}
}