Core: Add VBI Frequency Override
This feature allows overriding the frequency of the Vertical Blank Interrupt. For many games, this means that their gameplay speed will change without affecting audio, which would be useful by itself (e.g. grinding in RPGs). However, there are games that use delta time for their game logic, which allows them to be played at >60 FPS at the same gameplay speed! Some games aren't dynamic though, and require a patch to adjust their game speed variable.
This commit is contained in:
1 parent
c9bdda63dc
commit
832570c658
18 files changed
+176
-13
No files matched your search
@@ -13,8 +13,10 @@
|
||||
#include "Common/Config/Config.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
|
||||
#include "VideoCommon/OnScreenDisplay.h"
|
||||
#include "VideoCommon/PerformanceMetrics.h"
|
||||
|
||||
#include "Core/AchievementManager.h"
|
||||
#include "Core/Config/GraphicsSettings.h"
|
||||
#include "Core/Config/MainSettings.h"
|
||||
#include "Core/Config/SYSCONFSettings.h"
|
||||
@@ -41,7 +43,10 @@ VideoInterfaceManager::VideoInterfaceManager(Core::System& system) : m_system(sy
|
||||
{
|
||||
}
|
||||
|
||||
VideoInterfaceManager::~VideoInterfaceManager() = default;
|
||||
VideoInterfaceManager::~VideoInterfaceManager()
|
||||
{
|
||||
Config::RemoveConfigChangedCallback(m_config_changed_callback_id);
|
||||
}
|
||||
|
||||
static constexpr std::array<u32, 2> CLOCK_FREQUENCIES{{
|
||||
27000000,
|
||||
@@ -173,6 +178,22 @@ void VideoInterfaceManager::Preset(bool _bNTSC)
|
||||
void VideoInterfaceManager::Init()
|
||||
{
|
||||
Preset(true);
|
||||
|
||||
m_config_changed_callback_id = Config::AddConfigChangedCallback([this] { RefreshConfig(); });
|
||||
RefreshConfig();
|
||||
}
|
||||
|
||||
void VideoInterfaceManager::RefreshConfig()
|
||||
{
|
||||
m_config_vi_oc_factor =
|
||||
Config::Get(Config::MAIN_VI_OVERCLOCK_ENABLE) ? Config::Get(Config::MAIN_VI_OVERCLOCK) : 1.0f;
|
||||
if (AchievementManager::GetInstance().IsHardcoreModeActive() && m_config_vi_oc_factor < 1.0f)
|
||||
{
|
||||
Config::SetCurrent(Config::MAIN_VI_OVERCLOCK, 1.0f);
|
||||
m_config_vi_oc_factor = 1.0f;
|
||||
OSD::AddMessage("Minimum VBI frequency is 100% in Hardcore Mode");
|
||||
}
|
||||
UpdateRefreshRate();
|
||||
}
|
||||
|
||||
void VideoInterfaceManager::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||
@@ -488,7 +509,8 @@ float VideoInterfaceManager::GetAspectRatio() const
|
||||
float vertical_period = tick_length * GetTicksPerField();
|
||||
float horizontal_period = tick_length * GetTicksPerHalfLine() * 2;
|
||||
float vertical_active_area = active_lines * horizontal_period;
|
||||
float horizontal_active_area = tick_length * GetTicksPerSample() * active_width_samples;
|
||||
float horizontal_active_area =
|
||||
tick_length * GetTicksPerSample() * active_width_samples / m_config_vi_oc_factor;
|
||||
|
||||
// We are approximating the horizontal/vertical flyback transformers that control the
|
||||
// position of the electron beam on the screen. Our flyback transformers create a
|
||||
@@ -707,7 +729,11 @@ void VideoInterfaceManager::UpdateParameters()
|
||||
m_vblank_timing_even.PRB - odd_even_psb_diff;
|
||||
m_even_field_last_hl = m_even_field_first_hl + acv_hl - 1;
|
||||
|
||||
// Refresh rate:
|
||||
UpdateRefreshRate();
|
||||
}
|
||||
|
||||
void VideoInterfaceManager::UpdateRefreshRate()
|
||||
{
|
||||
m_target_refresh_rate_numerator = m_system.GetSystemTimers().GetTicksPerSecond() * 2;
|
||||
m_target_refresh_rate_denominator = GetTicksPerEvenField() + GetTicksPerOddField();
|
||||
m_target_refresh_rate =
|
||||
@@ -736,7 +762,7 @@ u32 VideoInterfaceManager::GetTicksPerSample() const
|
||||
|
||||
u32 VideoInterfaceManager::GetTicksPerHalfLine() const
|
||||
{
|
||||
return GetTicksPerSample() * m_h_timing_0.HLW;
|
||||
return GetTicksPerSample() * m_h_timing_0.HLW / m_config_vi_oc_factor;
|
||||
}
|
||||
|
||||
u32 VideoInterfaceManager::GetTicksPerField() const
|
||||
|
||||
Reference in new issue
Block a user