diff --git a/pcsx2/Config.h b/pcsx2/Config.h index a2c04f6499..157d4bf71e 100644 --- a/pcsx2/Config.h +++ b/pcsx2/Config.h @@ -63,6 +63,13 @@ enum GamefixId GamefixId_COUNT }; +enum class VsyncMode +{ + Off, + On, + Adaptive, +}; + // Template function for casting enumerations to their underlying type template typename std::underlying_type::type enum_cast(Enumeration E) @@ -291,9 +298,9 @@ struct Pcsx2Config bool DisableOutput; int VsyncQueueSize; - bool FrameLimitEnable; - bool FrameSkipEnable; - bool VsyncEnable; + bool FrameLimitEnable; + bool FrameSkipEnable; + VsyncMode VsyncEnable; int FramesToDraw; // number of consecutive frames (fields) to render int FramesToSkip; // number of consecutive frames (fields) to skip diff --git a/pcsx2/Pcsx2Config.cpp b/pcsx2/Pcsx2Config.cpp index f53d7cda90..77397813e7 100644 --- a/pcsx2/Pcsx2Config.cpp +++ b/pcsx2/Pcsx2Config.cpp @@ -201,7 +201,7 @@ Pcsx2Config::GSOptions::GSOptions() { FrameLimitEnable = true; FrameSkipEnable = false; - VsyncEnable = false; + VsyncEnable = VsyncMode::Off; SynchronousMTGS = false; DisableOutput = false; @@ -225,7 +225,7 @@ void Pcsx2Config::GSOptions::LoadSave( IniInterface& ini ) IniEntry( FrameLimitEnable ); IniEntry( FrameSkipEnable ); - IniEntry( VsyncEnable ); + ini.EnumEntry( L"VsyncEnable", VsyncEnable, NULL, VsyncEnable ); IniEntry( LimitScalar ); IniEntry( FramerateNTSC ); @@ -240,7 +240,15 @@ int Pcsx2Config::GSOptions::GetVsync() const if (g_LimiterMode == Limit_Turbo) return 0; - return VsyncEnable; + // D3D only support a boolean state. OpenGL waits a number of vsync + // interrupt (negative value for late vsync). + switch (VsyncEnable) { + case VsyncMode::Adaptive: return -1; + case VsyncMode::Off: return 0; + case VsyncMode::On: return 1; + + default: return 0; + } } const wxChar *const tbl_GamefixNames[] = diff --git a/pcsx2/gui/AppCoreThread.cpp b/pcsx2/gui/AppCoreThread.cpp index c448850284..a34268cf48 100644 --- a/pcsx2/gui/AppCoreThread.cpp +++ b/pcsx2/gui/AppCoreThread.cpp @@ -356,7 +356,7 @@ static void _ApplySettings( const Pcsx2Config& src, Pcsx2Config& fixup ) if( overrides.ProfilingMode ) { fixup.GS.FrameLimitEnable = false; - fixup.GS.VsyncEnable = false; + fixup.GS.VsyncEnable = VsyncMode::Off; } wxString gameCRC; diff --git a/pcsx2/gui/Panels/ConfigurationPanels.h b/pcsx2/gui/Panels/ConfigurationPanels.h index 3fc183a1bb..b38b8e834c 100644 --- a/pcsx2/gui/Panels/ConfigurationPanels.h +++ b/pcsx2/gui/Panels/ConfigurationPanels.h @@ -267,6 +267,7 @@ namespace Panels { protected: wxComboBox* m_combo_AspectRatio; + wxComboBox* m_combo_vsync; wxTextCtrl* m_text_Zoom; diff --git a/pcsx2/gui/Panels/GSWindowPanel.cpp b/pcsx2/gui/Panels/GSWindowPanel.cpp index f47d503a64..6a8ff3fbe1 100644 --- a/pcsx2/gui/Panels/GSWindowPanel.cpp +++ b/pcsx2/gui/Panels/GSWindowPanel.cpp @@ -32,11 +32,22 @@ Panels::GSWindowSettingsPanel::GSWindowSettingsPanel( wxWindow* parent ) _("Widescreen (16:9)") }; + // Warning must match the order of the VsyncMode Enum + const wxString vsync_label[] = + { + _("Disabled"), + _("Standard"), + _("Adaptive"), + }; + m_text_Zoom = CreateNumericalTextCtrl( this, 5 ); m_combo_AspectRatio = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, ArraySize(aspect_ratio_labels), aspect_ratio_labels, wxCB_READONLY ); + m_combo_vsync = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, + ArraySize(vsync_label), vsync_label, wxCB_READONLY ); + m_text_WindowWidth = CreateNumericalTextCtrl( this, 5 ); m_text_WindowHeight = CreateNumericalTextCtrl( this, 5 ); @@ -47,7 +58,6 @@ Panels::GSWindowSettingsPanel::GSWindowSettingsPanel( wxWindow* parent ) m_check_HideMouse = new pxCheckBox( this, _("Always hide mouse cursor") ); m_check_CloseGS = new pxCheckBox( this, _("Hide window when paused") ); m_check_Fullscreen = new pxCheckBox( this, _("Default to fullscreen mode on open") ); - m_check_VsyncEnable = new pxCheckBox( this, _("Wait for Vsync on refresh") ); m_check_DclickFullscreen = new pxCheckBox( this, _("Double-click toggles fullscreen mode") ); m_check_AspectRatioSwitch = new pxCheckBox(this, _("Switch to 4:3 aspect ratio when an FMV plays")); //m_check_ExclusiveFS = new pxCheckBox( this, _("Use exclusive fullscreen mode (if available)") ); @@ -55,7 +65,7 @@ Panels::GSWindowSettingsPanel::GSWindowSettingsPanel( wxWindow* parent ) m_text_Zoom->SetToolTip( pxEt( L"Zoom = 100: Fit the entire image to the window without any cropping.\nAbove/Below 100: Zoom In/Out\n0: Automatic-Zoom-In untill the black-bars are gone (Aspect ratio is kept, some of the image goes out of screen).\n NOTE: Some games draw their own black-bars, which will not be removed with '0'.\n\nKeyboard: CTRL + NUMPAD-PLUS: Zoom-In, CTRL + NUMPAD-MINUS: Zoom-Out, CTRL + NUMPAD-*: Toggle 100/0" ) ); - m_check_VsyncEnable->SetToolTip( pxEt( L"Vsync eliminates screen tearing but typically has a big performance hit. It usually only applies to fullscreen mode, and may not work with all GS plugins." + m_combo_vsync->SetToolTip( pxEt( L"Vsync eliminates screen tearing but typically has a big performance hit. It usually only applies to fullscreen mode, and may not work with all GS plugins." ) ); m_check_HideMouse->SetToolTip( pxEt( L"Check this to force the mouse cursor invisible inside the GS window; useful if using the mouse as a primary control device for gaming. By default the mouse auto-hides after 2 seconds of inactivity." @@ -91,6 +101,11 @@ Panels::GSWindowSettingsPanel::GSWindowSettingsPanel( wxWindow* parent ) s_AspectRatio += Label(_("Zoom:")) | StdExpand(); s_AspectRatio += m_text_Zoom; + wxFlexGridSizer& s_vsync( *new wxFlexGridSizer( 2, StdPadding, StdPadding ) ); + s_vsync.AddGrowableCol( 1 ); + + s_vsync += Label(_("Wait for Vsync on refresh:")) | pxMiddle; + s_vsync += m_combo_vsync | pxExpand; *this += s_AspectRatio | StdExpand(); *this += m_check_SizeLock; @@ -105,7 +120,7 @@ Panels::GSWindowSettingsPanel::GSWindowSettingsPanel( wxWindow* parent ) //*this += m_check_ExclusiveFS; *this += new wxStaticLine( this ) | StdExpand(); - *this += m_check_VsyncEnable; + *this += s_vsync; wxBoxSizer* centerSizer = new wxBoxSizer( wxVERTICAL ); *centerSizer += GetSizer() | pxCenter; @@ -140,8 +155,8 @@ void Panels::GSWindowSettingsPanel::ApplyConfigToGui( AppConfig& configToApply, m_text_WindowHeight ->ChangeValue( wxsFormat( L"%d", conf.WindowSize.GetHeight() ) ); } - m_check_VsyncEnable->SetValue( configToApply.EmuOptions.GS.VsyncEnable ); - m_check_VsyncEnable->Enable ( !configToApply.EnablePresets );//grayed-out when presets are enabled + m_combo_vsync->SetSelection(enum_cast(configToApply.EmuOptions.GS.VsyncEnable)); + m_combo_vsync->Enable( !configToApply.EnablePresets );//grayed-out when presets are enabled } void Panels::GSWindowSettingsPanel::Apply() @@ -157,7 +172,7 @@ void Panels::GSWindowSettingsPanel::Apply() appconf.AspectRatio = (AspectRatioType)m_combo_AspectRatio->GetSelection(); appconf.Zoom = Fixed100::FromString( m_text_Zoom->GetValue() ); - gsconf.VsyncEnable = m_check_VsyncEnable->GetValue(); + gsconf.VsyncEnable = static_cast(m_combo_vsync->GetSelection()); appconf.IsToggleFullscreenOnDoubleClick = m_check_DclickFullscreen->GetValue(); appconf.IsToggleAspectRatioSwitch = m_check_AspectRatioSwitch->GetValue();