X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=host.c;h=7e7bc56a7f2950de8df0e6c6a9ffa52273338326;hb=212a93f6f5c06d50d331d61e1792d12f11ca1595;hp=60db8ba1b1fa896a144e3f4cd028430f350444a4;hpb=70b6de8a98705a7d7097803a84bdd224b05103cc;p=xonotic%2Fdarkplaces.git diff --git a/host.c b/host.c index 60db8ba1..7e7bc56a 100644 --- a/host.c +++ b/host.c @@ -23,7 +23,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include "libcurl.h" +#ifdef CONFIG_CD #include "cdaudio.h" +#endif #include "cl_video.h" #include "progsvm.h" #include "csprogs.h" @@ -70,8 +72,9 @@ cvar_t cl_minfps_fade = {CVAR_SAVE, "cl_minfps_fade", "1", "how fast the quality cvar_t cl_minfps_qualitymax = {CVAR_SAVE, "cl_minfps_qualitymax", "1", "highest allowed drawdistance multiplier"}; cvar_t cl_minfps_qualitymin = {CVAR_SAVE, "cl_minfps_qualitymin", "0.25", "lowest allowed drawdistance multiplier"}; 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.025", "reduce all quality changes by this to reduce flickering"}; +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"}; @@ -96,6 +99,7 @@ Host_AbortCurrentFrame 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 @@ -148,7 +152,9 @@ void Host_Error (const char *error, ...) // 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); @@ -206,7 +212,7 @@ static void Host_ServerOptions (void) 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; } } @@ -244,6 +250,7 @@ static void Host_InitLocal (void) 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); @@ -333,8 +340,10 @@ void Host_LoadConfig_f(void) { // 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(); } @@ -474,9 +483,9 @@ void SV_DropClient(qboolean crash) 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); } } @@ -665,11 +674,12 @@ void Host_Main(void) 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)) @@ -704,14 +714,15 @@ void Host_Main(void) 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) @@ -725,7 +736,8 @@ void Host_Main(void) 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; } } @@ -792,8 +804,12 @@ void Host_Main(void) 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; @@ -894,7 +910,7 @@ void Host_Main(void) 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"); } @@ -920,7 +936,7 @@ void Host_Main(void) { R_TimeReport("---"); Collision_Cache_NewFrame(); - R_TimeReport("collisioncache"); + R_TimeReport("photoncache"); // decide the simulation time if (cls.capturevideo.active) { @@ -956,13 +972,15 @@ void Host_Main(void) 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; @@ -1017,8 +1035,10 @@ void Host_Main(void) else S_Update(&r_refdef.view.matrix); +#ifdef CONFIG_CD CDAudio_Update(); R_TimeReport("audio"); +#endif // reset gathering of mouse input in_mouse_x = in_mouse_y = 0; @@ -1066,7 +1086,9 @@ void Host_StartVideo(void) // make sure we open sockets before opening video because the Windows Firewall "unblock?" dialog can screw up the graphics context on some graphics drivers NetConn_UpdateSockets(); VID_Start(); +#ifdef CONFIG_CD CDAudio_Startup(); +#endif } } @@ -1099,7 +1121,7 @@ void Host_LockSession(void) 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); @@ -1262,12 +1284,16 @@ static void Host_Init (void) R_Modules_Init(); Palette_Init(); +#ifdef CONFIG_MENU MR_Init_Commands(); +#endif VID_Shared_Init(); VID_Init(); Render_Init(); S_Init(); +#ifdef CONFIG_CD CDAudio_Init(); +#endif Key_Init(); CL_Init(); } @@ -1295,12 +1321,14 @@ static void Host_Init (void) } // 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 runs a timedemo and quits, results of any timedemo can be found in gamedir/benchmark.log (for example id1/benchmark.log) @@ -1340,7 +1368,9 @@ static void Host_Init (void) if (!sv.active && !cls.demoplayback && !cls.connect_trying) { - Cbuf_AddText("togglemenu\n"); +#ifdef CONFIG_MENU + Cbuf_AddText("togglemenu 1\n"); +#endif Cbuf_Execute(); } @@ -1392,9 +1422,11 @@ void Host_Shutdown(void) Host_ShutdownServer (); SV_UnlockThreadMutex(); +#ifdef CONFIG_MENU // Shutdown menu if(MR_Shutdown) MR_Shutdown(); +#endif // AK shutdown PRVM // AK hmm, no PRVM_Shutdown(); yet @@ -1403,7 +1435,9 @@ void Host_Shutdown(void) Host_SaveConfig(); +#ifdef CONFIG_CD CDAudio_Shutdown (); +#endif S_Terminate (); Curl_Shutdown (); NetConn_Shutdown ();