reworked and unified sleeping

reduced client update rate when minimized
fixed timedemo playback
This commit is contained in:
myT 2018-01-25 06:41:30 +01:00
parent 4b99ff0cc5
commit ac4928e18d
6 changed files with 98 additions and 65 deletions

View file

@ -3,6 +3,8 @@ DD Mmm 18 - 1.50
add: the fs_restart command to manually restart the file system
chg: even lower CPU usage when minimized
chg: during id downloads (cl_allowDownload -1), the time-out is 5 seconds instead of cl_timeout
chg: the "nextdemo" cvar is now also used when playback stops before reaching the demo's end
@ -16,6 +18,10 @@ chg: on Windows, a fatal error will move the early console window to the foregro
chg: com_hunkMegs doesn't have a maximum value anymore
a value too high would reset it and the engine might fail to load with the default value
fix: "timedemo" playback runs at full speed again
fix: on Windows, when unfocused, the client would always sleep 5+ ms regardless of com_maxFPS
fix: conditional FS restarts will always re-order the pak list when connected to a pure server
fix: lifted the directory scanning restriction that affected pure listen servers

View file

@ -29,14 +29,14 @@ int main( int argc, char** argv )
*cmdline = 0;
for (i = 1; i < argc; ++i) {
if (i > 1)
strcat( cmdline, " " );
strcat( cmdline, argv[i] );
strcat(cmdline, " ");
strcat(cmdline, argv[i]);
}
Com_Init( cmdline );
Com_Init(cmdline);
NET_Init();
Com_Printf( "Working directory: %s\n", Sys_Cwd() );
Com_Printf("Working directory: %s\n", Sys_Cwd());
Lin_ConsoleInputInit();
Lin_TrackParentProcess();
@ -47,10 +47,16 @@ int main( int argc, char** argv )
for (;;) {
SIG_Frame();
#ifndef DEDICATED
sdl_Frame();
#endif
Com_Frame();
#ifdef DEDICATED
Com_Frame(qfalse);
#else
Com_Frame(clc.demoplaying);
#endif
}
return 0;

View file

@ -2417,7 +2417,66 @@ static int Com_ModifyMsec( int msec )
}
void Com_Frame()
static void Com_FrameSleep( qbool demoPlayback )
{
// "timedemo" playback means we run at full speed
if ( demoPlayback && com_timedemo->integer )
return;
// decide how much sleep we need
qbool preciseCap = qfalse;
int64_t sleepUS = 0;
if ( com_dedicated->integer ) {
sleepUS = 1000 * SV_FrameSleepMS();
} else {
preciseCap = qtrue;
sleepUS = 1000000 / com_maxfps->integer;
#ifndef DEDICATED
if ( Sys_IsMinimized() ) {
sleepUS = 20 * 1000;
preciseCap = qfalse;
}
#endif
}
// decide when we should stop sleeping
static int64_t targetTimeUS = INT64_MIN;
if ( Sys_Microseconds() > targetTimeUS + 3 * sleepUS )
targetTimeUS = Sys_Microseconds() + sleepUS;
else
targetTimeUS += sleepUS;
// sleep if needed
if ( com_dedicated->integer ) {
while ( targetTimeUS - Sys_Microseconds() > 1000 ) {
NET_Sleep( 1 );
Com_EventLoop();
}
} else {
int runEventLoop = 0;
if ( preciseCap ) {
for ( ;; ) {
runEventLoop ^= 1;
const int64_t remainingUS = targetTimeUS - Sys_Microseconds();
if ( remainingUS > 3000 && runEventLoop )
Com_EventLoop();
else if ( remainingUS > 1000 )
Sys_Sleep( 1 );
else if ( remainingUS > 50 )
Sys_MicroSleep( 50 );
else
break;
}
} else {
while ( targetTimeUS - Sys_Microseconds() > 1000 ) {
Sys_Sleep( 1 );
}
}
}
}
void Com_Frame( qbool demoPlayback )
{
if ( setjmp(abortframe) ) {
return; // an ERR_DROP was thrown
@ -2446,53 +2505,7 @@ void Com_Frame()
timeBeforeFirstEvents = Sys_Milliseconds();
}
// we may want to spin here if things are going too fast
int minMsec = 1;
if ( !com_dedicated->integer && com_maxfps->integer > 0 && !com_timedemo->integer )
minMsec = 1000 / com_maxfps->integer;
#ifndef DEDICATED
qbool preciseCap = qtrue;
// let's not limit the download speed by sleeping too much
qbool CL_MapDownload_Active(); // in client.h
if ( CL_MapDownload_Active() )
minMsec = 4;
else if ( Sys_IsMinimized() ) {
minMsec = 20;
preciseCap = qfalse;
}
#else
const qbool preciseCap = qfalse;
#endif
// decide when we should stop sleeping
static int64_t targetTimeUS = INT64_MIN;
const int64_t frameDurationUS = 1000000 / com_maxfps->integer;
if ( Sys_Microseconds() > targetTimeUS + 3 * frameDurationUS )
targetTimeUS = Sys_Microseconds() + frameDurationUS;
else
targetTimeUS += frameDurationUS;
// sleep if needed
int runEventLoop = 0;
if ( preciseCap ) {
for ( ;; ) {
runEventLoop ^= 1;
const int64_t remainingUS = targetTimeUS - Sys_Microseconds();
if ( remainingUS > 3000 && runEventLoop )
Com_EventLoop();
else if ( remainingUS > 1000 )
Sys_Sleep( 1 );
else if ( remainingUS > 50 )
Sys_MicroSleep( 50 );
else
break;
}
} else {
while ( targetTimeUS - Sys_Microseconds() > 1000 ) {
Sys_Sleep(1);
}
}
Com_FrameSleep( demoPlayback );
static int lastTime = 0;
lastTime = com_frameTime;

View file

@ -945,7 +945,7 @@ void Com_TouchMemory();
// commandLine should not include the executable name (argv[0])
void Com_Init( char *commandLine );
void Com_Frame();
void Com_Frame( qbool demoPlayback );
void Com_Shutdown();
@ -1030,6 +1030,7 @@ void S_ClearSoundBuffer( void );
void SV_Init();
void SV_Shutdown( const char* finalmsg );
void SV_Frame( int msec );
int SV_FrameSleepMS(); // the number of milli-seconds Com_Frame should sleep
void SV_PacketEvent( const netadr_t& from, msg_t* msg );
qbool SV_GameCommand();

View file

@ -768,13 +768,6 @@ void SV_Frame( int msec ) {
if (!com_dedicated->integer)
SV_BotFrame( svs.time + sv.timeResidual );
if ( com_dedicated->integer && sv.timeResidual < frameMsec ) {
// NET_Sleep will give the OS time slices until either get a packet
// or time enough for a server frame has gone by
NET_Sleep( frameMsec - sv.timeResidual );
return;
}
qbool hasHuman = qfalse;
for (int i=0; i < sv_maxclients->integer ; ++i) {
client_t *cl = &svs.clients[i];
@ -860,5 +853,15 @@ void SV_Frame( int msec ) {
SV_MasterHeartbeat();
}
//============================================================================
int SV_FrameSleepMS()
{
if ( !sv_fps )
return 1;
const int sleepMS = 1000 / sv_fps->value;
if ( sleepMS < sv.timeResidual )
return 0;
return sleepMS - sv.timeResidual;
}

View file

@ -758,8 +758,12 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
S_Frame();
#endif
// run the game
Com_Frame();
// run the game
#ifdef DEDICATED
Com_Frame( qfalse );
#else
Com_Frame( clc.demoplaying );
#endif
}
// never gets here