mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-21 05:09:34 -06:00
Merge pull request #13046 from SuperSamus/vi-overclock
Add VBI Frequency Override
This commit is contained in:
@ -222,6 +222,8 @@ const Info<bool> MAIN_PRECISION_FRAME_TIMING{{System::Main, "Core", "PrecisionFr
|
||||
DEFAULT_PRECISION_FRAME_TIMING};
|
||||
const Info<float> MAIN_OVERCLOCK{{System::Main, "Core", "Overclock"}, 1.0f};
|
||||
const Info<bool> MAIN_OVERCLOCK_ENABLE{{System::Main, "Core", "OverclockEnable"}, false};
|
||||
const Info<float> MAIN_VI_OVERCLOCK{{System::Main, "Core", "VIOverclock"}, 1.0f};
|
||||
const Info<bool> MAIN_VI_OVERCLOCK_ENABLE{{System::Main, "Core", "VIOverclockEnable"}, false};
|
||||
const Info<bool> MAIN_RAM_OVERRIDE_ENABLE{{System::Main, "Core", "RAMOverrideEnable"}, false};
|
||||
const Info<u32> MAIN_MEM1_SIZE{{System::Main, "Core", "MEM1Size"}, Memory::MEM1_SIZE_RETAIL};
|
||||
const Info<u32> MAIN_MEM2_SIZE{{System::Main, "Core", "MEM2Size"}, Memory::MEM2_SIZE_RETAIL};
|
||||
|
@ -128,6 +128,8 @@ extern const Info<float> MAIN_EMULATION_SPEED;
|
||||
extern const Info<bool> MAIN_PRECISION_FRAME_TIMING;
|
||||
extern const Info<float> MAIN_OVERCLOCK;
|
||||
extern const Info<bool> MAIN_OVERCLOCK_ENABLE;
|
||||
extern const Info<float> MAIN_VI_OVERCLOCK;
|
||||
extern const Info<bool> MAIN_VI_OVERCLOCK_ENABLE;
|
||||
extern const Info<bool> MAIN_RAM_OVERRIDE_ENABLE;
|
||||
extern const Info<u32> MAIN_MEM1_SIZE;
|
||||
extern const Info<u32> MAIN_MEM2_SIZE;
|
||||
|
@ -42,6 +42,8 @@ public:
|
||||
layer->Set(Config::MAIN_DSP_HLE, m_settings.dsp_hle);
|
||||
layer->Set(Config::MAIN_OVERCLOCK_ENABLE, m_settings.oc_enable);
|
||||
layer->Set(Config::MAIN_OVERCLOCK, m_settings.oc_factor);
|
||||
layer->Set(Config::MAIN_VI_OVERCLOCK_ENABLE, m_settings.vi_oc_enable);
|
||||
layer->Set(Config::MAIN_VI_OVERCLOCK, m_settings.vi_oc_factor);
|
||||
for (ExpansionInterface::Slot slot : ExpansionInterface::SLOTS)
|
||||
layer->Set(Config::GetInfoForEXIDevice(slot), m_settings.exi_device[slot]);
|
||||
layer->Set(Config::MAIN_MEMORY_CARD_SIZE, m_settings.memcard_size_override);
|
||||
|
@ -119,7 +119,9 @@ void CoreTimingManager::Shutdown()
|
||||
void CoreTimingManager::RefreshConfig()
|
||||
{
|
||||
m_config_oc_factor =
|
||||
Config::Get(Config::MAIN_OVERCLOCK_ENABLE) ? Config::Get(Config::MAIN_OVERCLOCK) : 1.0f;
|
||||
(Config::Get(Config::MAIN_OVERCLOCK_ENABLE) ? Config::Get(Config::MAIN_OVERCLOCK) : 1.0f) *
|
||||
(Config::Get(Config::MAIN_VI_OVERCLOCK_ENABLE) ? Config::Get(Config::MAIN_VI_OVERCLOCK) :
|
||||
1.0f);
|
||||
m_config_oc_inv_factor = 1.0f / m_config_oc_factor;
|
||||
m_config_sync_on_skip_idle = Config::Get(Config::MAIN_SYNC_ON_SKIP_IDLE);
|
||||
|
||||
@ -482,6 +484,11 @@ bool CoreTimingManager::GetVISkip() const
|
||||
return m_throttle_disable_vi_int && g_ActiveConfig.bVISkip && !Core::WantsDeterminism();
|
||||
}
|
||||
|
||||
float CoreTimingManager::GetOverclock() const
|
||||
{
|
||||
return m_config_oc_factor;
|
||||
}
|
||||
|
||||
bool CoreTimingManager::UseSyncOnSkipIdle() const
|
||||
{
|
||||
return m_config_sync_on_skip_idle;
|
||||
|
@ -165,6 +165,8 @@ public:
|
||||
// Used by VideoInterface
|
||||
bool GetVISkip() const;
|
||||
|
||||
float GetOverclock() const;
|
||||
|
||||
bool UseSyncOnSkipIdle() const;
|
||||
|
||||
private:
|
||||
|
@ -365,6 +365,8 @@ void DolphinAnalytics::MakePerGameBuilder()
|
||||
builder.AddData("cfg-audio-backend", Config::Get(Config::MAIN_AUDIO_BACKEND));
|
||||
builder.AddData("cfg-oc-enable", Config::Get(Config::MAIN_OVERCLOCK_ENABLE));
|
||||
builder.AddData("cfg-oc-factor", Config::Get(Config::MAIN_OVERCLOCK));
|
||||
builder.AddData("cfg-vi-oc-enable", Config::Get(Config::MAIN_VI_OVERCLOCK_ENABLE));
|
||||
builder.AddData("cfg-vi-oc-factor", Config::Get(Config::MAIN_VI_OVERCLOCK));
|
||||
builder.AddData("cfg-render-to-main", Config::Get(Config::MAIN_RENDER_TO_MAIN));
|
||||
if (g_video_backend)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Config/Config.h"
|
||||
|
||||
enum class FieldType;
|
||||
class PointerWrap;
|
||||
@ -407,6 +408,9 @@ private:
|
||||
void BeginField(FieldType field, u64 ticks);
|
||||
void EndField(FieldType field, u64 ticks);
|
||||
|
||||
void RefreshConfig();
|
||||
void UpdateRefreshRate();
|
||||
|
||||
// Registers listed in order:
|
||||
UVIVerticalTimingRegister m_vertical_timing_register;
|
||||
UVIDisplayControlRegister m_display_control_register;
|
||||
@ -447,6 +451,9 @@ private:
|
||||
u32 m_even_field_last_hl = 0; // index last halfline of the even field
|
||||
u32 m_odd_field_last_hl = 0; // index last halfline of the odd field
|
||||
|
||||
float m_config_vi_oc_factor = 0.0f;
|
||||
|
||||
Config::ConfigChangedCallbackID m_config_changed_callback_id;
|
||||
Core::System& m_system;
|
||||
};
|
||||
} // namespace VideoInterface
|
||||
|
@ -68,9 +68,7 @@ IPCReply GetCPUSpeed(Core::System& system, const IOCtlVRequest& request)
|
||||
return IPCReply(IPC_EINVAL);
|
||||
}
|
||||
|
||||
const bool overclock_enabled = Config::Get(Config::MAIN_OVERCLOCK_ENABLE);
|
||||
const float oc = overclock_enabled ? Config::Get(Config::MAIN_OVERCLOCK) : 1.0f;
|
||||
|
||||
const bool oc = system.GetCoreTiming().GetOverclock();
|
||||
const u32 core_clock = u32(float(system.GetSystemTimers().GetTicksPerSecond()) * oc);
|
||||
|
||||
auto& memory = system.GetMemory();
|
||||
|
@ -862,6 +862,8 @@ void NetPlayClient::OnStartGame(sf::Packet& packet)
|
||||
packet >> m_net_settings.allow_sd_writes;
|
||||
packet >> m_net_settings.oc_enable;
|
||||
packet >> m_net_settings.oc_factor;
|
||||
packet >> m_net_settings.vi_oc_enable;
|
||||
packet >> m_net_settings.vi_oc_factor;
|
||||
|
||||
for (auto slot : ExpansionInterface::SLOTS)
|
||||
packet >> m_net_settings.exi_device[slot];
|
||||
|
@ -47,6 +47,8 @@ struct NetSettings
|
||||
bool allow_sd_writes = false;
|
||||
bool oc_enable = false;
|
||||
float oc_factor = 0;
|
||||
bool vi_oc_enable = false;
|
||||
float vi_oc_factor = 0;
|
||||
Common::EnumMap<ExpansionInterface::EXIDeviceType, ExpansionInterface::MAX_SLOT> exi_device{};
|
||||
int memcard_size_override = -1;
|
||||
|
||||
|
@ -1376,6 +1376,8 @@ bool NetPlayServer::SetupNetSettings()
|
||||
settings.allow_sd_writes = Config::Get(Config::MAIN_ALLOW_SD_WRITES);
|
||||
settings.oc_enable = Config::Get(Config::MAIN_OVERCLOCK_ENABLE);
|
||||
settings.oc_factor = Config::Get(Config::MAIN_OVERCLOCK);
|
||||
settings.vi_oc_enable = Config::Get(Config::MAIN_VI_OVERCLOCK_ENABLE);
|
||||
settings.vi_oc_factor = Config::Get(Config::MAIN_VI_OVERCLOCK);
|
||||
|
||||
for (ExpansionInterface::Slot slot : ExpansionInterface::SLOTS)
|
||||
{
|
||||
@ -1603,6 +1605,8 @@ bool NetPlayServer::StartGame()
|
||||
spac << m_settings.allow_sd_writes;
|
||||
spac << m_settings.oc_enable;
|
||||
spac << m_settings.oc_factor;
|
||||
spac << m_settings.vi_oc_enable;
|
||||
spac << m_settings.vi_oc_factor;
|
||||
|
||||
for (auto slot : ExpansionInterface::SLOTS)
|
||||
spac << static_cast<int>(m_settings.exi_device[slot]);
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/HW/SystemTimers.h"
|
||||
#include "Core/HW/VideoInterface.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
#include "Core/System.h"
|
||||
|
||||
@ -111,14 +112,47 @@ void AdvancedPane::CreateLayout()
|
||||
|
||||
m_cpu_clock_override_checkbox->SetDescription(
|
||||
tr("Adjusts the emulated CPU's clock rate.<br><br>"
|
||||
"Higher values may make variable-framerate games run at a higher framerate, "
|
||||
"at the expense of performance. Lower values may activate a game's "
|
||||
"internal frameskip, potentially improving performance.<br><br>"
|
||||
"<b>WARNING</b>: Changing this from the default (100%) can and will "
|
||||
"On games that have an unstable frame rate despite full emulation speed, "
|
||||
"higher values can improve their performance, requiring a powerful device. "
|
||||
"Lower values reduce the emulated console's performance, but improve the "
|
||||
"emulation speed.<br><br>"
|
||||
"WARNING: Changing this from the default (100%) can and will "
|
||||
"break games and cause glitches. Do so at your own risk. "
|
||||
"Please do not report bugs that occur with a non-default clock."
|
||||
"<br><br><dolphin_emphasis>If unsure, leave this unchecked.</dolphin_emphasis>"));
|
||||
|
||||
auto* vi_rate_override = new QGroupBox(tr("VBI Frequency Override"));
|
||||
auto* vi_rate_override_layout = new QVBoxLayout();
|
||||
vi_rate_override->setLayout(vi_rate_override_layout);
|
||||
main_layout->addWidget(vi_rate_override);
|
||||
|
||||
m_vi_rate_override_checkbox =
|
||||
new ConfigBool(tr("Enable VBI Frequency Override"), Config::MAIN_VI_OVERCLOCK_ENABLE);
|
||||
vi_rate_override_layout->addWidget(m_vi_rate_override_checkbox);
|
||||
connect(m_vi_rate_override_checkbox, &QCheckBox::toggled, this, &AdvancedPane::Update);
|
||||
|
||||
auto* vi_rate_override_slider_layout = new QHBoxLayout();
|
||||
vi_rate_override_slider_layout->setContentsMargins(0, 0, 0, 0);
|
||||
vi_rate_override_layout->addLayout(vi_rate_override_slider_layout);
|
||||
|
||||
m_vi_rate_override_slider = new QSlider(Qt::Horizontal);
|
||||
m_vi_rate_override_slider->setRange(1, 500);
|
||||
vi_rate_override_slider_layout->addWidget(m_vi_rate_override_slider);
|
||||
|
||||
m_vi_rate_override_slider_label = new QLabel();
|
||||
vi_rate_override_slider_layout->addWidget(m_vi_rate_override_slider_label);
|
||||
|
||||
m_vi_rate_override_checkbox->SetDescription(
|
||||
tr("Adjusts the VBI frequency. Also adjusts the emulated CPU's "
|
||||
"clock rate, to keep it relatively the same.<br><br>"
|
||||
"Makes games run at a different frame rate, making the emulation less "
|
||||
"demanding when lowered, or improving smoothness when increased. This may "
|
||||
"affect gameplay speed, as it is often tied to the frame rate.<br><br>"
|
||||
"WARNING: Changing this from the default (100%) can and will "
|
||||
"break games and cause glitches. Do so at your own risk. "
|
||||
"Please do not report bugs that occur with a non-default frequency."
|
||||
"<br><br><dolphin_emphasis>If unsure, leave this unchecked.</dolphin_emphasis>"));
|
||||
|
||||
auto* ram_override = new QGroupBox(tr("Memory Override"));
|
||||
auto* ram_override_layout = new QVBoxLayout();
|
||||
ram_override->setLayout(ram_override_layout);
|
||||
@ -199,6 +233,18 @@ void AdvancedPane::ConnectLayout()
|
||||
Update();
|
||||
});
|
||||
|
||||
connect(m_vi_rate_override_slider, &QSlider::valueChanged, [this](int oc_factor) {
|
||||
const float factor = m_vi_rate_override_slider->value() / 100.f;
|
||||
Config::SetBaseOrCurrent(Config::MAIN_VI_OVERCLOCK, factor);
|
||||
Update();
|
||||
});
|
||||
|
||||
m_ram_override_checkbox->setChecked(Config::Get(Config::MAIN_RAM_OVERRIDE_ENABLE));
|
||||
connect(m_ram_override_checkbox, &QCheckBox::toggled, [this](bool enable_ram_override) {
|
||||
Config::SetBaseOrCurrent(Config::MAIN_RAM_OVERRIDE_ENABLE, enable_ram_override);
|
||||
Update();
|
||||
});
|
||||
|
||||
connect(m_mem1_override_slider, &QSlider::valueChanged, [this](int slider_value) {
|
||||
const u32 mem1_size = m_mem1_override_slider->value() * 0x100000;
|
||||
Config::SetBaseOrCurrent(Config::MAIN_MEM1_SIZE, mem1_size);
|
||||
@ -222,6 +268,7 @@ void AdvancedPane::Update()
|
||||
{
|
||||
const bool is_uninitialized = Core::IsUninitialized(Core::System::GetInstance());
|
||||
const bool enable_cpu_clock_override_widgets = Config::Get(Config::MAIN_OVERCLOCK_ENABLE);
|
||||
const bool enable_vi_rate_override_widgets = Config::Get(Config::MAIN_VI_OVERCLOCK_ENABLE);
|
||||
const bool enable_ram_override_widgets = Config::Get(Config::MAIN_RAM_OVERRIDE_ENABLE);
|
||||
const bool enable_custom_rtc_widgets =
|
||||
Config::Get(Config::MAIN_CUSTOM_RTC_ENABLE) && is_uninitialized;
|
||||
@ -264,6 +311,30 @@ void AdvancedPane::Update()
|
||||
return tr("%1% (%2 MHz)").arg(QString::number(percent), QString::number(clock));
|
||||
}());
|
||||
|
||||
QFont vi_bf = font();
|
||||
vi_bf.setBold(Config::GetActiveLayerForConfig(Config::MAIN_VI_OVERCLOCK_ENABLE) !=
|
||||
Config::LayerType::Base);
|
||||
m_vi_rate_override_checkbox->setFont(vi_bf);
|
||||
m_vi_rate_override_checkbox->setChecked(enable_vi_rate_override_widgets);
|
||||
|
||||
m_vi_rate_override_slider->setEnabled(enable_vi_rate_override_widgets);
|
||||
m_vi_rate_override_slider_label->setEnabled(enable_vi_rate_override_widgets);
|
||||
|
||||
{
|
||||
const QSignalBlocker blocker(m_vi_rate_override_slider);
|
||||
m_vi_rate_override_slider->setValue(
|
||||
static_cast<int>(std::round(Config::Get(Config::MAIN_VI_OVERCLOCK) * 100.f)));
|
||||
}
|
||||
|
||||
m_vi_rate_override_slider_label->setText([] {
|
||||
int percent = static_cast<int>(std::round(Config::Get(Config::MAIN_VI_OVERCLOCK) * 100.f));
|
||||
float vps =
|
||||
static_cast<float>(Core::System::GetInstance().GetVideoInterface().GetTargetRefreshRate());
|
||||
if (vps == 0.0f || !Config::Get(Config::MAIN_VI_OVERCLOCK_ENABLE))
|
||||
vps = 59.94f * Config::Get(Config::MAIN_VI_OVERCLOCK);
|
||||
return tr("%1% (%2 VPS)").arg(QString::number(percent), QString::number(vps, 'f', 2));
|
||||
}());
|
||||
|
||||
m_ram_override_checkbox->setEnabled(is_uninitialized);
|
||||
SignalBlocking(m_ram_override_checkbox)->setChecked(enable_ram_override_widgets);
|
||||
|
||||
|
@ -39,6 +39,10 @@ private:
|
||||
QSlider* m_cpu_clock_override_slider;
|
||||
QLabel* m_cpu_clock_override_slider_label;
|
||||
|
||||
ConfigBool* m_vi_rate_override_checkbox;
|
||||
QSlider* m_vi_rate_override_slider;
|
||||
QLabel* m_vi_rate_override_slider_label;
|
||||
|
||||
ConfigBool* m_custom_rtc_checkbox;
|
||||
QDateTimeEdit* m_custom_rtc_datetime;
|
||||
|
||||
|
@ -62,13 +62,13 @@ struct FrameDumpContext
|
||||
|
||||
namespace
|
||||
{
|
||||
AVRational GetTimeBaseForCurrentRefreshRate()
|
||||
AVRational GetTimeBaseForCurrentRefreshRate(s64 max_denominator)
|
||||
{
|
||||
auto& vi = Core::System::GetInstance().GetVideoInterface();
|
||||
int num;
|
||||
int den;
|
||||
av_reduce(&num, &den, int(vi.GetTargetRefreshRateDenominator()),
|
||||
int(vi.GetTargetRefreshRateNumerator()), std::numeric_limits<int>::max());
|
||||
int(vi.GetTargetRefreshRateNumerator()), max_denominator);
|
||||
return AVRational{num, den};
|
||||
}
|
||||
|
||||
@ -248,11 +248,16 @@ bool FFMpegFrameDump::CreateVideoFile()
|
||||
return false;
|
||||
}
|
||||
|
||||
m_max_denominator = std::numeric_limits<s64>::max();
|
||||
|
||||
// Force XVID FourCC for better compatibility when using H.263
|
||||
if (codec->id == AV_CODEC_ID_MPEG4)
|
||||
{
|
||||
m_context->codec->codec_tag = MKTAG('X', 'V', 'I', 'D');
|
||||
m_max_denominator = std::numeric_limits<unsigned short>::max();
|
||||
}
|
||||
|
||||
const auto time_base = GetTimeBaseForCurrentRefreshRate();
|
||||
const auto time_base = GetTimeBaseForCurrentRefreshRate(m_max_denominator);
|
||||
|
||||
INFO_LOG_FMT(FRAMEDUMP, "Creating video file: {} x {} @ {}/{} fps", m_context->width,
|
||||
m_context->height, time_base.den, time_base.num);
|
||||
@ -535,7 +540,7 @@ FrameState FFMpegFrameDump::FetchState(u64 ticks, int frame_number) const
|
||||
state.frame_number = frame_number;
|
||||
state.savestate_index = m_savestate_index;
|
||||
|
||||
const auto time_base = GetTimeBaseForCurrentRefreshRate();
|
||||
const auto time_base = GetTimeBaseForCurrentRefreshRate(m_max_denominator);
|
||||
state.refresh_rate_num = time_base.den;
|
||||
state.refresh_rate_den = time_base.num;
|
||||
return state;
|
||||
|
@ -4,6 +4,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <ctime>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
@ -62,6 +63,9 @@ private:
|
||||
// Used for filename generation.
|
||||
std::time_t m_start_time = {};
|
||||
u32 m_file_index = 0;
|
||||
|
||||
// Some codecs (like MPEG4) have a limit to this
|
||||
int64_t m_max_denominator = std::numeric_limits<s64>::max();
|
||||
};
|
||||
|
||||
#if !defined(HAVE_FFMPEG)
|
||||
|
Reference in New Issue
Block a user