]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - host.c
optimizing R_DrawSurfaces and WorldNode functions
[xonotic/darkplaces.git] / host.c
diff --git a/host.c b/host.c
index 1a20443e9c996ce9814f5aeb203e24db7a5c1335..7b6cd76ef06ba4efe97b3e4e8af10f945040b329 100644 (file)
--- a/host.c
+++ b/host.c
@@ -8,7 +8,7 @@ of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 See the GNU General Public License for more details.
 
@@ -19,7 +19,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
 // host.c -- coordinates spawning and killing of local servers
 
+#include <time.h>
 #include "quakedef.h"
+#include "cl_video.h"
 
 /*
 
@@ -32,8 +34,6 @@ 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       host_loopactive = false;        // LordHavoc: used to turn Host_Error into Sys_Error if starting up or shutting down
 qboolean       host_shuttingdown = false;      // LordHavoc: set when quit is executed
@@ -56,6 +56,8 @@ cvar_t        slowmo = {0, "slowmo", "1.0"};                                  // LordHavoc: framerate independent sl
 cvar_t host_minfps = {CVAR_SAVE, "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 = {CVAR_SAVE, "host_maxfps", "1000"};               // LordHavoc: framerate upper cap
 
+cvar_t sv_echobprint = {CVAR_SAVE, "sv_echobprint", "1"};      // print broadcast messages in dedicated mode
+
 cvar_t sys_ticrate = {CVAR_SAVE, "sys_ticrate","0.05"};
 cvar_t serverprofile = {0, "serverprofile","0"};
 
@@ -141,14 +143,14 @@ void Host_Error (char *error, ...)
                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 (hosterrorstring,error,argptr);
        va_end (argptr);
        Con_Printf ("Host_Error: %s\n",hosterrorstring);
-       
+
+       PR_Crash();
+
        if (sv.active)
                Host_ShutdownServer (false);
 
@@ -163,29 +165,19 @@ void Host_Error (char *error, ...)
        longjmp (host_abortserver, 1);
 }
 
-static mempool_t *clients_mempool;
-
-/*
-================
-Host_FindMaxClients
-================
-*/
-void   Host_FindMaxClients (void)
+void Host_ServerOptions (void)
 {
-       int             i;
+       int i, numplayers;
 
-       svs.maxclients = 1;
+       numplayers = 1;
 
        i = COM_CheckParm ("-dedicated");
        if (i)
        {
                cls.state = ca_dedicated;
+               numplayers = 0;
                if (i != (com_argc - 1))
-               {
-                       svs.maxclients = atoi (com_argv[i+1]);
-               }
-               else
-                       svs.maxclients = 8;
+                       numplayers = atoi (com_argv[i+1]);
        }
        else
                cls.state = ca_disconnected;
@@ -195,34 +187,43 @@ void      Host_FindMaxClients (void)
        {
                if (cls.state == ca_dedicated)
                        Sys_Error ("Only one of -dedicated or -listen can be specified");
+               numplayers = 0;
                if (i != (com_argc - 1))
-                       svs.maxclients = atoi (com_argv[i+1]);
-               else
-                       svs.maxclients = 8;
+                       numplayers = atoi (com_argv[i+1]);
        }
 
-       // BloodBath doesn't support single player games
-       if (gamemode == GAME_BLOODBATH && svs.maxclients < 4)
-               svs.maxclients = 4;
+       if (numplayers < 1)
+               numplayers = 8;
+       if (numplayers > MAX_SCOREBOARD)
+               numplayers = MAX_SCOREBOARD;
 
-       if (svs.maxclients < 1)
-               svs.maxclients = 8;
-       else if (svs.maxclients > MAX_SCOREBOARD)
-               svs.maxclients = MAX_SCOREBOARD;
+       // Transfusion doesn't support single player games
+       if (gamemode == GAME_TRANSFUSION && numplayers < 4)
+               numplayers = 4;
 
-       svs.maxclientslimit = svs.maxclients;
-       if (svs.maxclientslimit < MAX_SCOREBOARD) // LordHavoc: upped listen mode limit from 4 to MAX_SCOREBOARD
-               svs.maxclientslimit = MAX_SCOREBOARD;
+       if (numplayers > 1)
+               Cvar_SetValueQuick (&deathmatch, 1);
+       else
+               Cvar_SetValueQuick (&deathmatch, 0);
+
+       svs.maxclients = 0;
+       SV_SetMaxClients(numplayers);
+}
+
+static mempool_t *clients_mempool;
+void SV_SetMaxClients(int n)
+{
+       if (sv.active)
+               return;
+       n = bound(1, n, MAX_SCOREBOARD);
+       if (svs.maxclients == n)
+               return;
+       svs.maxclients = n;
        if (!clients_mempool)
                clients_mempool = Mem_AllocPool("clients");
        if (svs.clients)
                Mem_Free(svs.clients);
-       svs.clients = Mem_Alloc(clients_mempool, svs.maxclientslimit*sizeof(client_t));
-
-       if (svs.maxclients > 1)
-               Cvar_SetValue ("deathmatch", 1.0);
-       else
-               Cvar_SetValue ("deathmatch", 0.0);
+       svs.clients = Mem_Alloc(clients_mempool, svs.maxclients*sizeof(client_t));
 }
 
 
