]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - host.c
fixed specularscale calculation
[xonotic/darkplaces.git] / host.c
diff --git a/host.c b/host.c
index 2495e58c066cd7f74a36f1f3cd85e49c0e214082..aea36ef34baa8c75ec845f99f4faf83bf820c491 100644 (file)
--- a/host.c
+++ b/host.c
@@ -56,7 +56,7 @@ jmp_buf host_abortframe;
 cvar_t sv_random_seed = {0, "sv_random_seed", "", "random seed; when set, on every map start this random seed is used to initialize the random number generator. Don't touch it unless for benchmarking or debugging"};
 
 // pretend frames take this amount of time (in seconds), 0 = realtime
-cvar_t host_framerate = {0, "host_framerate","0", "locks frame timing to this value in seconds, 0.05 is 20fps for example, note that this can easily run too fast, use host_maxfps if you want to limit your framerate instead, or sys_ticrate to limit server speed"};
+cvar_t host_framerate = {0, "host_framerate","0", "locks frame timing to this value in seconds, 0.05 is 20fps for example, note that this can easily run too fast, use cl_maxfps if you want to limit your framerate instead, or sys_ticrate to limit server speed"};
 // shows time used by certain subsystems
 cvar_t host_speeds = {0, "host_speeds","0", "reports how much time is used in server/graphics/sound"};
 // LordHavoc: framerate independent slowmo
