// Copyright 2010 Dolphin Emulator Project // Licensed under GPLv2+ // Refer to the license.txt file included. #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include "Common/CommonTypes.h" #include "Common/SysConf.h" #include "Core/ConfigManager.h" #include "Core/Core.h" #include "DolphinWX/DolphinSlider.h" #include "DolphinWX/PostProcessingConfigDiag.h" #include "DolphinWX/WxUtils.h" #include "VideoCommon/PostProcessing.h" #include "VideoCommon/VideoBackendBase.h" #include "VideoCommon/VideoConfig.h" class wxBoxSizer; class wxControl; class wxPanel; template class BoolSetting : public W { public: BoolSetting(wxWindow* parent, const wxString& label, const wxString& tooltip, bool& setting, bool reverse = false, long style = 0); void UpdateValue(wxCommandEvent& ev) { m_setting = (ev.GetInt() != 0) ^ m_reverse; ev.Skip(); } private: bool& m_setting; const bool m_reverse; }; typedef BoolSetting SettingCheckBox; typedef BoolSetting SettingRadioButton; template class IntegerSetting : public wxSpinCtrl { public: IntegerSetting(wxWindow* parent, const wxString& label, T& setting, int minVal, int maxVal, long style = 0); void UpdateValue(wxCommandEvent& ev) { m_setting = ev.GetInt(); ev.Skip(); } private: T& m_setting; }; class SettingChoice : public wxChoice { public: SettingChoice(wxWindow* parent, int& setting, const wxString& tooltip, int num = 0, const wxString choices[] = nullptr, long style = 0); void UpdateValue(wxCommandEvent& ev); private: int& m_setting; }; class VideoConfigDiag : public wxDialog { public: VideoConfigDiag(wxWindow* parent, const std::string& title); protected: void Event_Backend(wxCommandEvent& ev) { auto& new_backend = g_available_video_backends[ev.GetInt()]; if (g_video_backend != new_backend.get()) { bool do_switch = !Core::IsRunning(); if (new_backend->GetName() == "Software Renderer") { do_switch = (wxYES == wxMessageBox(_("Software rendering is an order of magnitude slower than using the " "other backends.\nIt's only useful for debugging purposes.\nDo you " "really want to enable software rendering? If unsure, select 'No'."), _("Warning"), wxYES_NO | wxNO_DEFAULT | wxICON_EXCLAMATION, this)); } if (do_switch) { // TODO: Only reopen the dialog if the software backend is // selected (make sure to reinitialize backend info) // reopen the dialog Close(); g_video_backend = new_backend.get(); SConfig::GetInstance().m_strVideoBackend = g_video_backend->GetName(); g_video_backend->ShowConfig(GetParent()); } else { // Select current backend again choice_backend->SetStringSelection(StrToWxStr(g_video_backend->GetName())); } } ev.Skip(); } void Event_Adapter(wxCommandEvent& ev) { ev.Skip(); } // TODO void Event_DisplayResolution(wxCommandEvent& ev); void Event_ProgressiveScan(wxCommandEvent& ev) { SConfig::GetInstance().m_SYSCONF->SetData("IPL.PGS", ev.GetInt()); SConfig::GetInstance().bProgressive = ev.IsChecked(); ev.Skip(); } void Event_Stc(wxCommandEvent& ev) { int samples[] = {0, 512, 128}; vconfig.iSafeTextureCache_ColorSamples = samples[ev.GetInt()]; ev.Skip(); } void Event_PPShader(wxCommandEvent& ev) { const int sel = ev.GetInt(); if (sel) vconfig.sPostProcessingShader = WxStrToStr(ev.GetString()); else vconfig.sPostProcessingShader.clear(); // Should we enable the configuration button? PostProcessingShaderConfiguration postprocessing_shader; postprocessing_shader.LoadShader(vconfig.sPostProcessingShader); button_config_pp->Enable(postprocessing_shader.HasOptions()); ev.Skip(); } void Event_ConfigurePPShader(wxCommandEvent& ev) { PostProcessingConfigDiag dialog(this, vconfig.sPostProcessingShader); dialog.ShowModal(); ev.Skip(); } void Event_StereoDepth(wxCommandEvent& ev) { vconfig.iStereoDepth = ev.GetInt(); ev.Skip(); } void Event_StereoConvergence(wxCommandEvent& ev) { // Snap the slider int value = ev.GetInt(); if (90 < value && value < 110) conv_slider->SetValue(100); vconfig.iStereoConvergencePercentage = conv_slider->GetValue(); ev.Skip(); } void Event_StereoMode(wxCommandEvent& ev) { if (vconfig.backend_info.bSupportsPostProcessing) { // Anaglyph overrides post-processing shaders choice_ppshader->Clear(); } ev.Skip(); } void Event_Close(wxCommandEvent&); // Enables/disables UI elements depending on current config void OnUpdateUI(wxUpdateUIEvent& ev) { // Anti-aliasing choice_aamode->Enable(vconfig.backend_info.AAModes.size() > 1); text_aamode->Enable(vconfig.backend_info.AAModes.size() > 1); // XFB virtual_xfb->Enable(vconfig.bUseXFB); real_xfb->Enable(vconfig.bUseXFB); // custom textures cache_hires_textures->Enable(vconfig.bHiresTextures); // Repopulating the post-processing shaders can't be done from an event if (choice_ppshader && choice_ppshader->IsEmpty()) PopulatePostProcessingShaders(); // Things which shouldn't be changed during emulation if (Core::IsRunning()) { choice_backend->Disable(); label_backend->Disable(); // D3D only if (vconfig.backend_info.Adapters.size()) { choice_adapter->Disable(); label_adapter->Disable(); } #ifndef __APPLE__ // This isn't supported on OS X. choice_display_resolution->Disable(); label_display_resolution->Disable(); #endif progressive_scan_checkbox->Disable(); render_to_main_checkbox->Disable(); } ev.Skip(); } // Creates controls and connects their enter/leave window events to Evt_Enter/LeaveControl SettingCheckBox* CreateCheckBox(wxWindow* parent, const wxString& label, const wxString& description, bool& setting, bool reverse = false, long style = 0); SettingChoice* CreateChoice(wxWindow* parent, int& setting, const wxString& description, int num = 0, const wxString choices[] = nullptr, long style = 0); SettingRadioButton* CreateRadioButton(wxWindow* parent, const wxString& label, const wxString& description, bool& setting, bool reverse = false, long style = 0); // Same as above but only connects enter/leave window events wxControl* RegisterControl(wxControl* const control, const wxString& description); void Evt_EnterControl(wxMouseEvent& ev); void Evt_LeaveControl(wxMouseEvent& ev); void CreateDescriptionArea(wxPanel* const page, wxBoxSizer* const sizer); void PopulatePostProcessingShaders(); void PopulateAAList(); void OnAAChanged(wxCommandEvent& ev); wxChoice* choice_backend; wxChoice* choice_adapter; wxChoice* choice_display_resolution; wxStaticText* label_backend; wxStaticText* label_adapter; wxStaticText* text_aamode; wxChoice* choice_aamode; DolphinSlider* conv_slider; wxStaticText* label_display_resolution; wxButton* button_config_pp; SettingCheckBox* borderless_fullscreen; SettingCheckBox* render_to_main_checkbox; SettingRadioButton* virtual_xfb; SettingRadioButton* real_xfb; SettingCheckBox* cache_hires_textures; wxCheckBox* progressive_scan_checkbox; wxChoice* choice_ppshader; std::map ctrl_descs; // maps setting controls to their descriptions std::map desc_texts; // maps dialog tabs (which are the parents of the // setting controls) to their description text // objects VideoConfig& vconfig; size_t m_msaa_modes; };