@@ -241,6 +242,8 @@ void Host_InitLocal (void)
        Cvar_RegisterVariable (&host_minfps);
        Cvar_RegisterVariable (&host_maxfps);
 
+       Cvar_RegisterVariable (&sv_echobprint);
+
        Cvar_RegisterVariable (&sys_ticrate);
        Cvar_RegisterVariable (&serverprofile);
 
@@ -263,7 +266,7 @@ void Host_InitLocal (void)
        Cvar_RegisterVariable (&timestamps);
        Cvar_RegisterVariable (&timeformat);
 
-       Host_FindMaxClients ();
+       Host_ServerOptions ();
 }
 
 
@@ -301,7 +304,7 @@ void Host_WriteConfiguration (void)
 =================
 SV_ClientPrintf
 
-Sends text across to be displayed 
+Sends text across to be displayed
 FIXME: make this just a stuffed echo?
 =================
 */
@@ -341,6 +344,9 @@ void SV_BroadcastPrintf (char *fmt, ...)
                        MSG_WriteByte (&svs.clients[i].message, svc_print);
                        MSG_WriteString (&svs.clients[i].message, string);
                }
+
+       if (sv_echobprint.integer && cls.state == ca_dedicated)
+               Sys_Printf ("%s", string);
 }
 
 /*
@@ -358,7 +364,7 @@ void Host_ClientCommands (char *fmt, ...)
        va_start (argptr,fmt);
        vsprintf (string, fmt,argptr);
        va_end (argptr);
-       
+
        MSG_WriteByte (&host_client->message, svc_stufftext);
        MSG_WriteString (&host_client->message, string);
 }
@@ -444,6 +450,9 @@ void Host_ShutdownServer(qboolean crash)
        if (!sv.active)
                return;
 
+       // print out where the crash happened, if it was caused by QC
+       PR_Crash();
+
        sv.active = false;
 
 // stop all client sounds immediately
@@ -492,7 +501,7 @@ void Host_ShutdownServer(qboolean crash)
 // clear structures
 //
        memset (&sv, 0, sizeof(sv));
-       memset (svs.clients, 0, svs.maxclientslimit*sizeof(client_t));
+       memset (svs.clients, 0, svs.maxclients * sizeof(client_t));
 }
 
 
@@ -524,6 +533,7 @@ Host_FilterTime
 Returns false if the time is too short to run a frame
 ===================
 */
