/**************************************************************************** * * * Project64 - A Nintendo 64 emulator. * * http://www.pj64-emu.com/ * * Copyright (C) 2012 Project64. All rights reserved. * * * * License: * * GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * * * ****************************************************************************/ #include "stdafx.h" #include "FramePerSecondClass.h" #include CFramePerSecond::CFramePerSecond() : m_CurrentViFrame(0), m_CurrentDlistFrame(0), m_iFrameRateType(g_Settings->LoadDword(UserInterface_FrameDisplayType)), m_ScreenHertz(g_Settings->LoadDword(GameRunning_ScreenHertz)), m_ViFrameRateWhole(0), m_ViFrameRateFraction(0) { g_Settings->RegisterChangeCB(UserInterface_FrameDisplayType, this, (CSettings::SettingChangedFunc)FrameRateTypeChanged); g_Settings->RegisterChangeCB(GameRunning_ScreenHertz, this, (CSettings::SettingChangedFunc)ScreenHertzChanged); if (m_ScreenHertz == 0) { m_ScreenHertz = 60; } Reset(true); } CFramePerSecond::~CFramePerSecond() { g_Settings->UnregisterChangeCB(UserInterface_FrameDisplayType, this, (CSettings::SettingChangedFunc)FrameRateTypeChanged); g_Settings->UnregisterChangeCB(GameRunning_ScreenHertz, this, (CSettings::SettingChangedFunc)ScreenHertzChanged); } void CFramePerSecond::Reset(bool ClearDisplay) { m_CurrentDlistFrame = 0; m_CurrentViFrame = 0; m_LastViFrame.SetMicroSeconds(0); for (int count = 0; count < NoOfFrames; count++) { m_ViFrames[count] = 0; m_FramesDlist[count] = 0; } if (ClearDisplay) { g_Notify->DisplayMessage2(""); return; } if (m_iFrameRateType == FR_VIs) { DisplayViCounter(-1, 0); } } void CFramePerSecond::UpdateViCounter(void) { if (m_iFrameRateType != FR_VIs && m_iFrameRateType != FR_VIs_DLs && m_iFrameRateType != FR_PERCENT) { return; } if ((m_CurrentViFrame & 7) == 0) { HighResTimeStamp Time; Time.SetToNow(); uint64_t time_diff = Time.GetMicroSeconds() - m_LastViFrame.GetMicroSeconds(); m_ViFrames[(m_CurrentViFrame >> 3) % NoOfFrames] = time_diff; m_LastViFrame = Time; DisplayViCounter(-1, 0); } m_CurrentViFrame += 1; } void CFramePerSecond::UpdateDisplay(void) { std::string DisplayString; if (m_iFrameRateType == FR_VIs || m_iFrameRateType == FR_VIs_DLs) { DisplayString = stdstr_f(m_ViFrameRateWhole >= 0 ? "VI/s: %d.%d" : "VI/s: -.--", m_ViFrameRateWhole, m_ViFrameRateFraction); } if (m_iFrameRateType == FR_PERCENT && m_ViFrameRateWhole > 0) { float Percent = ((float)m_ViFrameRateWhole + ((float)m_ViFrameRateFraction / 100)) / m_ScreenHertz; DisplayString = stdstr_f("%.1f %%", Percent * 100).c_str(); } if (m_iFrameRateType == FR_DLs || m_iFrameRateType == FR_VIs_DLs) { if (DisplayString.length() > 0) { DisplayString += " "; } DisplayString += stdstr_f(m_DlistFrameRate >= 0 ? "DL/s: %.1f" : "DL/s: -.--", m_DlistFrameRate); } g_Notify->DisplayMessage2(DisplayString.c_str()); } void CFramePerSecond::DisplayViCounter(int32_t FrameRateWhole, uint32_t FrameRateFraction) { if (m_iFrameRateType != FR_VIs && m_iFrameRateType != FR_VIs_DLs && m_iFrameRateType != FR_PERCENT) { return; } if (FrameRateWhole >= 0) { m_ViFrameRateWhole = FrameRateWhole; m_ViFrameRateFraction = FrameRateFraction; } else { if (m_CurrentViFrame > (NoOfFrames << 3)) { uint64_t Total; Total = 0; for (int count = 0; count < NoOfFrames; count++) { Total += m_ViFrames[count]; } int baseFPS = (uint32_t)(((uint64_t)NoOfFrames << 3) * 100000000 / Total); m_ViFrameRateWhole = baseFPS / 100; m_ViFrameRateFraction = baseFPS % 100; } else { m_ViFrameRateWhole = -1; m_ViFrameRateFraction = 0; } } UpdateDisplay(); } void CFramePerSecond::FrameRateTypeChanged(CFramePerSecond * _this) { _this->m_iFrameRateType = g_Settings->LoadDword(UserInterface_FrameDisplayType); _this->Reset(true); } void CFramePerSecond::ScreenHertzChanged(CFramePerSecond * _this) { _this->m_ScreenHertz = g_Settings->LoadDword(GameRunning_ScreenHertz); _this->Reset(true); } void CFramePerSecond::UpdateDlCounter(void) { if (m_iFrameRateType != FR_DLs && m_iFrameRateType != FR_VIs_DLs) { return; } if ((m_CurrentDlistFrame & 3) == 0) { HighResTimeStamp Now; Now.SetToNow(); m_FramesDlist[(m_CurrentDlistFrame >> 2) % NoOfFrames] = Now.GetMicroSeconds() - m_LastDlistFrame.GetMicroSeconds(); m_LastDlistFrame = Now; if (m_CurrentDlistFrame > (NoOfFrames << 2)) { int64_t Total; Total = 0; for (int count = 0; count < NoOfFrames; count++) { Total += m_FramesDlist[count]; } m_DlistFrameRate = ((NoOfFrames << 2) / ((float)Total / 1000000)); } else { m_DlistFrameRate = -1.0; } UpdateDisplay(); } m_CurrentDlistFrame += 1; }