mirror of https://github.com/PCSX2/pcsx2.git
GS: Add sync to host refresh rate option
This commit is contained in:
parent
a05a655037
commit
ec43661664
|
@ -27,6 +27,7 @@
|
||||||
#include "common/StringUtil.h"
|
#include "common/StringUtil.h"
|
||||||
|
|
||||||
#include "pcsx2/CDVD/CDVD.h"
|
#include "pcsx2/CDVD/CDVD.h"
|
||||||
|
#include "pcsx2/Counters.h"
|
||||||
#include "pcsx2/Frontend/InputManager.h"
|
#include "pcsx2/Frontend/InputManager.h"
|
||||||
#include "pcsx2/Frontend/ImGuiManager.h"
|
#include "pcsx2/Frontend/ImGuiManager.h"
|
||||||
#include "pcsx2/GS.h"
|
#include "pcsx2/GS.h"
|
||||||
|
@ -361,6 +362,9 @@ void EmuThread::setFullscreen(bool fullscreen)
|
||||||
m_is_fullscreen = fullscreen;
|
m_is_fullscreen = fullscreen;
|
||||||
GetMTGS().UpdateDisplayWindow();
|
GetMTGS().UpdateDisplayWindow();
|
||||||
GetMTGS().WaitGS();
|
GetMTGS().WaitGS();
|
||||||
|
|
||||||
|
// If we're using exclusive fullscreen, the refresh rate may have changed.
|
||||||
|
UpdateVSyncRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuThread::setSurfaceless(bool surfaceless)
|
void EmuThread::setSurfaceless(bool surfaceless)
|
||||||
|
|
|
@ -435,6 +435,7 @@ struct Pcsx2Config
|
||||||
PCRTCOffsets : 1,
|
PCRTCOffsets : 1,
|
||||||
IntegerScaling : 1,
|
IntegerScaling : 1,
|
||||||
LinearPresent : 1,
|
LinearPresent : 1,
|
||||||
|
SyncToHostRefreshRate : 1,
|
||||||
UseDebugDevice : 1,
|
UseDebugDevice : 1,
|
||||||
UseBlitSwapChain : 1,
|
UseBlitSwapChain : 1,
|
||||||
DisableShaderCache : 1,
|
DisableShaderCache : 1,
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
|
|
||||||
#include "ps2/HwInternal.h"
|
#include "ps2/HwInternal.h"
|
||||||
#include "Sio.h"
|
#include "Sio.h"
|
||||||
|
#include "HostDisplay.h"
|
||||||
|
#include "SPU2/spu2.h"
|
||||||
|
|
||||||
#ifndef PCSX2_CORE
|
#ifndef PCSX2_CORE
|
||||||
#include "gui/App.h"
|
#include "gui/App.h"
|
||||||
|
@ -46,6 +48,7 @@ using namespace Threading;
|
||||||
extern u8 psxhblankgate;
|
extern u8 psxhblankgate;
|
||||||
static const uint EECNT_FUTURE_TARGET = 0x10000000;
|
static const uint EECNT_FUTURE_TARGET = 0x10000000;
|
||||||
static int gates = 0;
|
static int gates = 0;
|
||||||
|
static bool s_use_vsync_for_timing = false;
|
||||||
|
|
||||||
uint g_FrameCount = 0;
|
uint g_FrameCount = 0;
|
||||||
|
|
||||||
|
@ -346,6 +349,39 @@ double GetVerticalFrequency()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static double AdjustToHostRefreshRate(double vertical_frequency, double frame_limit)
|
||||||
|
{
|
||||||
|
if (!EmuConfig.GS.SyncToHostRefreshRate || EmuConfig.GS.LimitScalar != 1.0)
|
||||||
|
{
|
||||||
|
SPU2SetDeviceSampleRateMultiplier(1.0);
|
||||||
|
s_use_vsync_for_timing = false;
|
||||||
|
return frame_limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
float host_refresh_rate;
|
||||||
|
if (!Host::GetHostDisplay()->GetHostRefreshRate(&host_refresh_rate))
|
||||||
|
{
|
||||||
|
Console.Warning("Cannot sync to host refresh since the query failed.");
|
||||||
|
SPU2SetDeviceSampleRateMultiplier(1.0);
|
||||||
|
s_use_vsync_for_timing = false;
|
||||||
|
return frame_limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
const double ratio = host_refresh_rate / vertical_frequency;
|
||||||
|
const bool syncing_to_host = (ratio >= 0.95f && ratio <= 1.05f);
|
||||||
|
s_use_vsync_for_timing = (syncing_to_host && !EmuConfig.GS.SkipDuplicateFrames && EmuConfig.GS.VsyncEnable != VsyncMode::Off);
|
||||||
|
Console.WriteLn("Refresh rate: Host=%fhz Guest=%fhz Ratio=%f - %s %s", host_refresh_rate,
|
||||||
|
vertical_frequency, ratio, syncing_to_host ? "can sync" : "can't sync",
|
||||||
|
s_use_vsync_for_timing ? "and using vsync for pacing" : "and using sleep for pacing");
|
||||||
|
|
||||||
|
if (!syncing_to_host)
|
||||||
|
return frame_limit;
|
||||||
|
|
||||||
|
frame_limit *= ratio;
|
||||||
|
SPU2SetDeviceSampleRateMultiplier(ratio);
|
||||||
|
return frame_limit;
|
||||||
|
}
|
||||||
|
|
||||||
u32 UpdateVSyncRate()
|
u32 UpdateVSyncRate()
|
||||||
{
|
{
|
||||||
// Notice: (and I probably repeat this elsewhere, but it's worth repeating)
|
// Notice: (and I probably repeat this elsewhere, but it's worth repeating)
|
||||||
|
@ -357,7 +393,7 @@ u32 UpdateVSyncRate()
|
||||||
const double vertical_frequency = GetVerticalFrequency();
|
const double vertical_frequency = GetVerticalFrequency();
|
||||||
|
|
||||||
const double frames_per_second = vertical_frequency / 2.0;
|
const double frames_per_second = vertical_frequency / 2.0;
|
||||||
const double frame_limit = frames_per_second * EmuConfig.GS.LimitScalar;
|
const double frame_limit = AdjustToHostRefreshRate(vertical_frequency, frames_per_second * EmuConfig.GS.LimitScalar);
|
||||||
|
|
||||||
const double tick_rate = GetTickFrequency() / 2.0;
|
const double tick_rate = GetTickFrequency() / 2.0;
|
||||||
const s64 ticks = static_cast<s64>(tick_rate / std::max(frame_limit, 1.0));
|
const s64 ticks = static_cast<s64>(tick_rate / std::max(frame_limit, 1.0));
|
||||||
|
@ -515,7 +551,7 @@ static __fi void frameLimitUpdateCore()
|
||||||
static __fi void frameLimit()
|
static __fi void frameLimit()
|
||||||
{
|
{
|
||||||
// Framelimiter off in settings? Framelimiter go brrr.
|
// Framelimiter off in settings? Framelimiter go brrr.
|
||||||
if (EmuConfig.GS.LimitScalar == 0.0)
|
if (EmuConfig.GS.LimitScalar == 0.0 || s_use_vsync_for_timing)
|
||||||
{
|
{
|
||||||
frameLimitUpdateCore();
|
frameLimitUpdateCore();
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1371,6 +1371,7 @@ void GSApp::Init()
|
||||||
m_default_configuration["extrathreads_height"] = "4";
|
m_default_configuration["extrathreads_height"] = "4";
|
||||||
m_default_configuration["filter"] = std::to_string(static_cast<s8>(BiFiltering::PS2));
|
m_default_configuration["filter"] = std::to_string(static_cast<s8>(BiFiltering::PS2));
|
||||||
m_default_configuration["FMVSoftwareRendererSwitch"] = "0";
|
m_default_configuration["FMVSoftwareRendererSwitch"] = "0";
|
||||||
|
m_default_configuration["FullscreenMode"] = "";
|
||||||
m_default_configuration["fxaa"] = "0";
|
m_default_configuration["fxaa"] = "0";
|
||||||
m_default_configuration["GSDumpCompression"] = "0";
|
m_default_configuration["GSDumpCompression"] = "0";
|
||||||
m_default_configuration["HWDisableReadbacks"] = "0";
|
m_default_configuration["HWDisableReadbacks"] = "0";
|
||||||
|
|
|
@ -502,7 +502,6 @@ void GSRenderer::VSync(u32 field, bool registers_written)
|
||||||
|
|
||||||
const int fb_sprite_blits = g_perfmon.GetDisplayFramebufferSpriteBlits();
|
const int fb_sprite_blits = g_perfmon.GetDisplayFramebufferSpriteBlits();
|
||||||
const bool fb_sprite_frame = (fb_sprite_blits > 0);
|
const bool fb_sprite_frame = (fb_sprite_blits > 0);
|
||||||
PerformanceMetrics::Update(registers_written, fb_sprite_frame);
|
|
||||||
|
|
||||||
bool skip_frame = m_frameskip;
|
bool skip_frame = m_frameskip;
|
||||||
if (GSConfig.SkipDuplicateFrames)
|
if (GSConfig.SkipDuplicateFrames)
|
||||||
|
@ -540,6 +539,7 @@ void GSRenderer::VSync(u32 field, bool registers_written)
|
||||||
if (Host::BeginPresentFrame(true))
|
if (Host::BeginPresentFrame(true))
|
||||||
Host::EndPresentFrame();
|
Host::EndPresentFrame();
|
||||||
g_gs_device->RestoreAPIState();
|
g_gs_device->RestoreAPIState();
|
||||||
|
PerformanceMetrics::Update(registers_written, fb_sprite_frame);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,6 +572,7 @@ void GSRenderer::VSync(u32 field, bool registers_written)
|
||||||
PerformanceMetrics::OnGPUPresent(Host::GetHostDisplay()->GetAndResetAccumulatedGPUTime());
|
PerformanceMetrics::OnGPUPresent(Host::GetHostDisplay()->GetAndResetAccumulatedGPUTime());
|
||||||
}
|
}
|
||||||
g_gs_device->RestoreAPIState();
|
g_gs_device->RestoreAPIState();
|
||||||
|
PerformanceMetrics::Update(registers_written, fb_sprite_frame);
|
||||||
|
|
||||||
// snapshot
|
// snapshot
|
||||||
// wx is dumb and call this from the UI thread...
|
// wx is dumb and call this from the UI thread...
|
||||||
|
|
|
@ -301,6 +301,7 @@ Pcsx2Config::GSOptions::GSOptions()
|
||||||
PCRTCOffsets = false;
|
PCRTCOffsets = false;
|
||||||
IntegerScaling = false;
|
IntegerScaling = false;
|
||||||
LinearPresent = true;
|
LinearPresent = true;
|
||||||
|
SyncToHostRefreshRate = false;
|
||||||
UseDebugDevice = false;
|
UseDebugDevice = false;
|
||||||
UseBlitSwapChain = false;
|
UseBlitSwapChain = false;
|
||||||
DisableShaderCache = false;
|
DisableShaderCache = false;
|
||||||
|
@ -464,6 +465,7 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap)
|
||||||
|
|
||||||
#ifdef PCSX2_CORE
|
#ifdef PCSX2_CORE
|
||||||
// These are loaded from GSWindow in wx.
|
// These are loaded from GSWindow in wx.
|
||||||
|
SettingsWrapBitBool(SyncToHostRefreshRate);
|
||||||
SettingsWrapEnumEx(AspectRatio, "AspectRatio", AspectRatioNames);
|
SettingsWrapEnumEx(AspectRatio, "AspectRatio", AspectRatioNames);
|
||||||
SettingsWrapEnumEx(FMVAspectRatioSwitch, "FMVAspectRatioSwitch", FMVAspectRatioSwitchNames);
|
SettingsWrapEnumEx(FMVAspectRatioSwitch, "FMVAspectRatioSwitch", FMVAspectRatioSwitchNames);
|
||||||
|
|
||||||
|
|
|
@ -149,14 +149,6 @@ bool SndBuffer::CheckUnderrunStatus(int& nSamples, int& quietSampleCount)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SndBuffer::_InitFail()
|
|
||||||
{
|
|
||||||
// If a failure occurs, just initialize the NoSound driver. This'll allow
|
|
||||||
// the game to emulate properly (hopefully), albeit without sound.
|
|
||||||
OutputModule = FindOutputModuleById(NullOut->GetIdent());
|
|
||||||
mods[OutputModule]->Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
int SndBuffer::_GetApproximateDataInBuffer()
|
int SndBuffer::_GetApproximateDataInBuffer()
|
||||||
{
|
{
|
||||||
// WARNING: not necessarily 100% up to date by the time it's used, but it will have to do.
|
// WARNING: not necessarily 100% up to date by the time it's used, but it will have to do.
|
||||||
|
@ -357,13 +349,10 @@ void SndBuffer::_WriteSamples(StereoOut32* bData, int nSamples)
|
||||||
_WriteSamples_Safe(bData, nSamples);
|
_WriteSamples_Safe(bData, nSamples);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SndBuffer::Init()
|
bool SndBuffer::Init()
|
||||||
{
|
{
|
||||||
if (mods[OutputModule] == nullptr)
|
if (!mods[OutputModule])
|
||||||
{
|
return false;
|
||||||
_InitFail();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize sound buffer
|
// initialize sound buffer
|
||||||
// Buffer actually attempts to run ~50%, so allocate near double what
|
// Buffer actually attempts to run ~50%, so allocate near double what
|
||||||
|
@ -372,33 +361,25 @@ void SndBuffer::Init()
|
||||||
m_rpos = 0;
|
m_rpos = 0;
|
||||||
m_wpos = 0;
|
m_wpos = 0;
|
||||||
|
|
||||||
try
|
const float latencyMS = SndOutLatencyMS * 16;
|
||||||
{
|
m_size = GetAlignedBufferSize((int)(latencyMS * SampleRate / 1000.0f));
|
||||||
const float latencyMS = SndOutLatencyMS * 16;
|
m_buffer = new StereoOut32[m_size];
|
||||||
m_size = GetAlignedBufferSize((int)(latencyMS * SampleRate / 1000.0f));
|
m_underrun_freeze = false;
|
||||||
printf("%d SampleRate: \n", SampleRate);
|
|
||||||
m_buffer = new StereoOut32[m_size];
|
|
||||||
m_underrun_freeze = false;
|
|
||||||
|
|
||||||
sndTempBuffer = new StereoOut32[SndOutPacketSize];
|
|
||||||
sndTempBuffer16 = new StereoOut16[SndOutPacketSize * 2]; // in case of leftovers.
|
|
||||||
}
|
|
||||||
catch (std::bad_alloc&)
|
|
||||||
{
|
|
||||||
// out of memory exception (most likely)
|
|
||||||
|
|
||||||
SysMessage("Out of memory error occurred while initializing SPU2.");
|
|
||||||
_InitFail();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
sndTempBuffer = new StereoOut32[SndOutPacketSize];
|
||||||
|
sndTempBuffer16 = new StereoOut16[SndOutPacketSize * 2]; // in case of leftovers.
|
||||||
sndTempProgress = 0;
|
sndTempProgress = 0;
|
||||||
|
|
||||||
soundtouchInit(); // initializes the timestretching
|
soundtouchInit(); // initializes the timestretching
|
||||||
|
|
||||||
// initialize module
|
// initialize module
|
||||||
if (!mods[OutputModule]->Init())
|
if (!mods[OutputModule]->Init())
|
||||||
_InitFail();
|
{
|
||||||
|
Cleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SndBuffer::Cleanup()
|
void SndBuffer::Cleanup()
|
||||||
|
|
|
@ -586,7 +586,6 @@ private:
|
||||||
static float eTempo;
|
static float eTempo;
|
||||||
static int ssFreeze;
|
static int ssFreeze;
|
||||||
|
|
||||||
static void _InitFail();
|
|
||||||
static bool CheckUnderrunStatus(int& nSamples, int& quietSampleCount);
|
static bool CheckUnderrunStatus(int& nSamples, int& quietSampleCount);
|
||||||
|
|
||||||
static void soundtouchInit();
|
static void soundtouchInit();
|
||||||
|
@ -614,7 +613,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void UpdateTempoChangeAsyncMixing();
|
static void UpdateTempoChangeAsyncMixing();
|
||||||
static void Init();
|
static bool Init();
|
||||||
static void Cleanup();
|
static void Cleanup();
|
||||||
static void Write(const StereoOut32& Sample);
|
static void Write(const StereoOut32& Sample);
|
||||||
static void ClearContents();
|
static void ClearContents();
|
||||||
|
|
|
@ -33,8 +33,11 @@ using namespace Threading;
|
||||||
|
|
||||||
std::recursive_mutex mtx_SPU2Status;
|
std::recursive_mutex mtx_SPU2Status;
|
||||||
|
|
||||||
|
static int ConsoleSampleRate = 48000;
|
||||||
int SampleRate = 48000;
|
int SampleRate = 48000;
|
||||||
|
|
||||||
|
static double DeviceSampleRateMultiplier = 1.0;
|
||||||
|
|
||||||
static bool IsOpened = false;
|
static bool IsOpened = false;
|
||||||
static bool IsInitialized = false;
|
static bool IsInitialized = false;
|
||||||
|
|
||||||
|
@ -120,9 +123,44 @@ void SPU2writeDMA7Mem(u16* pMem, u32 size)
|
||||||
Cores[1].DoDMAwrite(pMem, size);
|
Cores[1].DoDMAwrite(pMem, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 SPU2reset(PS2Modes isRunningPSXMode)
|
static void SPU2InitSndBuffer()
|
||||||
{
|
{
|
||||||
int requiredSampleRate = (isRunningPSXMode == PS2Modes::PSX) ? 44100 : 48000;
|
Console.WriteLn("Initializing SndBuffer at sample rate of %u...", SampleRate);
|
||||||
|
if (SndBuffer::Init())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (SampleRate != ConsoleSampleRate)
|
||||||
|
{
|
||||||
|
// TODO: Resample on our side...
|
||||||
|
const int original_sample_rate = SampleRate;
|
||||||
|
Console.Error("Failed to init SPU2 at adjusted sample rate %u, trying console rate.", SampleRate);
|
||||||
|
SampleRate = ConsoleSampleRate;
|
||||||
|
if (SndBuffer::Init())
|
||||||
|
return;
|
||||||
|
|
||||||
|
SampleRate = original_sample_rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// just use nullout
|
||||||
|
OutputModule = FindOutputModuleById(NullOut->GetIdent());
|
||||||
|
if (!SndBuffer::Init())
|
||||||
|
pxFailRel("Failed to initialize nullout.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SPU2UpdateSampleRate()
|
||||||
|
{
|
||||||
|
const int new_sample_rate = static_cast<int>(std::round(static_cast<double>(ConsoleSampleRate) * DeviceSampleRateMultiplier));
|
||||||
|
if (SampleRate == new_sample_rate)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SndBuffer::Cleanup();
|
||||||
|
SampleRate = new_sample_rate;
|
||||||
|
SPU2InitSndBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SPU2InternalReset(PS2Modes isRunningPSXMode)
|
||||||
|
{
|
||||||
|
ConsoleSampleRate = (isRunningPSXMode == PS2Modes::PSX) ? 44100 : 48000;
|
||||||
|
|
||||||
if (isRunningPSXMode == PS2Modes::PS2)
|
if (isRunningPSXMode == PS2Modes::PS2)
|
||||||
{
|
{
|
||||||
|
@ -136,25 +174,24 @@ s32 SPU2reset(PS2Modes isRunningPSXMode)
|
||||||
Cores[0].Init(0);
|
Cores[0].Init(0);
|
||||||
Cores[1].Init(1);
|
Cores[1].Init(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (SampleRate != requiredSampleRate)
|
s32 SPU2reset(PS2Modes isRunningPSXMode)
|
||||||
{
|
{
|
||||||
SampleRate = requiredSampleRate;
|
SPU2InternalReset(isRunningPSXMode);
|
||||||
SndBuffer::Cleanup();
|
SPU2UpdateSampleRate();
|
||||||
try
|
|
||||||
{
|
|
||||||
SndBuffer::Init();
|
|
||||||
}
|
|
||||||
catch (std::exception& ex)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "SPU2 Error: Could not initialize device, or something.\nReason: %s", ex.what());
|
|
||||||
SPU2close();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SPU2SetDeviceSampleRateMultiplier(double multiplier)
|
||||||
|
{
|
||||||
|
if (DeviceSampleRateMultiplier == multiplier)
|
||||||
|
return;
|
||||||
|
|
||||||
|
DeviceSampleRateMultiplier = multiplier;
|
||||||
|
SPU2UpdateSampleRate();
|
||||||
|
}
|
||||||
|
|
||||||
s32 SPU2init()
|
s32 SPU2init()
|
||||||
{
|
{
|
||||||
assert(regtable[0x400] == nullptr);
|
assert(regtable[0x400] == nullptr);
|
||||||
|
@ -207,7 +244,7 @@ s32 SPU2init()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SPU2reset(PS2Modes::PS2);
|
SPU2InternalReset(PS2Modes::PS2);
|
||||||
|
|
||||||
DMALogOpen();
|
DMALogOpen();
|
||||||
InitADSR();
|
InitADSR();
|
||||||
|
@ -289,7 +326,8 @@ s32 SPU2open()
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
SndBuffer::Init();
|
SampleRate = static_cast<int>(std::round(static_cast<double>(ConsoleSampleRate) * DeviceSampleRateMultiplier));
|
||||||
|
SPU2InitSndBuffer();
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(PCSX2_CORE)
|
#if defined(_WIN32) && !defined(PCSX2_CORE)
|
||||||
DspLoadLibrary(dspPlugin, dspPluginModule);
|
DspLoadLibrary(dspPlugin, dspPluginModule);
|
||||||
|
|
|
@ -33,6 +33,7 @@ s32 SPU2open();
|
||||||
void SPU2close();
|
void SPU2close();
|
||||||
void SPU2shutdown();
|
void SPU2shutdown();
|
||||||
void SPU2SetOutputPaused(bool paused);
|
void SPU2SetOutputPaused(bool paused);
|
||||||
|
void SPU2SetDeviceSampleRateMultiplier(double multiplier);
|
||||||
void SPU2write(u32 mem, u16 value);
|
void SPU2write(u32 mem, u16 value);
|
||||||
u16 SPU2read(u32 mem);
|
u16 SPU2read(u32 mem);
|
||||||
|
|
||||||
|
|
|
@ -886,6 +886,7 @@ void AppConfig::GSWindowOptions::LoadSave(IniInterface& ini)
|
||||||
// WARNING: array must be NULL terminated to compute it size
|
// WARNING: array must be NULL terminated to compute it size
|
||||||
NULL};
|
NULL};
|
||||||
|
|
||||||
|
g_Conf->EmuOptions.GS.SyncToHostRefreshRate = ini.EntryBitBool(L"SyncToHostRefreshRate", g_Conf->EmuOptions.GS.SyncToHostRefreshRate, g_Conf->EmuOptions.GS.SyncToHostRefreshRate);
|
||||||
ini.EnumEntry(L"AspectRatio", g_Conf->EmuOptions.GS.AspectRatio, AspectRatioNames, g_Conf->EmuOptions.GS.AspectRatio);
|
ini.EnumEntry(L"AspectRatio", g_Conf->EmuOptions.GS.AspectRatio, AspectRatioNames, g_Conf->EmuOptions.GS.AspectRatio);
|
||||||
if (ini.IsLoading())
|
if (ini.IsLoading())
|
||||||
EmuConfig.CurrentAspectRatio = g_Conf->EmuOptions.GS.AspectRatio;
|
EmuConfig.CurrentAspectRatio = g_Conf->EmuOptions.GS.AspectRatio;
|
||||||
|
|
|
@ -285,6 +285,7 @@ namespace Panels
|
||||||
|
|
||||||
pxCheckBox* m_check_HideMouse;
|
pxCheckBox* m_check_HideMouse;
|
||||||
pxCheckBox* m_check_DclickFullscreen;
|
pxCheckBox* m_check_DclickFullscreen;
|
||||||
|
pxCheckBox* m_check_SyncToHostRefreshRate;
|
||||||
|
|
||||||
wxTextCtrl* m_text_WindowWidth;
|
wxTextCtrl* m_text_WindowWidth;
|
||||||
wxTextCtrl* m_text_WindowHeight;
|
wxTextCtrl* m_text_WindowHeight;
|
||||||
|
|
|
@ -74,6 +74,7 @@ Panels::GSWindowSettingsPanel::GSWindowSettingsPanel(wxWindow* parent)
|
||||||
// Implement custom hotkeys (Alt + Enter) with translatable string intact + not blank in GUI.
|
// Implement custom hotkeys (Alt + Enter) with translatable string intact + not blank in GUI.
|
||||||
m_check_Fullscreen = new pxCheckBox(this, _("Start in fullscreen mode by default") + wxString(" (") + wxGetApp().GlobalAccels->findKeycodeWithCommandId("FullscreenToggle").toTitleizedString() + wxString(")"));
|
m_check_Fullscreen = new pxCheckBox(this, _("Start in fullscreen mode by default") + wxString(" (") + wxGetApp().GlobalAccels->findKeycodeWithCommandId("FullscreenToggle").toTitleizedString() + wxString(")"));
|
||||||
m_check_DclickFullscreen = new pxCheckBox(this, _("Double-click toggles fullscreen mode"));
|
m_check_DclickFullscreen = new pxCheckBox(this, _("Double-click toggles fullscreen mode"));
|
||||||
|
m_check_SyncToHostRefreshRate = new pxCheckBox(this, _("Sync To Host Refresh Rate"));
|
||||||
|
|
||||||
m_combo_FMVAspectRatioSwitch->SetToolTip(pxEt(L"Off: Disables temporary aspect ratio switch. (It will use the above setting from Aspect Ratio instead of FMV Aspect Ratio Override.)\n\n"
|
m_combo_FMVAspectRatioSwitch->SetToolTip(pxEt(L"Off: Disables temporary aspect ratio switch. (It will use the above setting from Aspect Ratio instead of FMV Aspect Ratio Override.)\n\n"
|
||||||
L"Auto 4:3/3:2: Temporarily switch to a 4:3 aspect ratio while an FMV plays to correctly display a 4:3 FMV. Will use 3:2 is the resolution is 480P\n\n"
|
L"Auto 4:3/3:2: Temporarily switch to a 4:3 aspect ratio while an FMV plays to correctly display a 4:3 FMV. Will use 3:2 is the resolution is 480P\n\n"
|
||||||
|
@ -136,6 +137,7 @@ Panels::GSWindowSettingsPanel::GSWindowSettingsPanel(wxWindow* parent)
|
||||||
|
|
||||||
*this += m_check_Fullscreen;
|
*this += m_check_Fullscreen;
|
||||||
*this += m_check_DclickFullscreen;
|
*this += m_check_DclickFullscreen;
|
||||||
|
*this += m_check_SyncToHostRefreshRate;
|
||||||
*this += new wxStaticLine(this) | StdExpand();
|
*this += new wxStaticLine(this) | StdExpand();
|
||||||
|
|
||||||
*this += s_vsync | StdExpand();
|
*this += s_vsync | StdExpand();
|
||||||
|
@ -169,6 +171,7 @@ void Panels::GSWindowSettingsPanel::ApplyConfigToGui(AppConfig& configToApply, i
|
||||||
m_text_Zoom->ChangeValue(wxString::FromDouble(gsconf.Zoom, 2));
|
m_text_Zoom->ChangeValue(wxString::FromDouble(gsconf.Zoom, 2));
|
||||||
|
|
||||||
m_check_DclickFullscreen->SetValue(conf.IsToggleFullscreenOnDoubleClick);
|
m_check_DclickFullscreen->SetValue(conf.IsToggleFullscreenOnDoubleClick);
|
||||||
|
m_check_SyncToHostRefreshRate->SetValue(gsconf.SyncToHostRefreshRate);
|
||||||
|
|
||||||
m_text_WindowWidth->ChangeValue(wxsFormat(L"%d", conf.WindowSize.GetWidth()));
|
m_text_WindowWidth->ChangeValue(wxsFormat(L"%d", conf.WindowSize.GetWidth()));
|
||||||
m_text_WindowHeight->ChangeValue(wxsFormat(L"%d", conf.WindowSize.GetHeight()));
|
m_text_WindowHeight->ChangeValue(wxsFormat(L"%d", conf.WindowSize.GetHeight()));
|
||||||
|
@ -199,6 +202,7 @@ void Panels::GSWindowSettingsPanel::Apply()
|
||||||
gsconf.VsyncEnable = static_cast<VsyncMode>(m_combo_vsync->GetSelection());
|
gsconf.VsyncEnable = static_cast<VsyncMode>(m_combo_vsync->GetSelection());
|
||||||
|
|
||||||
appconf.IsToggleFullscreenOnDoubleClick = m_check_DclickFullscreen->GetValue();
|
appconf.IsToggleFullscreenOnDoubleClick = m_check_DclickFullscreen->GetValue();
|
||||||
|
gsconf.SyncToHostRefreshRate = m_check_SyncToHostRefreshRate->GetValue();
|
||||||
|
|
||||||
long xr, yr = 1;
|
long xr, yr = 1;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue