static bool Cmd_GetFPS_Execute(COMMAND_ARGS) { #if 0 float frameTime = g_timeInfo->frameTime; #else float frameTime = GetAverageFrameTime(); #endif // clamp to prevent weird behavior const float kFPSCap = 10000.0f; // 10K FPS ought to be enough for anybody const float kMinFrameTime = 1.0f / kFPSCap; if(frameTime < kMinFrameTime) frameTime = kMinFrameTime; *result = 1.0f / frameTime; return true; }
void gkTimer::UpdateOnFrameStart() { if(!m_bEnabled) return; if (sys_max_fps != 0) { CTimeValue timeFrameMax; timeFrameMax.SetMilliSeconds((int64)(1000.f/(float)sys_max_fps)); static CTimeValue sTimeLast = gEnv->pTimer->GetAsyncTime(); const CTimeValue timeLast = timeFrameMax + sTimeLast; while(timeLast.GetValue() > gEnv->pTimer->GetAsyncTime().GetValue()) { volatile int i=0; while(i++ < 1000); } sTimeLast = gEnv->pTimer->GetAsyncTime(); } assert(m_pfnUpdate); // call Init() before if ((m_nFrameCounter & 127)==0) { // every bunch of frames, check frequency to adapt to // CPU power management clock rate changes #ifdef OS_WIN32 LARGE_INTEGER TTicksPerSec; if (QueryPerformanceFrequency(&TTicksPerSec)) { // if returns false, no performance counter is available m_lTicksPerSec=TTicksPerSec.QuadPart; } #endif } m_nFrameCounter++; #ifdef PROFILING m_fFrameTime = 0.020f; // 20ms = 50fps g_lCurrentTime += (int)(m_fFrameTime*(float)(CTimeValue::TIMEVALUE_PRECISION)); m_lCurrentTime = g_lCurrentTime; m_lLastTime = m_lCurrentTime; RefreshGameTime(m_lCurrentTime); RefreshUITime(m_lCurrentTime); return; #endif int64 now = (*m_pfnUpdate)(); if (m_lForcedGameTime >= 0) { // m_lCurrentTime contains the time, which should be current // but time has passed since Serialize until UpdateOnFrameStart // so we have to make sure to compensate! m_lOffsetTime = m_lForcedGameTime - now + m_lBaseTime; m_lLastTime = now - m_lBaseTime; m_lForcedGameTime = -1; } // Real time. m_lCurrentTime = now - m_lBaseTime; //m_fRealFrameTime = m_fFrameTime = (float)(m_lCurrentTime-m_lLastTime) / (float)(m_lTicksPerSec); m_fRealFrameTime = m_fFrameTime = (float)((double)(m_lCurrentTime-m_lLastTime) / (double)(m_lTicksPerSec)); if( 0 != m_fixed_time_step) // Absolute zero used as a switch. looks wrong, but runs right ;-) { #ifdef OS_WIN32 if (m_fixed_time_step < 0) { // Enforce real framerate by sleeping. float sleep = -m_fixed_time_step - m_fFrameTime; if (sleep > 0) { // while first // float now = GetAsyncCurTime(); bool breaksleep = 0; // if (sleep < 0.01f) // { // for (int i=0; i < 1000000; ++i) // { // if( GetAsyncCurTime() - now > sleep ) // { // breaksleep = 1; // break; // } // } // } if (!breaksleep) { Sleep((unsigned int)(sleep*1000.f)); m_lCurrentTime = (*m_pfnUpdate)() - m_lBaseTime; //m_fRealFrameTime = (float)(m_lCurrentTime-m_lLastTime) / (float)(m_lTicksPerSec); m_fRealFrameTime = (float)((double)(m_lCurrentTime-m_lLastTime) / (double)(m_lTicksPerSec)); } } } #endif m_fFrameTime = abs(m_fixed_time_step); } else { // Clamp it m_fFrameTime = min(m_fFrameTime, m_max_time_step); // Dilate it. m_fFrameTime *= m_time_scale; } if (m_fFrameTime < 0) m_fFrameTime = 0; //----------------------------------------------- if(m_TimeSmoothing>0) { /* if(m_TimeSmoothing>FPS_FRAMES-1) m_TimeSmoothing=FPS_FRAMES-2; if(m_fFrameTime < 0.0000001f) m_fFrameTime = 0.0000001f; m_previousTimes[m_timecount] = m_fFrameTime; m_timecount++; if(m_timecount>=m_TimeSmoothing) m_timecount=0; // average multiple frames together to smooth changes out a bit float total = 0; for(int i = 0 ; i < m_TimeSmoothing+1; i++ ) total += m_previousTimes[i]; if(!total) total = 1; m_fFrameTime=total/(float)(m_TimeSmoothing+1); */ m_fAverageFrameTime = GetAverageFrameTime( 0.25f, m_fFrameTime, m_fAverageFrameTime); m_fFrameTime=m_fAverageFrameTime; } //else { // Adjust. if (m_fFrameTime != m_fRealFrameTime) { float fBefore = GetAsyncCurTime(); int64 nAdjust = (int64)((m_fFrameTime - m_fRealFrameTime) * (double)(m_lTicksPerSec)); m_lCurrentTime += nAdjust; m_lBaseTime -= nAdjust; } } RefreshUITime(m_lCurrentTime); if (m_bGameTimerPaused == false) RefreshGameTime(m_lCurrentTime); m_lLastTime = m_lCurrentTime; if (m_fRealFrameTime < 0.f) // Can happen after loading a saved game and // at any time on dual core AMD machines and laptops :) m_fRealFrameTime = 0.0f; UpdateBlending(); }