X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=host.c;h=2ba18dca9a9c278170398282a23ddf78a12fa17a;hb=7d0ec7ce187f7333a7ada2884108757a4fec6449;hp=8ca544a437d354c33660c6ed7a17f2d6a3a7cb2b;hpb=400e4a34bbef54082e7d39758fa5aa7ab1b654c7;p=xonotic%2Fdarkplaces.git diff --git a/host.c b/host.c index 8ca544a4..2ba18dca 100644 --- a/host.c +++ b/host.c @@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /* -A server can allways be started, even if the system started out as a client +A server can always be started, even if the system started out as a client to a remote system. A client can NOT be started if the system started as a dedicated server. @@ -35,9 +35,10 @@ Memory is cleared / released when a server or client begins, not when they end. quakeparms_t host_parms; qboolean host_initialized; // true if into command execution +qboolean hostloopactive = 0; // LordHavoc: used to turn Host_Error into Sys_Error if Host_Frame has not yet run double host_frametime; -double host_time; +double host_realframetime; // LordHavoc: the real frametime, before slowmo and clamping are applied (used for console scrolling) double realtime; // without any filtering or bounding double oldrealtime; // last frame run int host_framecount; @@ -55,6 +56,8 @@ jmp_buf host_abortserver; 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 host_minfps = {"host_minfps", "10"}; // LordHavoc: game logic lower cap on framerate (if framerate is below this is, it pretends it is this, so game logic will run normally) +cvar_t host_maxfps = {"host_maxfps", "1000"}; // LordHavoc: framerate upper cap cvar_t sys_ticrate = {"sys_ticrate","0.05"}; cvar_t serverprofile = {"serverprofile","0"}; @@ -115,15 +118,25 @@ Host_Error This shuts down both the client and server ================ */ -char hosterrorstring[1024]; +char hosterrorstring[4096]; void Host_Error (char *error, ...) { va_list argptr; static qboolean inerror = false; - + + // LordHavoc: if host_frame loop has not been run yet, do a Sys_Error instead + if (!hostloopactive) + { + char string[4096]; + va_start (argptr,error); + vsprintf (string,error,argptr); + va_end (argptr); + Sys_Error ("%s", string); + } + if (inerror) { - char string[1024]; + char string[4096]; va_start (argptr,error); vsprintf (string,error,argptr); va_end (argptr); @@ -131,7 +144,7 @@ void Host_Error (char *error, ...) } inerror = true; - SCR_EndLoadingPlaque (); // reenable screen updates +// SCR_EndLoadingPlaque (); // reenable screen updates va_start (argptr,error); vsprintf (hosterrorstring,error,argptr); @@ -216,6 +229,8 @@ void Host_InitLocal (void) Cvar_RegisterVariable (&host_framerate); Cvar_RegisterVariable (&host_speeds); Cvar_RegisterVariable (&slowmo); + Cvar_RegisterVariable (&host_minfps); + Cvar_RegisterVariable (&host_maxfps); Cvar_RegisterVariable (&sys_ticrate); Cvar_RegisterVariable (&serverprofile); @@ -238,8 +253,6 @@ void Host_InitLocal (void) Cvar_RegisterVariable (&timeformat); Host_FindMaxClients (); - - host_time = 1.0; // so a think at time 0 won't get called } @@ -252,13 +265,13 @@ Writes key bindings and archived cvars to config.cfg */ void Host_WriteConfiguration (void) { - FILE *f; + QFile *f; // dedicated servers initialize the host but don't parse and set the // config.cfg cvars if (host_initialized & !isDedicated) { - f = fopen (va("%s/config.cfg",com_gamedir), "w"); + f = Qopen (va("%s/config.cfg",com_gamedir), "w"); if (!f) { Con_Printf ("Couldn't write config.cfg.\n"); @@ -268,7 +281,7 @@ void Host_WriteConfiguration (void) Key_WriteBindings (f); Cvar_WriteVariables (f); - fclose (f); + Qclose (f); } } @@ -368,7 +381,7 @@ void SV_DropClient (qboolean crash) // this will set the body to a dead frame, among other things saveSelf = pr_global_struct->self; pr_global_struct->self = EDICT_TO_PROG(host_client->edict); - PR_ExecuteProgram (pr_global_struct->ClientDisconnect); + PR_ExecuteProgram (pr_global_struct->ClientDisconnect, "QC function ClientDisconnect is missing"); pr_global_struct->self = saveSelf; } @@ -427,7 +440,7 @@ void Host_ShutdownServer(qboolean crash) CL_Disconnect (); // flush any pending messages - like the score!!! - start = Sys_FloatTime(); + start = Sys_DoubleTime(); do { count = 0; @@ -447,7 +460,7 @@ void Host_ShutdownServer(qboolean crash) } } } - if ((Sys_FloatTime() - start) > 3.0) + if ((Sys_DoubleTime() - start) > 3.0) break; } while (count); @@ -503,25 +516,50 @@ Host_FilterTime Returns false if the time is too short to run a frame =================== */ -qboolean Host_FilterTime (float time) +qboolean Host_FilterTime (double time) { + double timecap; realtime += time; -// if (!cls.timedemo && realtime - oldrealtime < (1.0 / 72.0)) -// return false; // framerate is too high + if (slowmo.value < 0.0f) + Cvar_SetValue("slowmo", 0.0f); + if (host_minfps.value < 10.0f) + Cvar_SetValue("host_minfps", 10.0f); + if (host_maxfps.value < host_minfps.value) + Cvar_SetValue("host_maxfps", host_minfps.value); + + // check if framerate is too high + if (!cls.timedemo) + { + timecap = sys_ticrate.value; + if (cls.state == ca_connected) + timecap = 1.0 / host_maxfps.value; - host_frametime = (realtime - oldrealtime) * slowmo.value; // LordHavoc: slowmo cvar + if ((realtime - oldrealtime) < timecap) + return false; + } + + // LordHavoc: copy into host_realframetime as well + host_realframetime = host_frametime = realtime - oldrealtime; oldrealtime = realtime; + if (cls.timedemo) + { + // disable time effects + cl.frametime = host_frametime; + return true; + } + if (host_framerate.value > 0) host_frametime = host_framerate.value; else - { // don't allow really long or short frames - if (host_frametime > 0.1) - host_frametime = 0.1; - if (host_frametime < 0.001) - host_frametime = 0.001; + { + // don't allow really short frames + if (host_frametime > (1.0 / host_minfps.value)) + host_frametime = (1.0 / host_minfps.value); } + + cl.frametime = host_frametime = bound(0, host_frametime * slowmo.value, 0.1f); // LordHavoc: the QC code relies on no less than 10fps return true; } @@ -554,16 +592,17 @@ Host_ServerFrame ================== */ -double frametimetotal = 0, lastservertime = 0; void Host_ServerFrame (void) { + static double frametimetotal = 0, lastservertime = 0; 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; + sv.frametime = pr_global_struct->frametime = frametimetotal; frametimetotal = 0; + lastservertime = realtime; // pr_global_struct->frametime = host_frametime; // set the time and clear the general datagram @@ -601,13 +640,18 @@ void _Host_Frame (float time) if (setjmp (host_abortserver) ) return; // something bad happened, or the server disconnected + hostloopactive = 1; // keep the random time dependent rand (); // decide the simulation time if (!Host_FilterTime (time)) - return; // don't run too fast, or packets will flood out + { + // if time was rejected, don't totally hog the CPU + Sys_Sleep(); + return; + } // get new key events Sys_SendKeyEvents (); @@ -647,22 +691,18 @@ void _Host_Frame (float time) if (!sv.active) CL_SendCmd (); - host_time += host_frametime; - // fetch results from server if (cls.state == ca_connected) - { CL_ReadFromServer (); - } // update video if (host_speeds.value) - time1 = Sys_FloatTime (); + time1 = Sys_DoubleTime (); SCR_UpdateScreen (); if (host_speeds.value) - time2 = Sys_FloatTime (); + time2 = Sys_DoubleTime (); // update audio if (cls.signon == SIGNONS) @@ -677,11 +717,11 @@ void _Host_Frame (float time) if (host_speeds.value) { - pass1 = (time1 - time3)*1000; - time3 = Sys_FloatTime (); - pass2 = (time2 - time1)*1000; - pass3 = (time3 - time2)*1000; - Con_Printf ("%3i tot %3i server %3i gfx %3i snd\n", + pass1 = (time1 - time3)*1000000; + time3 = Sys_DoubleTime (); + pass2 = (time2 - time1)*1000000; + pass3 = (time3 - time2)*1000000; + Con_Printf ("%6ius total %6ius server %6ius gfx %6ius snd\n", pass1+pass2+pass3, pass1, pass2, pass3); } @@ -701,9 +741,9 @@ void Host_Frame (float time) return; } - time1 = Sys_FloatTime (); + time1 = Sys_DoubleTime (); _Host_Frame (time); - time2 = Sys_FloatTime (); + time2 = Sys_DoubleTime (); timetotal += time2 - time1; timecount++; @@ -726,78 +766,16 @@ void Host_Frame (float time) //============================================================================ - -extern int vcrFile; -#define VCR_SIGNATURE 0x56435231 -// "VCR1" - -void Host_InitVCR () -{ - int i, len, n; - char *p; - - if (COM_CheckParm("-playback")) - { - if (com_argc != 2) - Sys_Error("No other parameters allowed with -playback\n"); - - Sys_FileOpenRead("quake.vcr", &vcrFile); - if (vcrFile == -1) - Sys_Error("playback file not found\n"); - - Sys_FileRead (vcrFile, &i, sizeof(int)); - if (i != VCR_SIGNATURE) - Sys_Error("Invalid signature in vcr file\n"); - - Sys_FileRead (vcrFile, &com_argc, sizeof(int)); - com_argv = qmalloc(com_argc * sizeof(char *)); - com_argv[0] = host_parms.argv[0]; - for (i = 0; i < com_argc; i++) - { - Sys_FileRead (vcrFile, &len, sizeof(int)); - p = qmalloc(len); - Sys_FileRead (vcrFile, p, len); - com_argv[i+1] = p; - } - com_argc++; /* add one for arg[0] */ - host_parms.argc = com_argc; - host_parms.argv = com_argv; - } - - if ( (n = COM_CheckParm("-record")) != 0) - { - vcrFile = Sys_FileOpenWrite("quake.vcr"); - - i = VCR_SIGNATURE; - Sys_FileWrite(vcrFile, &i, sizeof(int)); - i = com_argc - 1; - Sys_FileWrite(vcrFile, &i, sizeof(int)); - for (i = 1; i < com_argc; i++) - { - if (i == n) - { - len = 10; - Sys_FileWrite(vcrFile, &len, sizeof(int)); - Sys_FileWrite(vcrFile, "-playback", len); - continue; - } - len = strlen(com_argv[i]) + 1; - Sys_FileWrite(vcrFile, &len, sizeof(int)); - Sys_FileWrite(vcrFile, com_argv[i], len); - } - } - -} - -void Render_Init(); +void Render_Init(void); /* ==================== Host_Init ==================== */ -void Host_Init () +void Host_Init (void) { + int i; /* if (standard_quake) minimum_memory = MINIMUM_MEMORY; @@ -811,6 +789,24 @@ void Host_Init () Sys_Error ("Only %4.1f megs of memory available, can't execute game", host_parms.memsize / (float)0x100000); */ + host_parms.memsize = DEFAULTMEM * 1024 * 1024; + + i = COM_CheckParm("-mem"); + if (i) + host_parms.memsize = (int) (atof(com_argv[i+1]) * 1024 * 1024); + + i = COM_CheckParm("-winmem"); + if (i) + host_parms.memsize = (int) (atof(com_argv[i+1]) * 1024 * 1024); + + i = COM_CheckParm("-heapsize"); + if (i) + host_parms.memsize = (int) (atof(com_argv[i+1]) * 1024); + + host_parms.membase = qmalloc(host_parms.memsize); + if (!host_parms.membase) + Sys_Error("Not enough memory free, close some programs and try again, or free disk space\n"); + com_argc = host_parms.argc; com_argv = host_parms.argv; @@ -819,7 +815,6 @@ void Host_Init () Cmd_Init (); V_Init (); Chase_Init (); - Host_InitVCR (); COM_Init (host_parms.basedir); Host_InitLocal (); W_LoadWadFile ("gfx.wad"); @@ -834,11 +829,13 @@ void Host_Init () Con_Printf ("Exe: "__TIME__" "__DATE__"\n"); 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) { - Palette_Init("gfx/palette.lmp"); + VID_InitCvars(); + + Gamma_Init(); + + Palette_Init(); #ifndef _WIN32 // on non win32, mouse comes before video for security reasons IN_Init (); @@ -897,7 +894,7 @@ void Host_Shutdown(void) if (cls.state != ca_dedicated) { - R_ShutdownModules(); + R_Modules_Shutdown(); VID_Shutdown(); } }