From 20ad9a13b884a7e3c443cd1bca580cadb3a1d584 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sat, 30 Sep 2017 03:31:31 +0200 Subject: [PATCH] Qt: add high resolution settings to gui tab --- rpcs3/Json/tooltips.json | 11 +- rpcs3/rpcs3qt/emu_settings.cpp | 48 ++++- rpcs3/rpcs3qt/emu_settings.h | 114 ++++++----- rpcs3/rpcs3qt/settings_dialog.cpp | 81 ++++++++ rpcs3/rpcs3qt/settings_dialog.ui | 311 ++++++++++++++++++++++++------ 5 files changed, 450 insertions(+), 115 deletions(-) diff --git a/rpcs3/Json/tooltips.json b/rpcs3/Json/tooltips.json index ba24ad7998..ce008ac2f9 100644 --- a/rpcs3/Json/tooltips.json +++ b/rpcs3/Json/tooltips.json @@ -66,10 +66,15 @@ "gpu": { "comboboxes": { "renderBox": "Vulkan is the fastest renderer. OpenGL is the most accurate renderer.\nIf unsure, use Vulkan. Should you have any compatibility issues, fall back to OpenGL.\nDirectX 12 is deprecated and should never be used.", - "resBox": "Leave this on 1280x720; every PS3 game is compatible with this resolution.\nSet it to 1920x1080 only if supported by the game. Lower resolutions may work but are not practical.\nHowever, due to emulation bugs, some games will only render at low resolutions like 480p.", + "resBox": "This setting will be ignored if the Resolution Scale is set to anything other than 100%!\nLeave this on 1280x720, every PS3 game is compatible with this resolution.\nSet it to 1920x1080 only if supported by the game. Lower resolutions may work but are not practical.\nHowever rarely due to emulation bugs some games will only render at low resolutions like 480p.", "graphicsAdapterBox": "On multi GPU systems select which GPU to use in RPCS3 when using Vulkan or DirectX 12.\nThis is not needed when using OpenGL.", - "aspectBox": "Leave this on 16:9 unless you have a 4:3 monitor.\nAuto also works well, especially if you use a resolution that is not 720p.", - "frameLimitBox": "Off is the best option as it performs faster.\nUsing the frame limiter will add extra overhead and slow down the game.\nHowever, some games will crash if the framerate is too high.\nIf that happens, set value to anything other than Off." + "aspectBox": "Leave this on 16:9 unless you have a 4:3 monitor.\nAuto also works well especially if you use a resolution that is not 720p.", + "frameLimitBox": "Off is the best option as it performs faster.\nUsing the frame limiter will add extra overhead and slow down the game.\nHowever, some games will crash if the framerate is too high.\nIf that happens, set value to anything other than Off.", + "anisotropicFilterOverride": "Higher values increase sharpness of textures on sloped surfaces at the cost of GPU resources.\nModern GPUs can handle this setting just fine even at 16x.\nKeep this on Automatic if you want to use the original setting used by a real PS3." + }, + "sliders": { + "resolutionScale": "Scales the game's resolution by the given percentage.\nThe base resolution is always 1280x720.\nSet this value to 100% if you want to use the normal Resolution options.", + "minimumScalableDimension": "Only framebuffers greater than this size will be upscaled.\nIncreasing this value might fix problems with missing graphics when upscaling, especially when Write Color Buffers is enabled.\nDo not touch this setting if you are unsure." }, "main": { "dumpColor": "Enable this option if you get missing graphics or broken lighting ingame.\nMight degrade performance and introduce stuttering in some cases.\nRequired for Demon's Souls.", diff --git a/rpcs3/rpcs3qt/emu_settings.cpp b/rpcs3/rpcs3qt/emu_settings.cpp index db5f374416..36a1533cba 100644 --- a/rpcs3/rpcs3qt/emu_settings.cpp +++ b/rpcs3/rpcs3qt/emu_settings.cpp @@ -191,6 +191,7 @@ void emu_settings::LoadSettings(const std::string& path) fs::create_path(fs::get_config_dir() + path); // Load default config + m_defaultSettings = YAML::Load(g_cfg_defaults); m_currentSettings = YAML::Load(g_cfg_defaults); // Add global config @@ -259,9 +260,6 @@ void emu_settings::EnhanceComboBox(QComboBox* combobox, SettingsType type, bool void emu_settings::EnhanceCheckBox(QCheckBox* checkbox, SettingsType type) { - cfg_location loc = SettingsLoc[type]; - std::string name = loc[loc.size() - 1]; - std::string currSet = GetSetting(type); if (currSet == "true") { @@ -279,6 +277,39 @@ void emu_settings::EnhanceCheckBox(QCheckBox* checkbox, SettingsType type) }); } +void emu_settings::EnhanceSlider(QSlider* slider, SettingsType type, bool is_ranged) +{ + QString selected = qstr(GetSetting(type)); + + if (is_ranged) + { + QStringList range = GetSettingOptions(type); + int min = range.first().toInt(); + int max = range.last().toInt(); + int val = selected.toInt(); + + if (val < min || val > max) + { + LOG_ERROR(GENERAL, "Passed in an invalid setting for creating enhanced slider"); + val = min; + } + + slider->setMinimum(min); + slider->setMaximum(max); + slider->setValue(val); + } + else + { + //TODO ? + LOG_ERROR(GENERAL, "TODO: implement unranged enhanced slider"); + } + + connect(slider, &QSlider::valueChanged, [=](int value) + { + SetSetting(type, sstr(slider->value())); + }); +} + std::vector emu_settings::GetLoadedLibraries() { return m_currentSettings["Core"]["Load libraries"].as, std::initializer_list>({}); @@ -294,6 +325,17 @@ QStringList emu_settings::GetSettingOptions(SettingsType type) const return getOptions(const_cast(SettingsLoc[type])); } +std::string emu_settings::GetSettingName(SettingsType type) const +{ + cfg_location loc = SettingsLoc[type]; + return loc[loc.size() - 1]; +} + +std::string emu_settings::GetSettingDefault(SettingsType type) const +{ + return cfg_adapter::get_node(m_defaultSettings, SettingsLoc[type]).Scalar(); +} + std::string emu_settings::GetSetting(SettingsType type) const { return cfg_adapter::get_node(m_currentSettings, SettingsLoc[type]).Scalar(); diff --git a/rpcs3/rpcs3qt/emu_settings.h b/rpcs3/rpcs3qt/emu_settings.h index b54f320225..0fb93507cb 100644 --- a/rpcs3/rpcs3qt/emu_settings.h +++ b/rpcs3/rpcs3qt/emu_settings.h @@ -60,6 +60,9 @@ public: StrictRenderingMode, DisableVertexCache, DisableOcclusionQueries, + AnisotropicFilterOverride, + ResolutionScale, + MinimumScalableDimension, // Audio AudioRenderer, @@ -142,12 +145,21 @@ public: /** Connects a check box with the target settings type*/ void EnhanceCheckBox(QCheckBox* checkbox, SettingsType type); + /** Connects a slider with the target settings type*/ + void EnhanceSlider(QSlider* slider, SettingsType type, bool is_ranged = false); + std::vector GetLoadedLibraries(); void SaveSelectedLibraries(const std::vector& libs); /** Returns the valid options for a given setting.*/ QStringList GetSettingOptions(SettingsType type) const; + /** Returns the string for a given setting.*/ + std::string GetSettingName(SettingsType type) const; + + /** Returns the default value of the setting type.*/ + std::string GetSettingDefault(SettingsType type) const; + /** Returns the value of the setting type.*/ std::string GetSetting(SettingsType type) const; @@ -168,76 +180,80 @@ private: const QMap SettingsLoc = { // Core Tab - { PPUDecoder, { "Core", "PPU Decoder"}}, - { SPUDecoder, { "Core", "SPU Decoder"}}, - { LibLoadOptions, { "Core", "Lib Loader"}}, - { HookStaticFuncs, { "Core", "Hook static functions"}}, - { BindSPUThreads, { "Core", "Bind SPU threads to secondary cores"}}, - { LowerSPUThreadPrio, { "Core", "Lower SPU thread priority"}}, - { SPULoopDetection, { "Core", "SPU loop detection"}}, + { PPUDecoder, { "Core", "PPU Decoder"}}, + { SPUDecoder, { "Core", "SPU Decoder"}}, + { LibLoadOptions, { "Core", "Lib Loader"}}, + { HookStaticFuncs, { "Core", "Hook static functions"}}, + { BindSPUThreads, { "Core", "Bind SPU threads to secondary cores"}}, + { LowerSPUThreadPrio, { "Core", "Lower SPU thread priority"}}, + { SPULoopDetection, { "Core", "SPU loop detection"}}, { PreferredSPUThreads, { "Core", "Preferred SPU Threads"}}, { PPUDebug, { "Core", "PPU Debug"}}, { SPUDebug, { "Core", "SPU Debug"}}, // Graphics Tab - { Renderer, { "Video", "Renderer"}}, - { Resolution, { "Video", "Resolution"}}, - { AspectRatio, { "Video", "Aspect ratio"}}, - { FrameLimit, { "Video", "Frame limit"}}, - { LogShaderPrograms,{ "Video", "Log shader programs"}}, - { WriteDepthBuffer, { "Video", "Write Depth Buffer"}}, - { WriteColorBuffers,{ "Video", "Write Color Buffers"}}, - { ReadColorBuffers, { "Video", "Read Color Buffers"}}, - { ReadDepthBuffer, { "Video", "Read Depth Buffer"}}, - { VSync, { "Video", "VSync"}}, - { DebugOutput, { "Video", "Debug output"}}, - { DebugOverlay, { "Video", "Debug overlay"}}, - { LegacyBuffers, { "Video", "Use Legacy OpenGL Buffers"}}, - { GPUTextureScaling,{ "Video", "Use GPU texture scaling"}}, - { StretchToDisplayArea, { "Video", "Stretch To Display Area"}}, - { ForceHighpZ, { "Video", "Force High Precision Z buffer"}}, - { AutoInvalidateCache, { "Video", "Invalidate Cache Every Frame"}}, - { StrictRenderingMode, { "Video", "Strict Rendering Mode"}}, - { DisableVertexCache, { "Video", "Disable Vertex Cache"}}, - { DisableOcclusionQueries,{ "Video", "Disable ZCull Occlusion Queries" }}, - { D3D12Adapter, { "Video", "D3D12", "Adapter"}}, - { VulkanAdapter, { "Video", "Vulkan", "Adapter"}}, + { Renderer, { "Video", "Renderer"}}, + { Resolution, { "Video", "Resolution"}}, + { AspectRatio, { "Video", "Aspect ratio"}}, + { FrameLimit, { "Video", "Frame limit"}}, + { LogShaderPrograms, { "Video", "Log shader programs"}}, + { WriteDepthBuffer, { "Video", "Write Depth Buffer"}}, + { WriteColorBuffers, { "Video", "Write Color Buffers"}}, + { ReadColorBuffers, { "Video", "Read Color Buffers"}}, + { ReadDepthBuffer, { "Video", "Read Depth Buffer"}}, + { VSync, { "Video", "VSync"}}, + { DebugOutput, { "Video", "Debug output"}}, + { DebugOverlay, { "Video", "Debug overlay"}}, + { LegacyBuffers, { "Video", "Use Legacy OpenGL Buffers"}}, + { GPUTextureScaling, { "Video", "Use GPU texture scaling"}}, + { StretchToDisplayArea, { "Video", "Stretch To Display Area"}}, + { ForceHighpZ, { "Video", "Force High Precision Z buffer"}}, + { AutoInvalidateCache, { "Video", "Invalidate Cache Every Frame"}}, + { StrictRenderingMode, { "Video", "Strict Rendering Mode"}}, + { DisableVertexCache, { "Video", "Disable Vertex Cache"}}, + { DisableOcclusionQueries, { "Video", "Disable ZCull Occlusion Queries" }}, + { AnisotropicFilterOverride,{ "Video", "Anisotropic Filter Override" }}, + { ResolutionScale, { "Video", "Resolution Scale" }}, + { MinimumScalableDimension, { "Video", "Minimum Scalable Dimension" }}, + { D3D12Adapter, { "Video", "D3D12", "Adapter"}}, + { VulkanAdapter, { "Video", "Vulkan", "Adapter"}}, // Audio - { AudioRenderer, { "Audio", "Renderer"}}, - { DumpToFile, { "Audio", "Dump to file"}}, - { ConvertTo16Bit, { "Audio", "Convert to 16 bit"}}, - { DownmixStereo, { "Audio", "Downmix to Stereo"}}, + { AudioRenderer, { "Audio", "Renderer"}}, + { DumpToFile, { "Audio", "Dump to file"}}, + { ConvertTo16Bit, { "Audio", "Convert to 16 bit"}}, + { DownmixStereo, { "Audio", "Downmix to Stereo"}}, // Input / Output - { PadHandler, { "Input/Output", "Pad"}}, - { KeyboardHandler, { "Input/Output", "Keyboard"}}, - { MouseHandler, { "Input/Output", "Mouse"}}, - { Camera, { "Input/Output", "Camera"}}, - { CameraType, { "Input/Output", "Camera type"}}, + { PadHandler, { "Input/Output", "Pad"}}, + { KeyboardHandler, { "Input/Output", "Keyboard"}}, + { MouseHandler, { "Input/Output", "Mouse"}}, + { Camera, { "Input/Output", "Camera"}}, + { CameraType, { "Input/Output", "Camera type"}}, // Misc - {ExitRPCS3OnFinish, { "Miscellaneous", "Exit RPCS3 when process finishes" }}, - {StartOnBoot, { "Miscellaneous", "Automatically start games after boot" }}, + {ExitRPCS3OnFinish, { "Miscellaneous", "Exit RPCS3 when process finishes" }}, + {StartOnBoot, { "Miscellaneous", "Automatically start games after boot" }}, {StartGameFullscreen, { "Miscellaneous", "Start games in fullscreen mode"}}, - {ShowFPSInTitle, { "Miscellaneous", "Show FPS counter in window title"}}, - {ShowWelcomeScreen, { "Miscellaneous", "Show Welcome Screen"}}, + {ShowFPSInTitle, { "Miscellaneous", "Show FPS counter in window title"}}, + {ShowWelcomeScreen, { "Miscellaneous", "Show Welcome Screen"}}, // Networking - {ConnectionStatus, { "Net", "Connection status"}}, + {ConnectionStatus, { "Net", "Connection status"}}, // System - {Language, { "System", "Language"}}, - {EnableHostRoot, { "VFS", "Enable /host_root/"}}, + {Language, { "System", "Language"}}, + {EnableHostRoot, { "VFS", "Enable /host_root/"}}, // Virtual File System - { emulatorLocation, { "VFS", "$(EmulatorDir)"}}, - { dev_hdd0Location, { "VFS", "/dev_hdd0/" }}, - { dev_hdd1Location, { "VFS", "/dev_hdd1/" }}, - { dev_flashLocation, { "VFS", "/dev_flash/"}}, + { emulatorLocation, { "VFS", "$(EmulatorDir)"}}, + { dev_hdd0Location, { "VFS", "/dev_hdd0/" }}, + { dev_hdd1Location, { "VFS", "/dev_hdd1/" }}, + { dev_flashLocation, { "VFS", "/dev_flash/"}}, { dev_usb000Location, { "VFS", "/dev_usb000/"}}, }; + YAML::Node m_defaultSettings; // The default settings as a YAML node. YAML::Node m_currentSettings; // The current settings as a YAML node. fs::file m_config; //! File to read/write the config settings. std::string m_path; diff --git a/rpcs3/rpcs3qt/settings_dialog.cpp b/rpcs3/rpcs3qt/settings_dialog.cpp index 6297df4fd1..fcdbdcbd8d 100644 --- a/rpcs3/rpcs3qt/settings_dialog.cpp +++ b/rpcs3/rpcs3qt/settings_dialog.cpp @@ -57,6 +57,7 @@ settings_dialog::settings_dialog(std::shared_ptr guiSettings, std: QJsonObject json_gpu_cbo = json_gpu.value("comboboxes").toObject(); QJsonObject json_gpu_main = json_gpu.value("main").toObject(); QJsonObject json_gpu_deb = json_gpu.value("debug").toObject(); + QJsonObject json_gpu_slid = json_gpu.value("sliders").toObject(); QJsonObject json_audio = json_obj.value("audio").toObject(); QJsonObject json_input = json_obj.value("input").toObject(); @@ -365,6 +366,7 @@ settings_dialog::settings_dialog(std::shared_ptr guiSettings, std: xemu_settings->EnhanceComboBox(ui->resBox, emu_settings::Resolution); ui->resBox->setToolTip(json_gpu_cbo["resBox"].toString()); + ui->resBox->setItemText(ui->resBox->findData("1280x720"), "1280x720 (Recommended)"); xemu_settings->EnhanceComboBox(ui->aspectBox, emu_settings::AspectRatio); ui->aspectBox->setToolTip(json_gpu_cbo["aspectBox"].toString()); @@ -372,6 +374,31 @@ settings_dialog::settings_dialog(std::shared_ptr guiSettings, std: xemu_settings->EnhanceComboBox(ui->frameLimitBox, emu_settings::FrameLimit); ui->frameLimitBox->setToolTip(json_gpu_cbo["frameLimitBox"].toString()); + xemu_settings->EnhanceComboBox(ui->anisotropicFilterOverride, emu_settings::AnisotropicFilterOverride, true); + ui->anisotropicFilterOverride->setToolTip(json_gpu_cbo["anisotropicFilterOverride"].toString()); + // only allow values 0,2,4,8,16 + for (int i = ui->anisotropicFilterOverride->count() - 1; i >= 0; i--) + { + switch (int val = ui->anisotropicFilterOverride->itemData(i).toInt()) + { + case 0: + ui->anisotropicFilterOverride->setItemText(i, tr("Automatic")); + break; + case 1: + ui->anisotropicFilterOverride->setItemText(i, tr("Disabled")); + break; + case 2: + case 4: + case 8: + case 16: + ui->anisotropicFilterOverride->setItemText(i, tr("%1x").arg(val)); + break; + default: + ui->anisotropicFilterOverride->removeItem(i); + break; + } + } + // Checkboxes: main options xemu_settings->EnhanceCheckBox(ui->dumpColor, emu_settings::WriteColorBuffers); ui->dumpColor->setToolTip(json_gpu_main["dumpColor"].toString()); @@ -391,6 +418,60 @@ settings_dialog::settings_dialog(std::shared_ptr guiSettings, std: xemu_settings->EnhanceCheckBox(ui->scrictModeRendering, emu_settings::StrictRenderingMode); ui->scrictModeRendering->setToolTip(json_gpu_main["scrictModeRendering"].toString()); + // Sliders + static const auto& minmaxLabelWidth = [](const QString& sizer) + { + return QLabel(sizer).sizeHint().width(); + }; + + xemu_settings->EnhanceSlider(ui->resolutionScale, emu_settings::ResolutionScale, true); + ui->gb_resolutionScale->setToolTip(json_gpu_slid["resolutionScale"].toString()); + // rename label texts to fit current state of Resolution Scale + int resolutionScaleDef = stoi(xemu_settings->GetSettingDefault(emu_settings::ResolutionScale)); + auto ScaledResolution = [resolutionScaleDef](int percentage) + { + if (percentage == resolutionScaleDef) return QString("100% (Automatic)"); + return QString("%1% (%2x%3)").arg(percentage).arg(1280 * percentage / 100).arg(720 * percentage / 100); + }; + ui->resolutionScale->setPageStep(50); + ui->resolutionScaleMin->setText(QString::number(ui->resolutionScale->minimum())); + ui->resolutionScaleMin->setFixedWidth(minmaxLabelWidth("00")); + ui->resolutionScaleMax->setText(QString::number(ui->resolutionScale->maximum())); + ui->resolutionScaleMax->setFixedWidth(minmaxLabelWidth("0000")); + ui->resolutionScaleVal->setText(ScaledResolution(ui->resolutionScale->value())); + connect(ui->resolutionScale, &QSlider::valueChanged, [=](int value) + { + ui->resolutionScaleVal->setText(ScaledResolution(value)); + }); + connect(ui->resolutionScaleReset, &QAbstractButton::clicked, [=]() + { + ui->resolutionScale->setValue(resolutionScaleDef); + }); + + xemu_settings->EnhanceSlider(ui->minimumScalableDimension, emu_settings::MinimumScalableDimension, true); + ui->gb_minimumScalableDimension->setToolTip(json_gpu_slid["minimumScalableDimension"].toString()); + // rename label texts to fit current state of Minimum Scalable Dimension + int minimumScalableDimensionDef = stoi(xemu_settings->GetSettingDefault(emu_settings::MinimumScalableDimension)); + auto MinScalableDimension = [minimumScalableDimensionDef](int dim) + { + if (dim == minimumScalableDimensionDef) return QString("%1x%1 (Default)").arg(dim); + return QString("%1x%1").arg(dim); + }; + ui->minimumScalableDimension->setPageStep(64); + ui->minimumScalableDimensionMin->setText(QString::number(ui->minimumScalableDimension->minimum())); + ui->minimumScalableDimensionMin->setFixedWidth(minmaxLabelWidth("00")); + ui->minimumScalableDimensionMax->setText(QString::number(ui->minimumScalableDimension->maximum())); + ui->minimumScalableDimensionMax->setFixedWidth(minmaxLabelWidth("0000")); + ui->minimumScalableDimensionVal->setText(MinScalableDimension(ui->minimumScalableDimension->value())); + connect(ui->minimumScalableDimension, &QSlider::valueChanged, [=](int value) + { + ui->minimumScalableDimensionVal->setText(MinScalableDimension(value)); + }); + connect(ui->minimumScalableDimensionReset, &QAbstractButton::clicked, [=]() + { + ui->minimumScalableDimension->setValue(minimumScalableDimensionDef); + }); + // Remove renderers from the renderer Combobox if not supported for (const auto& renderer : render_creator.renderers) { diff --git a/rpcs3/rpcs3qt/settings_dialog.ui b/rpcs3/rpcs3qt/settings_dialog.ui index 4f8f6db38e..1e0e7101b0 100644 --- a/rpcs3/rpcs3qt/settings_dialog.ui +++ b/rpcs3/rpcs3qt/settings_dialog.ui @@ -36,7 +36,7 @@ - 0 + 7 @@ -340,7 +340,7 @@ - + @@ -354,58 +354,7 @@ - - - Resolution - - - - - - - - - - - - - - - - Graphics Device - - - - - - - - - - - - false - - - Enhancements - - - - - - Advanced Settings - - - - - - - - - - - - + @@ -432,23 +381,122 @@ + + + + - + + + Graphics Device + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Anisotropic Filter + + + + + + + + + + + + false + + + Anti-Aliasing + + + + + + + + + + - - + + + + + false + + + Enhancements + + + + + + Advanced Settings + + + + + + + + + + Resolution + + + + + + + + + + + + + + + + 0 + 0 + + Additional Settings - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - + Write Color Buffers @@ -494,7 +542,150 @@ - + + + 6 + + + 0 + + + + + Resolution Scale + + + + + + + + 0 + + + Qt::AlignCenter + + + + + + + Reset + + + + + + + + + + 12 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 50 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + + + + 800 + + + + + + + + + + + + + Resolution Scale Threshold + + + + + + + + 1x1 + + + Qt::AlignCenter + + + + + + + Reset + + + + + + + + + 12 + + + + + 1 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + + + + 1024 + + + + + + + + +