+ double cl_wait, sv_wait;
+
+ TaskQueue_Frame(false);
+
+ // keep the random time dependent, but not when playing demos/benchmarking
+ if(!*sv_random_seed.string && !host.restless)
+ rand();
+
+ NetConn_UpdateSockets();
+
+ Log_DestBuffer_Flush();
+
+ // Run any downloads
+ Curl_Frame();
+
+ // get new SDL events and add commands from keybindings to the cbuf
+ Sys_SDL_HandleEvents();
+
+ // process console commands
+ Cbuf_Frame(host.cbuf);
+
+ R_TimeReport("---");
+
+ // if the accumulators haven't become positive yet, wait a while
+ sv_wait = - SV_Frame(time);
+ cl_wait = - CL_Frame(time);
+
+ Mem_CheckSentinelsGlobal();
+
+ if (cls.state == ca_dedicated)
+ return sv_wait; // dedicated
+ else if (!sv.active || svs.threaded)
+ return cl_wait; // connected to server, main menu, or server is on different thread
+ else
+ return min(cl_wait, sv_wait); // listen server or singleplayer
+}
+
+static inline double Host_Sleep(double time)
+{
+ double delta, time0;
+
+ // convert to microseconds
+ time *= 1000000.0;
+
+ if (time < 1 || host.restless)
+ return 0; // not sleeping this frame
+
+ if(host_maxwait.value <= 0)
+ time = min(time, 1000000.0);
+ else
+ time = min(time, host_maxwait.value * 1000.0);
+
+ time0 = Sys_DirtyTime();
+ if (sv_checkforpacketsduringsleep.integer && !sys_usenoclockbutbenchmark.integer && !svs.threaded) {
+ NetConn_SleepMicroseconds((int)time);
+ if (cls.state != ca_dedicated)
+ NetConn_ClientFrame(); // helps server browser get good ping values
+ // TODO can we do the same for ServerFrame? Probably not.
+ }
+ else
+ {
+ if (cls.state != ca_dedicated)
+ Curl_Select(&time);
+ Sys_Sleep((int)time);
+ }
+
+ delta = Sys_DirtyTime() - time0;
+ if (delta < 0 || delta >= 1800)
+ delta = 0;
+
+// R_TimeReport("sleep");
+ return delta;
+}
+
+// Cloudwalk: Most overpowered function declaration...
+static inline double Host_UpdateTime (double newtime, double oldtime)
+{
+ double time = newtime - oldtime;
+
+ if (time < 0)
+ {
+ // warn if it's significant
+ if (time < -0.01)
+ Con_Printf(CON_WARN "Host_UpdateTime: time stepped backwards (went from %f to %f, difference %f)\n", oldtime, newtime, time);
+ time = 0;
+ }
+ else if (time >= 1800)
+ {
+ Con_Printf(CON_WARN "Host_UpdateTime: time stepped forward (went from %f to %f, difference %f)\n", oldtime, newtime, time);
+ time = 0;
+ }
+
+ return time;
+}
+
+void Host_Main(void)
+{
+ double time, oldtime, sleeptime;
+
+ Host_Init(); // Start!
+
+ host.realtime = 0;
+ oldtime = Sys_DirtyTime();
+
+ // Main event loop
+ while(host.state != host_shutdown)
+ {
+ // Something bad happened, or the server disconnected
+ if (setjmp(host.abortframe))
+ {
+ host.state = host_active; // In case we were loading
+ continue;
+ }
+
+ host.dirtytime = Sys_DirtyTime();
+ host.realtime += time = Host_UpdateTime(host.dirtytime, oldtime);
+
+ sleeptime = Host_Frame(time);
+ oldtime = host.dirtytime;
+ ++host.framecount;
+
+ sleeptime -= Sys_DirtyTime() - host.dirtytime; // execution time
+ host.sleeptime = Host_Sleep(sleeptime);
+ }
+
+ return;