+ // get new packets
+ if (sv.active)
+ NetConn_ServerFrame();
+
+ // if the accumulators haven't become positive yet, wait a while
+ wait = sv_timer * -1000000.0;
+ if (wait >= 1)
+ {
+ double time0, delta;
+ SV_UnlockThreadMutex(); // don't keep mutex locked while sleeping
+ if (host_maxwait.value <= 0)
+ wait = min(wait, 1000000.0);
+ else
+ wait = min(wait, host_maxwait.value * 1000.0);
+ if(wait < 1)
+ wait = 1; // because we cast to int
+ time0 = Sys_DirtyTime();
+ Sys_Sleep((int)wait);
+ delta = Sys_DirtyTime() - time0;if (delta < 0 || delta >= 1800) delta = 0;
+ svs.perf_acc_sleeptime += delta;
+ continue;
+ }
+
+ if (sv.active && sv_timer > 0)
+ {
+ // execute one server frame
+ double advancetime;
+ float offset;
+
+ if (sys_ticrate.value <= 0)
+ advancetime = min(sv_timer, 0.1); // don't step more than 100ms
+ else
+ advancetime = sys_ticrate.value;
+
+ if(advancetime > 0)
+ {
+ offset = sv_timer + (Sys_DirtyTime() - sv_realtime); // LordHavoc: FIXME: I don't understand this line
+ ++svs.perf_acc_offset_samples;
+ svs.perf_acc_offset += offset;
+ svs.perf_acc_offset_squared += offset * offset;
+ if(svs.perf_acc_offset_max < offset)
+ svs.perf_acc_offset_max = offset;
+ }
+
+ // 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 || cl.csqc_paused)))
+ sv.frametime = 0;
+
+ sv_timer -= advancetime;
+
+ // move things around and think unless paused
+ if (sv.frametime)
+ SV_Physics();
+
+ // send all messages to the clients
+ SV_SendClientMessages();
+
+ if (sv.paused == 1 && sv_realtime > sv.pausedstart && sv.pausedstart > 0)
+ {
+ PRVM_serverglobalfloat(time) = sv.time;
+ prog->globals.fp[OFS_PARM0] = sv_realtime - sv.pausedstart;
+ prog->ExecuteProgram(prog, PRVM_serverfunction(SV_PausedTic), "QC function SV_PausedTic is missing");
+ }
+
+ // send an heartbeat if enough time has passed since the last one
+ NetConn_Heartbeat(0);
+
+ }
+
+ // we're back to safe code now
+ SV_UnlockThreadMutex();
+
+ // if there is some time remaining from this frame, reset the timers
+ if (sv_timer >= 0)
+ {
+ svs.perf_acc_lost += sv_timer;
+ sv_timer = 0;
+ }
+ }
+ return 0;