180 lines
5.8 KiB
C++
180 lines
5.8 KiB
C++
/****************************************************************************
|
|
* *
|
|
* 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 <Project64-core/N64System/N64Types.h>
|
|
|
|
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;
|
|
} |