From 5d20018faea982495f8b78b6cbbc0a0512a0f5d4 Mon Sep 17 00:00:00 2001 From: JackCarterSmith Date: Sun, 1 Dec 2024 12:59:36 +0100 Subject: [PATCH] Fixed unstable FPS and profiler inaccuracy --- Game.cpp | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/Game.cpp b/Game.cpp index e78205c..329086d 100644 --- a/Game.cpp +++ b/Game.cpp @@ -52,19 +52,24 @@ Game::Game(std::shared_ptr mainWnd, bool dbgFlag) : mbDbgModeE GAME_STATUS Game::Tick() { static std::vector msTicksMonitoring; - static double mPrevdelta = 0; static double mLastCycleSleepDelta = 0; static unsigned int mFrameCnt = 0; - double mDelta = mSysTimer.GetDeltaTimeUs(); // Debug performance computations if (mDbgUI != nullptr && mPerfsTimer != nullptr) { msTicksMonitoring.push_back(((1000000.f / TARGET_FPS) - mLastCycleSleepDelta) * TARGET_FPS / 1000000.f); if (mPerfsTimer->GetDeltaTime() >= 1000) { // Every 1s // This average CPU/cycle_time method can monitor when CPU is in overload state (>0%) or in underload one (<0%) - double cpuUsage = 200 * std::accumulate(msTicksMonitoring.begin(), msTicksMonitoring.end(), static_cast(0)) / msTicksMonitoring.size() - 100; + double cpuUsage = 100 * std::accumulate(msTicksMonitoring.begin(), msTicksMonitoring.end(), static_cast(0)) / msTicksMonitoring.size(); - mDbgUI->UpdateDebugData(cpuUsage, (((1000000.f / TARGET_FPS) - mLastCycleSleepDelta) / 1000), ((-mPrevdelta + mSysTimer.GetDeltaTimeUs()) / 1000), mFrameCnt, (PerfsGetVirtMem() / 1000), (PerfsGetPhysMem() / 1000)); + mDbgUI->UpdateDebugData( + cpuUsage, + ((1000000.f / TARGET_FPS) - mLastCycleSleepDelta) / 1000, + 1000.f / TARGET_FPS, + mFrameCnt, + PerfsGetVirtMem() / 1000, + PerfsGetPhysMem() / 1000 + ); mFrameCnt = 0; msTicksMonitoring.clear(); @@ -75,22 +80,20 @@ GAME_STATUS Game::Tick() { // Update game stats and internal stuff Update(); - // Ugly way to wait for next frame... Maybe create a separate thread for rendering? - //while(time.GetDeltaTime() < (1000/TARGET_FPS)) {} - - // Process to the final rendering if the window have the focus - if (mSysTimer.GetDeltaTime() >= (1000/TARGET_FPS) && mMainWindow->hasFocus()) { - Render(); - mFrameCnt++; + // Loop the timer when reached the target FPS + if ((mSysTimer.GetDeltaTime() >= (1000/TARGET_FPS))) { mSysTimer.Reset(); - mDelta = -mDelta; + mFrameCnt++; + + // Process to the final rendering if the window have the focus + if (mMainWindow->hasFocus()) + Render(); } - mPrevdelta = mDelta; // Sleep for remaining time to avoid useless CPU usage - mLastCycleSleepDelta = (1000000.f / TARGET_FPS) - (-mPrevdelta + mSysTimer.GetDeltaTimeUs()); + mLastCycleSleepDelta = (1000000.f / TARGET_FPS) - mSysTimer.GetDeltaTimeUs(); if (mLastCycleSleepDelta > 0) - sf::sleep(sf::microseconds(mLastCycleSleepDelta)); + sf::sleep(sf::microseconds(mLastCycleSleepDelta + (1000000.f / TARGET_FPS * 0.02f))); else mLastCycleSleepDelta = 0;