@@ -91,6 +91,8 @@ cvar_t temp1 = {0, "temp1","0", "general cvar for mods to use, in stock id1 this
 cvar_t timestamps = {CVAR_SAVE, "timestamps", "0", "prints timestamps on console messages"};
 cvar_t timeformat = {CVAR_SAVE, "timeformat", "[%Y-%m-%d %H:%M:%S] ", "time format to use on timestamped console messages"};
 
+cvar_t sv_checkforpacketsduringsleep = {0, "sv_checkforpacketsduringsleep", "0", "uses select() function to wait between frames which can be interrupted by packets being received, instead of Sleep()/usleep()/SDL_Sleep() functions which do not check for packets"};
+
 /*
 ================
 Host_AbortCurrentFrame
@@ -250,6 +252,8 @@ static void Host_InitLocal (void)
 
        Cvar_RegisterVariable (&timestamps);
        Cvar_RegisterVariable (&timeformat);
+
+       Cvar_RegisterVariable (&sv_checkforpacketsduringsleep);
 }
 
 
@@ -267,7 +271,7 @@ void Host_SaveConfig_f(void)
 // dedicated servers initialize the host but don't parse and set the
 // config.cfg cvars
        // LordHavoc: don't save a config if it crashed in startup
-       if (host_framecount >= 3 && cls.state != ca_dedicated)
+       if (host_framecount >= 3 && cls.state != ca_dedicated && !COM_CheckParm("-benchmark"))
        {
                f = FS_Open ("config.cfg", "wb", false, false);
                if (!f)
@@ -350,7 +354,7 @@ void SV_BroadcastPrint(const char *msg)
 
        for (i = 0, client = svs.clients;i < svs.maxclients;i++, client++)
        {
-               if (client->spawned && client->netconnection)
+               if (client->active && client->netconnection)
                {
                        MSG_WriteByte(&client->netconnection->message, svc_print);
                        MSG_WriteString(&client->netconnection->message, msg);
@@ -466,10 +470,6 @@ void SV_DropClient(qboolean crash)
        }
 
        // remove leaving player from scoreboard
-       //host_client->edict->fields.server->netname = PRVM_SetEngineString(host_client->name);
-       //if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_clientcolors)))
-       //      val->_float = 0;
-       //host_client->edict->fields.server->frags = 0;
        host_client->name[0] = 0;
        host_client->colors = 0;
        host_client->frags = 0;
@@ -581,7 +581,10 @@ void Host_Main(void)
        static double time2 = 0;
        static double time3 = 0;
        // these are static because of setjmp/longjmp warnings in mingw32 gcc 2.95.3
-       static double frameoldtime, framenewtime, frametime, cl_timer, sv_timer;
+       static double frameoldtime, framenewtime, framedeltatime, cl_timer, sv_timer;
+       double clframetime;
+       double wait;
+       int pass1, pass2, pass3;
 
        Host_Init();
 
@@ -596,18 +599,12 @@ void Host_Main(void)
 
                frameoldtime = framenewtime;
                framenewtime = Sys_DoubleTime();
-               frametime = framenewtime - frameoldtime;
-               realtime += frametime;
-
-               // if there is some time remaining from last frame, rest the timers
-               if (cl_timer >= 0)
-                       cl_timer = 0;
-               if (sv_timer >= 0)
-                       sv_timer = 0;
+               framedeltatime = framenewtime - frameoldtime;
+               realtime += framedeltatime;
 
                // accumulate the new frametime into the timers
-               cl_timer += frametime;
-               sv_timer += frametime;
+               cl_timer += framedeltatime;
+               sv_timer += framedeltatime;
 
                if (slowmo.value < 0)
                        Cvar_SetValue("slowmo", 0);
@@ -616,23 +613,6 @@ void Host_Main(void)
                if (cl_maxfps.value < 1)
                        Cvar_SetValue("cl_maxfps", 1);
 
-               // if the accumulators haven't become positive yet, keep waiting
-               if (!cls.timedemo && cl_timer <= 0 && sv_timer <= 0)
-               {
-                       double wait;
-                       int msleft;
-                       if (cls.state == ca_dedicated)
-                               wait = sv_timer;
-                       else if (!sv.active)
-                               wait = cl_timer;
-                       else
-                               wait = max(cl_timer, sv_timer);
-                       msleft = (int)floor(wait * -1000.0);
-                       if (msleft >= 1)
-                               Sys_Sleep(msleft);
-                       continue;
-               }
-
                // keep the random time dependent
                if(!*sv_random_seed.string)
                        rand();
@@ -642,6 +622,18 @@ void Host_Main(void)
                // get new key events
                Sys_SendKeyEvents();
 
+               NetConn_UpdateSockets();
+
+               // receive packets on each main loop iteration, as the main loop may
+               // be undersleeping due to select() detecting a new packet
+               if (sv.active)
+                       NetConn_ServerFrame();
+
+               Curl_Run();
+
+               // check for commands typed to the host
+               Host_GetConsoleCommands();
+
                // when a server is running we only execute console commands on server frames
                // (this mainly allows frikbot .way config files to work properly by staying in sync with the server qc)
                // otherwise we execute them on all frames
@@ -651,9 +643,31 @@ void Host_Main(void)
                        Cbuf_Execute();
                }
 
-               NetConn_UpdateSockets();
+               //Con_Printf("%6.0f %6.0f\n", cl_timer * 1000000.0, sv_timer * 1000000.0);
 
-               Curl_Run();
+               // if the accumulators haven't become positive yet, wait a while
+               if (cls.state == ca_dedicated)
+                       wait = sv_timer * -1000000.0;
+               else if (!sv.active)
+                       wait = cl_timer * -1000000.0;
+               else
+                       wait = max(cl_timer, sv_timer) * -1000000.0;
+               if (wait > 100000)
+                       wait = 100000;
+               if (!cls.timedemo && wait > 0)
+               {
+                       if (sv_checkforpacketsduringsleep.integer)
+                       {
+                               if (wait >= 1)
+                                       NetConn_SleepMicroseconds((int)wait);
+                       }
+                       else
+                       {
+                               if (wait >= 1000)
+                                       Sys_Sleep((int)wait / 1000);
+                       }
+                       continue;
+               }
 
        //-------------------
        //
@@ -661,91 +675,81 @@ void Host_Main(void)
        //
        //-------------------
 
-               // check for commands typed to the host
-               Host_GetConsoleCommands();
+               // limit the frametime steps to no more than 100ms each
+               if (cl_timer > 0.1)
+                       cl_timer = 0.1;
+               if (sv_timer > 0.1)
+                       sv_timer = 0.1;
 
-               if (sv_timer > 0)
+               if (sv.active && sv_timer > 0)
                {
-                       if (!sv.active)
+                       // execute one or more server frames, with an upper limit on how much
+                       // execution time to spend on server frames to avoid freezing the game if
+                       // the server is overloaded, this execution time limit means the game will
+                       // slow down if the server is taking too long.
+                       int framecount, framelimit = 1;
+                       double advancetime, aborttime = 0;
+
+                       // run the world state
+                       // don't allow simulation to run too fast or too slow or logic glitches can occur
+
+                       // stop running server frames if the wall time reaches this value
+                       if (sys_ticrate.value <= 0)
+                               advancetime = sv_timer;
+                       else if (cl.islocalgame && !sv_fixedframeratesingleplayer.integer)
                        {
-                               // if there is no server, run server timing at 10fps
-                               sv_timer -= 0.1;
+                               // synchronize to the client frametime, but no less than 10ms and no more than sys_ticrate
+                               advancetime = bound(0.01, cl_timer, sys_ticrate.value);
+                               framelimit = 10;
+                               aborttime = Sys_DoubleTime() + 0.1;
                        }
                        else
                        {
-                               // execute one or more server frames, with an upper limit on how much
-                               // execution time to spend on server frames to avoid freezing the game if
-                               // the server is overloaded, this execution time limit means the game will
-                               // slow down if the server is taking too long.
-                               int framecount, framelimit = 1;
-                               double advancetime, aborttime = 0;
-
-                               // receive server packets now, which might contain rcon commands, which
-                               // may change level or other such things we don't want to have happen in
-                               // the middle of Host_Frame
-                               NetConn_ServerFrame();
-
-                               // run the world state
-                               // don't allow simulation to run too fast or too slow or logic glitches can occur
-
-                               // stop running server frames if the wall time reaches this value
-                               if (sys_ticrate.value <= 0)
-                                       advancetime = sv_timer;
-                               else if (cl.islocalgame && !sv_fixedframeratesingleplayer.integer)
+                               advancetime = sys_ticrate.value;
+                               // listen servers can run multiple server frames per client frame
+                               if (cls.state == ca_connected)
                                {
-                                       // synchronize to the client frametime, but no less than 10ms and no more than sys_ticrate
-                                       advancetime = bound(0.01, cl_timer, sys_ticrate.value);
                                        framelimit = 10;
                                        aborttime = Sys_DoubleTime() + 0.1;
                                }
-                               else
-                               {
-                                       advancetime = sys_ticrate.value;
-                                       // listen servers can run multiple server frames per client frame
-                                       if (cls.state == ca_connected)
-                                       {
-                                               framelimit = 10;
-                                               aborttime = Sys_DoubleTime() + 0.1;
-                                       }
-                               }
-                               advancetime = min(advancetime, 0.1);
+                       }
+                       advancetime = min(advancetime, 0.1);
 
-                               // only advance time if not paused
-                               // the game also pauses in singleplayer when menu or console is used
-                               sv.frametime = advancetime * slowmo.value;
-                               if (host_framerate.value)
-                                       sv.frametime = host_framerate.value;
-                               if (sv.paused || (cl.islocalgame && (key_dest != key_game || key_consoleactive)))
-                                       sv.frametime = 0;
+                       // only advance time if not paused
+                       // the game also pauses in singleplayer when menu or console is used
+                       sv.frametime = advancetime * slowmo.value;
+                       if (host_framerate.value)
+                               sv.frametime = host_framerate.value;
+                       if (sv.paused || (cl.islocalgame && (key_dest != key_game || key_consoleactive)))
+                               sv.frametime = 0;
 
-                               // setup the VM frame
-                               SV_VM_Begin();
+                       // setup the VM frame
+                       SV_VM_Begin();
 
-                               for (framecount = 0;framecount < framelimit && sv_timer > 0;framecount++)
-                               {
-                                       sv_timer -= advancetime;
+                       for (framecount = 0;framecount < framelimit && sv_timer > 0;framecount++)
+                       {
+                               sv_timer -= advancetime;
 
-                                       // move things around and think unless paused
-                                       if (sv.frametime)
-                                               SV_Physics();
+                               // move things around and think unless paused
+                               if (sv.frametime)
+                                       SV_Physics();
 
-                                       // send all messages to the clients
-                                       SV_SendClientMessages();
+                               // send all messages to the clients
+                               SV_SendClientMessages();
 
-                                       // clear the general datagram
-                                       SV_ClearDatagram();
+                               // clear the general datagram
+                               SV_ClearDatagram();
 
-                                       // if this server frame took too long, break out of the loop
-                                       if (framelimit > 1 && Sys_DoubleTime() >= aborttime)
-                                               break;
-                               }
+                               // if this server frame took too long, break out of the loop
+                               if (framelimit > 1 && Sys_DoubleTime() >= aborttime)
+                                       break;
+                       }
 
-                               // end the server VM frame
-                               SV_VM_End();
+                       // end the server VM frame
+                       SV_VM_End();
 
-                               // send an heartbeat if enough time has passed since the last one
-                               NetConn_Heartbeat(0);
-                       }
+                       // send an heartbeat if enough time has passed since the last one
+                       NetConn_Heartbeat(0);
                }
 
        //-------------------
@@ -754,94 +758,80 @@ void Host_Main(void)
        //
        //-------------------
 
-               if (cl_timer > 0 || cls.timedemo)
+               if (cls.state != ca_dedicated && (cl_timer > 0 || cls.timedemo))
                {
-                       if (cls.state == ca_dedicated)
+                       // decide the simulation time
+                       if (cls.capturevideo.active)
                        {
-                               // if there is no client, run client timing at 10fps
-                               cl_timer -= 0.1;
-                               if (host_speeds.integer)
-                                       time1 = time2 = Sys_DoubleTime();
+                               if (cls.capturevideo.realtime)
+                                       clframetime = cl.realframetime = max(cl_timer, 1.0 / cls.capturevideo.framerate);
+                               else
+                               {
+                                       clframetime = 1.0 / cls.capturevideo.framerate;
+                                       cl.realframetime = max(cl_timer, clframetime);
+                               }
                        }
+                       else if (vid_activewindow)
+                               clframetime = cl.realframetime = max(cl_timer, 1.0 / cl_maxfps.value);
                        else
-                       {
-                               double frametime;
-                               frametime = cl.realframetime = min(cl_timer, 1);
+                               clframetime = cl.realframetime = 0.1;
 
-                               // decide the simulation time
-                               if (!cls.timedemo)
-                               {
-                                       if (cls.capturevideo.active)
-                                       {
-                                               if (cls.capturevideo.realtime)
-                                                       frametime = cl.realframetime = max(cl.realframetime, 1.0 / cls.capturevideo.framerate);
-                                               else
-                                               {
-                                                       frametime = 1.0 / cls.capturevideo.framerate;
-                                                       cl.realframetime = max(cl.realframetime, frametime);
-                                               }
-                                       }
-                                       else if (vid_activewindow)
-                                               frametime = cl.realframetime = max(cl.realframetime, 1.0 / cl_maxfps.value);
-                                       else
-                                               frametime = cl.realframetime = 0.1;
-
-                                       // deduct the frame time from the accumulator
-                                       cl_timer -= cl.realframetime;
-
-                                       // apply slowmo scaling
-                                       frametime *= slowmo.value;
-
-                                       // host_framerate overrides all else
-                                       if (host_framerate.value)
-                                               frametime = host_framerate.value;
-                               }
+                       // apply slowmo scaling
+                       clframetime *= slowmo.value;
 
-                               cl.oldtime = cl.time;
-                               cl.time += frametime;
+                       // host_framerate overrides all else
+                       if (host_framerate.value)
+                               clframetime = host_framerate.value;
 
-                               // Collect input into cmd
-                               CL_Move();
+                       if (cls.timedemo)
+                               clframetime = cl.realframetime = cl_timer;
 
-                               NetConn_ClientFrame();
+                       // deduct the frame time from the accumulator
+                       cl_timer -= cl.realframetime;
 
-                               if (cls.state == ca_connected)
-                               {
-                                       CL_ReadFromServer();
-                                       // if running the server remotely, send intentions now after
-                                       // the incoming messages have been read
-                                       //if (!cl.islocalgame)
-                                       //      CL_SendCmd();
-                               }
+                       cl.oldtime = cl.time;
+                       cl.time += clframetime;
 
-                               // update video
-                               if (host_speeds.integer)
-                                       time1 = Sys_DoubleTime();
+                       // Collect input into cmd
+                       CL_Input();
 
-                               //ui_update();
+                       NetConn_ClientFrame();
 
-                               CL_VideoFrame();
+                       if (cls.state == ca_connected)
+                       {
+                               CL_ReadFromServer();
+                               // if running the server remotely, send intentions now after
+                               // the incoming messages have been read
+                               //if (!cl.islocalgame)
+                               //      CL_SendCmd();
+                       }
 
-                               CL_UpdateScreen();
+                       // update video
+                       if (host_speeds.integer)
+                               time1 = Sys_DoubleTime();
 
-                               if (host_speeds.integer)
-                                       time2 = Sys_DoubleTime();
+                       //ui_update();
 
-                               // update audio
-                               if(csqc_usecsqclistener)
-                               {
-                                       S_Update(&csqc_listenermatrix);
-                                       csqc_usecsqclistener = false;
-                               }
-                               else
-                                       S_Update(&r_view.matrix);
+                       CL_VideoFrame();
+
+                       CL_UpdateScreen();
 
-                               CDAudio_Update();
+                       if (host_speeds.integer)
+                               time2 = Sys_DoubleTime();
+
+                       // update audio
+                       if(csqc_usecsqclistener)
+                       {
+                               S_Update(&csqc_listenermatrix);
+                               csqc_usecsqclistener = false;
                        }
+                       else
+                               S_Update(&r_view.matrix);
+
+                       CDAudio_Update();
 
                        if (host_speeds.integer)
                        {
-                               int pass1, pass2, pass3;
                                pass1 = (int)((time1 - time3)*1000000);
                                time3 = Sys_DoubleTime();
                                pass2 = (int)((time2 - time1)*1000000);
@@ -851,6 +841,12 @@ void Host_Main(void)
                        }
                }
 
+               // if there is some time remaining from this frame, reset the timers
+               if (cl_timer >= 0)
+                       cl_timer = 0;
+               if (sv_timer >= 0)
+                       sv_timer = 0;
+
                host_framecount++;
        }
 }
@@ -965,7 +961,7 @@ static void Host_Init (void)
        // initialize ixtable
        Mathlib_Init();
 
-       // initialize filesystem (including fs_basedir, fs_gamedir, -path, -game, scr_screenshot_name)
+       // initialize filesystem (including fs_basedir, fs_gamedir, -game, scr_screenshot_name)
        FS_Init();
 
        NetConn_Init();
@@ -974,6 +970,7 @@ static void Host_Init (void)
        //PR_Cmd_Init();
        PRVM_Init();
        Mod_Init();
+       World_Init();
        SV_Init();
        Host_InitCommands();
        Host_InitLocal();
@@ -1051,16 +1048,6 @@ static void Host_Init (void)
                Cbuf_Execute();
        }
 
-       // check for special demolooponly mode
-// COMMANDLINEOPTION: Client: -demolooponly <demoname> runs a playdemo and quits
-       i = COM_CheckParm("-demolooponly");
-       if (i && i + 1 < com_argc)
-       if (!sv.active && !cls.demoplayback && !cls.connect_trying)
-       {
-               Cbuf_AddText(va("playdemo %s\n", com_argv[i + 1]));
-               Cbuf_Execute();
-       }
-
        if (cls.state == ca_dedicated || COM_CheckParm("-listen"))
        if (!sv.active && !cls.demoplayback && !cls.connect_trying)
        {