+extern cvar_t cl_avidemo;
 qboolean Host_FilterTime (double time)
 {
        double timecap;
@@ -535,12 +545,21 @@ qboolean Host_FilterTime (double time)
                Cvar_SetValue("host_minfps", 10.0f);
        if (host_maxfps.value < host_minfps.value)
                Cvar_SetValue("host_maxfps", host_minfps.value);
+       if (cl_avidemo.value < 0.1f && cl_avidemo.value != 0.0f)
+               Cvar_SetValue("cl_avidemo", 0.0f);
 
-        // check if framerate is too high
-       if (!cls.timedemo)
+       // check if framerate is too high
+       if (cl_avidemo.value >= 0.1f)
+       {
+               timecap = 1.0 / (double)cl_avidemo.value;
+               if ((realtime - oldrealtime) < timecap)
+                       return false;
+       }
+       else if (!cls.timedemo)
        {
+               // default to sys_ticrate (server framerate - presumably low) unless we're the active window and either connected to a server or playing a video
                timecap = sys_ticrate.value;
-               if (cls.state == ca_connected)
+               if (vid_activewindow && (cls.state == ca_connected || cl_videoplaying))
                        timecap = 1.0 / host_maxfps.value;
 
                if ((realtime - oldrealtime) < timecap)
@@ -560,6 +579,8 @@ qboolean Host_FilterTime (double time)
 
        if (host_framerate.value > 0)
                host_frametime = host_framerate.value;
+       else if (cl_avidemo.value >= 0.1f)
+               host_frametime = (1.0 / cl_avidemo.value);
        else
        {
                // don't allow really short frames
@@ -568,7 +589,7 @@ qboolean Host_FilterTime (double time)
        }
 
        cl.frametime = host_frametime = bound(0, host_frametime * slowmo.value, 0.1f); // LordHavoc: the QC code relies on no less than 10fps
-       
+
        return true;
 }
 
@@ -608,13 +629,12 @@ void Host_ServerFrame (void)
        if (cls.state != ca_dedicated && svs.maxclients > 1 && ((realtime - lastservertime) < sys_ticrate.value))
                return;
 // run the world state
-       if (!sv.paused && (svs.maxclients > 1 || key_dest == key_game) )
+       if (!sv.paused && (svs.maxclients > 1 || (key_dest == key_game && !key_consoleactive)))
                sv.frametime = pr_global_struct->frametime = frametimetotal;
        else
                sv.frametime = 0;
        frametimetotal = 0;
        lastservertime = realtime;
-//     pr_global_struct->frametime = host_frametime;
 
 // set the time and clear the general datagram
        SV_ClearDatagram ();
@@ -627,7 +647,7 @@ void Host_ServerFrame (void)
 
 // 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) )
+       if (sv.frametime)
                SV_Physics ();
 
 // send all messages to the clients
@@ -707,6 +727,8 @@ void _Host_Frame (float time)
 
        ui_update();
 
+       CL_VideoFrame();
+
 // update video
        if (host_speeds.integer)
                time1 = Sys_DoubleTime ();
@@ -791,8 +813,9 @@ Host_Init
 */
 void Host_Init (void)
 {
-       com_argc = host_parms.argc;
-       com_argv = host_parms.argv;
+       // LordHavoc: quake never seeded the random number generator before... heh
+       srand(time(NULL));
+
        // FIXME: this is evil, but possibly temporary
        if (COM_CheckParm("-developer"))
        {
@@ -801,7 +824,6 @@ void Host_Init (void)
                developer.value = 1;
        }
 
-       Memory_Init ();
        Cmd_Init ();
        Memory_Init_Commands();
        R_Modules_Init();
@@ -820,7 +842,7 @@ void Host_Init (void)
        NET_Init ();
        SV_Init ();
 
-       Con_Printf ("Exe: "__TIME__" "__DATE__"\n");
+       Con_Printf ("Builddate: %s\n", buildstring);
 
        if (cls.state != ca_dedicated)
        {
@@ -872,9 +894,6 @@ void Host_Shutdown(void)
        }
        isdown = true;
 
-// keep Con_Printf from trying to update the screen
-//     scr_disabled_for_loading = true;
-
        Host_WriteConfiguration (); 
 
        CDAudio_Shutdown ();