From 3dabb5c2bd9f902a236c0fc81b175a11d29b3ddd Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Thu, 1 Mar 2018 07:31:09 +0100 Subject: [PATCH 01/15] ensure right internal image format, to prevent unsupported reformatting --- src/engine/client/backend_sdl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/client/backend_sdl.cpp b/src/engine/client/backend_sdl.cpp index 59c7eec1d..6c3d5c9ae 100644 --- a/src/engine/client/backend_sdl.cpp +++ b/src/engine/client/backend_sdl.cpp @@ -902,7 +902,7 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Texture_Create(const CCommandBuffe { case GL_RGB: StoreOglformat = GL_COMPRESSED_RGB; break; //this needs further checks. it seems on some gpus COMPRESSED_ALPHA isnt in the core profile - case GL_RED: StoreOglformat = GL_COMPRESSED_RGBA; break; + case GL_RED: StoreOglformat = GL_COMPRESSED_RED; break; case GL_RGBA: StoreOglformat = GL_COMPRESSED_RGBA; break; default: StoreOglformat = GL_COMPRESSED_RGBA; } @@ -927,7 +927,7 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Texture_Create(const CCommandBuffe //Bind the texture 2D. GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_RED}; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); - StoreOglformat = GL_RGBA; + StoreOglformat = GL_R8; } if(pCommand->m_Flags&CCommandBuffer::TEXFLAG_NOMIPMAPS) From 238c8847c030aa527ed1d6e52014d0e4b56f3668 Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Thu, 1 Mar 2018 07:34:14 +0100 Subject: [PATCH 02/15] keep track of lost frames and updates, to ensure FPS stability and better CPU sleep times --- src/engine/client/client.cpp | 40 +++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 039df5347..63b7d5299 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -2701,6 +2701,7 @@ void CClient::Run() bool LastG = false; int64 LastTime = time_get(); + int64 LastRenderTime = time_get(); while (1) { @@ -2789,7 +2790,7 @@ void CClient::Run() if((g_Config.m_GfxBackgroundRender || m_pGraphics->WindowOpen()) && (!g_Config.m_GfxAsyncRenderOld || m_pGraphics->IsIdle()) - && (!g_Config.m_GfxRefreshRate || Now >= m_LastRenderTime + time_freq() / g_Config.m_GfxRefreshRate)) + && (!g_Config.m_GfxRefreshRate || ((int64)((float)time_freq() / (float)g_Config.m_GfxRefreshRate)) <= Now - LastRenderTime)) { m_RenderFrames++; @@ -2801,6 +2802,12 @@ void CClient::Run() m_RenderFrameTimeHigh = m_RenderFrameTime; m_FpsGraph.Add(1.0f/m_RenderFrameTime, 1,1,1); + // keep the overflow time - it's used to make sure the gfx refreshrate is reached + int64 AdditionalTime = (Now - LastRenderTime) - (int64)((float)time_freq() / (float)g_Config.m_GfxRefreshRate); + // if the value is over a second time loose, reset the additional time (drop the frames we lost already) + if(AdditionalTime > time_freq()) + AdditionalTime = time_freq(); + LastRenderTime = Now - AdditionalTime; m_LastRenderTime = Now; #ifdef CONF_DEBUG @@ -2830,8 +2837,8 @@ void CClient::Run() } m_pGraphics->Swap(); } - Input()->NextFrame(); } + Input()->NextFrame(); if(Input()->VideoRestartNeeded()) { m_pGraphics->Init(); @@ -2853,19 +2860,42 @@ void CClient::Run() // beNice int64 Now = time_get(); + int64 SleepTimeInMicroSeconds = 0; + bool Slept = false; if( #ifdef CONF_DEBUG g_Config.m_DbgStress || #endif (g_Config.m_ClRefreshRateInactive && !m_pGraphics->WindowActive())) { - thread_sleep(max(1000 * (LastTime + time_freq() / g_Config.m_ClRefreshRateInactive - Now) / time_freq(), (int64)0)); + int64 TimeNowInMicroSeconds = (Now * 1000000ll) / time_freq(); + int64 TimeLastInMicroSeconds = (LastTime * 1000000ll) / time_freq(); + SleepTimeInMicroSeconds = (1000000ll / g_Config.m_ClRefreshRate) - (TimeNowInMicroSeconds - TimeLastInMicroSeconds); + thread_sleep(max(SleepTimeInMicroSeconds / 1000ll, 0)); + Slept = true; } else if(g_Config.m_ClRefreshRate) { - net_socket_read_wait(m_NetClient[0].m_Socket, max(1000000 * (LastTime + time_freq() / g_Config.m_ClRefreshRate - Now) / time_freq(), (int64)0)); + int64 TimeNowInMicroSeconds = (Now * 1000000ll) / time_freq(); + int64 TimeLastInMicroSeconds = (LastTime * 1000000ll) / time_freq(); + SleepTimeInMicroSeconds = (1000000ll / g_Config.m_ClRefreshRate) - (TimeNowInMicroSeconds - TimeLastInMicroSeconds); + net_socket_read_wait(m_NetClient[0].m_Socket, max(SleepTimeInMicroSeconds, 0)); + Slept = true; } - LastTime = Now; + if(Slept) + { + // look how much we actually slept/waited + int64 After = time_get(); + int64 TimeNowInMicroSeconds = (Now * 1000000ll) / time_freq(); + int64 TimeAfterInMicroSeconds = (After * 1000000ll) / time_freq(); + int64 TimeDiff = SleepTimeInMicroSeconds - (TimeAfterInMicroSeconds - TimeNowInMicroSeconds); + // if the diff gets too small it shouldn't get even smaller (drop the updates, that could not be handled) + if(TimeDiff < -1000000ll) + TimeDiff = -1000000ll; + LastTime = Now + (TimeDiff * time_freq()) / 1000000ll; + } + else + LastTime = Now; if(g_Config.m_DbgHitch) { From 6f0509cfaee35259645e3cbfcf112349a04ac7c3 Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Thu, 1 Mar 2018 07:44:22 +0100 Subject: [PATCH 03/15] the actual description to the problem --- src/engine/client/backend_sdl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/client/backend_sdl.cpp b/src/engine/client/backend_sdl.cpp index 95f0e955b..acd8680fd 100644 --- a/src/engine/client/backend_sdl.cpp +++ b/src/engine/client/backend_sdl.cpp @@ -901,7 +901,7 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Texture_Create(const CCommandBuffe switch(StoreOglformat) { case GL_RGB: StoreOglformat = GL_COMPRESSED_RGB; break; - //this needs further checks. it seems on some gpus COMPRESSED_ALPHA isnt in the core profile + // COMPRESSED_ALPHA is deprecated, so use different single channel format. case GL_RED: StoreOglformat = GL_COMPRESSED_RED; break; case GL_RGBA: StoreOglformat = GL_COMPRESSED_RGBA; break; default: StoreOglformat = GL_COMPRESSED_RGBA; From 3458ee097644f993a8e507f38ebc81ec9af2d1c3 Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Thu, 1 Mar 2018 07:50:52 +0100 Subject: [PATCH 04/15] check if gfx_refresh_rate is non zero --- src/engine/client/client.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 1cbf0ee00..b0f714f57 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -2803,7 +2803,7 @@ void CClient::Run() m_FpsGraph.Add(1.0f/m_RenderFrameTime, 1,1,1); // keep the overflow time - it's used to make sure the gfx refreshrate is reached - int64 AdditionalTime = (Now - LastRenderTime) - (int64)((float)time_freq() / (float)g_Config.m_GfxRefreshRate); + int64 AdditionalTime = g_Config.m_GfxRefreshRate ? ((Now - LastRenderTime) - (int64)((float)time_freq() / (float)g_Config.m_GfxRefreshRate)) : 0; // if the value is over a second time loose, reset the additional time (drop the frames we lost already) if(AdditionalTime > time_freq()) AdditionalTime = time_freq(); From a808ee07d3d486f30050e5e8970844a16bccd08b Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Thu, 1 Mar 2018 08:07:48 +0100 Subject: [PATCH 05/15] add accedentially removed cast --- src/engine/client/client.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index b0f714f57..8115a3a28 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -2871,7 +2871,7 @@ void CClient::Run() int64 TimeNowInMicroSeconds = (Now * 1000000ll) / time_freq(); int64 TimeLastInMicroSeconds = (LastTime * 1000000ll) / time_freq(); SleepTimeInMicroSeconds = (1000000ll / g_Config.m_ClRefreshRate) - (TimeNowInMicroSeconds - TimeLastInMicroSeconds); - thread_sleep(max(SleepTimeInMicroSeconds / 1000ll, 0)); + thread_sleep(max(SleepTimeInMicroSeconds / 1000ll, (int64)0)); Slept = true; } else if(g_Config.m_ClRefreshRate) @@ -2879,7 +2879,7 @@ void CClient::Run() int64 TimeNowInMicroSeconds = (Now * 1000000ll) / time_freq(); int64 TimeLastInMicroSeconds = (LastTime * 1000000ll) / time_freq(); SleepTimeInMicroSeconds = (1000000ll / g_Config.m_ClRefreshRate) - (TimeNowInMicroSeconds - TimeLastInMicroSeconds); - net_socket_read_wait(m_NetClient[0].m_Socket, max(SleepTimeInMicroSeconds, 0)); + net_socket_read_wait(m_NetClient[0].m_Socket, max(SleepTimeInMicroSeconds, (int64)0)); Slept = true; } if(Slept) From 089cb1ea449f31daf1808d76876509c368c17c93 Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Thu, 1 Mar 2018 08:25:34 +0100 Subject: [PATCH 06/15] this must be inactive ofc --- src/engine/client/client.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 8115a3a28..49f5939bc 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -2870,7 +2870,7 @@ void CClient::Run() { int64 TimeNowInMicroSeconds = (Now * 1000000ll) / time_freq(); int64 TimeLastInMicroSeconds = (LastTime * 1000000ll) / time_freq(); - SleepTimeInMicroSeconds = (1000000ll / g_Config.m_ClRefreshRate) - (TimeNowInMicroSeconds - TimeLastInMicroSeconds); + SleepTimeInMicroSeconds = (1000000ll / g_Config.m_ClRefreshRateInactive) - (TimeNowInMicroSeconds - TimeLastInMicroSeconds); thread_sleep(max(SleepTimeInMicroSeconds / 1000ll, (int64)0)); Slept = true; } From cc7371c1cd6613029756c3cbe91c623c35ffa808 Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Fri, 2 Mar 2018 03:12:30 +0100 Subject: [PATCH 07/15] set upper limit, for the case, if the refreshrate is smaller than the gameticks --- src/engine/client/client.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 49f5939bc..2070b80d8 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -2892,6 +2892,9 @@ void CClient::Run() // if the diff gets too small it shouldn't get even smaller (drop the updates, that could not be handled) if(TimeDiff < -1000000ll) TimeDiff = -1000000ll; + // don't go higher than the game ticks speed, because the network is waking up the client with the server's snapshots anyway + else if(TimeDiff > 1000000ll / m_GameTickSpeed) + TimeDiff = 1000000ll / m_GameTickSpeed; LastTime = Now + (TimeDiff * time_freq()) / 1000000ll; } else From ced0ea3f82fbbd9b38330b18321c67fa160f0d10 Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Fri, 2 Mar 2018 03:29:02 +0100 Subject: [PATCH 08/15] set the gfx refresh rate limit higher for the console --- src/engine/shared/config_variables.h | 2 +- src/game/client/components/menus_settings.cpp | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index d9b862ef0..f092f36fe 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -112,7 +112,7 @@ MACRO_CONFIG_INT(GfxHighDetail, gfx_high_detail, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_C MACRO_CONFIG_INT(GfxTextureQuality, gfx_texture_quality, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "") #endif MACRO_CONFIG_INT(GfxFsaaSamples, gfx_fsaa_samples, 0, 0, 16, CFGFLAG_SAVE|CFGFLAG_CLIENT, "FSAA Samples") -MACRO_CONFIG_INT(GfxRefreshRate, gfx_refresh_rate, 0, 0, 1000, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Screen refresh rate") +MACRO_CONFIG_INT(GfxRefreshRate, gfx_refresh_rate, 0, 0, 10000, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Screen refresh rate") MACRO_CONFIG_INT(GfxFinish, gfx_finish, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "") MACRO_CONFIG_INT(GfxBackgroundRender, gfx_backgroundrender, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Render graphics when window is in background") MACRO_CONFIG_INT(GfxTextOverlay, gfx_text_overlay, 10, 1, 100, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Stop rendering textoverlay in editor or with entities: high value = less details = more speed") diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index 5114b4104..79691c6d1 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -1077,7 +1077,9 @@ void CMenus::RenderSettingsGraphics(CUIRect MainView) str_format(aBuf, sizeof(aBuf), "%s: %s", Localize("Refresh Rate"), "∞"); UI()->DoLabelScaled(&Label, aBuf, 14.0f, -1); Button.HMargin(2.0f, &Button); - g_Config.m_GfxRefreshRate = static_cast(DoScrollbarH(&g_Config.m_GfxRefreshRate, &Button, g_Config.m_GfxRefreshRate/1000.0f)*1000.0f+0.1f); + int NewRefreshRate = static_cast(DoScrollbarH(&g_Config.m_GfxRefreshRate, &Button, (min(g_Config.m_GfxRefreshRate, 1000))/1000.0f)*1000.0f+0.1f); + if(g_Config.m_GfxRefreshRate <= 1000 || NewRefreshRate < 1000) + g_Config.m_GfxRefreshRate = NewRefreshRate; CUIRect Text; MainView.HSplitTop(20.0f, 0, &MainView); From 5e1bee2760b3ce95eb2cc1bacd4fee43c09406d8 Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Mon, 12 Mar 2018 15:10:49 +0100 Subject: [PATCH 09/15] clean up a bit to and descripe it better --- src/base/system.c | 42 ++++++++++++++++++++++++++++++++++ src/base/system.h | 9 ++++++++ src/engine/client/client.cpp | 44 +++++++++++++++++------------------- 3 files changed, 72 insertions(+), 23 deletions(-) diff --git a/src/base/system.c b/src/base/system.c index 01b67e44e..8b417d41e 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -1001,6 +1001,48 @@ int64 time_freq() #endif } +int64 time_get_microseconds() +{ + static int64 last = 0; + { +#if defined(CONF_PLATFORM_MACOSX) + static int got_timebase = 0; + mach_timebase_info_data_t timebase; + uint64_t time; + uint64_t q; + uint64_t r; + if (!got_timebase) + { + mach_timebase_info(&timebase); + } + time = mach_absolute_time(); + q = time / timebase.denom; + r = time % timebase.denom; + last = q * timebase.numer + r * timebase.numer / timebase.denom; + return last / (int64)1000; +#elif defined(CONF_FAMILY_UNIX) + struct timespec spec; + clock_gettime(CLOCK_MONOTONIC, &spec); + last = (int64)spec.tv_sec*(int64)1000000 + (int64)spec.tv_nsec / 1000; + return last; +#elif defined(CONF_FAMILY_WINDOWS) + int64 t; + QueryPerformanceCounter((PLARGE_INTEGER)&t); + + int64 tf; + QueryPerformanceFrequency((PLARGE_INTEGER)&tf); + + t = (t * (int64)1000000) / tf; + if(t < last) // for some reason, QPC can return values in the past + return last; + last = t; + return t; +#else +#error not implemented +#endif + } +} + /* ----- network ----- */ static void netaddr_to_sockaddr_in(const NETADDR *src, struct sockaddr_in *dest) { diff --git a/src/base/system.h b/src/base/system.h index 18fef446e..7ae09f661 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -621,6 +621,15 @@ int64 time_freq(); */ int time_timestamp(); +/* +Function: time_get_microseconds +Fetches a sample from a high resolution timer and converts it in microseconds. + +Returns: +Current value of the timer in microseconds. +*/ +int64 time_get_microseconds(); + /* Group: Network General */ typedef struct { diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 2070b80d8..a732802d0 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -2699,11 +2699,11 @@ void CClient::Run() bool LastQ = false; bool LastE = false; bool LastG = false; - - int64 LastTime = time_get(); + + int64 LastTime = time_get_microseconds(); int64 LastRenderTime = time_get(); - while (1) + while(1) { set_new_tick(); @@ -2804,7 +2804,7 @@ void CClient::Run() // keep the overflow time - it's used to make sure the gfx refreshrate is reached int64 AdditionalTime = g_Config.m_GfxRefreshRate ? ((Now - LastRenderTime) - (int64)((float)time_freq() / (float)g_Config.m_GfxRefreshRate)) : 0; - // if the value is over a second time loose, reset the additional time (drop the frames we lost already) + // if the value is over a second time loose, reset the additional time (drop the frames, that are lost already) if(AdditionalTime > time_freq()) AdditionalTime = time_freq(); LastRenderTime = Now - AdditionalTime; @@ -2859,7 +2859,7 @@ void CClient::Run() #endif // beNice - int64 Now = time_get(); + int64 Now = time_get_microseconds(); int64 SleepTimeInMicroSeconds = 0; bool Slept = false; if( @@ -2868,34 +2868,32 @@ void CClient::Run() #endif (g_Config.m_ClRefreshRateInactive && !m_pGraphics->WindowActive())) { - int64 TimeNowInMicroSeconds = (Now * 1000000ll) / time_freq(); - int64 TimeLastInMicroSeconds = (LastTime * 1000000ll) / time_freq(); - SleepTimeInMicroSeconds = (1000000ll / g_Config.m_ClRefreshRateInactive) - (TimeNowInMicroSeconds - TimeLastInMicroSeconds); - thread_sleep(max(SleepTimeInMicroSeconds / 1000ll, (int64)0)); + SleepTimeInMicroSeconds = ((int64)1000000 / (int64)g_Config.m_ClRefreshRateInactive) - (Now - LastTime); + if (SleepTimeInMicroSeconds / (int64)1000 > (int64)0) + thread_sleep(SleepTimeInMicroSeconds / (int64)1000); Slept = true; } else if(g_Config.m_ClRefreshRate) { - int64 TimeNowInMicroSeconds = (Now * 1000000ll) / time_freq(); - int64 TimeLastInMicroSeconds = (LastTime * 1000000ll) / time_freq(); - SleepTimeInMicroSeconds = (1000000ll / g_Config.m_ClRefreshRate) - (TimeNowInMicroSeconds - TimeLastInMicroSeconds); - net_socket_read_wait(m_NetClient[0].m_Socket, max(SleepTimeInMicroSeconds, (int64)0)); + SleepTimeInMicroSeconds = ((int64)1000000 / (int64)g_Config.m_ClRefreshRate) - (Now - LastTime); + if(SleepTimeInMicroSeconds > (int64)0) + net_socket_read_wait(m_NetClient[0].m_Socket, SleepTimeInMicroSeconds); Slept = true; } if(Slept) { - // look how much we actually slept/waited - int64 After = time_get(); - int64 TimeNowInMicroSeconds = (Now * 1000000ll) / time_freq(); - int64 TimeAfterInMicroSeconds = (After * 1000000ll) / time_freq(); - int64 TimeDiff = SleepTimeInMicroSeconds - (TimeAfterInMicroSeconds - TimeNowInMicroSeconds); // if the diff gets too small it shouldn't get even smaller (drop the updates, that could not be handled) - if(TimeDiff < -1000000ll) - TimeDiff = -1000000ll; + if(SleepTimeInMicroSeconds < (int64)-1000000) + SleepTimeInMicroSeconds = (int64)-1000000; // don't go higher than the game ticks speed, because the network is waking up the client with the server's snapshots anyway - else if(TimeDiff > 1000000ll / m_GameTickSpeed) - TimeDiff = 1000000ll / m_GameTickSpeed; - LastTime = Now + (TimeDiff * time_freq()) / 1000000ll; + else if(SleepTimeInMicroSeconds > (int64)1000000 / m_GameTickSpeed) + SleepTimeInMicroSeconds = (int64)1000000 / m_GameTickSpeed; + // the time diff between the time that was used actually used and the time the thread should sleep/wait + // will be calculated in the sleep time of the next update tick by faking the time it should have slept/wait. + // so two cases (and the case it slept exactly the time it should): + // - the thread slept/waited too long, then it adjust the time to sleep/wait less in the next update tick + // - the thread slept/waited too less, then it adjust the time to sleep/wait more in the next update tick + LastTime = Now + SleepTimeInMicroSeconds; } else LastTime = Now; From 081057d6b91c000755ca3c0f1a2f5cdc1da9e2dd Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Mon, 12 Mar 2018 15:43:31 +0100 Subject: [PATCH 10/15] style fixes and remove float cast --- src/engine/client/client.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index a732802d0..356c3a93a 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -343,7 +343,7 @@ CClient::CClient() : m_DemoPlayer(&m_SnapshotDelta) m_VersionInfo.m_State = CVersionInfo::STATE_INIT; - if (g_Config.m_ClDummy == 0) + if(g_Config.m_ClDummy == 0) m_LastDummyConnectTime = 0; m_ReconnectTime = 0; @@ -605,7 +605,7 @@ void CClient::OnEnterGame() m_CurGameTick[g_Config.m_ClDummy] = 0; m_PrevGameTick[g_Config.m_ClDummy] = 0; - if (g_Config.m_ClDummy == 0) + if(g_Config.m_ClDummy == 0) m_LastDummyConnectTime = 0; GameClient()->OnEnterGame(); @@ -2378,7 +2378,7 @@ void CClient::Update() m_CurGameTick[g_Config.m_ClDummy] = m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT]->m_Tick; m_PrevGameTick[g_Config.m_ClDummy] = m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV]->m_Tick; - if (m_LastDummy2 == (bool)g_Config.m_ClDummy && m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT] && m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV]) + if(m_LastDummy2 == (bool)g_Config.m_ClDummy && m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT] && m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV]) { GameClient()->OnNewSnapshot(); Repredict = 1; @@ -2391,7 +2391,7 @@ void CClient::Update() break; } - if (m_LastDummy2 != (bool)g_Config.m_ClDummy) + if(m_LastDummy2 != (bool)g_Config.m_ClDummy) { m_LastDummy2 = g_Config.m_ClDummy; } @@ -2716,7 +2716,7 @@ void CClient::Run() } // progress on dummy connect if security token handshake skipped/passed - if (m_DummySendConnInfo && !m_NetClient[1].SecurityTokenUnknown()) + if(m_DummySendConnInfo && !m_NetClient[1].SecurityTokenUnknown()) { m_DummySendConnInfo = false; @@ -2790,7 +2790,7 @@ void CClient::Run() if((g_Config.m_GfxBackgroundRender || m_pGraphics->WindowOpen()) && (!g_Config.m_GfxAsyncRenderOld || m_pGraphics->IsIdle()) - && (!g_Config.m_GfxRefreshRate || ((int64)((float)time_freq() / (float)g_Config.m_GfxRefreshRate)) <= Now - LastRenderTime)) + && (!g_Config.m_GfxRefreshRate || (time_freq() / (int64)g_Config.m_GfxRefreshRate) <= Now - LastRenderTime)) { m_RenderFrames++; @@ -2803,7 +2803,7 @@ void CClient::Run() m_FpsGraph.Add(1.0f/m_RenderFrameTime, 1,1,1); // keep the overflow time - it's used to make sure the gfx refreshrate is reached - int64 AdditionalTime = g_Config.m_GfxRefreshRate ? ((Now - LastRenderTime) - (int64)((float)time_freq() / (float)g_Config.m_GfxRefreshRate)) : 0; + int64 AdditionalTime = g_Config.m_GfxRefreshRate ? ((Now - LastRenderTime) - (time_freq() / (int64)g_Config.m_GfxRefreshRate)) : 0; // if the value is over a second time loose, reset the additional time (drop the frames, that are lost already) if(AdditionalTime > time_freq()) AdditionalTime = time_freq(); @@ -2869,7 +2869,7 @@ void CClient::Run() (g_Config.m_ClRefreshRateInactive && !m_pGraphics->WindowActive())) { SleepTimeInMicroSeconds = ((int64)1000000 / (int64)g_Config.m_ClRefreshRateInactive) - (Now - LastTime); - if (SleepTimeInMicroSeconds / (int64)1000 > (int64)0) + if(SleepTimeInMicroSeconds / (int64)1000 > (int64)0) thread_sleep(SleepTimeInMicroSeconds / (int64)1000); Slept = true; } @@ -2931,7 +2931,7 @@ bool CClient::CtrlShiftKey(int Key, bool &Last) Last = true; return true; } - else if (Last && !Input()->KeyIsPressed(Key)) + else if(Last && !Input()->KeyIsPressed(Key)) Last = false; return false; @@ -3030,15 +3030,15 @@ void CClient::AutoStatScreenshot_Cleanup() void CClient::AutoCSV_Start() { - if (g_Config.m_ClAutoCSV) + if(g_Config.m_ClAutoCSV) m_AutoCSVRecycle = true; } void CClient::AutoCSV_Cleanup() { - if (m_AutoCSVRecycle) + if(m_AutoCSVRecycle) { - if (g_Config.m_ClAutoCSVMax) + if(g_Config.m_ClAutoCSVMax) { // clean up auto csvs CFileCollection AutoRecord; @@ -3114,7 +3114,7 @@ void CClient::Con_DemoSliceEnd(IConsole::IResult *pResult, void *pUserData) void CClient::DemoSlice(const char *pDstPath, CLIENTFUNC_FILTER pfnFilter, void *pUser) { - if (m_DemoPlayer.IsPlaying()) + if(m_DemoPlayer.IsPlaying()) { const char *pDemoFileName = m_DemoPlayer.GetDemoFileName(); m_DemoEditor.Slice(pDemoFileName, pDstPath, g_Config.m_ClDemoSliceBegin, g_Config.m_ClDemoSliceEnd, pfnFilter, pUser); From e0b8ecabe42d5ccc828572b605074b12a0436e85 Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Mon, 12 Mar 2018 16:12:06 +0100 Subject: [PATCH 11/15] move time fetch to time_get_impl --- src/base/system.c | 55 +++++++++++++++-------------------------------- src/base/system.h | 13 +++++++++++ 2 files changed, 30 insertions(+), 38 deletions(-) diff --git a/src/base/system.c b/src/base/system.c index 8b417d41e..d66d98930 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -944,14 +944,9 @@ void set_new_tick() } /* ----- time ----- */ -int64 time_get() +int64 time_get_impl() { static int64 last = 0; - if(new_tick == 0) - return last; - if(new_tick != -1) - new_tick = 0; - { #if defined(CONF_PLATFORM_MACOSX) static int got_timebase = 0; @@ -971,7 +966,7 @@ int64 time_get() #elif defined(CONF_FAMILY_UNIX) struct timespec spec; clock_gettime(CLOCK_MONOTONIC, &spec); - last = (int64)spec.tv_sec*(int64)1000000+(int64)spec.tv_nsec/1000; + last = (int64)spec.tv_sec*(int64)1000000 + (int64)spec.tv_nsec / 1000; return last; #elif defined(CONF_FAMILY_WINDOWS) int64 t; @@ -986,6 +981,17 @@ int64 time_get() } } +int64 time_get() +{ + static int64 last = 0; + if(new_tick == 0) + return last; + if(new_tick != -1) + new_tick = 0; + + last = time_get_impl(); +} + int64 time_freq() { #if defined(CONF_PLATFORM_MACOSX) @@ -1003,42 +1009,15 @@ int64 time_freq() int64 time_get_microseconds() { - static int64 last = 0; { #if defined(CONF_PLATFORM_MACOSX) - static int got_timebase = 0; - mach_timebase_info_data_t timebase; - uint64_t time; - uint64_t q; - uint64_t r; - if (!got_timebase) - { - mach_timebase_info(&timebase); - } - time = mach_absolute_time(); - q = time / timebase.denom; - r = time % timebase.denom; - last = q * timebase.numer + r * timebase.numer / timebase.denom; - return last / (int64)1000; + return time_get_impl() / (int64)1000; #elif defined(CONF_FAMILY_UNIX) - struct timespec spec; - clock_gettime(CLOCK_MONOTONIC, &spec); - last = (int64)spec.tv_sec*(int64)1000000 + (int64)spec.tv_nsec / 1000; - return last; + return time_get_impl(); #elif defined(CONF_FAMILY_WINDOWS) - int64 t; - QueryPerformanceCounter((PLARGE_INTEGER)&t); - - int64 tf; - QueryPerformanceFrequency((PLARGE_INTEGER)&tf); - - t = (t * (int64)1000000) / tf; - if(t < last) // for some reason, QPC can return values in the past - return last; - last = t; - return t; + return (time_get_impl() * (int64)1000000) / time_freq(); #else -#error not implemented + #error not implemented #endif } } diff --git a/src/base/system.h b/src/base/system.h index 7ae09f661..43e211533 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -591,6 +591,18 @@ typedef unsigned long long uint64; void set_new_tick(); +/* + Function: time_get_impl + Fetches a sample from a high resolution timer. + + Returns: + Current value of the timer. + + Remarks: + To know how fast the timer is ticking, see . +*/ +int64 time_get_impl(); + /* Function: time_get Fetches a sample from a high resolution timer. @@ -600,6 +612,7 @@ void set_new_tick(); Remarks: To know how fast the timer is ticking, see . + Uses to fetch the sample. */ int64 time_get(); From c6a9aadbb0fc21df82f4eac1df214db685f755b8 Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Mon, 12 Mar 2018 16:21:21 +0100 Subject: [PATCH 12/15] add missing return statement --- src/base/system.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/base/system.c b/src/base/system.c index d66d98930..74d5134d1 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -990,6 +990,7 @@ int64 time_get() new_tick = 0; last = time_get_impl(); + return last; } int64 time_freq() @@ -1009,17 +1010,15 @@ int64 time_freq() int64 time_get_microseconds() { - { #if defined(CONF_PLATFORM_MACOSX) - return time_get_impl() / (int64)1000; + return time_get_impl() / (int64)1000; #elif defined(CONF_FAMILY_UNIX) - return time_get_impl(); + return time_get_impl(); #elif defined(CONF_FAMILY_WINDOWS) - return (time_get_impl() * (int64)1000000) / time_freq(); + return (time_get_impl() * (int64)1000000) / time_freq(); #else - #error not implemented + #error not implemented #endif - } } /* ----- network ----- */ From 72c38bca0c0f0ebefe6084db5fdbae9393c97548 Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Mon, 12 Mar 2018 16:41:02 +0100 Subject: [PATCH 13/15] devide by the time_freq --- src/base/system.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/base/system.c b/src/base/system.c index 74d5134d1..5f35ff250 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -1011,9 +1011,9 @@ int64 time_freq() int64 time_get_microseconds() { #if defined(CONF_PLATFORM_MACOSX) - return time_get_impl() / (int64)1000; + return time_get_impl() / (time_freq() / 1000 / 1000 / 1000); #elif defined(CONF_FAMILY_UNIX) - return time_get_impl(); + return time_get_impl() / (time_freq() / 1000 / 1000); #elif defined(CONF_FAMILY_WINDOWS) return (time_get_impl() * (int64)1000000) / time_freq(); #else From 5b56e5b2c497f3ca42c7292ed43692566392fad4 Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Mon, 12 Mar 2018 16:51:31 +0100 Subject: [PATCH 14/15] move the keyboard state back into the gfx update --- src/engine/client/client.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 356c3a93a..6f943e92a 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -2837,8 +2837,10 @@ void CClient::Run() } m_pGraphics->Swap(); } + + Input()->NextFrame(); } - Input()->NextFrame(); + if(Input()->VideoRestartNeeded()) { m_pGraphics->Init(); From 3858a930a9d3df332f5311719af4507972033004 Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Mon, 12 Mar 2018 17:10:11 +0100 Subject: [PATCH 15/15] merge mac and linux impl into one --- src/base/system.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/base/system.c b/src/base/system.c index 5f35ff250..edc0474da 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -1010,14 +1010,10 @@ int64 time_freq() int64 time_get_microseconds() { -#if defined(CONF_PLATFORM_MACOSX) - return time_get_impl() / (time_freq() / 1000 / 1000 / 1000); -#elif defined(CONF_FAMILY_UNIX) - return time_get_impl() / (time_freq() / 1000 / 1000); -#elif defined(CONF_FAMILY_WINDOWS) +#if defined(CONF_FAMILY_WINDOWS) return (time_get_impl() * (int64)1000000) / time_freq(); #else - #error not implemented + return time_get_impl() / (time_freq() / 1000 / 1000); #endif }