#include "csprogs.h"
#include "sv_demo.h"
#include "snd_main.h"
+#include "taskqueue.h"
#include "thread.h"
#include "utf8lib.h"
// how many frames have occurred
// (checked by Host_Error and Host_SaveConfig_f)
int host_framecount = 0;
-// LordHavoc: set when quit is executed
+// LadyHavoc: set when quit is executed
qboolean host_shuttingdown = false;
// the accumulated mainloop time since application started (with filtering), without any slowmo or clamping
cvar_t cl_minfps_qualitymultiply = {CVAR_SAVE, "cl_minfps_qualitymultiply", "0.2", "multiplier for quality changes in quality change per second render time (1 assumes linearity of quality and render time)"};
cvar_t cl_minfps_qualityhysteresis = {CVAR_SAVE, "cl_minfps_qualityhysteresis", "0.05", "reduce all quality increments by this to reduce flickering"};
cvar_t cl_minfps_qualitystepmax = {CVAR_SAVE, "cl_minfps_qualitystepmax", "0.1", "maximum quality change in a single frame"};
+cvar_t cl_minfps_force = {0, "cl_minfps_force", "0", "also apply quality reductions in timedemo/capturevideo"};
cvar_t cl_maxfps = {CVAR_SAVE, "cl_maxfps", "0", "maximum fps cap, 0 = unlimited, if game is running faster than this it will wait before running another frame (useful to make cpu time available to other programs)"};
cvar_t cl_maxfps_alwayssleep = {0, "cl_maxfps_alwayssleep","1", "gives up some processing time to other applications each frame, value in milliseconds, disabled if cl_maxfps is 0"};
cvar_t cl_maxidlefps = {CVAR_SAVE, "cl_maxidlefps", "20", "maximum fps cap when the game is not the active window (makes cpu time available to other programs"};
aborts the current host frame and goes on with the next one
================
*/
+void Host_AbortCurrentFrame(void) DP_FUNC_NORETURN;
void Host_AbortCurrentFrame(void)
{
// in case we were previously nice, make us mean again
Con_Printf("Host_Error: %s\n", hosterrorstring1);
- // LordHavoc: if crashing very early, or currently shutting down, do
+ // LadyHavoc: if crashing very early, or currently shutting down, do
// Sys_Error instead
if (host_framecount < 3 || host_shuttingdown)
Sys_Error ("Host_Error: %s", hosterrorstring1);
// print out where the crash happened, if it was caused by QC (and do a cleanup)
PRVM_Crash(SVVM_prog);
PRVM_Crash(CLVM_prog);
+#ifdef CONFIG_MENU
PRVM_Crash(MVM_prog);
+#endif
cl.csqc_loaded = false;
Cvar_SetValueQuick(&csqc_progcrc, -1);
else
{
// default players in some games, singleplayer in most
- if (gamemode != GAME_GOODVSBAD2 && gamemode != GAME_NEXUIZ && gamemode != GAME_XONOTIC && gamemode != GAME_BATTLEMECH)
+ if (gamemode != GAME_GOODVSBAD2 && !IS_NEXUIZ_DERIVED(gamemode) && gamemode != GAME_BATTLEMECH)
svs.maxclients = 1;
}
}
Cvar_RegisterVariable (&cl_minfps_qualitystepmax);
Cvar_RegisterVariable (&cl_minfps_qualityhysteresis);
Cvar_RegisterVariable (&cl_minfps_qualitymultiply);
+ Cvar_RegisterVariable (&cl_minfps_force);
Cvar_RegisterVariable (&cl_maxfps);
Cvar_RegisterVariable (&cl_maxfps_alwayssleep);
Cvar_RegisterVariable (&cl_maxidlefps);
// 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
+ // LadyHavoc: don't save a config if it crashed in startup
if (host_framecount >= 3 && cls.state != ca_dedicated && !COM_CheckParm("-benchmark") && !COM_CheckParm("-capturedemo"))
{
f = FS_OpenRealFile(file, "wb", false);
{
// reset all cvars, commands and aliases to init values
Cmd_RestoreInitState();
+#ifdef CONFIG_MENU
// prepend a menu restart command to execute after the config
Cbuf_InsertText("\nmenu_restart\n");
+#endif
// reset cvars to their defaults, and then exec startup scripts again
Host_AddConfigText();
}
// tell the client to be gone
if (!crash)
{
- // LordHavoc: no opportunity for resending, so use unreliable 3 times
+ // LadyHavoc: no opportunity for resending, so use unreliable 3 times
unsigned char bufdata[8];
sizebuf_t buf;
memset(&buf, 0, sizeof(buf));
buf.data = bufdata;
buf.maxsize = sizeof(bufdata);
MSG_WriteByte(&buf, svc_disconnect);
- NetConn_SendUnreliableMessage(host_client->netconnection, &buf, sv.protocol, 10000, false);
- NetConn_SendUnreliableMessage(host_client->netconnection, &buf, sv.protocol, 10000, false);
- NetConn_SendUnreliableMessage(host_client->netconnection, &buf, sv.protocol, 10000, false);
+ NetConn_SendUnreliableMessage(host_client->netconnection, &buf, sv.protocol, 10000, 0, false);
+ NetConn_SendUnreliableMessage(host_client->netconnection, &buf, sv.protocol, 10000, 0, false);
+ NetConn_SendUnreliableMessage(host_client->netconnection, &buf, sv.protocol, 10000, 0, false);
}
}
// call qc ClientDisconnect function
- // LordHavoc: don't call QC if server is dead (avoids recursive
+ // LadyHavoc: don't call QC if server is dead (avoids recursive
// Host_Error in some mods when they run out of edicts)
if (host_client->clientconnectcalled && sv.active && host_client->edict)
{
double wait;
int pass1, pass2, pass3, i;
char vabuf[1024];
+ qboolean playing;
Host_Init();
realtime = 0;
- dirtytime = Sys_DirtyTime();
+ host_dirtytime = Sys_DirtyTime();
for (;;)
{
if (setjmp(host_abortframe))
svs.perf_acc_realtime += deltacleantime;
// Look for clients who have spawned
+ playing = false;
for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
- if(host_client->spawned)
+ if(host_client->begun)
if(host_client->netconnection)
- break;
- if(i == svs.maxclients)
+ playing = true;
+ if(sv.time < 10)
{
- // Nobody is looking? Then we won't do timing...
- // Instead, reset it to zero
+ // don't accumulate time for the first 10 seconds of a match
+ // so things can settle
svs.perf_acc_realtime = svs.perf_acc_sleeptime = svs.perf_acc_lost = svs.perf_acc_offset = svs.perf_acc_offset_squared = svs.perf_acc_offset_max = svs.perf_acc_offset_samples = 0;
}
else if(svs.perf_acc_realtime > 5)
svs.perf_offset_sdev = sqrt(svs.perf_acc_offset_squared / svs.perf_acc_offset_samples - svs.perf_offset_avg * svs.perf_offset_avg);
}
if(svs.perf_lost > 0 && developer_extra.integer)
- Con_DPrintf("Server can't keep up: %s\n", Host_TimingReport(vabuf, sizeof(vabuf)));
+ if(playing) // only complain if anyone is looking
+ Con_DPrintf("Server can't keep up: %s\n", Host_TimingReport(vabuf, sizeof(vabuf)));
svs.perf_acc_realtime = svs.perf_acc_sleeptime = svs.perf_acc_lost = svs.perf_acc_offset = svs.perf_acc_offset_squared = svs.perf_acc_offset_max = svs.perf_acc_offset_samples = 0;
}
}
if (host_framerate.value < 0.00001 && host_framerate.value != 0)
Cvar_SetValue("host_framerate", 0);
+ TaskQueue_Frame(false);
+
// keep the random time dependent, but not when playing demos/benchmarking
if(!*sv_random_seed.string && !cls.demoplayback)
rand();
wait = 1; // because we cast to int
time0 = Sys_DirtyTime();
- if (sv_checkforpacketsduringsleep.integer && !sys_usenoclockbutbenchmark.integer && !svs.threaded)
+ if (sv_checkforpacketsduringsleep.integer && !sys_usenoclockbutbenchmark.integer && !svs.threaded) {
NetConn_SleepMicroseconds((int)wait);
+ 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
Sys_Sleep((int)wait);
delta = Sys_DirtyTime() - time0;
SV_SendClientMessages();
if (sv.paused == 1 && realtime > sv.pausedstart && sv.pausedstart > 0) {
- prog->globals.generic[OFS_PARM0] = realtime - sv.pausedstart;
+ prog->globals.fp[OFS_PARM0] = realtime - sv.pausedstart;
PRVM_serverglobalfloat(time) = sv.time;
prog->ExecuteProgram(prog, PRVM_serverfunction(SV_PausedTic), "QC function SV_PausedTic is missing");
}
{
R_TimeReport("---");
Collision_Cache_NewFrame();
- R_TimeReport("collisioncache");
+ R_TimeReport("photoncache");
// decide the simulation time
if (cls.capturevideo.active)
{
if (cls.demopaused)
clframetime = 0;
}
+ else
+ {
+ // host_framerate overrides all else
+ if (host_framerate.value)
+ clframetime = host_framerate.value;
- // host_framerate overrides all else
- if (host_framerate.value)
- clframetime = host_framerate.value;
-
- if (cl.paused || (cl.islocalgame && (key_dest != key_game || key_consoleactive || cl.csqc_paused)))
- clframetime = 0;
+ if (cl.paused || (cl.islocalgame && (key_dest != key_game || key_consoleactive || cl.csqc_paused)))
+ clframetime = 0;
+ }
if (cls.timedemo)
clframetime = cl.realframetime = cl_timer;
R_TimeReport("client");
CL_UpdateScreen();
+ CL_MeshEntities_Reset();
R_TimeReport("render");
if (host_speeds.integer)
if(locksession_run)
return;
locksession_run = true;
- if(locksession.integer != 0)
+ if(locksession.integer != 0 && !COM_CheckParm("-readonly"))
{
char vabuf[1024];
char *p = va(vabuf, sizeof(vabuf), "%slock%s", *fs_userdir ? fs_userdir : fs_basedir, sessionid.string);
if (COM_CheckParm("-profilegameonly"))
Sys_AllowProfiling(false);
- // LordHavoc: quake never seeded the random number generator before... heh
+ // LadyHavoc: quake never seeded the random number generator before... heh
if (COM_CheckParm("-benchmark"))
srand(0); // predictable random sequence for -benchmark
else
srand((unsigned int)time(NULL));
// FIXME: this is evil, but possibly temporary
- // LordHavoc: doesn't seem very temporary...
- // LordHavoc: made this a saved cvar
+ // LadyHavoc: doesn't seem very temporary...
+ // LadyHavoc: made this a saved cvar
// COMMANDLINEOPTION: Console: -developer enables warnings and other notices (RECOMMENDED for mod developers)
if (COM_CheckParm("-developer"))
{
Host_ServerOptions();
Thread_Init();
+ TaskQueue_Init();
if (cls.state == ca_dedicated)
Cmd_AddCommand ("disconnect", CL_Disconnect_f, "disconnect from server (or disconnect all clients if running a server)");
R_Modules_Init();
Palette_Init();
+#ifdef CONFIG_MENU
MR_Init_Commands();
+#endif
VID_Shared_Init();
VID_Init();
Render_Init();
}
// put up the loading image so the user doesn't stare at a black screen...
- SCR_BeginLoadingPlaque();
+ SCR_BeginLoadingPlaque(true);
+#ifdef CONFIG_MENU
if (cls.state != ca_dedicated)
{
MR_Init();
}
+#endif
// check for special benchmark mode
// COMMANDLINEOPTION: Client: -benchmark <demoname> runs a timedemo and quits, results of any timedemo can be found in gamedir/benchmark.log (for example id1/benchmark.log)
if (!sv.active && !cls.demoplayback && !cls.connect_trying)
{
- Cbuf_AddText("togglemenu\n");
+#ifdef CONFIG_MENU
+ Cbuf_AddText("togglemenu 1\n");
+#endif
Cbuf_Execute();
}
Host_ShutdownServer ();
SV_UnlockThreadMutex();
+#ifdef CONFIG_MENU
// Shutdown menu
if(MR_Shutdown)
MR_Shutdown();
+#endif
// AK shutdown PRVM
// AK hmm, no PRVM_Shutdown(); yet
}
SV_StopThread();
+ TaskQueue_Shutdown();
Thread_Shutdown();
Cmd_Shutdown();
Key_Shutdown();