Qt: Redesign graphics settings panel

Add screenshot format/type.
This commit is contained in:
Stenzek 2024-03-02 19:08:38 +10:00
parent b8127facdc
commit 04b837a418
No known key found for this signature in database
38 changed files with 2467 additions and 1572 deletions

View File

@ -2484,7 +2484,7 @@ void FullscreenUI::DrawSettingsWindow()
static constexpr std::array<const char*, static_cast<u32>(SettingsPage::Count)> titles = { static constexpr std::array<const char*, static_cast<u32>(SettingsPage::Count)> titles = {
{FSUI_NSTR("Summary"), FSUI_NSTR("Interface Settings"), FSUI_NSTR("Console Settings"), {FSUI_NSTR("Summary"), FSUI_NSTR("Interface Settings"), FSUI_NSTR("Console Settings"),
FSUI_NSTR("Emulation Settings"), FSUI_NSTR("BIOS Settings"), FSUI_NSTR("Controller Settings"), FSUI_NSTR("Emulation Settings"), FSUI_NSTR("BIOS Settings"), FSUI_NSTR("Controller Settings"),
FSUI_NSTR("Hotkey Settings"), FSUI_NSTR("Memory Card Settings"), FSUI_NSTR("Display Settings"), FSUI_NSTR("Hotkey Settings"), FSUI_NSTR("Memory Card Settings"), FSUI_NSTR("Graphics Settings"),
FSUI_NSTR("Post-Processing Settings"), FSUI_NSTR("Audio Settings"), FSUI_NSTR("Achievements Settings"), FSUI_NSTR("Post-Processing Settings"), FSUI_NSTR("Audio Settings"), FSUI_NSTR("Achievements Settings"),
FSUI_NSTR("Advanced Settings")}}; FSUI_NSTR("Advanced Settings")}};
@ -3898,7 +3898,7 @@ void FullscreenUI::DrawDisplaySettingsPage()
MenuHeading(FSUI_CSTR("Rendering")); MenuHeading(FSUI_CSTR("Rendering"));
DrawIntListSetting( DrawIntListSetting(
bsi, FSUI_CSTR("Internal Resolution Scale"), bsi, FSUI_CSTR("Internal Resolution"),
FSUI_CSTR("Scales internal VRAM resolution by the specified multiplier. Some games require 1x VRAM resolution."), FSUI_CSTR("Scales internal VRAM resolution by the specified multiplier. Some games require 1x VRAM resolution."),
"GPU", "ResolutionScale", 1, resolution_scales.data(), resolution_scales.size(), true, 0, is_hardware); "GPU", "ResolutionScale", 1, resolution_scales.data(), resolution_scales.size(), true, 0, is_hardware);
@ -3975,9 +3975,19 @@ void FullscreenUI::DrawDisplaySettingsPage()
"Display", "Scaling", Settings::DEFAULT_DISPLAY_SCALING, &Settings::ParseDisplayScaling, "Display", "Scaling", Settings::DEFAULT_DISPLAY_SCALING, &Settings::ParseDisplayScaling,
&Settings::GetDisplayScalingName, &Settings::GetDisplayScalingDisplayName, DisplayScalingMode::Count); &Settings::GetDisplayScalingName, &Settings::GetDisplayScalingDisplayName, DisplayScalingMode::Count);
DrawToggleSetting(bsi, FSUI_CSTR("Internal Resolution Screenshots"), DrawEnumSetting(bsi, FSUI_CSTR("Screenshot Size"),
FSUI_CSTR("Saves screenshots at internal render resolution and without postprocessing."), "Display", FSUI_CSTR("Determines the size of screenshots created by DuckStation."), "Display", "ScreenshotMode",
"InternalResolutionScreenshots", false); Settings::DEFAULT_DISPLAY_SCREENSHOT_MODE, &Settings::ParseDisplayScreenshotMode,
&Settings::GetDisplayScreenshotModeName, &Settings::GetDisplayScreenshotModeDisplayName,
DisplayScreenshotMode::Count);
DrawEnumSetting(bsi, FSUI_CSTR("Screenshot Format"),
FSUI_CSTR("Determines the format that screenshots will be saved/compressed with."), "Display",
"ScreenshotFormat", Settings::DEFAULT_DISPLAY_SCREENSHOT_FORMAT,
&Settings::ParseDisplayScreenshotFormat, &Settings::GetDisplayScreenshotFormatName,
&Settings::GetDisplayScreenshotFormatDisplayName, DisplayScreenshotFormat::Count);
DrawIntRangeSetting(bsi, FSUI_CSTR("Screenshot Quality"),
FSUI_CSTR("Selects the quality at which screenshots will be compressed."), "Display",
"ScreenshotQuality", Settings::DEFAULT_DISPLAY_SCREENSHOT_QUALITY, 1, 100, "%d%%");
MenuHeading(FSUI_CSTR("Enhancements")); MenuHeading(FSUI_CSTR("Enhancements"));
DrawToggleSetting( DrawToggleSetting(
@ -6651,7 +6661,9 @@ TRANSLATE_NOOP("FullscreenUI", "Determines quality of audio when not running at
TRANSLATE_NOOP("FullscreenUI", "Determines that field that the game list will be sorted by."); TRANSLATE_NOOP("FullscreenUI", "Determines that field that the game list will be sorted by.");
TRANSLATE_NOOP("FullscreenUI", "Determines the amount of audio buffered before being pulled by the host API."); TRANSLATE_NOOP("FullscreenUI", "Determines the amount of audio buffered before being pulled by the host API.");
TRANSLATE_NOOP("FullscreenUI", "Determines the emulated hardware type."); TRANSLATE_NOOP("FullscreenUI", "Determines the emulated hardware type.");
TRANSLATE_NOOP("FullscreenUI", "Determines the format that screenshots will be saved/compressed with.");
TRANSLATE_NOOP("FullscreenUI", "Determines the position on the screen when black borders must be added."); TRANSLATE_NOOP("FullscreenUI", "Determines the position on the screen when black borders must be added.");
TRANSLATE_NOOP("FullscreenUI", "Determines the size of screenshots created by DuckStation.");
TRANSLATE_NOOP("FullscreenUI", "Determines whether a prompt will be displayed to confirm shutting down the emulator/game when the hotkey is pressed."); TRANSLATE_NOOP("FullscreenUI", "Determines whether a prompt will be displayed to confirm shutting down the emulator/game when the hotkey is pressed.");
TRANSLATE_NOOP("FullscreenUI", "Device Settings"); TRANSLATE_NOOP("FullscreenUI", "Device Settings");
TRANSLATE_NOOP("FullscreenUI", "Disable All Enhancements"); TRANSLATE_NOOP("FullscreenUI", "Disable All Enhancements");
@ -6754,6 +6766,7 @@ TRANSLATE_NOOP("FullscreenUI", "Genre: %s");
TRANSLATE_NOOP("FullscreenUI", "GitHub Repository"); TRANSLATE_NOOP("FullscreenUI", "GitHub Repository");
TRANSLATE_NOOP("FullscreenUI", "Global Slot {0} - {1}##global_slot_{0}"); TRANSLATE_NOOP("FullscreenUI", "Global Slot {0} - {1}##global_slot_{0}");
TRANSLATE_NOOP("FullscreenUI", "Global Slot {0}##global_slot_{0}"); TRANSLATE_NOOP("FullscreenUI", "Global Slot {0}##global_slot_{0}");
TRANSLATE_NOOP("FullscreenUI", "Graphics Settings");
TRANSLATE_NOOP("FullscreenUI", "Hardcore Mode"); TRANSLATE_NOOP("FullscreenUI", "Hardcore Mode");
TRANSLATE_NOOP("FullscreenUI", "Hardcore mode will be enabled on next game restart."); TRANSLATE_NOOP("FullscreenUI", "Hardcore mode will be enabled on next game restart.");
TRANSLATE_NOOP("FullscreenUI", "Hide Cursor In Fullscreen"); TRANSLATE_NOOP("FullscreenUI", "Hide Cursor In Fullscreen");
@ -6773,8 +6786,7 @@ TRANSLATE_NOOP("FullscreenUI", "Input profile '{}' loaded.");
TRANSLATE_NOOP("FullscreenUI", "Input profile '{}' saved."); TRANSLATE_NOOP("FullscreenUI", "Input profile '{}' saved.");
TRANSLATE_NOOP("FullscreenUI", "Integration"); TRANSLATE_NOOP("FullscreenUI", "Integration");
TRANSLATE_NOOP("FullscreenUI", "Interface Settings"); TRANSLATE_NOOP("FullscreenUI", "Interface Settings");
TRANSLATE_NOOP("FullscreenUI", "Internal Resolution Scale"); TRANSLATE_NOOP("FullscreenUI", "Internal Resolution");
TRANSLATE_NOOP("FullscreenUI", "Internal Resolution Screenshots");
TRANSLATE_NOOP("FullscreenUI", "Issue Tracker"); TRANSLATE_NOOP("FullscreenUI", "Issue Tracker");
TRANSLATE_NOOP("FullscreenUI", "Last Played"); TRANSLATE_NOOP("FullscreenUI", "Last Played");
TRANSLATE_NOOP("FullscreenUI", "Last Played: %s"); TRANSLATE_NOOP("FullscreenUI", "Last Played: %s");
@ -6926,7 +6938,6 @@ TRANSLATE_NOOP("FullscreenUI", "Save Screenshot");
TRANSLATE_NOOP("FullscreenUI", "Save State"); TRANSLATE_NOOP("FullscreenUI", "Save State");
TRANSLATE_NOOP("FullscreenUI", "Save State On Exit"); TRANSLATE_NOOP("FullscreenUI", "Save State On Exit");
TRANSLATE_NOOP("FullscreenUI", "Saved {:%c}"); TRANSLATE_NOOP("FullscreenUI", "Saved {:%c}");
TRANSLATE_NOOP("FullscreenUI", "Saves screenshots at internal render resolution and without postprocessing.");
TRANSLATE_NOOP("FullscreenUI", "Saves state periodically so you can rewind any mistakes while playing."); TRANSLATE_NOOP("FullscreenUI", "Saves state periodically so you can rewind any mistakes while playing.");
TRANSLATE_NOOP("FullscreenUI", "Scaled Dithering"); TRANSLATE_NOOP("FullscreenUI", "Scaled Dithering");
TRANSLATE_NOOP("FullscreenUI", "Scales internal VRAM resolution by the specified multiplier. Some games require 1x VRAM resolution."); TRANSLATE_NOOP("FullscreenUI", "Scales internal VRAM resolution by the specified multiplier. Some games require 1x VRAM resolution.");
@ -6935,6 +6946,9 @@ TRANSLATE_NOOP("FullscreenUI", "Scaling");
TRANSLATE_NOOP("FullscreenUI", "Scan For New Games"); TRANSLATE_NOOP("FullscreenUI", "Scan For New Games");
TRANSLATE_NOOP("FullscreenUI", "Scanning Subdirectories"); TRANSLATE_NOOP("FullscreenUI", "Scanning Subdirectories");
TRANSLATE_NOOP("FullscreenUI", "Screen Display"); TRANSLATE_NOOP("FullscreenUI", "Screen Display");
TRANSLATE_NOOP("FullscreenUI", "Screenshot Format");
TRANSLATE_NOOP("FullscreenUI", "Screenshot Quality");
TRANSLATE_NOOP("FullscreenUI", "Screenshot Size");
TRANSLATE_NOOP("FullscreenUI", "Search Directories"); TRANSLATE_NOOP("FullscreenUI", "Search Directories");
TRANSLATE_NOOP("FullscreenUI", "Seek Speedup"); TRANSLATE_NOOP("FullscreenUI", "Seek Speedup");
TRANSLATE_NOOP("FullscreenUI", "Select Device"); TRANSLATE_NOOP("FullscreenUI", "Select Device");
@ -6942,6 +6956,7 @@ TRANSLATE_NOOP("FullscreenUI", "Select Disc Image");
TRANSLATE_NOOP("FullscreenUI", "Select Macro {} Binds"); TRANSLATE_NOOP("FullscreenUI", "Select Macro {} Binds");
TRANSLATE_NOOP("FullscreenUI", "Selects the GPU to use for rendering."); TRANSLATE_NOOP("FullscreenUI", "Selects the GPU to use for rendering.");
TRANSLATE_NOOP("FullscreenUI", "Selects the percentage of the normal clock speed the emulated hardware will run at."); TRANSLATE_NOOP("FullscreenUI", "Selects the percentage of the normal clock speed the emulated hardware will run at.");
TRANSLATE_NOOP("FullscreenUI", "Selects the quality at which screenshots will be compressed.");
TRANSLATE_NOOP("FullscreenUI", "Selects the resolution scale that will be applied to the final image. 1x will downsample to the original console resolution."); TRANSLATE_NOOP("FullscreenUI", "Selects the resolution scale that will be applied to the final image. 1x will downsample to the original console resolution.");
TRANSLATE_NOOP("FullscreenUI", "Selects the resolution to use in fullscreen modes."); TRANSLATE_NOOP("FullscreenUI", "Selects the resolution to use in fullscreen modes.");
TRANSLATE_NOOP("FullscreenUI", "Selects the view that the game list will open to."); TRANSLATE_NOOP("FullscreenUI", "Selects the view that the game list will open to.");

View File

@ -1906,8 +1906,8 @@ Common::Rectangle<s32> GPU::CalculateDrawRect(s32 window_width, s32 window_heigh
} }
static bool CompressAndWriteTextureToFile(u32 width, u32 height, std::string filename, FileSystem::ManagedCFilePtr fp, static bool CompressAndWriteTextureToFile(u32 width, u32 height, std::string filename, FileSystem::ManagedCFilePtr fp,
bool clear_alpha, bool flip_y, u32 resize_width, u32 resize_height, u8 quality, bool clear_alpha, bool flip_y, u32 resize_width,
std::vector<u8> texture_data, u32 texture_data_stride, u32 resize_height, std::vector<u8> texture_data, u32 texture_data_stride,
GPUTexture::Format texture_format) GPUTexture::Format texture_format)
{ {
@ -1964,12 +1964,13 @@ static bool CompressAndWriteTextureToFile(u32 width, u32 height, std::string fil
bool result = false; bool result = false;
if (StringUtil::Strcasecmp(extension, ".png") == 0) if (StringUtil::Strcasecmp(extension, ".png") == 0)
{ {
// TODO: Use quality... libpng is better.
result = result =
(stbi_write_png_to_func(write_func, fp.get(), width, height, 4, texture_data.data(), texture_data_stride) != 0); (stbi_write_png_to_func(write_func, fp.get(), width, height, 4, texture_data.data(), texture_data_stride) != 0);
} }
else if (StringUtil::Strcasecmp(extension, ".jpg") == 0) else if (StringUtil::Strcasecmp(extension, ".jpg") == 0)
{ {
result = (stbi_write_jpg_to_func(write_func, fp.get(), width, height, 4, texture_data.data(), 95) != 0); result = (stbi_write_jpg_to_func(write_func, fp.get(), width, height, 4, texture_data.data(), quality) != 0);
} }
else if (StringUtil::Strcasecmp(extension, ".tga") == 0) else if (StringUtil::Strcasecmp(extension, ".tga") == 0)
{ {
@ -2072,14 +2073,16 @@ bool GPU::WriteDisplayTextureToFile(std::string filename, bool full_resolution /
if (!compress_on_thread) if (!compress_on_thread)
{ {
return CompressAndWriteTextureToFile(read_width, read_height, std::move(filename), std::move(fp), clear_alpha, return CompressAndWriteTextureToFile(read_width, read_height, std::move(filename), std::move(fp),
flip_y, resize_width, resize_height, std::move(texture_data), g_settings.display_screenshot_quality, clear_alpha, flip_y, resize_width,
texture_data_stride, m_display_texture->GetFormat()); resize_height, std::move(texture_data), texture_data_stride,
m_display_texture->GetFormat());
} }
std::thread compress_thread(CompressAndWriteTextureToFile, read_width, read_height, std::move(filename), std::thread compress_thread(CompressAndWriteTextureToFile, read_width, read_height, std::move(filename),
std::move(fp), clear_alpha, flip_y, resize_width, resize_height, std::move(texture_data), std::move(fp), g_settings.display_screenshot_quality, clear_alpha, flip_y, resize_width,
texture_data_stride, m_display_texture->GetFormat()); resize_height, std::move(texture_data), texture_data_stride,
m_display_texture->GetFormat());
compress_thread.detach(); compress_thread.detach();
return true; return true;
} }
@ -2131,53 +2134,61 @@ bool GPU::RenderScreenshotToBuffer(u32 width, u32 height, const Common::Rectangl
return true; return true;
} }
bool GPU::RenderScreenshotToFile(std::string filename, bool internal_resolution /* = false */, bool GPU::RenderScreenshotToFile(std::string filename, DisplayScreenshotMode mode, u8 quality, bool compress_on_thread)
bool compress_on_thread /* = false */)
{ {
u32 width = g_gpu_device->GetWindowWidth(); u32 width = g_gpu_device->GetWindowWidth();
u32 height = g_gpu_device->GetWindowHeight(); u32 height = g_gpu_device->GetWindowHeight();
Common::Rectangle<s32> draw_rect = CalculateDrawRect(width, height); Common::Rectangle<s32> draw_rect = CalculateDrawRect(width, height);
const bool internal_resolution = (mode != DisplayScreenshotMode::ScreenResolution);
if (internal_resolution && m_display_texture_view_width != 0 && m_display_texture_view_height != 0) if (internal_resolution && m_display_texture_view_width != 0 && m_display_texture_view_height != 0)
{ {
const u32 draw_width = static_cast<u32>(draw_rect.GetWidth()); if (mode == DisplayScreenshotMode::InternalResolution)
const u32 draw_height = static_cast<u32>(draw_rect.GetHeight()); {
const u32 draw_width = static_cast<u32>(draw_rect.GetWidth());
// If internal res, scale the computed draw rectangle to the internal res. const u32 draw_height = static_cast<u32>(draw_rect.GetHeight());
// We re-use the draw rect because it's already been AR corrected.
const float sar = // If internal res, scale the computed draw rectangle to the internal res.
static_cast<float>(m_display_texture_view_width) / static_cast<float>(m_display_texture_view_height); // We re-use the draw rect because it's already been AR corrected.
const float dar = static_cast<float>(draw_width) / static_cast<float>(draw_height); const float sar =
if (sar >= dar) static_cast<float>(m_display_texture_view_width) / static_cast<float>(m_display_texture_view_height);
const float dar = static_cast<float>(draw_width) / static_cast<float>(draw_height);
if (sar >= dar)
{
// stretch height, preserve width
const float scale = static_cast<float>(m_display_texture_view_width) / static_cast<float>(draw_width);
width = m_display_texture_view_width;
height = static_cast<u32>(std::round(static_cast<float>(draw_height) * scale));
}
else
{
// stretch width, preserve height
const float scale = static_cast<float>(m_display_texture_view_height) / static_cast<float>(draw_height);
width = static_cast<u32>(std::round(static_cast<float>(draw_width) * scale));
height = m_display_texture_view_height;
}
// DX11 won't go past 16K texture size.
const u32 max_texture_size = g_gpu_device->GetMaxTextureSize();
if (width > max_texture_size)
{
height = static_cast<u32>(static_cast<float>(height) /
(static_cast<float>(width) / static_cast<float>(max_texture_size)));
width = max_texture_size;
}
if (height > max_texture_size)
{
height = max_texture_size;
width = static_cast<u32>(static_cast<float>(width) /
(static_cast<float>(height) / static_cast<float>(max_texture_size)));
}
}
else // if (mode == DisplayScreenshotMode::UncorrectedInternalResolution)
{ {
// stretch height, preserve width
const float scale = static_cast<float>(m_display_texture_view_width) / static_cast<float>(draw_width);
width = m_display_texture_view_width; width = m_display_texture_view_width;
height = static_cast<u32>(std::round(static_cast<float>(draw_height) * scale));
}
else
{
// stretch width, preserve height
const float scale = static_cast<float>(m_display_texture_view_height) / static_cast<float>(draw_height);
width = static_cast<u32>(std::round(static_cast<float>(draw_width) * scale));
height = m_display_texture_view_height; height = m_display_texture_view_height;
} }
// DX11 won't go past 16K texture size.
constexpr u32 MAX_TEXTURE_SIZE = 16384;
if (width > MAX_TEXTURE_SIZE)
{
height = static_cast<u32>(static_cast<float>(height) /
(static_cast<float>(width) / static_cast<float>(MAX_TEXTURE_SIZE)));
width = MAX_TEXTURE_SIZE;
}
if (height > MAX_TEXTURE_SIZE)
{
height = MAX_TEXTURE_SIZE;
width = static_cast<u32>(static_cast<float>(width) /
(static_cast<float>(height) / static_cast<float>(MAX_TEXTURE_SIZE)));
}
// Remove padding, it's not part of the framebuffer. // Remove padding, it's not part of the framebuffer.
draw_rect.Set(0, 0, static_cast<s32>(width), static_cast<s32>(height)); draw_rect.Set(0, 0, static_cast<s32>(width), static_cast<s32>(height));
} }
@ -2203,14 +2214,14 @@ bool GPU::RenderScreenshotToFile(std::string filename, bool internal_resolution
if (!compress_on_thread) if (!compress_on_thread)
{ {
return CompressAndWriteTextureToFile(width, height, std::move(filename), std::move(fp), true, return CompressAndWriteTextureToFile(width, height, std::move(filename), std::move(fp), quality, true,
g_gpu_device->UsesLowerLeftOrigin(), width, height, std::move(pixels), g_gpu_device->UsesLowerLeftOrigin(), width, height, std::move(pixels),
pixels_stride, pixels_format); pixels_stride, pixels_format);
} }
std::thread compress_thread(CompressAndWriteTextureToFile, width, height, std::move(filename), std::move(fp), true, std::thread compress_thread(CompressAndWriteTextureToFile, width, height, std::move(filename), std::move(fp), quality,
g_gpu_device->UsesLowerLeftOrigin(), width, height, std::move(pixels), pixels_stride, true, g_gpu_device->UsesLowerLeftOrigin(), width, height, std::move(pixels),
pixels_format); pixels_stride, pixels_format);
compress_thread.detach(); compress_thread.detach();
return true; return true;
} }

View File

@ -209,7 +209,7 @@ public:
std::vector<u8>* out_pixels, u32* out_stride, GPUTexture::Format* out_format); std::vector<u8>* out_pixels, u32* out_stride, GPUTexture::Format* out_format);
/// Helper function to save screenshot to PNG. /// Helper function to save screenshot to PNG.
bool RenderScreenshotToFile(std::string filename, bool internal_resolution = false, bool compress_on_thread = false); bool RenderScreenshotToFile(std::string filename, DisplayScreenshotMode mode, u8 quality, bool compress_on_thread);
/// Draws the current display texture, with any post-processing. /// Draws the current display texture, with any post-processing.
bool PresentDisplay(); bool PresentDisplay();

View File

@ -180,6 +180,12 @@ bool Host::RemoveValueFromBaseStringListSetting(const char* section, const char*
->RemoveFromStringList(section, key, value); ->RemoveFromStringList(section, key, value);
} }
bool Host::ContainsBaseSettingValue(const char* section, const char* key)
{
std::unique_lock lock(s_settings_mutex);
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->ContainsValue(section, key);
}
void Host::DeleteBaseSettingValue(const char* section, const char* key) void Host::DeleteBaseSettingValue(const char* section, const char* key)
{ {
std::unique_lock lock(s_settings_mutex); std::unique_lock lock(s_settings_mutex);

View File

@ -47,6 +47,7 @@ void SetBaseStringSettingValue(const char* section, const char* key, const char*
void SetBaseStringListSettingValue(const char* section, const char* key, const std::vector<std::string>& values); void SetBaseStringListSettingValue(const char* section, const char* key, const std::vector<std::string>& values);
bool AddValueToBaseStringListSetting(const char* section, const char* key, const char* value); bool AddValueToBaseStringListSetting(const char* section, const char* key, const char* value);
bool RemoveValueFromBaseStringListSetting(const char* section, const char* key, const char* value); bool RemoveValueFromBaseStringListSetting(const char* section, const char* key, const char* value);
bool ContainsBaseSettingValue(const char* section, const char* key);
void DeleteBaseSettingValue(const char* section, const char* key); void DeleteBaseSettingValue(const char* section, const char* key);
void CommitBaseSettingChanges(); void CommitBaseSettingChanges();

View File

@ -249,6 +249,18 @@ void Settings::Load(SettingsInterface& si)
GetDisplayExclusiveFullscreenControlName(DEFAULT_DISPLAY_EXCLUSIVE_FULLSCREEN_CONTROL)) GetDisplayExclusiveFullscreenControlName(DEFAULT_DISPLAY_EXCLUSIVE_FULLSCREEN_CONTROL))
.c_str()) .c_str())
.value_or(DEFAULT_DISPLAY_EXCLUSIVE_FULLSCREEN_CONTROL); .value_or(DEFAULT_DISPLAY_EXCLUSIVE_FULLSCREEN_CONTROL);
display_screenshot_mode =
ParseDisplayScreenshotMode(
si.GetStringValue("Display", "ScreenshotMode", GetDisplayScreenshotModeName(DEFAULT_DISPLAY_SCREENSHOT_MODE))
.c_str())
.value_or(DEFAULT_DISPLAY_SCREENSHOT_MODE);
display_screenshot_format =
ParseDisplayScreenshotFormat(si.GetStringValue("Display", "ScreenshotFormat",
GetDisplayScreenshotFormatName(DEFAULT_DISPLAY_SCREENSHOT_FORMAT))
.c_str())
.value_or(DEFAULT_DISPLAY_SCREENSHOT_FORMAT);
display_screenshot_quality = static_cast<u8>(
std::clamp<u32>(si.GetUIntValue("Display", "ScreenshotQuality", DEFAULT_DISPLAY_SCREENSHOT_QUALITY), 1, 100));
display_force_4_3_for_24bit = si.GetBoolValue("Display", "Force4_3For24Bit", false); display_force_4_3_for_24bit = si.GetBoolValue("Display", "Force4_3For24Bit", false);
display_active_start_offset = static_cast<s16>(si.GetIntValue("Display", "ActiveStartOffset", 0)); display_active_start_offset = static_cast<s16>(si.GetIntValue("Display", "ActiveStartOffset", 0));
display_active_end_offset = static_cast<s16>(si.GetIntValue("Display", "ActiveEndOffset", 0)); display_active_end_offset = static_cast<s16>(si.GetIntValue("Display", "ActiveEndOffset", 0));
@ -266,7 +278,6 @@ void Settings::Load(SettingsInterface& si)
display_show_inputs = si.GetBoolValue("Display", "ShowInputs", false); display_show_inputs = si.GetBoolValue("Display", "ShowInputs", false);
display_show_enhancements = si.GetBoolValue("Display", "ShowEnhancements", false); display_show_enhancements = si.GetBoolValue("Display", "ShowEnhancements", false);
display_all_frames = si.GetBoolValue("Display", "DisplayAllFrames", false); display_all_frames = si.GetBoolValue("Display", "DisplayAllFrames", false);
display_internal_resolution_screenshots = si.GetBoolValue("Display", "InternalResolutionScreenshots", false);
display_stretch_vertically = si.GetBoolValue("Display", "StretchVertically", false); display_stretch_vertically = si.GetBoolValue("Display", "StretchVertically", false);
video_sync_enabled = si.GetBoolValue("Display", "VSync", DEFAULT_VSYNC_VALUE); video_sync_enabled = si.GetBoolValue("Display", "VSync", DEFAULT_VSYNC_VALUE);
display_max_fps = si.GetFloatValue("Display", "MaxFPS", DEFAULT_DISPLAY_MAX_FPS); display_max_fps = si.GetFloatValue("Display", "MaxFPS", DEFAULT_DISPLAY_MAX_FPS);
@ -495,6 +506,9 @@ void Settings::Save(SettingsInterface& si) const
si.SetStringValue("Display", "Scaling", GetDisplayScalingName(display_scaling)); si.SetStringValue("Display", "Scaling", GetDisplayScalingName(display_scaling));
si.SetStringValue("Display", "ExclusiveFullscreenControl", si.SetStringValue("Display", "ExclusiveFullscreenControl",
GetDisplayExclusiveFullscreenControlName(display_exclusive_fullscreen_control)); GetDisplayExclusiveFullscreenControlName(display_exclusive_fullscreen_control));
si.SetStringValue("Display", "ScreenshotMode", GetDisplayScreenshotModeName(display_screenshot_mode));
si.SetStringValue("Display", "ScreenshotFormat", GetDisplayScreenshotFormatName(display_screenshot_format));
si.SetUIntValue("Display", "ScreenshotQuality", display_screenshot_quality);
si.SetIntValue("Display", "CustomAspectRatioNumerator", display_aspect_ratio_custom_numerator); si.SetIntValue("Display", "CustomAspectRatioNumerator", display_aspect_ratio_custom_numerator);
si.GetIntValue("Display", "CustomAspectRatioDenominator", display_aspect_ratio_custom_denominator); si.GetIntValue("Display", "CustomAspectRatioDenominator", display_aspect_ratio_custom_denominator);
si.SetBoolValue("Display", "ShowOSDMessages", display_show_osd_messages); si.SetBoolValue("Display", "ShowOSDMessages", display_show_osd_messages);
@ -509,7 +523,6 @@ void Settings::Save(SettingsInterface& si) const
si.SetBoolValue("Display", "ShowInputs", display_show_inputs); si.SetBoolValue("Display", "ShowInputs", display_show_inputs);
si.SetBoolValue("Display", "ShowEnhancements", display_show_enhancements); si.SetBoolValue("Display", "ShowEnhancements", display_show_enhancements);
si.SetBoolValue("Display", "DisplayAllFrames", display_all_frames); si.SetBoolValue("Display", "DisplayAllFrames", display_all_frames);
si.SetBoolValue("Display", "InternalResolutionScreenshots", display_internal_resolution_screenshots);
si.SetBoolValue("Display", "StretchVertically", display_stretch_vertically); si.SetBoolValue("Display", "StretchVertically", display_stretch_vertically);
si.SetBoolValue("Display", "VSync", video_sync_enabled); si.SetBoolValue("Display", "VSync", video_sync_enabled);
si.SetFloatValue("Display", "MaxFPS", display_max_fps); si.SetFloatValue("Display", "MaxFPS", display_max_fps);
@ -945,16 +958,16 @@ static constexpr const std::array s_gpu_renderer_names = {
static constexpr const std::array s_gpu_renderer_display_names = { static constexpr const std::array s_gpu_renderer_display_names = {
TRANSLATE_NOOP("GPURenderer", "Automatic"), TRANSLATE_NOOP("GPURenderer", "Automatic"),
#ifdef _WIN32 #ifdef _WIN32
TRANSLATE_NOOP("GPURenderer", "Hardware (D3D11)"), TRANSLATE_NOOP("GPURenderer", "Hardware (D3D12)"), TRANSLATE_NOOP("GPURenderer", "Direct3D 11"), TRANSLATE_NOOP("GPURenderer", "Direct3D 12"),
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__
TRANSLATE_NOOP("GPURenderer", "Hardware (Metal)"), TRANSLATE_NOOP("GPURenderer", "Metal"),
#endif #endif
#ifdef ENABLE_VULKAN #ifdef ENABLE_VULKAN
TRANSLATE_NOOP("GPURenderer", "Hardware (Vulkan)"), TRANSLATE_NOOP("GPURenderer", "Vulkan"),
#endif #endif
#ifdef ENABLE_OPENGL #ifdef ENABLE_OPENGL
TRANSLATE_NOOP("GPURenderer", "Hardware (OpenGL)"), TRANSLATE_NOOP("GPURenderer", "OpenGL"),
#endif #endif
TRANSLATE_NOOP("GPURenderer", "Software"), TRANSLATE_NOOP("GPURenderer", "Software"),
}; };
@ -1011,6 +1024,44 @@ RenderAPI Settings::GetRenderAPIForRenderer(GPURenderer renderer)
} }
} }
GPURenderer Settings::GetRendererForRenderAPI(RenderAPI api)
{
switch (api)
{
#ifdef _WIN32
case RenderAPI::D3D11:
return GPURenderer::HardwareD3D11;
case RenderAPI::D3D12:
return GPURenderer::HardwareD3D12;
#endif
#ifdef __APPLE__
case RenderAPI::Metal:
return GPURenderer::HardwareMetal;
#endif
#ifdef ENABLE_VULKAN
case RenderAPI::Vulkan:
return GPURenderer::HardwareVulkan;
#endif
#ifdef ENABLE_OPENGL
case RenderAPI::OpenGL:
case RenderAPI::OpenGLES:
return GPURenderer::HardwareOpenGL;
#endif
default:
return GPURenderer::Automatic;
}
}
GPURenderer Settings::GetAutomaticRenderer()
{
return GetRendererForRenderAPI(GPUDevice::GetPreferredAPI());
}
static constexpr const std::array s_texture_filter_names = { static constexpr const std::array s_texture_filter_names = {
"Nearest", "Bilinear", "BilinearBinAlpha", "JINC2", "JINC2BinAlpha", "xBR", "xBRBinAlpha", "Nearest", "Bilinear", "BilinearBinAlpha", "JINC2", "JINC2BinAlpha", "xBR", "xBRBinAlpha",
}; };
@ -1312,7 +1363,7 @@ static constexpr const std::array s_display_exclusive_fullscreen_mode_names = {
"Allowed", "Allowed",
}; };
static constexpr const std::array s_display_exclusive_fullscreen_mode_display_names = { static constexpr const std::array s_display_exclusive_fullscreen_mode_display_names = {
TRANSLATE_NOOP("Settings", "Automatic (Default)"), TRANSLATE_NOOP("Settings", "Automatic"),
TRANSLATE_NOOP("Settings", "Disallowed"), TRANSLATE_NOOP("Settings", "Disallowed"),
TRANSLATE_NOOP("Settings", "Allowed"), TRANSLATE_NOOP("Settings", "Allowed"),
}; };
@ -1342,6 +1393,89 @@ const char* Settings::GetDisplayExclusiveFullscreenControlDisplayName(DisplayExc
s_display_exclusive_fullscreen_mode_display_names[static_cast<int>(mode)]); s_display_exclusive_fullscreen_mode_display_names[static_cast<int>(mode)]);
} }
static constexpr const std::array s_display_screenshot_mode_names = {
"ScreenResolution",
"InternalResolution",
"UncorrectedInternalResolution",
};
static constexpr const std::array s_display_screenshot_mode_display_names = {
TRANSLATE_NOOP("Settings", "Screen Resolution"),
TRANSLATE_NOOP("Settings", "Internal Resolution"),
TRANSLATE_NOOP("Settings", "Internal Resolution (Aspect Uncorrected)"),
};
std::optional<DisplayScreenshotMode> Settings::ParseDisplayScreenshotMode(const char* str)
{
int index = 0;
for (const char* name : s_display_screenshot_mode_names)
{
if (StringUtil::Strcasecmp(name, str) == 0)
return static_cast<DisplayScreenshotMode>(index);
index++;
}
return std::nullopt;
}
const char* Settings::GetDisplayScreenshotModeName(DisplayScreenshotMode mode)
{
return s_display_screenshot_mode_names[static_cast<size_t>(mode)];
}
const char* Settings::GetDisplayScreenshotModeDisplayName(DisplayScreenshotMode mode)
{
return Host::TranslateToCString("Settings", s_display_screenshot_mode_display_names[static_cast<size_t>(mode)]);
}
static constexpr const std::array s_display_screenshot_format_names = {
"PNG",
"JPEG",
"TGA",
"BMP",
};
static constexpr const std::array s_display_screenshot_format_display_names = {
TRANSLATE_NOOP("Settings", "PNG"),
TRANSLATE_NOOP("Settings", "JPEG"),
TRANSLATE_NOOP("Settings", "TGA"),
TRANSLATE_NOOP("Settings", "BMP"),
};
static constexpr const std::array s_display_screenshot_format_extensions = {
"png",
"jpg",
"tga",
"bmp",
};
std::optional<DisplayScreenshotFormat> Settings::ParseDisplayScreenshotFormat(const char* str)
{
int index = 0;
for (const char* name : s_display_screenshot_format_names)
{
if (StringUtil::Strcasecmp(name, str) == 0)
return static_cast<DisplayScreenshotFormat>(index);
index++;
}
return std::nullopt;
}
const char* Settings::GetDisplayScreenshotFormatName(DisplayScreenshotFormat format)
{
return s_display_screenshot_format_names[static_cast<size_t>(format)];
}
const char* Settings::GetDisplayScreenshotFormatDisplayName(DisplayScreenshotFormat mode)
{
return Host::TranslateToCString("Settings", s_display_screenshot_format_display_names[static_cast<size_t>(mode)]);
}
const char* Settings::GetDisplayScreenshotFormatExtension(DisplayScreenshotFormat format)
{
return s_display_screenshot_format_extensions[static_cast<size_t>(format)];
}
static constexpr const std::array s_audio_backend_names = { static constexpr const std::array s_audio_backend_names = {
"Null", "Null",
#ifdef ENABLE_CUBEB #ifdef ENABLE_CUBEB

View File

@ -135,6 +135,9 @@ struct Settings
DisplayAlignment display_alignment = DEFAULT_DISPLAY_ALIGNMENT; DisplayAlignment display_alignment = DEFAULT_DISPLAY_ALIGNMENT;
DisplayScalingMode display_scaling = DEFAULT_DISPLAY_SCALING; DisplayScalingMode display_scaling = DEFAULT_DISPLAY_SCALING;
DisplayExclusiveFullscreenControl display_exclusive_fullscreen_control = DEFAULT_DISPLAY_EXCLUSIVE_FULLSCREEN_CONTROL; DisplayExclusiveFullscreenControl display_exclusive_fullscreen_control = DEFAULT_DISPLAY_EXCLUSIVE_FULLSCREEN_CONTROL;
DisplayScreenshotMode display_screenshot_mode = DEFAULT_DISPLAY_SCREENSHOT_MODE;
DisplayScreenshotFormat display_screenshot_format = DEFAULT_DISPLAY_SCREENSHOT_FORMAT;
u8 display_screenshot_quality = DEFAULT_DISPLAY_SCREENSHOT_QUALITY;
u16 display_aspect_ratio_custom_numerator = 0; u16 display_aspect_ratio_custom_numerator = 0;
u16 display_aspect_ratio_custom_denominator = 0; u16 display_aspect_ratio_custom_denominator = 0;
s16 display_active_start_offset = 0; s16 display_active_start_offset = 0;
@ -155,7 +158,6 @@ struct Settings
bool display_show_inputs : 1 = false; bool display_show_inputs : 1 = false;
bool display_show_enhancements : 1 = false; bool display_show_enhancements : 1 = false;
bool display_all_frames : 1 = false; bool display_all_frames : 1 = false;
bool display_internal_resolution_screenshots : 1 = false;
bool display_stretch_vertically : 1 = false; bool display_stretch_vertically : 1 = false;
bool video_sync_enabled = DEFAULT_VSYNC_VALUE; bool video_sync_enabled = DEFAULT_VSYNC_VALUE;
float display_osd_scale = 100.0f; float display_osd_scale = 100.0f;
@ -374,6 +376,8 @@ struct Settings
static const char* GetRendererName(GPURenderer renderer); static const char* GetRendererName(GPURenderer renderer);
static const char* GetRendererDisplayName(GPURenderer renderer); static const char* GetRendererDisplayName(GPURenderer renderer);
static RenderAPI GetRenderAPIForRenderer(GPURenderer renderer); static RenderAPI GetRenderAPIForRenderer(GPURenderer renderer);
static GPURenderer GetRendererForRenderAPI(RenderAPI api);
static GPURenderer GetAutomaticRenderer();
static std::optional<GPUTextureFilter> ParseTextureFilterName(const char* str); static std::optional<GPUTextureFilter> ParseTextureFilterName(const char* str);
static const char* GetTextureFilterName(GPUTextureFilter filter); static const char* GetTextureFilterName(GPUTextureFilter filter);
@ -411,6 +415,15 @@ struct Settings
static const char* GetDisplayExclusiveFullscreenControlName(DisplayExclusiveFullscreenControl mode); static const char* GetDisplayExclusiveFullscreenControlName(DisplayExclusiveFullscreenControl mode);
static const char* GetDisplayExclusiveFullscreenControlDisplayName(DisplayExclusiveFullscreenControl mode); static const char* GetDisplayExclusiveFullscreenControlDisplayName(DisplayExclusiveFullscreenControl mode);
static std::optional<DisplayScreenshotMode> ParseDisplayScreenshotMode(const char* str);
static const char* GetDisplayScreenshotModeName(DisplayScreenshotMode mode);
static const char* GetDisplayScreenshotModeDisplayName(DisplayScreenshotMode mode);
static std::optional<DisplayScreenshotFormat> ParseDisplayScreenshotFormat(const char* str);
static const char* GetDisplayScreenshotFormatName(DisplayScreenshotFormat mode);
static const char* GetDisplayScreenshotFormatDisplayName(DisplayScreenshotFormat mode);
static const char* GetDisplayScreenshotFormatExtension(DisplayScreenshotFormat mode);
static std::optional<AudioBackend> ParseAudioBackend(const char* str); static std::optional<AudioBackend> ParseAudioBackend(const char* str);
static const char* GetAudioBackendName(AudioBackend backend); static const char* GetAudioBackendName(AudioBackend backend);
static const char* GetAudioBackendDisplayName(AudioBackend backend); static const char* GetAudioBackendDisplayName(AudioBackend backend);
@ -473,6 +486,9 @@ struct Settings
static constexpr DisplayScalingMode DEFAULT_DISPLAY_SCALING = DisplayScalingMode::BilinearSmooth; static constexpr DisplayScalingMode DEFAULT_DISPLAY_SCALING = DisplayScalingMode::BilinearSmooth;
static constexpr DisplayExclusiveFullscreenControl DEFAULT_DISPLAY_EXCLUSIVE_FULLSCREEN_CONTROL = static constexpr DisplayExclusiveFullscreenControl DEFAULT_DISPLAY_EXCLUSIVE_FULLSCREEN_CONTROL =
DisplayExclusiveFullscreenControl::Automatic; DisplayExclusiveFullscreenControl::Automatic;
static constexpr DisplayScreenshotMode DEFAULT_DISPLAY_SCREENSHOT_MODE = DisplayScreenshotMode::ScreenResolution;
static constexpr DisplayScreenshotFormat DEFAULT_DISPLAY_SCREENSHOT_FORMAT = DisplayScreenshotFormat::PNG;
static constexpr u8 DEFAULT_DISPLAY_SCREENSHOT_QUALITY = 85;
static constexpr float DEFAULT_OSD_SCALE = 100.0f; static constexpr float DEFAULT_OSD_SCALE = 100.0f;
static constexpr u8 DEFAULT_CDROM_READAHEAD_SECTORS = 8; static constexpr u8 DEFAULT_CDROM_READAHEAD_SECTORS = 8;

View File

@ -4306,8 +4306,8 @@ void System::StopDumpingAudio()
Host::AddOSDMessage(TRANSLATE_STR("OSDMessage", "Stopped dumping audio."), 5.0f); Host::AddOSDMessage(TRANSLATE_STR("OSDMessage", "Stopped dumping audio."), 5.0f);
} }
bool System::SaveScreenshot(const char* filename /* = nullptr */, bool full_resolution /* = true */, bool System::SaveScreenshot(const char* filename, DisplayScreenshotMode mode, DisplayScreenshotFormat format,
bool apply_aspect_ratio /* = true */, bool compress_on_thread /* = true */) u8 quality, bool compress_on_thread)
{ {
if (!System::IsValid()) if (!System::IsValid())
return false; return false;
@ -4316,7 +4316,7 @@ bool System::SaveScreenshot(const char* filename /* = nullptr */, bool full_reso
if (!filename) if (!filename)
{ {
const auto& code = System::GetGameSerial(); const auto& code = System::GetGameSerial();
const char* extension = "png"; const char* extension = Settings::GetDisplayScreenshotFormatExtension(format);
if (code.empty()) if (code.empty())
{ {
auto_filename = auto_filename =
@ -4337,10 +4337,7 @@ bool System::SaveScreenshot(const char* filename /* = nullptr */, bool full_reso
return false; return false;
} }
const bool screenshot_saved = if (!g_gpu->RenderScreenshotToFile(filename, mode, quality, compress_on_thread))
g_gpu->RenderScreenshotToFile(filename, g_settings.display_internal_resolution_screenshots, compress_on_thread);
if (!screenshot_saved)
{ {
Host::AddFormattedOSDMessage(10.0f, TRANSLATE("OSDMessage", "Failed to save screenshot to '%s'"), filename); Host::AddFormattedOSDMessage(10.0f, TRANSLATE("OSDMessage", "Failed to save screenshot to '%s'"), filename);
return false; return false;

View File

@ -416,9 +416,10 @@ bool StartDumpingAudio(const char* filename = nullptr);
/// Stops dumping audio to file if it has been started. /// Stops dumping audio to file if it has been started.
void StopDumpingAudio(); void StopDumpingAudio();
/// Saves a screenshot to the specified file. IF no file name is provided, one will be generated automatically. /// Saves a screenshot to the specified file. If no file name is provided, one will be generated automatically.
bool SaveScreenshot(const char* filename = nullptr, bool full_resolution = true, bool apply_aspect_ratio = true, bool SaveScreenshot(const char* filename = nullptr, DisplayScreenshotMode mode = g_settings.display_screenshot_mode,
bool compress_on_thread = true); DisplayScreenshotFormat format = g_settings.display_screenshot_format,
u8 quality = g_settings.display_screenshot_quality, bool compress_on_thread = true);
/// Loads the cheat list from the specified file. /// Loads the cheat list from the specified file.
bool LoadCheatList(const char* filename); bool LoadCheatList(const char* filename);

View File

@ -160,6 +160,23 @@ enum class DisplayExclusiveFullscreenControl : u8
Count Count
}; };
enum class DisplayScreenshotMode : u8
{
ScreenResolution,
InternalResolution,
UncorrectedInternalResolution,
Count
};
enum class DisplayScreenshotFormat : u8
{
PNG,
JPEG,
TGA,
BMP,
Count
};
enum class AudioBackend : u8 enum class AudioBackend : u8
{ {
Null, Null,

View File

@ -70,18 +70,12 @@ set(SRCS
debuggerwindow.cpp debuggerwindow.cpp
debuggerwindow.h debuggerwindow.h
debuggerwindow.ui debuggerwindow.ui
displaysettingswidget.cpp
displaysettingswidget.h
displaysettingswidget.ui
displaywidget.cpp displaywidget.cpp
displaywidget.h displaywidget.h
emptygamelistwidget.ui emptygamelistwidget.ui
emulationsettingswidget.cpp emulationsettingswidget.cpp
emulationsettingswidget.h emulationsettingswidget.h
emulationsettingswidget.ui emulationsettingswidget.ui
enhancementsettingswidget.cpp
enhancementsettingswidget.h
enhancementsettingswidget.ui
foldersettingswidget.cpp foldersettingswidget.cpp
foldersettingswidget.h foldersettingswidget.h
foldersettingswidget.ui foldersettingswidget.ui
@ -104,9 +98,9 @@ set(SRCS
gdbconnection.h gdbconnection.h
gdbserver.cpp gdbserver.cpp
gdbserver.h gdbserver.h
generalsettingswidget.cpp graphicssettingswidget.cpp
generalsettingswidget.h graphicssettingswidget.h
generalsettingswidget.ui graphicssettingswidget.ui
hotkeysettingswidget.cpp hotkeysettingswidget.cpp
hotkeysettingswidget.h hotkeysettingswidget.h
inputbindingdialog.cpp inputbindingdialog.cpp
@ -114,6 +108,9 @@ set(SRCS
inputbindingdialog.ui inputbindingdialog.ui
inputbindingwidgets.cpp inputbindingwidgets.cpp
inputbindingwidgets.h inputbindingwidgets.h
interfacesettingswidget.cpp
interfacesettingswidget.h
interfacesettingswidget.ui
logwindow.cpp logwindow.cpp
logwindow.h logwindow.h
mainwindow.cpp mainwindow.cpp

View File

@ -72,42 +72,6 @@ static QSpinBox* setIntRangeTweakOption(QTableWidget* table, int row, int value)
return cb; return cb;
} }
static QDoubleSpinBox* addFloatRangeTweakOption(SettingsWindow* dialog, QTableWidget* table, QString name,
std::string section, std::string key, float min_value, float max_value,
float step_value, float default_value)
{
const int row = table->rowCount();
table->insertRow(row);
QTableWidgetItem* name_item = new QTableWidgetItem(name);
name_item->setFlags(name_item->flags() & ~(Qt::ItemIsEditable | Qt::ItemIsSelectable));
table->setItem(row, 0, name_item);
QDoubleSpinBox* cb = new QDoubleSpinBox(table);
cb->setMinimum(min_value);
cb->setMaximum(max_value);
cb->setSingleStep(step_value);
if (!section.empty() || !key.empty())
{
SettingWidgetBinder::BindWidgetToFloatSetting(dialog->getSettingsInterface(), cb, std::move(section),
std::move(key), default_value);
}
table->setCellWidget(row, 1, cb);
return cb;
}
static QDoubleSpinBox* setFloatRangeTweakOption(QTableWidget* table, int row, float value)
{
QWidget* widget = table->cellWidget(row, 1);
QDoubleSpinBox* cb = qobject_cast<QDoubleSpinBox*>(widget);
Assert(cb);
cb->setValue(value);
return cb;
}
template<typename T> template<typename T>
static QComboBox* addChoiceTweakOption(SettingsWindow* dialog, QTableWidget* table, QString name, std::string section, static QComboBox* addChoiceTweakOption(SettingsWindow* dialog, QTableWidget* table, QString name, std::string section,
std::string key, std::optional<T> (*parse_callback)(const char*), std::string key, std::optional<T> (*parse_callback)(const char*),
@ -145,36 +109,6 @@ static void setChoiceTweakOption(QTableWidget* table, int row, T value)
cb->setCurrentIndex(static_cast<int>(value)); cb->setCurrentIndex(static_cast<int>(value));
} }
static void addMSAATweakOption(SettingsWindow* dialog, QTableWidget* table, const QString& name)
{
const int row = table->rowCount();
table->insertRow(row);
QTableWidgetItem* name_item = new QTableWidgetItem(name);
name_item->setFlags(name_item->flags() & ~(Qt::ItemIsEditable | Qt::ItemIsSelectable));
table->setItem(row, 0, name_item);
QComboBox* msaa = new QComboBox(table);
QtUtils::FillComboBoxWithMSAAModes(msaa);
const QVariant current_msaa_mode(
QtUtils::GetMSAAModeValue(static_cast<uint>(dialog->getEffectiveIntValue("GPU", "Multisamples", 1)),
dialog->getEffectiveBoolValue("GPU", "PerSampleShading", false)));
const int current_msaa_index = msaa->findData(current_msaa_mode);
if (current_msaa_index >= 0)
msaa->setCurrentIndex(current_msaa_index);
msaa->connect(msaa, QOverload<int>::of(&QComboBox::currentIndexChanged), [dialog, msaa](int index) {
uint multisamples;
bool ssaa;
QtUtils::DecodeMSAAModeValue(msaa->itemData(index), &multisamples, &ssaa);
dialog->setIntSettingValue("GPU", "Multisamples", static_cast<int>(multisamples));
dialog->setBoolSettingValue("GPU", "PerSampleShading", ssaa);
g_emu_thread->applySettings(false);
});
table->setCellWidget(row, 1, msaa);
}
static void addDirectoryOption(SettingsWindow* dialog, QTableWidget* table, const QString& name, std::string section, static void addDirectoryOption(SettingsWindow* dialog, QTableWidget* table, const QString& name, std::string section,
std::string key) std::string key)
{ {
@ -242,8 +176,9 @@ AdvancedSettingsWidget::AdvancedSettingsWidget(SettingsWindow* dialog, QWidget*
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showDebugMenu, "Main", "ShowDebugMenu", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showDebugMenu, "Main", "ShowDebugMenu", false);
connect(m_ui.resetToDefaultButton, &QPushButton::clicked, this, &AdvancedSettingsWidget::onResetToDefaultClicked); connect(m_ui.resetToDefaultButton, &QPushButton::clicked, this, &AdvancedSettingsWidget::onResetToDefaultClicked);
connect(m_ui.showDebugMenu, &QCheckBox::toggled, g_main_window, &MainWindow::updateDebugMenuVisibility, connect(m_ui.showDebugMenu, &QCheckBox::stateChanged, g_main_window, &MainWindow::updateDebugMenuVisibility,
Qt::QueuedConnection); Qt::QueuedConnection);
connect(m_ui.showDebugMenu, &QCheckBox::stateChanged, this, &AdvancedSettingsWidget::onShowDebugOptionsStateChanged);
m_ui.tweakOptionTable->setColumnWidth(0, 380); m_ui.tweakOptionTable->setColumnWidth(0, 380);
m_ui.tweakOptionTable->setColumnWidth(1, 170); m_ui.tweakOptionTable->setColumnWidth(1, 170);
@ -266,29 +201,18 @@ AdvancedSettingsWidget::AdvancedSettingsWidget(SettingsWindow* dialog, QWidget*
AdvancedSettingsWidget::~AdvancedSettingsWidget() = default; AdvancedSettingsWidget::~AdvancedSettingsWidget() = default;
void AdvancedSettingsWidget::onShowDebugOptionsStateChanged()
{
const bool enabled = QtHost::ShouldShowDebugOptions();
emit onShowDebugOptionsChanged(enabled);
}
void AdvancedSettingsWidget::addTweakOptions() void AdvancedSettingsWidget::addTweakOptions()
{ {
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Disable All Enhancements"), "Main",
"DisableAllEnhancements", false);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Show Status Indicators"), "Display",
"ShowStatusIndicators", true);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Show Frame Times"), "Display", "ShowFrameTimes", false);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Show Settings Overlay"), "Display", "ShowEnhancements", false);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Apply Compatibility Settings"), "Main", addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Apply Compatibility Settings"), "Main",
"ApplyCompatibilitySettings", true); "ApplyCompatibilitySettings", true);
addIntRangeTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Display FPS Limit"), "Display", "MaxFPS", 0, 1000, 0); addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Increase Timer Resolution"), "Main",
addChoiceTweakOption( "IncreaseTimerResolution", true);
m_dialog, m_ui.tweakOptionTable, tr("Exclusive Fullscreen Control"), "Display", "ExclusiveFullscreenControl",
&Settings::ParseDisplayExclusiveFullscreenControl, &Settings::GetDisplayExclusiveFullscreenControlName,
&Settings::GetDisplayExclusiveFullscreenControlDisplayName,
static_cast<u32>(DisplayExclusiveFullscreenControl::Count), Settings::DEFAULT_DISPLAY_EXCLUSIVE_FULLSCREEN_CONTROL);
addMSAATweakOption(m_dialog, m_ui.tweakOptionTable, tr("Multisample Antialiasing"));
addChoiceTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Wireframe Mode"), "GPU", "WireframeMode",
Settings::ParseGPUWireframeMode, Settings::GetGPUWireframeModeName,
Settings::GetGPUWireframeModeDisplayName, static_cast<u32>(GPUWireframeMode::Count),
GPUWireframeMode::Disabled);
if (m_dialog->isPerGameSettings()) if (m_dialog->isPerGameSettings())
{ {
@ -302,11 +226,14 @@ void AdvancedSettingsWidget::addTweakOptions()
-128, 127, 0); -128, 127, 0);
} }
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("PGXP Vertex Cache"), "GPU", "PGXPVertexCache", false); addIntRangeTweakOption(m_dialog, m_ui.tweakOptionTable, tr("DMA Max Slice Ticks"), "Hacks", "DMAMaxSliceTicks", 100,
addFloatRangeTweakOption(m_dialog, m_ui.tweakOptionTable, tr("PGXP Geometry Tolerance"), "GPU", "PGXPTolerance", 10000, Settings::DEFAULT_DMA_MAX_SLICE_TICKS);
-1.0f, 100.0f, 0.25f, -1.0f); addIntRangeTweakOption(m_dialog, m_ui.tweakOptionTable, tr("DMA Halt Ticks"), "Hacks", "DMAHaltTicks", 100, 10000,
addFloatRangeTweakOption(m_dialog, m_ui.tweakOptionTable, tr("PGXP Depth Clear Threshold"), "GPU", Settings::DEFAULT_DMA_HALT_TICKS);
"PGXPDepthClearThreshold", 0.0f, 4096.0f, 1.0f, Settings::DEFAULT_GPU_PGXP_DEPTH_THRESHOLD); addIntRangeTweakOption(m_dialog, m_ui.tweakOptionTable, tr("GPU FIFO Size"), "Hacks", "GPUFIFOSize", 16, 4096,
Settings::DEFAULT_GPU_FIFO_SIZE);
addIntRangeTweakOption(m_dialog, m_ui.tweakOptionTable, tr("GPU Max Run-Ahead"), "Hacks", "GPUMaxRunAhead", 0, 1000,
Settings::DEFAULT_GPU_MAX_RUN_AHEAD);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Enable Recompiler Memory Exceptions"), "CPU", addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Enable Recompiler Memory Exceptions"), "CPU",
"RecompilerMemoryExceptions", false); "RecompilerMemoryExceptions", false);
@ -317,50 +244,6 @@ void AdvancedSettingsWidget::addTweakOptions()
Settings::GetCPUFastmemModeDisplayName, static_cast<u32>(CPUFastmemMode::Count), Settings::GetCPUFastmemModeDisplayName, static_cast<u32>(CPUFastmemMode::Count),
Settings::DEFAULT_CPU_FASTMEM_MODE); Settings::DEFAULT_CPU_FASTMEM_MODE);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Use Old MDEC Routines"), "Hacks", "UseOldMDECRoutines",
false);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Enable VRAM Write Texture Replacement"),
"TextureReplacements", "EnableVRAMWriteReplacements", false);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Preload Texture Replacements"), "TextureReplacements",
"PreloadTextures", false);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Dump Replaceable VRAM Writes"), "TextureReplacements",
"DumpVRAMWrites", false);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Set Dumped VRAM Write Alpha Channel"),
"TextureReplacements", "DumpVRAMWriteForceAlphaChannel", true);
addIntRangeTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Minimum Dumped VRAM Write Width"), "TextureReplacements",
"DumpVRAMWriteWidthThreshold", 1, VRAM_WIDTH,
Settings::DEFAULT_VRAM_WRITE_DUMP_WIDTH_THRESHOLD);
addIntRangeTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Minimum Dumped VRAM Write Height"), "TextureReplacements",
"DumpVRAMWriteHeightThreshold", 1, VRAM_HEIGHT,
Settings::DEFAULT_VRAM_WRITE_DUMP_HEIGHT_THRESHOLD);
addIntRangeTweakOption(m_dialog, m_ui.tweakOptionTable, tr("DMA Max Slice Ticks"), "Hacks", "DMAMaxSliceTicks", 100,
10000, Settings::DEFAULT_DMA_MAX_SLICE_TICKS);
addIntRangeTweakOption(m_dialog, m_ui.tweakOptionTable, tr("DMA Halt Ticks"), "Hacks", "DMAHaltTicks", 100, 10000,
Settings::DEFAULT_DMA_HALT_TICKS);
addIntRangeTweakOption(m_dialog, m_ui.tweakOptionTable, tr("GPU FIFO Size"), "Hacks", "GPUFIFOSize", 16, 4096,
Settings::DEFAULT_GPU_FIFO_SIZE);
addIntRangeTweakOption(m_dialog, m_ui.tweakOptionTable, tr("GPU Max Run-Ahead"), "Hacks", "GPUMaxRunAhead", 0, 1000,
Settings::DEFAULT_GPU_MAX_RUN_AHEAD);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Use Debug Host GPU Device"), "GPU", "UseDebugDevice",
false);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Disable Shader Cache"), "GPU", "DisableShaderCache",
false);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Disable Dual-Source Blend"), "GPU",
"DisableDualSourceBlend", false);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Disable Framebuffer Fetch"), "GPU",
"DisableFramebufferFetch", false);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Disable Texture Buffers"), "GPU", "DisableTextureBuffers",
false);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Disable Texture Copy To Self"), "GPU",
"DisableTextureCopyToSelf", false);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Stretch Display Vertically"), "Display",
"StretchVertically", false);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Increase Timer Resolution"), "Main",
"IncreaseTimerResolution", true);
addChoiceTweakOption(m_dialog, m_ui.tweakOptionTable, tr("CD-ROM Mechacon Version"), "CDROM", "MechaconVersion", addChoiceTweakOption(m_dialog, m_ui.tweakOptionTable, tr("CD-ROM Mechacon Version"), "CDROM", "MechaconVersion",
Settings::ParseCDROMMechVersionName, Settings::GetCDROMMechVersionName, Settings::ParseCDROMMechVersionName, Settings::GetCDROMMechVersionName,
Settings::GetCDROMMechVersionDisplayName, static_cast<u8>(CDROMMechaconVersion::Count), Settings::GetCDROMMechVersionDisplayName, static_cast<u8>(CDROMMechaconVersion::Count),
@ -368,9 +251,6 @@ void AdvancedSettingsWidget::addTweakOptions()
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Allow Booting Without SBI File"), "CDROM", addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Allow Booting Without SBI File"), "CDROM",
"AllowBootingWithoutSBIFile", false); "AllowBootingWithoutSBIFile", false);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Create Save State Backups"), "General",
"CreateSaveStateBackups", false);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Enable PCDrv"), "PCDrv", "Enabled", false); addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Enable PCDrv"), "PCDrv", "Enabled", false);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Enable PCDrv Writes"), "PCDrv", "EnableWrites", false); addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Enable PCDrv Writes"), "PCDrv", "EnableWrites", false);
addDirectoryOption(m_dialog, m_ui.tweakOptionTable, tr("PCDrv Root Directory"), "PCDrv", "Root"); addDirectoryOption(m_dialog, m_ui.tweakOptionTable, tr("PCDrv Root Directory"), "PCDrv", "Root");
@ -382,31 +262,8 @@ void AdvancedSettingsWidget::onResetToDefaultClicked()
{ {
int i = 0; int i = 0;
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Disable all enhancements setBooleanTweakOption(m_ui.tweakOptionTable, i++, true); // Apply compatibility settings
setBooleanTweakOption(m_ui.tweakOptionTable, i++, true); // Show status indicators setBooleanTweakOption(m_ui.tweakOptionTable, i++, true); // Increase Timer Resolution
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Show frame times
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Show settings overlay
setBooleanTweakOption(m_ui.tweakOptionTable, i++, true); // Apply compatibility settings
setIntRangeTweakOption(m_ui.tweakOptionTable, i++, 0); // Display FPS limit
setChoiceTweakOption(m_ui.tweakOptionTable, i++, Settings::DEFAULT_DISPLAY_EXCLUSIVE_FULLSCREEN_CONTROL);
setChoiceTweakOption(m_ui.tweakOptionTable, i++, 0); // Multisample antialiasing
setChoiceTweakOption(m_ui.tweakOptionTable, i++, 0); // Wireframe mode
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // PGXP vertex cache
setFloatRangeTweakOption(m_ui.tweakOptionTable, i++, -1.0f); // PGXP geometry tolerance
setFloatRangeTweakOption(m_ui.tweakOptionTable, i++,
Settings::DEFAULT_GPU_PGXP_DEPTH_THRESHOLD); // PGXP depth clear threshold
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Recompiler memory exceptions
setBooleanTweakOption(m_ui.tweakOptionTable, i++, true); // Recompiler block linking
setChoiceTweakOption(m_ui.tweakOptionTable, i++, Settings::DEFAULT_CPU_FASTMEM_MODE); // Recompiler fastmem mode
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Use Old MDEC Routines
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // VRAM write texture replacement
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Preload texture replacements
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Dump replacable VRAM writes
setBooleanTweakOption(m_ui.tweakOptionTable, i++, true); // Set dumped VRAM write alpha channel
setIntRangeTweakOption(m_ui.tweakOptionTable, i++,
Settings::DEFAULT_VRAM_WRITE_DUMP_WIDTH_THRESHOLD); // Minimum dumped VRAM width
setIntRangeTweakOption(m_ui.tweakOptionTable, i++,
Settings::DEFAULT_VRAM_WRITE_DUMP_HEIGHT_THRESHOLD); // Minimum dumped VRAM height
setIntRangeTweakOption(m_ui.tweakOptionTable, i++, setIntRangeTweakOption(m_ui.tweakOptionTable, i++,
static_cast<int>(Settings::DEFAULT_DMA_MAX_SLICE_TICKS)); // DMA max slice ticks static_cast<int>(Settings::DEFAULT_DMA_MAX_SLICE_TICKS)); // DMA max slice ticks
setIntRangeTweakOption(m_ui.tweakOptionTable, i++, setIntRangeTweakOption(m_ui.tweakOptionTable, i++,
@ -415,18 +272,13 @@ void AdvancedSettingsWidget::onResetToDefaultClicked()
static_cast<int>(Settings::DEFAULT_GPU_FIFO_SIZE)); // GPU FIFO size static_cast<int>(Settings::DEFAULT_GPU_FIFO_SIZE)); // GPU FIFO size
setIntRangeTweakOption(m_ui.tweakOptionTable, i++, setIntRangeTweakOption(m_ui.tweakOptionTable, i++,
static_cast<int>(Settings::DEFAULT_GPU_MAX_RUN_AHEAD)); // GPU max run-ahead static_cast<int>(Settings::DEFAULT_GPU_MAX_RUN_AHEAD)); // GPU max run-ahead
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Use debug host GPU device setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Recompiler memory exceptions
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Disable Shader Cache setBooleanTweakOption(m_ui.tweakOptionTable, i++, true); // Recompiler block linking
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Disable Dual-Source Blend setChoiceTweakOption(m_ui.tweakOptionTable, i++,
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Disable Framebuffer Fetch Settings::DEFAULT_CPU_FASTMEM_MODE); // Recompiler fastmem mode
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Disable Texture Buffers
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Disable Texture Copy To Self
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Stretch Display Vertically
setBooleanTweakOption(m_ui.tweakOptionTable, i++, true); // Increase Timer Resolution
setChoiceTweakOption(m_ui.tweakOptionTable, i++, setChoiceTweakOption(m_ui.tweakOptionTable, i++,
Settings::DEFAULT_CDROM_MECHACON_VERSION); // CDROM Mechacon Version Settings::DEFAULT_CDROM_MECHACON_VERSION); // CDROM Mechacon Version
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Allow booting without SBI file setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Allow booting without SBI file
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Create save state backups
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Enable PCDRV setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Enable PCDRV
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Enable PCDRV Writes setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Enable PCDRV Writes
setDirectoryOption(m_ui.tweakOptionTable, i++, ""); // PCDrv Root Directory setDirectoryOption(m_ui.tweakOptionTable, i++, ""); // PCDrv Root Directory
@ -436,49 +288,21 @@ void AdvancedSettingsWidget::onResetToDefaultClicked()
// for per-game it's easier to just clear and recreate // for per-game it's easier to just clear and recreate
SettingsInterface* sif = m_dialog->getSettingsInterface(); SettingsInterface* sif = m_dialog->getSettingsInterface();
sif->DeleteValue("Main", "DisableAllEnhancements");
sif->DeleteValue("Display", "ShowEnhancements");
sif->DeleteValue("Display", "ShowStatusIndicators");
sif->DeleteValue("Display", "ShowFrameTimes");
sif->DeleteValue("Display", "ShowEnhancements");
sif->DeleteValue("Main", "ApplyCompatibilitySettings"); sif->DeleteValue("Main", "ApplyCompatibilitySettings");
sif->DeleteValue("Display", "MaxFPS"); sif->DeleteValue("Main", "IncreaseTimerResolution");
sif->DeleteValue("Display", "ActiveStartOffset"); sif->DeleteValue("Display", "ActiveStartOffset");
sif->DeleteValue("Display", "ActiveEndOffset"); sif->DeleteValue("Display", "ActiveEndOffset");
sif->DeleteValue("Display", "LineStartOffset"); sif->DeleteValue("Display", "LineStartOffset");
sif->DeleteValue("Display", "LineEndOffset"); sif->DeleteValue("Display", "LineEndOffset");
sif->DeleteValue("Display", "StretchVertically");
sif->DeleteValue("Display", "ExclusiveFullscreenControl");
sif->DeleteValue("GPU", "Multisamples");
sif->DeleteValue("GPU", "PerSampleShading");
sif->DeleteValue("GPU", "PGXPVertexCache");
sif->DeleteValue("GPU", "PGXPTolerance");
sif->DeleteValue("GPU", "PGXPDepthClearThreshold");
sif->DeleteValue("CPU", "RecompilerMemoryExceptions");
sif->DeleteValue("CPU", "RecompilerBlockLinking");
sif->DeleteValue("CPU", "FastmemMode");
sif->DeleteValue("TextureReplacements", "EnableVRAMWriteReplacements");
sif->DeleteValue("TextureReplacements", "PreloadTextures");
sif->DeleteValue("TextureReplacements", "DumpVRAMWrites");
sif->DeleteValue("TextureReplacements", "DumpVRAMWriteForceAlphaChannel");
sif->DeleteValue("TextureReplacements", "DumpVRAMWriteWidthThreshold");
sif->DeleteValue("TextureReplacements", "DumpVRAMWriteHeightThreshold");
sif->DeleteValue("Hacks", "UseOldMDECRoutines");
sif->DeleteValue("Hacks", "DMAMaxSliceTicks"); sif->DeleteValue("Hacks", "DMAMaxSliceTicks");
sif->DeleteValue("Hacks", "DMAHaltTicks"); sif->DeleteValue("Hacks", "DMAHaltTicks");
sif->DeleteValue("Hacks", "GPUFIFOSize"); sif->DeleteValue("Hacks", "GPUFIFOSize");
sif->DeleteValue("Hacks", "GPUMaxRunAhead"); sif->DeleteValue("Hacks", "GPUMaxRunAhead");
sif->DeleteValue("GPU", "UseDebugDevice"); sif->DeleteValue("CPU", "RecompilerMemoryExceptions");
sif->DeleteValue("GPU", "DisableShaderCache"); sif->DeleteValue("CPU", "RecompilerBlockLinking");
sif->DeleteValue("GPU", "DisableDualSourceBlend"); sif->DeleteValue("CPU", "FastmemMode");
sif->DeleteValue("GPU", "DisableFramebufferFetch");
sif->DeleteValue("GPU", "DisableTextureBuffers");
sif->DeleteValue("GPU", "DisableTextureCopyToSelf");
sif->DeleteValue("Display", "StretchVertically");
sif->DeleteValue("Main", "IncreaseTimerResolution");
sif->DeleteValue("CDROM", "MechaconVersion"); sif->DeleteValue("CDROM", "MechaconVersion");
sif->DeleteValue("CDROM", "AllowBootingWithoutSBIFile"); sif->DeleteValue("CDROM", "AllowBootingWithoutSBIFile");
sif->DeleteValue("General", "CreateSaveStateBackups");
sif->DeleteValue("PCDrv", "Enabled"); sif->DeleteValue("PCDrv", "Enabled");
sif->DeleteValue("PCDrv", "EnableWrites"); sif->DeleteValue("PCDrv", "EnableWrites");
sif->DeleteValue("PCDrv", "Root"); sif->DeleteValue("PCDrv", "Root");
@ -486,4 +310,4 @@ void AdvancedSettingsWidget::onResetToDefaultClicked()
while (m_ui.tweakOptionTable->rowCount() > 0) while (m_ui.tweakOptionTable->rowCount() > 0)
m_ui.tweakOptionTable->removeRow(m_ui.tweakOptionTable->rowCount() - 1); m_ui.tweakOptionTable->removeRow(m_ui.tweakOptionTable->rowCount() - 1);
addTweakOptions(); addTweakOptions();
} }

View File

@ -17,6 +17,12 @@ public:
explicit AdvancedSettingsWidget(SettingsWindow* dialog, QWidget* parent); explicit AdvancedSettingsWidget(SettingsWindow* dialog, QWidget* parent);
~AdvancedSettingsWidget(); ~AdvancedSettingsWidget();
Q_SIGNALS:
void onShowDebugOptionsChanged(bool enabled);
private Q_SLOTS:
void onShowDebugOptionsStateChanged();
private: private:
struct TweakOption struct TweakOption
{ {

View File

@ -40,6 +40,8 @@ ConsoleSettingsWidget::ConsoleSettingsWidget(SettingsWindow* dialog, QWidget* pa
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.region, "Console", "Region", &Settings::ParseConsoleRegionName, SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.region, "Console", "Region", &Settings::ParseConsoleRegionName,
&Settings::GetConsoleRegionName, Settings::DEFAULT_CONSOLE_REGION); &Settings::GetConsoleRegionName, Settings::DEFAULT_CONSOLE_REGION);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enable8MBRAM, "Console", "Enable8MBRAM", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enable8MBRAM, "Console", "Enable8MBRAM", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableAllEnhancements, "Main", "DisableAllEnhancements",
false);
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.cpuExecutionMode, "CPU", "ExecutionMode", SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.cpuExecutionMode, "CPU", "ExecutionMode",
&Settings::ParseCPUExecutionMode, &Settings::GetCPUExecutionModeName, &Settings::ParseCPUExecutionMode, &Settings::GetCPUExecutionModeName,
Settings::DEFAULT_CPU_EXECUTION_MODE); Settings::DEFAULT_CPU_EXECUTION_MODE);
@ -72,6 +74,9 @@ ConsoleSettingsWidget::ConsoleSettingsWidget(SettingsWindow* dialog, QWidget* pa
"to use a larger heap size for " "to use a larger heap size for "
"this additional RAM to be usable. Titles which rely on memory mirrors may break, so it should only be used " "this additional RAM to be usable. Titles which rely on memory mirrors may break, so it should only be used "
"with compatible mods.")); "with compatible mods."));
dialog->registerWidgetHelp(m_ui.disableAllEnhancements, tr("Disable All Enhancements"), tr("Unchecked"),
tr("Disables all enhancement options, simulating the system as accurately as possible. "
"Use to quickly determine whether an enhancement is responsible for game bugs."));
dialog->registerWidgetHelp( dialog->registerWidgetHelp(
m_ui.cdromLoadImageToRAM, tr("Preload Image to RAM"), tr("Unchecked"), m_ui.cdromLoadImageToRAM, tr("Preload Image to RAM"), tr("Unchecked"),
tr("Loads the game image into RAM. Useful for network paths that may become unreliable during gameplay. In some " tr("Loads the game image into RAM. Useful for network paths that may become unreliable during gameplay. In some "

View File

@ -40,11 +40,22 @@
<widget class="QComboBox" name="region"/> <widget class="QComboBox" name="region"/>
</item> </item>
<item row="1" column="0" colspan="2"> <item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="enable8MBRAM"> <layout class="QGridLayout" name="gridLayout_2">
<property name="text"> <item row="0" column="0">
<string>Enable 8MB RAM (Dev Console)</string> <widget class="QCheckBox" name="enable8MBRAM">
</property> <property name="text">
</widget> <string>Enable 8MB RAM (Dev Console)</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="disableAllEnhancements">
<property name="text">
<string>Disable All Enhancements</string>
</property>
</widget>
</item>
</layout>
</item> </item>
</layout> </layout>
</widget> </widget>

View File

@ -1,305 +0,0 @@
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#include "displaysettingswidget.h"
#include "core/gpu.h"
#include "core/settings.h"
#include "qtutils.h"
#include "settingswindow.h"
#include "settingwidgetbinder.h"
#include <QtWidgets/QMessageBox>
// For enumerating adapters.
#ifdef _WIN32
#include "util/d3d11_device.h"
#include "util/d3d12_device.h"
#endif
#ifdef ENABLE_VULKAN
#include "util/vulkan_device.h"
#endif
DisplaySettingsWidget::DisplaySettingsWidget(SettingsWindow* dialog, QWidget* parent)
: QWidget(parent), m_dialog(dialog)
{
SettingsInterface* sif = dialog->getSettingsInterface();
m_ui.setupUi(this);
setupAdditionalUi();
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.renderer, "GPU", "Renderer", &Settings::ParseRendererName,
&Settings::GetRendererName, Settings::DEFAULT_GPU_RENDERER);
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.displayAspectRatio, "Display", "AspectRatio",
&Settings::ParseDisplayAspectRatio, &Settings::GetDisplayAspectRatioName,
Settings::DEFAULT_DISPLAY_ASPECT_RATIO);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.customAspectRatioNumerator, "Display",
"CustomAspectRatioNumerator", 1);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.customAspectRatioDenominator, "Display",
"CustomAspectRatioDenominator", 1);
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.displayCropMode, "Display", "CropMode",
&Settings::ParseDisplayCropMode, &Settings::GetDisplayCropModeName,
Settings::DEFAULT_DISPLAY_CROP_MODE);
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.displayAlignment, "Display", "Alignment",
&Settings::ParseDisplayAlignment, &Settings::GetDisplayAlignmentName,
Settings::DEFAULT_DISPLAY_ALIGNMENT);
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.displayScaling, "Display", "Scaling",
&Settings::ParseDisplayScaling, &Settings::GetDisplayScalingName,
Settings::DEFAULT_DISPLAY_SCALING);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.internalResolutionScreenshots, "Display",
"InternalResolutionScreenshots", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.vsync, "Display", "VSync", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.gpuThread, "GPU", "UseThread", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.threadedPresentation, "GPU", "ThreadedPresentation", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showOSDMessages, "Display", "ShowOSDMessages", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showFPS, "Display", "ShowFPS", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showSpeed, "Display", "ShowSpeed", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showResolution, "Display", "ShowResolution", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showCPU, "Display", "ShowCPU", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showGPU, "Display", "ShowGPU", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showInput, "Display", "ShowInputs", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showGPUStatistics, "Display", "ShowGPUStatistics", false);
connect(m_ui.renderer, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&DisplaySettingsWidget::populateGPUAdaptersAndResolutions);
connect(m_ui.adapter, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&DisplaySettingsWidget::onGPUAdapterIndexChanged);
connect(m_ui.fullscreenMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&DisplaySettingsWidget::onGPUFullscreenModeIndexChanged);
connect(m_ui.displayAspectRatio, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&DisplaySettingsWidget::onAspectRatioChanged);
populateGPUAdaptersAndResolutions();
onAspectRatioChanged();
dialog->registerWidgetHelp(
m_ui.renderer, tr("Renderer"), QString::fromUtf8(Settings::GetRendererDisplayName(Settings::DEFAULT_GPU_RENDERER)),
tr("Chooses the backend to use for rendering the console/game visuals. <br>Depending on your system and hardware, "
"Direct3D 11 and OpenGL hardware backends may be available. <br>The software renderer offers the best "
"compatibility, but is the slowest and does not offer any enhancements."));
dialog->registerWidgetHelp(
m_ui.adapter, tr("Adapter"), tr("(Default)"),
tr("If your system contains multiple GPUs or adapters, you can select which GPU you wish to use for the hardware "
"renderers. <br>This option is only supported in Direct3D and Vulkan. OpenGL will always use the default "
"device."));
dialog->registerWidgetHelp(m_ui.fullscreenMode, tr("Fullscreen Mode"), tr("Borderless Fullscreen"),
tr("Chooses the fullscreen resolution and frequency."));
dialog->registerWidgetHelp(
m_ui.displayAspectRatio, tr("Aspect Ratio"),
QString::fromUtf8(Settings::GetDisplayAspectRatioDisplayName(Settings::DEFAULT_DISPLAY_ASPECT_RATIO)),
tr("Changes the aspect ratio used to display the console's output to the screen. The default is Auto (Game Native) "
"which automatically adjusts the aspect ratio to match how a game would be shown on a typical TV of the era."));
dialog->registerWidgetHelp(
m_ui.displayCropMode, tr("Crop Mode"),
QString::fromUtf8(Settings::GetDisplayCropModeDisplayName(Settings::DEFAULT_DISPLAY_CROP_MODE)),
tr("Determines how much of the area typically not visible on a consumer TV set to crop/hide. <br>"
"Some games display content in the overscan area, or use it for screen effects. <br>May "
"not display correctly with the \"All Borders\" setting. \"Only Overscan\" offers a good "
"compromise between stability and hiding black borders."));
dialog->registerWidgetHelp(
m_ui.displayAlignment, tr("Position"),
QString::fromUtf8(Settings::GetDisplayAlignmentDisplayName(Settings::DEFAULT_DISPLAY_ALIGNMENT)),
tr("Determines the position on the screen when black borders must be added."));
dialog->registerWidgetHelp(
m_ui.displayScaling, tr("Scaling"), tr("Bilinear (Smooth)"),
tr("Determines how the emulated console's output is upscaled or downscaled to your monitor's resolution."));
dialog->registerWidgetHelp(m_ui.internalResolutionScreenshots, tr("Internal Resolution Screenshots"), tr("Unchecked"),
tr("Saves screenshots at internal render resolution and without postprocessing. If this "
"option is disabled, the screenshots will be taken at the window's resolution. "
"Internal resolution screenshots can be very large at high rendering scales."));
dialog->registerWidgetHelp(
m_ui.vsync, tr("VSync"), tr("Unchecked"),
tr("Enable this option to match DuckStation's refresh rate with your current monitor or screen. "
"VSync is automatically disabled when it is not possible (e.g. running at non-100% speed)."));
dialog->registerWidgetHelp(m_ui.threadedPresentation, tr("Threaded Presentation"), tr("Checked"),
tr("Presents frames on a background thread when fast forwarding or vsync is disabled. "
"This can measurably improve performance in the Vulkan renderer."));
dialog->registerWidgetHelp(m_ui.gpuThread, tr("Threaded Rendering"), tr("Checked"),
tr("Uses a second thread for drawing graphics. Currently only available for the software "
"renderer, but can provide a significant speed improvement, and is safe to use."));
dialog->registerWidgetHelp(m_ui.showOSDMessages, tr("Show OSD Messages"), tr("Checked"),
tr("Shows on-screen-display messages when events occur such as save states being "
"created/loaded, screenshots being taken, etc."));
dialog->registerWidgetHelp(m_ui.showFPS, tr("Show FPS"), tr("Unchecked"),
tr("Shows the internal frame rate of the game in the top-right corner of the display."));
dialog->registerWidgetHelp(
m_ui.showSpeed, tr("Show Emulation Speed"), tr("Unchecked"),
tr("Shows the current emulation speed of the system in the top-right corner of the display as a percentage."));
dialog->registerWidgetHelp(m_ui.showResolution, tr("Show Resolution"), tr("Unchecked"),
tr("Shows the resolution of the game in the top-right corner of the display."));
dialog->registerWidgetHelp(
m_ui.showCPU, tr("Show CPU Usage"), tr("Unchecked"),
tr("Shows the host's CPU usage based on threads in the top-right corner of the display. This does not display the "
"emulated system CPU's usage. If a value close to 100% is being displayed, this means your host's CPU is likely "
"the bottleneck. In this case, you should reduce enhancement-related settings such as overclocking."));
dialog->registerWidgetHelp(m_ui.showGPUStatistics, tr("Show GPU Statistics"), tr("Unchecked"),
tr("Shows information about the emulated GPU in the top-right corner of the display."));
dialog->registerWidgetHelp(m_ui.showGPU, tr("Show GPU Usage"), tr("Unchecked"),
tr("Shows the host's GPU usage in the top-right corner of the display."));
dialog->registerWidgetHelp(
m_ui.showInput, tr("Show Controller Input"), tr("Unchecked"),
tr("Shows the current controller state of the system in the bottom-left corner of the display."));
#ifdef _WIN32
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.blitSwapChain, "Display", "UseBlitSwapChain", false);
dialog->registerWidgetHelp(m_ui.blitSwapChain, tr("Use Blit Swap Chain"), tr("Unchecked"),
tr("Uses a blit presentation model instead of flipping when using the Direct3D 11 "
"renderer. This usually results in slower performance, but may be required for some "
"streaming applications, or to uncap framerates on some systems."));
#else
m_ui.blitSwapChain->setEnabled(false);
#endif
}
DisplaySettingsWidget::~DisplaySettingsWidget() = default;
void DisplaySettingsWidget::setupAdditionalUi()
{
for (u32 i = 0; i < static_cast<u32>(GPURenderer::Count); i++)
{
m_ui.renderer->addItem(QString::fromUtf8(Settings::GetRendererDisplayName(static_cast<GPURenderer>(i))));
}
for (u32 i = 0; i < static_cast<u32>(DisplayAspectRatio::Count); i++)
{
m_ui.displayAspectRatio->addItem(
QString::fromUtf8(Settings::GetDisplayAspectRatioDisplayName(static_cast<DisplayAspectRatio>(i))));
}
for (u32 i = 0; i < static_cast<u32>(DisplayCropMode::Count); i++)
{
m_ui.displayCropMode->addItem(
QString::fromUtf8(Settings::GetDisplayCropModeDisplayName(static_cast<DisplayCropMode>(i))));
}
for (u32 i = 0; i < static_cast<u32>(DisplayScalingMode::Count); i++)
{
m_ui.displayScaling->addItem(
QString::fromUtf8(Settings::GetDisplayScalingDisplayName(static_cast<DisplayScalingMode>(i))));
}
for (u32 i = 0; i < static_cast<u32>(DisplayAlignment::Count); i++)
{
m_ui.displayAlignment->addItem(
QString::fromUtf8(Settings::GetDisplayAlignmentDisplayName(static_cast<DisplayAlignment>(i))));
}
}
void DisplaySettingsWidget::populateGPUAdaptersAndResolutions()
{
GPUDevice::AdapterAndModeList aml;
bool thread_supported = false;
bool threaded_presentation_supported = false;
switch (static_cast<GPURenderer>(m_ui.renderer->currentIndex()))
{
#ifdef _WIN32
case GPURenderer::HardwareD3D11:
aml = D3D11Device::StaticGetAdapterAndModeList();
break;
case GPURenderer::HardwareD3D12:
aml = D3D12Device::StaticGetAdapterAndModeList();
break;
#endif
#ifdef __APPLE__
case GPURenderer::HardwareMetal:
aml = GPUDevice::WrapGetMetalAdapterAndModeList();
break;
#endif
#ifdef ENABLE_VULKAN
case GPURenderer::HardwareVulkan:
aml = VulkanDevice::StaticGetAdapterAndModeList();
threaded_presentation_supported = true;
break;
#endif
case GPURenderer::Software:
thread_supported = true;
break;
default:
break;
}
{
const std::string current_adapter(m_dialog->getEffectiveStringValue("GPU", "Adapter", ""));
QSignalBlocker blocker(m_ui.adapter);
// add the default entry - we'll fall back to this if the GPU no longer exists, or there's no options
m_ui.adapter->clear();
m_ui.adapter->addItem(tr("(Default)"));
// add the other adapters
for (const std::string& adapter_name : aml.adapter_names)
{
m_ui.adapter->addItem(QString::fromStdString(adapter_name));
if (adapter_name == current_adapter)
m_ui.adapter->setCurrentIndex(m_ui.adapter->count() - 1);
}
// disable it if we don't have a choice
m_ui.adapter->setEnabled(!aml.adapter_names.empty());
}
{
const std::string current_mode(m_dialog->getEffectiveStringValue("GPU", "FullscreenMode", ""));
QSignalBlocker blocker(m_ui.fullscreenMode);
m_ui.fullscreenMode->clear();
m_ui.fullscreenMode->addItem(tr("Borderless Fullscreen"));
m_ui.fullscreenMode->setCurrentIndex(0);
for (const std::string& mode_name : aml.fullscreen_modes)
{
m_ui.fullscreenMode->addItem(QString::fromStdString(mode_name));
if (mode_name == current_mode)
m_ui.fullscreenMode->setCurrentIndex(m_ui.fullscreenMode->count() - 1);
}
// disable it if we don't have a choice
m_ui.fullscreenMode->setEnabled(!aml.fullscreen_modes.empty());
}
m_ui.gpuThread->setEnabled(thread_supported);
m_ui.threadedPresentation->setEnabled(threaded_presentation_supported);
}
void DisplaySettingsWidget::onGPUAdapterIndexChanged()
{
if (m_ui.adapter->currentIndex() == 0)
{
// default
m_dialog->removeSettingValue("GPU", "Adapter");
return;
}
m_dialog->setStringSettingValue("GPU", "Adapter", m_ui.adapter->currentText().toUtf8().constData());
}
void DisplaySettingsWidget::onGPUFullscreenModeIndexChanged()
{
if (m_ui.fullscreenMode->currentIndex() == 0)
{
// default
m_dialog->removeSettingValue("GPU", "FullscreenMode");
return;
}
m_dialog->setStringSettingValue("GPU", "FullscreenMode", m_ui.fullscreenMode->currentText().toUtf8().constData());
}
void DisplaySettingsWidget::onAspectRatioChanged()
{
const DisplayAspectRatio ratio =
Settings::ParseDisplayAspectRatio(
m_dialog
->getEffectiveStringValue("Display", "AspectRatio",
Settings::GetDisplayAspectRatioName(Settings::DEFAULT_DISPLAY_ASPECT_RATIO))
.c_str())
.value_or(Settings::DEFAULT_DISPLAY_ASPECT_RATIO);
const bool is_custom = (ratio == DisplayAspectRatio::Custom);
m_ui.customAspectRatioNumerator->setVisible(is_custom);
m_ui.customAspectRatioDenominator->setVisible(is_custom);
m_ui.customAspectRatioSeparator->setVisible(is_custom);
}

View File

@ -1,33 +0,0 @@
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#pragma once
#include <QtWidgets/QWidget>
#include "ui_displaysettingswidget.h"
class PostProcessingChainConfigWidget;
class SettingsWindow;
class DisplaySettingsWidget : public QWidget
{
Q_OBJECT
public:
DisplaySettingsWidget(SettingsWindow* dialog, QWidget* parent);
~DisplaySettingsWidget();
private Q_SLOTS:
void populateGPUAdaptersAndResolutions();
void onGPUAdapterIndexChanged();
void onGPUFullscreenModeIndexChanged();
void onAspectRatioChanged();
private:
void setupAdditionalUi();
Ui::DisplaySettingsWidget m_ui;
SettingsWindow* m_dialog;
};

View File

@ -1,270 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DisplaySettingsWidget</class>
<widget class="QWidget" name="DisplaySettingsWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>485</width>
<height>525</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="basicGroupBox">
<property name="title">
<string>Basic</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Renderer:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="renderer"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Adapter:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="adapter"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Fullscreen Mode:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="fullscreenMode"/>
</item>
<item row="3" column="0" colspan="2">
<layout class="QGridLayout" name="basicCheckboxGridLayout">
<item row="1" column="0">
<widget class="QCheckBox" name="vsync">
<property name="text">
<string>VSync</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="gpuThread">
<property name="text">
<string>Threaded Rendering</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="threadedPresentation">
<property name="text">
<string>Threaded Presentation</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="blitSwapChain">
<property name="text">
<string>Use Blit Swap Chain</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Screen Display</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Aspect Ratio:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0,0,0">
<item>
<widget class="QComboBox" name="displayAspectRatio"/>
</item>
<item>
<widget class="QSpinBox" name="customAspectRatioNumerator">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="customAspectRatioSeparator">
<property name="text">
<string>:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="customAspectRatioDenominator">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Crop:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="displayCropMode"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Position:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="displayAlignment"/>
</item>
<item row="4" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QCheckBox" name="internalResolutionScreenshots">
<property name="text">
<string>Internal Resolution Screenshots</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Scaling:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="displayScaling"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>On-Screen Display</string>
</property>
<layout class="QGridLayout" name="formLayout_5">
<item row="3" column="0">
<widget class="QCheckBox" name="showSpeed">
<property name="text">
<string>Show Emulation Speed</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="showCPU">
<property name="text">
<string>Show CPU Usage</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="showOSDMessages">
<property name="text">
<string>Show OSD Messages</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="showFPS">
<property name="text">
<string>Show FPS</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="showInput">
<property name="text">
<string>Show Controller Input</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="showResolution">
<property name="text">
<string>Show Resolution</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="showGPU">
<property name="text">
<string>Show GPU Usage</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="showGPUStatistics">
<property name="text">
<string>Show GPU Statistics</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -21,12 +21,11 @@
<ClCompile Include="emulationsettingswidget.cpp" /> <ClCompile Include="emulationsettingswidget.cpp" />
<ClCompile Include="debuggermodels.cpp" /> <ClCompile Include="debuggermodels.cpp" />
<ClCompile Include="debuggerwindow.cpp" /> <ClCompile Include="debuggerwindow.cpp" />
<ClCompile Include="enhancementsettingswidget.cpp" />
<ClCompile Include="foldersettingswidget.cpp" /> <ClCompile Include="foldersettingswidget.cpp" />
<ClCompile Include="gamelistmodel.cpp" /> <ClCompile Include="gamelistmodel.cpp" />
<ClCompile Include="gamelistsearchdirectoriesmodel.cpp" /> <ClCompile Include="gamelistsearchdirectoriesmodel.cpp" />
<ClCompile Include="generalsettingswidget.cpp" /> <ClCompile Include="interfacesettingswidget.cpp" />
<ClCompile Include="displaysettingswidget.cpp" /> <ClCompile Include="graphicssettingswidget.cpp" />
<ClCompile Include="hotkeysettingswidget.cpp" /> <ClCompile Include="hotkeysettingswidget.cpp" />
<ClCompile Include="inputbindingdialog.cpp" /> <ClCompile Include="inputbindingdialog.cpp" />
<ClCompile Include="inputbindingwidgets.cpp" /> <ClCompile Include="inputbindingwidgets.cpp" />
@ -62,12 +61,10 @@
<QtMoc Include="cheatmanagerdialog.h" /> <QtMoc Include="cheatmanagerdialog.h" />
<QtMoc Include="cheatcodeeditordialog.h" /> <QtMoc Include="cheatcodeeditordialog.h" />
<QtMoc Include="coverdownloaddialog.h" /> <QtMoc Include="coverdownloaddialog.h" />
<QtMoc Include="enhancementsettingswidget.h" />
<QtMoc Include="memorycardsettingswidget.h" /> <QtMoc Include="memorycardsettingswidget.h" />
<QtMoc Include="memorycardeditorwindow.h" /> <QtMoc Include="memorycardeditorwindow.h" />
<QtMoc Include="displaywidget.h" /> <QtMoc Include="displaywidget.h" />
<QtMoc Include="generalsettingswidget.h" /> <QtMoc Include="interfacesettingswidget.h" />
<QtMoc Include="displaysettingswidget.h" />
<QtMoc Include="hotkeysettingswidget.h" /> <QtMoc Include="hotkeysettingswidget.h" />
<QtMoc Include="inputbindingwidgets.h" /> <QtMoc Include="inputbindingwidgets.h" />
<QtMoc Include="advancedsettingswidget.h" /> <QtMoc Include="advancedsettingswidget.h" />
@ -88,6 +85,7 @@
<ClInclude Include="controllersettingwidgetbinder.h" /> <ClInclude Include="controllersettingwidgetbinder.h" />
<QtMoc Include="memoryviewwidget.h" /> <QtMoc Include="memoryviewwidget.h" />
<QtMoc Include="logwindow.h" /> <QtMoc Include="logwindow.h" />
<QtMoc Include="graphicssettingswidget.h" />
<ClInclude Include="pch.h" /> <ClInclude Include="pch.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
<ClInclude Include="settingwidgetbinder.h" /> <ClInclude Include="settingwidgetbinder.h" />
@ -122,13 +120,10 @@
<QtUi Include="emulationsettingswidget.ui"> <QtUi Include="emulationsettingswidget.ui">
<FileType>Document</FileType> <FileType>Document</FileType>
</QtUi> </QtUi>
<QtUi Include="enhancementsettingswidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="gamelistsettingswidget.ui"> <QtUi Include="gamelistsettingswidget.ui">
<FileType>Document</FileType> <FileType>Document</FileType>
</QtUi> </QtUi>
<QtUi Include="generalsettingswidget.ui"> <QtUi Include="interfacesettingswidget.ui">
<FileType>Document</FileType> <FileType>Document</FileType>
</QtUi> </QtUi>
<QtUi Include="mainwindow.ui"> <QtUi Include="mainwindow.ui">
@ -137,9 +132,6 @@
<QtUi Include="settingswindow.ui"> <QtUi Include="settingswindow.ui">
<FileType>Document</FileType> <FileType>Document</FileType>
</QtUi> </QtUi>
<QtUi Include="displaysettingswidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="advancedsettingswidget.ui"> <QtUi Include="advancedsettingswidget.ui">
<FileType>Document</FileType> <FileType>Document</FileType>
</QtUi> </QtUi>
@ -243,7 +235,6 @@
<ClCompile Include="$(IntDir)moc_coverdownloaddialog.cpp" /> <ClCompile Include="$(IntDir)moc_coverdownloaddialog.cpp" />
<ClCompile Include="$(IntDir)moc_displaywidget.cpp" /> <ClCompile Include="$(IntDir)moc_displaywidget.cpp" />
<ClCompile Include="$(IntDir)moc_emulationsettingswidget.cpp" /> <ClCompile Include="$(IntDir)moc_emulationsettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_enhancementsettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_foldersettingswidget.cpp" /> <ClCompile Include="$(IntDir)moc_foldersettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_gamelistmodel.cpp" /> <ClCompile Include="$(IntDir)moc_gamelistmodel.cpp" />
<ClCompile Include="$(IntDir)moc_gamelistrefreshthread.cpp" /> <ClCompile Include="$(IntDir)moc_gamelistrefreshthread.cpp" />
@ -253,13 +244,13 @@
<ClCompile Include="$(IntDir)moc_gamesummarywidget.cpp" /> <ClCompile Include="$(IntDir)moc_gamesummarywidget.cpp" />
<ClCompile Include="$(IntDir)moc_gdbconnection.cpp" /> <ClCompile Include="$(IntDir)moc_gdbconnection.cpp" />
<ClCompile Include="$(IntDir)moc_gdbserver.cpp" /> <ClCompile Include="$(IntDir)moc_gdbserver.cpp" />
<ClCompile Include="$(IntDir)moc_generalsettingswidget.cpp" /> <ClCompile Include="$(IntDir)moc_graphicssettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_debuggermodels.cpp" /> <ClCompile Include="$(IntDir)moc_debuggermodels.cpp" />
<ClCompile Include="$(IntDir)moc_debuggerwindow.cpp" /> <ClCompile Include="$(IntDir)moc_debuggerwindow.cpp" />
<ClCompile Include="$(IntDir)moc_displaysettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_hotkeysettingswidget.cpp" /> <ClCompile Include="$(IntDir)moc_hotkeysettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_inputbindingdialog.cpp" /> <ClCompile Include="$(IntDir)moc_inputbindingdialog.cpp" />
<ClCompile Include="$(IntDir)moc_inputbindingwidgets.cpp" /> <ClCompile Include="$(IntDir)moc_inputbindingwidgets.cpp" />
<ClCompile Include="$(IntDir)moc_interfacesettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_logwindow.cpp" /> <ClCompile Include="$(IntDir)moc_logwindow.cpp" />
<ClCompile Include="$(IntDir)moc_mainwindow.cpp" /> <ClCompile Include="$(IntDir)moc_mainwindow.cpp" />
<ClCompile Include="$(IntDir)moc_memorycardsettingswidget.cpp" /> <ClCompile Include="$(IntDir)moc_memorycardsettingswidget.cpp" />
@ -335,6 +326,9 @@
<QtUi Include="debuggeraddbreakpointdialog.ui"> <QtUi Include="debuggeraddbreakpointdialog.ui">
<FileType>Document</FileType> <FileType>Document</FileType>
</QtUi> </QtUi>
<QtUi Include="graphicssettingswidget.ui">
<FileType>Document</FileType>
</QtUi>
<None Include="translations\duckstation-qt_es-es.ts" /> <None Include="translations\duckstation-qt_es-es.ts" />
<None Include="translations\duckstation-qt_tr.ts" /> <None Include="translations\duckstation-qt_tr.ts" />
</ItemGroup> </ItemGroup>

View File

@ -13,7 +13,7 @@
<ClCompile Include="audiosettingswidget.cpp" /> <ClCompile Include="audiosettingswidget.cpp" />
<ClCompile Include="displaywidget.cpp" /> <ClCompile Include="displaywidget.cpp" />
<ClCompile Include="qtprogresscallback.cpp" /> <ClCompile Include="qtprogresscallback.cpp" />
<ClCompile Include="generalsettingswidget.cpp" /> <ClCompile Include="interfacesettingswidget.cpp" />
<ClCompile Include="advancedsettingswidget.cpp" /> <ClCompile Include="advancedsettingswidget.cpp" />
<ClCompile Include="gdbconnection.cpp" /> <ClCompile Include="gdbconnection.cpp" />
<ClCompile Include="gdbserver.cpp" /> <ClCompile Include="gdbserver.cpp" />
@ -25,8 +25,6 @@
<ClCompile Include="gamelistsearchdirectoriesmodel.cpp" /> <ClCompile Include="gamelistsearchdirectoriesmodel.cpp" />
<ClCompile Include="autoupdaterdialog.cpp" /> <ClCompile Include="autoupdaterdialog.cpp" />
<ClCompile Include="biossettingswidget.cpp" /> <ClCompile Include="biossettingswidget.cpp" />
<ClCompile Include="enhancementsettingswidget.cpp" />
<ClCompile Include="displaysettingswidget.cpp" />
<ClCompile Include="memorycardeditorwindow.cpp" /> <ClCompile Include="memorycardeditorwindow.cpp" />
<ClCompile Include="postprocessingsettingswidget.cpp" /> <ClCompile Include="postprocessingsettingswidget.cpp" />
<ClCompile Include="cheatmanagerdialog.cpp" /> <ClCompile Include="cheatmanagerdialog.cpp" />
@ -105,18 +103,12 @@
<ClCompile Include="$(IntDir)moc_debuggerwindow.cpp"> <ClCompile Include="$(IntDir)moc_debuggerwindow.cpp">
<Filter>moc</Filter> <Filter>moc</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="$(IntDir)moc_displaysettingswidget.cpp">
<Filter>moc</Filter>
</ClCompile>
<ClCompile Include="$(IntDir)moc_displaywidget.cpp"> <ClCompile Include="$(IntDir)moc_displaywidget.cpp">
<Filter>moc</Filter> <Filter>moc</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="$(IntDir)moc_emulationsettingswidget.cpp"> <ClCompile Include="$(IntDir)moc_emulationsettingswidget.cpp">
<Filter>moc</Filter> <Filter>moc</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="$(IntDir)moc_enhancementsettingswidget.cpp">
<Filter>moc</Filter>
</ClCompile>
<ClCompile Include="$(IntDir)moc_foldersettingswidget.cpp"> <ClCompile Include="$(IntDir)moc_foldersettingswidget.cpp">
<Filter>moc</Filter> <Filter>moc</Filter>
</ClCompile> </ClCompile>
@ -144,9 +136,6 @@
<ClCompile Include="$(IntDir)moc_gdbserver.cpp"> <ClCompile Include="$(IntDir)moc_gdbserver.cpp">
<Filter>moc</Filter> <Filter>moc</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="$(IntDir)moc_generalsettingswidget.cpp">
<Filter>moc</Filter>
</ClCompile>
<ClCompile Include="$(IntDir)moc_hotkeysettingswidget.cpp"> <ClCompile Include="$(IntDir)moc_hotkeysettingswidget.cpp">
<Filter>moc</Filter> <Filter>moc</Filter>
</ClCompile> </ClCompile>
@ -186,6 +175,13 @@
<ClCompile Include="$(IntDir)moc_setupwizarddialog.cpp"> <ClCompile Include="$(IntDir)moc_setupwizarddialog.cpp">
<Filter>moc</Filter> <Filter>moc</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="graphicssettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_graphicssettingswidget.cpp">
<Filter>moc</Filter>
</ClCompile>
<ClCompile Include="$(IntDir)moc_interfacesettingswidget.cpp">
<Filter>moc</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="qtutils.h" /> <ClInclude Include="qtutils.h" />
@ -216,7 +212,7 @@
<QtMoc Include="inputbindingwidgets.h" /> <QtMoc Include="inputbindingwidgets.h" />
<QtMoc Include="audiosettingswidget.h" /> <QtMoc Include="audiosettingswidget.h" />
<QtMoc Include="displaywidget.h" /> <QtMoc Include="displaywidget.h" />
<QtMoc Include="generalsettingswidget.h" /> <QtMoc Include="interfacesettingswidget.h" />
<QtMoc Include="qtprogresscallback.h" /> <QtMoc Include="qtprogresscallback.h" />
<QtMoc Include="advancedsettingswidget.h" /> <QtMoc Include="advancedsettingswidget.h" />
<QtMoc Include="gdbconnection.h" /> <QtMoc Include="gdbconnection.h" />
@ -228,9 +224,7 @@
<QtMoc Include="gamelistsearchdirectoriesmodel.h" /> <QtMoc Include="gamelistsearchdirectoriesmodel.h" />
<QtMoc Include="autoupdaterdialog.h" /> <QtMoc Include="autoupdaterdialog.h" />
<QtMoc Include="biossettingswidget.h" /> <QtMoc Include="biossettingswidget.h" />
<QtMoc Include="enhancementsettingswidget.h" />
<QtMoc Include="memorycardeditorwindow.h" /> <QtMoc Include="memorycardeditorwindow.h" />
<QtMoc Include="displaysettingswidget.h" />
<QtMoc Include="postprocessingsettingswidget.h" /> <QtMoc Include="postprocessingsettingswidget.h" />
<QtMoc Include="cheatmanagerdialog.h" /> <QtMoc Include="cheatmanagerdialog.h" />
<QtMoc Include="cheatcodeeditordialog.h" /> <QtMoc Include="cheatcodeeditordialog.h" />
@ -251,6 +245,7 @@
<QtMoc Include="colorpickerbutton.h" /> <QtMoc Include="colorpickerbutton.h" />
<QtMoc Include="setupwizarddialog.h" /> <QtMoc Include="setupwizarddialog.h" />
<QtMoc Include="logwindow.h" /> <QtMoc Include="logwindow.h" />
<QtMoc Include="graphicssettingswidget.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtUi Include="consolesettingswidget.ui" /> <QtUi Include="consolesettingswidget.ui" />
@ -258,14 +253,12 @@
<QtUi Include="mainwindow.ui" /> <QtUi Include="mainwindow.ui" />
<QtUi Include="settingswindow.ui" /> <QtUi Include="settingswindow.ui" />
<QtUi Include="audiosettingswidget.ui" /> <QtUi Include="audiosettingswidget.ui" />
<QtUi Include="generalsettingswidget.ui" /> <QtUi Include="interfacesettingswidget.ui" />
<QtUi Include="advancedsettingswidget.ui" /> <QtUi Include="advancedsettingswidget.ui" />
<QtUi Include="aboutdialog.ui" /> <QtUi Include="aboutdialog.ui" />
<QtUi Include="inputbindingdialog.ui" /> <QtUi Include="inputbindingdialog.ui" />
<QtUi Include="autoupdaterdialog.ui" /> <QtUi Include="autoupdaterdialog.ui" />
<QtUi Include="biossettingswidget.ui" /> <QtUi Include="biossettingswidget.ui" />
<QtUi Include="enhancementsettingswidget.ui" />
<QtUi Include="displaysettingswidget.ui" />
<QtUi Include="postprocessingsettingswidget.ui" /> <QtUi Include="postprocessingsettingswidget.ui" />
<QtUi Include="memorycardeditorwindow.ui" /> <QtUi Include="memorycardeditorwindow.ui" />
<QtUi Include="cheatmanagerdialog.ui" /> <QtUi Include="cheatmanagerdialog.ui" />
@ -293,6 +286,7 @@
<QtUi Include="setupwizarddialog.ui" /> <QtUi Include="setupwizarddialog.ui" />
<QtUi Include="controllerledsettingsdialog.ui" /> <QtUi Include="controllerledsettingsdialog.ui" />
<QtUi Include="debuggeraddbreakpointdialog.ui" /> <QtUi Include="debuggeraddbreakpointdialog.ui" />
<QtUi Include="graphicssettingswidget.ui" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Natvis Include="qt5.natvis" /> <Natvis Include="qt5.natvis" />

View File

@ -1,223 +0,0 @@
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#include "enhancementsettingswidget.h"
#include "core/gpu.h"
#include "core/settings.h"
#include "qtutils.h"
#include "settingswindow.h"
#include "settingwidgetbinder.h"
EnhancementSettingsWidget::EnhancementSettingsWidget(SettingsWindow* dialog, QWidget* parent)
: QWidget(parent), m_dialog(dialog)
{
SettingsInterface* sif = dialog->getSettingsInterface();
m_ui.setupUi(this);
setupAdditionalUi();
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.resolutionScale, "GPU", "ResolutionScale", 1);
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.textureFiltering, "GPU", "TextureFilter",
&Settings::ParseTextureFilterName, &Settings::GetTextureFilterName,
Settings::DEFAULT_GPU_TEXTURE_FILTER);
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.gpuLineDetectMode, "GPU", "LineDetectMode",
&Settings::ParseLineDetectModeName, &Settings::GetLineDetectModeName,
Settings::DEFAULT_GPU_LINE_DETECT_MODE);
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.gpuDownsampleMode, "GPU", "DownsampleMode",
&Settings::ParseDownsampleModeName, &Settings::GetDownsampleModeName,
Settings::DEFAULT_GPU_DOWNSAMPLE_MODE);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.gpuDownsampleScale, "GPU", "DownsampleScale", 1);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.trueColor, "GPU", "TrueColor", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.debanding, "GPU", "Debanding", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.scaledDithering, "GPU", "ScaledDithering", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableInterlacing, "GPU", "DisableInterlacing", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.forceNTSCTimings, "GPU", "ForceNTSCTimings", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.force43For24Bit, "Display", "Force4_3For24Bit", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chromaSmoothingFor24Bit, "GPU", "ChromaSmoothing24Bit", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.widescreenHack, "GPU", "WidescreenHack", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useSoftwareRendererForReadbacks, "GPU",
"UseSoftwareRendererForReadbacks", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpEnable, "GPU", "PGXPEnable", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpCulling, "GPU", "PGXPCulling", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpTextureCorrection, "GPU", "PGXPTextureCorrection", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpColorCorrection, "GPU", "PGXPColorCorrection", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpDepthBuffer, "GPU", "PGXPDepthBuffer", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpPreserveProjPrecision, "GPU", "PGXPPreserveProjFP", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpCPU, "GPU", "PGXPCPU", false);
connect(m_ui.resolutionScale, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&EnhancementSettingsWidget::onTrueColorChanged);
connect(m_ui.gpuDownsampleMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&EnhancementSettingsWidget::updateDownsampleScaleVisible);
connect(m_ui.trueColor, &QCheckBox::stateChanged, this, &EnhancementSettingsWidget::onTrueColorChanged);
updateDownsampleScaleVisible();
onTrueColorChanged();
connect(m_ui.pgxpEnable, &QCheckBox::stateChanged, this, &EnhancementSettingsWidget::updatePGXPSettingsEnabled);
connect(m_ui.pgxpTextureCorrection, &QCheckBox::stateChanged, this,
&EnhancementSettingsWidget::updatePGXPSettingsEnabled);
updatePGXPSettingsEnabled();
dialog->registerWidgetHelp(
m_ui.gpuDownsampleMode, tr("Downsampling"), tr("Disabled"),
tr("Downsamples the rendered image prior to displaying it. Can improve overall image quality in mixed 2D/3D games, "
"but should be disabled for pure 3D games. Only applies to the hardware renderers."));
dialog->registerWidgetHelp(m_ui.gpuDownsampleScale, tr("Downsampling Display Scale"), tr("1x"),
tr("Selects the resolution scale that will be applied to the final image. 1x will "
"downsample to the original console resolution."));
dialog->registerWidgetHelp(
m_ui.disableInterlacing, tr("Disable Interlacing"), tr("Checked"),
tr(
"Forces the rendering and display of frames to progressive mode. <br>This removes the \"combing\" effect seen in "
"480i games by rendering them in 480p. Usually safe to enable.<br> "
"<b><u>May not be compatible with all games.</u></b>"));
dialog->registerWidgetHelp(
m_ui.resolutionScale, tr("Resolution Scale"), "1x",
tr("Setting this beyond 1x will enhance the resolution of rendered 3D polygons and lines. Only applies "
"to the hardware backends. <br>This option is usually safe, with most games looking fine at "
"higher resolutions. Higher resolutions require a more powerful GPU."));
dialog->registerWidgetHelp(
m_ui.trueColor, tr("True Color Rendering"), tr("Checked"),
tr("Forces the precision of colours output to the console's framebuffer to use the full 8 bits of precision per "
"channel. This produces nicer looking gradients at the cost of making some colours look slightly different. "
"Disabling the option also enables dithering, which makes the transition between colours less sharp by applying "
"a pattern around those pixels. Most games are compatible with this option, but there is a number which aren't "
"and will have broken effects with it enabled. Only applies to the hardware renderers."));
dialog->registerWidgetHelp(
m_ui.debanding, tr("True Color Debanding"), tr("Unchecked"),
tr("Applies modern dithering techniques to further smooth out gradients when true color is enabled. "
"This debanding is performed during rendering (as opposed to a post-processing step), which allows it to be "
"fast while preserving detail. "
"Debanding increases the file size of screenshots due to the subtle dithering pattern present in screenshots."));
dialog->registerWidgetHelp(
m_ui.scaledDithering, tr("Scaled Dithering"), tr("Checked"),
tr("Scales the dither pattern to the resolution scale of the emulated GPU. This makes the dither pattern much less "
"obvious at higher resolutions. <br>Usually safe to enable, and only supported by the hardware renderers."));
dialog->registerWidgetHelp(m_ui.forceNTSCTimings, tr("Force NTSC Timings (60hz-on-PAL)"), tr("Unchecked"),
tr("Uses NTSC frame timings when the console is in PAL mode, forcing PAL games to run at "
"60hz. <br>For most games which "
"have a speed tied to the framerate, this will result in the game running "
"approximately 17% faster. <br>For variable "
"frame rate games, it may not affect the speed."));
dialog->registerWidgetHelp(
m_ui.force43For24Bit, tr("Force 4:3 For 24-bit Display"), tr("Unchecked"),
tr("Switches back to 4:3 display aspect ratio when displaying 24-bit content, usually FMVs."));
dialog->registerWidgetHelp(m_ui.chromaSmoothingFor24Bit, tr("Chroma Smoothing For 24-Bit Display"), tr("Unchecked"),
tr("Smooths out blockyness between colour transitions in 24-bit content, usually FMVs. "
"Only applies to the hardware renderers."));
dialog->registerWidgetHelp(
m_ui.textureFiltering, tr("Texture Filtering"),
QString::fromUtf8(Settings::GetTextureFilterDisplayName(Settings::DEFAULT_GPU_TEXTURE_FILTER)),
tr("Smooths out the blockiness of magnified textures on 3D object by using filtering. <br>Will have a "
"greater effect on higher resolution scales. Only applies to the hardware renderers. <br>The JINC2 and "
"especially xBR filtering modes are very demanding, and may not be worth the speed penalty."));
dialog->registerWidgetHelp(m_ui.gpuLineDetectMode, tr("Line Detection"),
QString::fromUtf8(Settings::GetLineDetectModeName(Settings::DEFAULT_GPU_LINE_DETECT_MODE)),
tr("Attempts to detect one pixel high/wide lines that rely on non-upscaled rasterization "
"behavior, filling in gaps introduced by upscaling."));
dialog->registerWidgetHelp(
m_ui.widescreenHack, tr("Widescreen Hack"), tr("Unchecked"),
tr("Scales vertex positions in screen-space to a widescreen aspect ratio, essentially "
"increasing the field of view from 4:3 to the chosen display aspect ratio in 3D games. <br>For 2D games, or "
"games which use pre-rendered backgrounds, this enhancement will not work as expected. <br><b><u>May not be "
"compatible with all games.</u></b>"));
dialog->registerWidgetHelp(
m_ui.useSoftwareRendererForReadbacks, tr("Use Software Renderer For Readbacks"), tr("Unchecked"),
tr("Runs the software renderer in parallel for VRAM readbacks. On some systems, this may result in greater "
"performance when using graphical enhancements with the hardware renderer."));
dialog->registerWidgetHelp(
m_ui.pgxpEnable, tr("Geometry Correction"), tr("Unchecked"),
tr("Reduces \"wobbly\" polygons and \"warping\" textures that are common in PS1 games. <br>Only "
"works with the hardware renderers. <b><u>May not be compatible with all games.</u></b>"));
dialog->registerWidgetHelp(m_ui.pgxpCulling, tr("Culling Correction"), tr("Checked"),
tr("Increases the precision of polygon culling, reducing the number of holes in geometry. "
"Requires geometry correction enabled."));
dialog->registerWidgetHelp(m_ui.pgxpTextureCorrection, tr("Perspective Correct Textures"), tr("Checked"),
tr("Uses perspective-correct interpolation for texture coordinates, straightening out "
"warped textures. Requires geometry correction enabled."));
dialog->registerWidgetHelp(
m_ui.pgxpColorCorrection, tr("Perspective Correct Colors"), tr("Unchecked"),
tr("Uses perspective-correct interpolation for vertex colors, which can improve visuals in some games, but cause "
"rendering errors in others. Requires geometry correction enabled."));
dialog->registerWidgetHelp(
m_ui.pgxpDepthBuffer, tr("Depth Buffer (Low Compatibility)"), tr("Unchecked"),
tr("Attempts to reduce polygon Z-fighting by testing pixels against the depth values from PGXP. Low compatibility, "
"but can work well in some games. Other games may need a threshold adjustment."));
dialog->registerWidgetHelp(
m_ui.pgxpPreserveProjPrecision, tr("Preserve Projection Precision"), tr("Unchecked"),
tr("Adds additional precision to PGXP data post-projection. May improve visuals in some games."));
dialog->registerWidgetHelp(m_ui.pgxpCPU, tr("CPU Mode (Very Slow)"), tr("Unchecked"),
tr("Uses PGXP for all instructions, not just memory operations. Required for PGXP to "
"correct wobble in some games, but has a very high performance cost."));
}
EnhancementSettingsWidget::~EnhancementSettingsWidget() = default;
void EnhancementSettingsWidget::onTrueColorChanged()
{
const int resolution_scale = m_ui.resolutionScale->currentIndex();
const bool true_color = m_ui.trueColor->isChecked();
const bool allow_scaled_dithering = (resolution_scale != 1 && !true_color);
const bool allow_debanding = true_color;
m_ui.scaledDithering->setEnabled(allow_scaled_dithering);
m_ui.debanding->setEnabled(allow_debanding);
}
void EnhancementSettingsWidget::updateDownsampleScaleVisible()
{
const GPUDownsampleMode mode =
Settings::ParseDownsampleModeName(
m_dialog
->getEffectiveStringValue("GPU", "DownsampleMode",
Settings::GetDownsampleModeName(Settings::DEFAULT_GPU_DOWNSAMPLE_MODE))
.c_str())
.value_or(Settings::DEFAULT_GPU_DOWNSAMPLE_MODE);
const bool visible = (mode == GPUDownsampleMode::Box);
if (visible && m_ui.gpuDownsampleLayout->indexOf(m_ui.gpuDownsampleScale) < 0)
{
m_ui.gpuDownsampleScale->setVisible(true);
m_ui.gpuDownsampleLayout->addWidget(m_ui.gpuDownsampleScale, 0);
}
else if (!visible && m_ui.gpuDownsampleLayout->indexOf(m_ui.gpuDownsampleScale) >= 0)
{
m_ui.gpuDownsampleScale->setVisible(false);
m_ui.gpuDownsampleLayout->removeWidget(m_ui.gpuDownsampleScale);
}
}
void EnhancementSettingsWidget::setupAdditionalUi()
{
QtUtils::FillComboBoxWithResolutionScales(m_ui.resolutionScale);
for (u32 i = 0; i < static_cast<u32>(GPUTextureFilter::Count); i++)
{
m_ui.textureFiltering->addItem(
QString::fromUtf8(Settings::GetTextureFilterDisplayName(static_cast<GPUTextureFilter>(i))));
}
for (u32 i = 0; i < static_cast<u32>(GPULineDetectMode::Count); i++)
{
m_ui.gpuLineDetectMode->addItem(
QString::fromUtf8(Settings::GetLineDetectModeDisplayName(static_cast<GPULineDetectMode>(i))));
}
for (u32 i = 0; i < static_cast<u32>(GPUDownsampleMode::Count); i++)
{
m_ui.gpuDownsampleMode->addItem(
QString::fromUtf8(Settings::GetDownsampleModeDisplayName(static_cast<GPUDownsampleMode>(i))));
}
}
void EnhancementSettingsWidget::updatePGXPSettingsEnabled()
{
const bool enabled = m_dialog->getEffectiveBoolValue("GPU", "PGXPEnable", false);
const bool tc_enabled = enabled && m_dialog->getEffectiveBoolValue("GPU", "PGXPTextureCorrection", true);
m_ui.pgxpCulling->setEnabled(enabled);
m_ui.pgxpTextureCorrection->setEnabled(enabled);
m_ui.pgxpColorCorrection->setEnabled(tc_enabled);
m_ui.pgxpDepthBuffer->setEnabled(enabled);
m_ui.pgxpPreserveProjPrecision->setEnabled(enabled);
m_ui.pgxpCPU->setEnabled(enabled);
}

View File

@ -1,31 +0,0 @@
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#pragma once
#include <QtWidgets/QWidget>
#include "ui_enhancementsettingswidget.h"
class SettingsWindow;
class EnhancementSettingsWidget : public QWidget
{
Q_OBJECT
public:
EnhancementSettingsWidget(SettingsWindow* dialog, QWidget* parent);
~EnhancementSettingsWidget();
private Q_SLOTS:
void onTrueColorChanged();
void updateDownsampleScaleVisible();
void updatePGXPSettingsEnabled();
private:
void setupAdditionalUi();
Ui::EnhancementSettingsWidget m_ui;
SettingsWindow* m_dialog;
};

View File

@ -1,243 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>EnhancementSettingsWidget</class>
<widget class="QWidget" name="EnhancementSettingsWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>640</width>
<height>480</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Rendering Enhancements</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Internal Resolution Scale:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="resolutionScale"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Texture Filtering:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="textureFiltering"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Downsampling:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<layout class="QHBoxLayout" name="gpuDownsampleLayout" stretch="1,0">
<item>
<widget class="QComboBox" name="gpuDownsampleMode"/>
</item>
<item>
<widget class="QSpinBox" name="gpuDownsampleScale">
<property name="suffix">
<string>x</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>16</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="5" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QCheckBox" name="trueColor">
<property name="text">
<string>True Color Rendering</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="debanding">
<property name="text">
<string>True Color Debanding</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="scaledDithering">
<property name="text">
<string>Scaled Dithering</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="widescreenHack">
<property name="text">
<string>Widescreen Hack</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="useSoftwareRendererForReadbacks">
<property name="text">
<string>Software Renderer Readbacks</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="disableInterlacing">
<property name="text">
<string>Disable Interlacing</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Line Detection:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="gpuLineDetectMode"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Display Enhancements</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QCheckBox" name="force43For24Bit">
<property name="text">
<string>Force 4:3 For FMVs</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="chromaSmoothingFor24Bit">
<property name="text">
<string>FMV Chroma Smoothing</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="forceNTSCTimings">
<property name="text">
<string>Force NTSC Timings</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>PGXP (Precision Geometry Transform Pipeline)</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="QCheckBox" name="pgxpCulling">
<property name="text">
<string>Culling Correction</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="pgxpTextureCorrection">
<property name="text">
<string>Perspective Correct Textures</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="pgxpEnable">
<property name="text">
<string>Geometry Correction</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="pgxpCPU">
<property name="text">
<string>CPU Mode (Very Slow)</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="pgxpDepthBuffer">
<property name="text">
<string>Depth Buffer (Low Compatibility)</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="pgxpPreserveProjPrecision">
<property name="text">
<string>Preserve Projection Precision</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="pgxpColorCorrection">
<property name="text">
<string>Perspective Correct Colors</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,861 @@
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#include "graphicssettingswidget.h"
#include "core/gpu.h"
#include "core/settings.h"
#include "qtutils.h"
#include "settingswindow.h"
#include "settingwidgetbinder.h"
// For enumerating adapters.
#ifdef _WIN32
#include "util/d3d11_device.h"
#include "util/d3d12_device.h"
#endif
#ifdef ENABLE_VULKAN
#include "util/vulkan_device.h"
#endif
static QVariant GetMSAAModeValue(uint multisamples, bool ssaa)
{
const uint userdata = (multisamples & 0x7FFFFFFFu) | (static_cast<uint>(ssaa) << 31);
return QVariant(userdata);
}
static void DecodeMSAAModeValue(const QVariant& userdata, uint* multisamples, bool* ssaa)
{
bool ok;
const uint value = userdata.toUInt(&ok);
if (!ok || value == 0)
{
*multisamples = 1;
*ssaa = false;
return;
}
*multisamples = value & 0x7FFFFFFFu;
*ssaa = (value & (1u << 31)) != 0u;
}
GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget* parent)
: QWidget(parent), m_dialog(dialog)
{
SettingsInterface* sif = dialog->getSettingsInterface();
m_ui.setupUi(this);
setupAdditionalUi();
removePlatformSpecificUi();
// Rendering Tab
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.renderer, "GPU", "Renderer", &Settings::ParseRendererName,
&Settings::GetRendererName, Settings::DEFAULT_GPU_RENDERER);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.vsync, "Display", "VSync", false);
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.displayAspectRatio, "Display", "AspectRatio",
&Settings::ParseDisplayAspectRatio, &Settings::GetDisplayAspectRatioName,
Settings::DEFAULT_DISPLAY_ASPECT_RATIO);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.customAspectRatioNumerator, "Display",
"CustomAspectRatioNumerator", 1);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.customAspectRatioDenominator, "Display",
"CustomAspectRatioDenominator", 1);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.widescreenHack, "GPU", "WidescreenHack", false);
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.displayCropMode, "Display", "CropMode",
&Settings::ParseDisplayCropMode, &Settings::GetDisplayCropModeName,
Settings::DEFAULT_DISPLAY_CROP_MODE);
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.displayScaling, "Display", "Scaling",
&Settings::ParseDisplayScaling, &Settings::GetDisplayScalingName,
Settings::DEFAULT_DISPLAY_SCALING);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.resolutionScale, "GPU", "ResolutionScale", 1);
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.textureFiltering, "GPU", "TextureFilter",
&Settings::ParseTextureFilterName, &Settings::GetTextureFilterName,
Settings::DEFAULT_GPU_TEXTURE_FILTER);
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.gpuDownsampleMode, "GPU", "DownsampleMode",
&Settings::ParseDownsampleModeName, &Settings::GetDownsampleModeName,
Settings::DEFAULT_GPU_DOWNSAMPLE_MODE);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.gpuDownsampleScale, "GPU", "DownsampleScale", 1);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.trueColor, "GPU", "TrueColor", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableInterlacing, "GPU", "DisableInterlacing", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpEnable, "GPU", "PGXPEnable", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpDepthBuffer, "GPU", "PGXPDepthBuffer", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.force43For24Bit, "Display", "Force4_3For24Bit", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chromaSmoothingFor24Bit, "GPU", "ChromaSmoothing24Bit", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.forceNTSCTimings, "GPU", "ForceNTSCTimings", false);
connect(m_ui.renderer, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&GraphicsSettingsWidget::updateRendererDependentOptions);
connect(m_ui.adapter, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&GraphicsSettingsWidget::onAdapterChanged);
connect(m_ui.resolutionScale, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&GraphicsSettingsWidget::onTrueColorChanged);
connect(m_ui.displayAspectRatio, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&GraphicsSettingsWidget::onAspectRatioChanged);
connect(m_ui.gpuDownsampleMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&GraphicsSettingsWidget::onDownsampleModeChanged);
connect(m_ui.trueColor, &QCheckBox::stateChanged, this, &GraphicsSettingsWidget::onTrueColorChanged);
connect(m_ui.pgxpEnable, &QCheckBox::stateChanged, this, &GraphicsSettingsWidget::updatePGXPSettingsEnabled);
if (!dialog->isPerGameSettings() ||
(dialog->containsSettingValue("GPU", "Multisamples") || dialog->containsSettingValue("GPU", "PerSampleShading")))
{
const QVariant current_msaa_mode(
GetMSAAModeValue(static_cast<uint>(dialog->getEffectiveIntValue("GPU", "Multisamples", 1)),
dialog->getEffectiveBoolValue("GPU", "PerSampleShading", false)));
const int current_msaa_index = m_ui.msaaMode->findData(current_msaa_mode);
if (current_msaa_index >= 0)
m_ui.msaaMode->setCurrentIndex(current_msaa_index);
}
else
{
m_ui.msaaMode->setCurrentIndex(0);
}
connect(m_ui.msaaMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&GraphicsSettingsWidget::onMSAAModeChanged);
// Advanced Tab
SettingWidgetBinder::BindWidgetToEnumSetting(
sif, m_ui.exclusiveFullscreenControl, "Display", "ExclusiveFullscreenControl",
&Settings::ParseDisplayExclusiveFullscreenControl, &Settings::GetDisplayExclusiveFullscreenControlName,
Settings::DEFAULT_DISPLAY_EXCLUSIVE_FULLSCREEN_CONTROL);
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.displayAlignment, "Display", "Alignment",
&Settings::ParseDisplayAlignment, &Settings::GetDisplayAlignmentName,
Settings::DEFAULT_DISPLAY_ALIGNMENT);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.displayFPSLimit, "Display", "MaxFPS",
Settings::DEFAULT_DISPLAY_MAX_FPS);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.gpuThread, "GPU", "UseThread", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.threadedPresentation, "GPU", "ThreadedPresentation", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.stretchDisplayVertically, "Display", "StretchVertically",
false);
#ifdef _WIN32
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.blitSwapChain, "Display", "UseBlitSwapChain", false);
#endif
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.gpuLineDetectMode, "GPU", "LineDetectMode",
&Settings::ParseLineDetectModeName, &Settings::GetLineDetectModeName,
Settings::DEFAULT_GPU_LINE_DETECT_MODE);
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.gpuWireframeMode, "GPU", "WireframeMode",
Settings::ParseGPUWireframeMode, Settings::GetGPUWireframeModeName,
Settings::DEFAULT_GPU_WIREFRAME_MODE);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.debanding, "GPU", "Debanding", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.scaledDithering, "GPU", "ScaledDithering", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useSoftwareRendererForReadbacks, "GPU",
"UseSoftwareRendererForReadbacks", false);
connect(m_ui.fullscreenMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&GraphicsSettingsWidget::onFullscreenModeChanged);
// PGXP Tab
SettingWidgetBinder::BindWidgetToFloatSetting(sif, m_ui.pgxpGeometryTolerance, "GPU", "PGXPTolerance", -1.0f);
SettingWidgetBinder::BindWidgetToFloatSetting(sif, m_ui.pgxpDepthClearThreshold, "GPU", "PGXPDepthClearThreshold",
Settings::DEFAULT_GPU_PGXP_DEPTH_THRESHOLD);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpTextureCorrection, "GPU", "PGXPTextureCorrection", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpColorCorrection, "GPU", "PGXPColorCorrection", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpCulling, "GPU", "PGXPCulling", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpPreserveProjPrecision, "GPU", "PGXPPreserveProjFP", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpCPU, "GPU", "PGXPCPU", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpVertexCache, "GPU", "PGXPVertexCache", false);
connect(m_ui.pgxpTextureCorrection, &QCheckBox::stateChanged, this,
&GraphicsSettingsWidget::updatePGXPSettingsEnabled);
connect(m_ui.pgxpDepthBuffer, &QCheckBox::stateChanged, this, &GraphicsSettingsWidget::updatePGXPSettingsEnabled);
// OSD Tab
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.osdScale, "Display", "OSDScale", 100);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showOSDMessages, "Display", "ShowOSDMessages", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showFPS, "Display", "ShowFPS", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showSpeed, "Display", "ShowSpeed", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showResolution, "Display", "ShowResolution", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showCPU, "Display", "ShowCPU", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showGPU, "Display", "ShowGPU", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showInput, "Display", "ShowInputs", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showGPUStatistics, "Display", "ShowGPUStatistics", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showStatusIndicators, "Display", "ShowStatusIndicators", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showFrameTimes, "Display", "ShowFrameTimes", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.showSettings, "Display", "ShowEnhancements", false);
// Capture Tab
SettingWidgetBinder::BindWidgetToEnumSetting(
sif, m_ui.screenshotSize, "Display", "ScreenshotMode", &Settings::ParseDisplayScreenshotMode,
&Settings::GetDisplayScreenshotModeName, Settings::DEFAULT_DISPLAY_SCREENSHOT_MODE);
SettingWidgetBinder::BindWidgetToEnumSetting(
sif, m_ui.screenshotFormat, "Display", "ScreenshotFormat", &Settings::ParseDisplayScreenshotFormat,
&Settings::GetDisplayScreenshotFormatName, Settings::DEFAULT_DISPLAY_SCREENSHOT_FORMAT);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.screenshotQuality, "Display", "ScreenshotQuality",
Settings::DEFAULT_DISPLAY_SCREENSHOT_QUALITY);
// Texture Replacements Tab
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.vramWriteReplacement, "TextureReplacements",
"EnableVRAMWriteReplacements", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.preloadTextureReplacements, "TextureReplacements",
"PreloadTextures", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useOldMDECRoutines, "Hacks", "UseOldMDECRoutines", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.vramWriteDumping, "TextureReplacements", "DumpVRAMWrites",
false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.setVRAMWriteAlphaChannel, "TextureReplacements",
"DumpVRAMWriteForceAlphaChannel", true);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.minDumpedVRAMWriteWidth, "TextureReplacements",
"DumpVRAMWriteWidthThreshold",
Settings::DEFAULT_VRAM_WRITE_DUMP_WIDTH_THRESHOLD);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.minDumpedVRAMWriteHeight, "TextureReplacements",
"DumpVRAMWriteHeightThreshold",
Settings::DEFAULT_VRAM_WRITE_DUMP_HEIGHT_THRESHOLD);
connect(m_ui.vramWriteReplacement, &QCheckBox::stateChanged, this,
&GraphicsSettingsWidget::onEnableAnyTextureReplacementsChanged);
connect(m_ui.vramWriteDumping, &QCheckBox::stateChanged, this,
&GraphicsSettingsWidget::onEnableVRAMWriteDumpingChanged);
// Debugging Tab
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useDebugDevice, "GPU", "UseDebugDevice", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableShaderCache, "GPU", "DisableShaderCache", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableDualSource, "GPU", "DisableDualSourceBlend", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableFramebufferFetch, "GPU", "DisableFramebufferFetch",
false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableTextureBuffers, "GPU", "DisableTextureBuffers", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableTextureCopyToSelf, "GPU", "DisableTextureCopyToSelf",
false);
// Init all dependent options.
updateRendererDependentOptions();
onAspectRatioChanged();
onDownsampleModeChanged();
onTrueColorChanged();
onEnableAnyTextureReplacementsChanged();
onEnableVRAMWriteDumpingChanged();
onShowDebugSettingsChanged(QtHost::ShouldShowDebugOptions());
// Rendering Tab
dialog->registerWidgetHelp(
m_ui.renderer, tr("Renderer"), QString::fromUtf8(Settings::GetRendererDisplayName(Settings::DEFAULT_GPU_RENDERER)),
tr("Chooses the backend to use for rendering the console/game visuals. <br>Depending on your system and hardware, "
"Direct3D 11 and OpenGL hardware backends may be available. <br>The software renderer offers the best "
"compatibility, but is the slowest and does not offer any enhancements."));
dialog->registerWidgetHelp(
m_ui.adapter, tr("Adapter"), tr("(Default)"),
tr("If your system contains multiple GPUs or adapters, you can select which GPU you wish to use for the hardware "
"renderers. <br>This option is only supported in Direct3D and Vulkan. OpenGL will always use the default "
"device."));
dialog->registerWidgetHelp(
m_ui.vsync, tr("VSync"), tr("Unchecked"),
tr("Enable this option to match DuckStation's refresh rate with your current monitor or screen. "
"VSync is automatically disabled when it is not possible (e.g. running at non-100% speed)."));
dialog->registerWidgetHelp(
m_ui.displayAspectRatio, tr("Aspect Ratio"),
QString::fromUtf8(Settings::GetDisplayAspectRatioDisplayName(Settings::DEFAULT_DISPLAY_ASPECT_RATIO)),
tr("Changes the aspect ratio used to display the console's output to the screen. The default is Auto (Game Native) "
"which automatically adjusts the aspect ratio to match how a game would be shown on a typical TV of the era."));
dialog->registerWidgetHelp(
m_ui.displayCropMode, tr("Crop Mode"),
QString::fromUtf8(Settings::GetDisplayCropModeDisplayName(Settings::DEFAULT_DISPLAY_CROP_MODE)),
tr("Determines how much of the area typically not visible on a consumer TV set to crop/hide. Some games display "
"content in the overscan area, or use it for screen effects. May not display correctly with the \"All Borders\" "
"setting. \"Only Overscan\" offers a good compromise between stability and hiding black borders."));
dialog->registerWidgetHelp(
m_ui.displayScaling, tr("Scaling"), tr("Bilinear (Smooth)"),
tr("Determines how the emulated console's output is upscaled or downscaled to your monitor's resolution."));
dialog->registerWidgetHelp(
m_ui.resolutionScale, tr("Internal Resolution"), "1x",
tr("Setting this beyond 1x will enhance the resolution of rendered 3D polygons and lines. Only applies "
"to the hardware backends. <br>This option is usually safe, with most games looking fine at "
"higher resolutions. Higher resolutions require a more powerful GPU."));
dialog->registerWidgetHelp(
m_ui.msaaMode, tr("Multi-Sampling"), tr("Disabled"),
tr("Uses multi-sampled anti-aliasing when rendering 3D polygons. Can improve visuals with a lower performance "
"requirement compared to upscaling, <strong>but often introduces rendering errors.</strong>"));
dialog->registerWidgetHelp(
m_ui.gpuDownsampleMode, tr("Down-Sampling"), tr("Disabled"),
tr("Downsamples the rendered image prior to displaying it. Can improve overall image quality in mixed 2D/3D games, "
"but should be disabled for pure 3D games. Only applies to the hardware renderers."));
dialog->registerWidgetHelp(m_ui.gpuDownsampleScale, tr("Down-Sampling Display Scale"), tr("1x"),
tr("Selects the resolution scale that will be applied to the final image. 1x will "
"downsample to the original console resolution."));
dialog->registerWidgetHelp(
m_ui.textureFiltering, tr("Texture Filtering"),
QString::fromUtf8(Settings::GetTextureFilterDisplayName(Settings::DEFAULT_GPU_TEXTURE_FILTER)),
tr("Smooths out the blockiness of magnified textures on 3D object by using filtering. <br>Will have a "
"greater effect on higher resolution scales. Only applies to the hardware renderers. <br>The JINC2 and "
"especially xBR filtering modes are very demanding, and may not be worth the speed penalty."));
dialog->registerWidgetHelp(
m_ui.trueColor, tr("True Color Rendering"), tr("Checked"),
tr("Forces the precision of colours output to the console's framebuffer to use the full 8 bits of precision per "
"channel. This produces nicer looking gradients at the cost of making some colours look slightly different. "
"Disabling the option also enables dithering, which makes the transition between colours less sharp by applying "
"a pattern around those pixels. Most games are compatible with this option, but there is a number which aren't "
"and will have broken effects with it enabled. Only applies to the hardware renderers."));
dialog->registerWidgetHelp(
m_ui.widescreenHack, tr("Widescreen Rendering"), tr("Unchecked"),
tr("Scales vertex positions in screen-space to a widescreen aspect ratio, essentially "
"increasing the field of view from 4:3 to the chosen display aspect ratio in 3D games. <b><u>May not be "
"compatible with all games.</u></b>"));
dialog->registerWidgetHelp(
m_ui.pgxpEnable, tr("PGXP Geometry Correction"), tr("Unchecked"),
tr("Reduces \"wobbly\" polygons and \"warping\" textures that are common in PS1 games. <br>Only "
"works with the hardware renderers. <b><u>May not be compatible with all games.</u></b>"));
dialog->registerWidgetHelp(
m_ui.pgxpDepthBuffer, tr("PGXP Depth Buffer"), tr("Unchecked"),
tr("Attempts to reduce polygon Z-fighting by testing pixels against the depth values from PGXP. Low compatibility, "
"but can work well in some games. Other games may need a threshold adjustment."));
dialog->registerWidgetHelp(
m_ui.force43For24Bit, tr("Force 4:3 For FMVs"), tr("Unchecked"),
tr("Switches back to 4:3 display aspect ratio when displaying 24-bit content, usually FMVs."));
dialog->registerWidgetHelp(m_ui.chromaSmoothingFor24Bit, tr("FMV Chroma Smoothing"), tr("Unchecked"),
tr("Smooths out blockyness between colour transitions in 24-bit content, usually FMVs. "
"Only applies to the hardware renderers."));
dialog->registerWidgetHelp(
m_ui.disableInterlacing, tr("Disable Interlacing"), tr("Checked"),
tr(
"Forces the rendering and display of frames to progressive mode. <br>This removes the \"combing\" effect seen in "
"480i games by rendering them in 480p. Usually safe to enable.<br><b><u>May not be compatible with all "
"games.</u></b>"));
dialog->registerWidgetHelp(
m_ui.forceNTSCTimings, tr("Force NTSC Timings"), tr("Unchecked"),
tr("Uses NTSC frame timings when the console is in PAL mode, forcing PAL games to run at 60hz. <br>For most games "
"which have a speed tied to the framerate, this will result in the game running approximately 17% faster. "
"<br>For variable frame rate games, it may not affect the speed."));
// Advanced Tab
dialog->registerWidgetHelp(m_ui.fullscreenMode, tr("Fullscreen Mode"), tr("Borderless Fullscreen"),
tr("Chooses the fullscreen resolution and frequency."));
dialog->registerWidgetHelp(m_ui.exclusiveFullscreenControl, tr("Exclusive Fullscreen Control"), tr("Automatic"),
tr("Controls whether exclusive fullscreen can be utilized by Vulkan drivers."));
dialog->registerWidgetHelp(
m_ui.displayAlignment, tr("Position"),
QString::fromUtf8(Settings::GetDisplayAlignmentDisplayName(Settings::DEFAULT_DISPLAY_ALIGNMENT)),
tr("Determines the position on the screen when black borders must be added."));
dialog->registerWidgetHelp(
m_ui.displayFPSLimit, tr("Display FPS Limit"), tr("0"),
tr("Limits the number of frames that are <strong>displayed</strong> every second. Discard frames are <strong>still "
"rendered.</strong> This option can increase frame rates when fast forwarding on some systems."));
dialog->registerWidgetHelp(m_ui.gpuThread, tr("Threaded Rendering"), tr("Checked"),
tr("Uses a second thread for drawing graphics. Currently only available for the software "
"renderer, but can provide a significant speed improvement, and is safe to use."));
dialog->registerWidgetHelp(m_ui.threadedPresentation, tr("Threaded Presentation"), tr("Checked"),
tr("Presents frames on a background thread when fast forwarding or vsync is disabled. "
"This can measurably improve performance in the Vulkan renderer."));
dialog->registerWidgetHelp(
m_ui.stretchDisplayVertically, tr("Stretch Vertically"), tr("Unchecked"),
tr("Prefers stretching the display vertically instead of horizontally, wheen applying the display aspect ratio."));
#ifdef _WIN32
dialog->registerWidgetHelp(m_ui.blitSwapChain, tr("Use Blit Swap Chain"), tr("Unchecked"),
tr("Uses a blit presentation model instead of flipping when using the Direct3D 11 "
"renderer. This usually results in slower performance, but may be required for some "
"streaming applications, or to uncap framerates on some systems."));
#endif
dialog->registerWidgetHelp(m_ui.gpuLineDetectMode, tr("Line Detection"),
QString::fromUtf8(Settings::GetLineDetectModeName(Settings::DEFAULT_GPU_LINE_DETECT_MODE)),
tr("Attempts to detect one pixel high/wide lines that rely on non-upscaled rasterization "
"behavior, filling in gaps introduced by upscaling."));
dialog->registerWidgetHelp(m_ui.gpuWireframeMode, tr("Wireframe Mode"), tr("Disabled"),
tr("Draws a wireframe outline of the triangles rendered by the console's GPU, either as a "
"replacement or an overlay."));
dialog->registerWidgetHelp(
m_ui.debanding, tr("True Color Debanding"), tr("Unchecked"),
tr("Applies modern dithering techniques to further smooth out gradients when true color is enabled. "
"This debanding is performed during rendering (as opposed to a post-processing step), which allows it to be "
"fast while preserving detail. "
"Debanding increases the file size of screenshots due to the subtle dithering pattern present in screenshots."));
dialog->registerWidgetHelp(
m_ui.scaledDithering, tr("Scaled Dithering"), tr("Checked"),
tr("Scales the dither pattern to the resolution scale of the emulated GPU. This makes the dither pattern much less "
"obvious at higher resolutions. <br>Usually safe to enable, and only supported by the hardware renderers."));
dialog->registerWidgetHelp(
m_ui.useSoftwareRendererForReadbacks, tr("Software Renderer Readbacks"), tr("Unchecked"),
tr("Runs the software renderer in parallel for VRAM readbacks. On some systems, this may result in greater "
"performance when using graphical enhancements with the hardware renderer."));
// PGXP Tab
dialog->registerWidgetHelp(
m_ui.pgxpGeometryTolerance, tr("Geometry Tolerance"), tr("-1.00px (Disabled)"),
tr("Discards precise geometry when it is found to be offset past the specified threshold. This can help with games "
"that have vertices significantly moved by PGXP, but is still a hack/workaround."));
dialog->registerWidgetHelp(m_ui.pgxpDepthClearThreshold, tr("Depth Clear Threshold"),
QStringLiteral("%1").arg(Settings::DEFAULT_GPU_PGXP_DEPTH_THRESHOLD),
tr("Determines the increase in depth that will result in the depth buffer being cleared. "
"Can help with depth issues in some games, but is still a hack/workaround."));
dialog->registerWidgetHelp(m_ui.pgxpTextureCorrection, tr("Perspective Correct Textures"), tr("Checked"),
tr("Uses perspective-correct interpolation for texture coordinates, straightening out "
"warped textures. Requires geometry correction enabled."));
dialog->registerWidgetHelp(
m_ui.pgxpColorCorrection, tr("Perspective Correct Colors"), tr("Unchecked"),
tr("Uses perspective-correct interpolation for vertex colors, which can improve visuals in some games, but cause "
"rendering errors in others. Requires geometry correction enabled."));
dialog->registerWidgetHelp(m_ui.pgxpCulling, tr("Culling Correction"), tr("Checked"),
tr("Increases the precision of polygon culling, reducing the number of holes in geometry. "
"Requires geometry correction enabled."));
dialog->registerWidgetHelp(
m_ui.pgxpPreserveProjPrecision, tr("Preserve Projection Precision"), tr("Unchecked"),
tr("Adds additional precision to PGXP data post-projection. May improve visuals in some games."));
dialog->registerWidgetHelp(m_ui.pgxpCPU, tr("CPU Mode"), tr("Unchecked"),
tr("Uses PGXP for all instructions, not just memory operations. Required for PGXP to "
"correct wobble in some games, but has a high performance cost."));
dialog->registerWidgetHelp(
m_ui.pgxpVertexCache, tr("Vertex Cache"), tr("Unchecked"),
tr("Uses screen-space vertex positions to obtain precise positions, instead of tracking memory accesses. Can "
"provide PGXP compatibility for some games, but <strong>generally provides no benefit.</strong>"));
// OSD Tab
dialog->registerWidgetHelp(
m_ui.osdScale, tr("OSD Scale"), tr("100%"),
tr("Changes the size at which on-screen elements, including status and messages are displayed."));
dialog->registerWidgetHelp(m_ui.showOSDMessages, tr("Show OSD Messages"), tr("Checked"),
tr("Shows on-screen-display messages when events occur such as save states being "
"created/loaded, screenshots being taken, etc."));
dialog->registerWidgetHelp(m_ui.showResolution, tr("Show Resolution"), tr("Unchecked"),
tr("Shows the resolution of the game in the top-right corner of the display."));
dialog->registerWidgetHelp(
m_ui.showSpeed, tr("Show Emulation Speed"), tr("Unchecked"),
tr("Shows the current emulation speed of the system in the top-right corner of the display as a percentage."));
dialog->registerWidgetHelp(m_ui.showFPS, tr("Show FPS"), tr("Unchecked"),
tr("Shows the internal frame rate of the game in the top-right corner of the display."));
dialog->registerWidgetHelp(
m_ui.showCPU, tr("Show CPU Usage"), tr("Unchecked"),
tr("Shows the host's CPU usage based on threads in the top-right corner of the display. This does not display the "
"emulated system CPU's usage. If a value close to 100% is being displayed, this means your host's CPU is likely "
"the bottleneck. In this case, you should reduce enhancement-related settings such as overclocking."));
dialog->registerWidgetHelp(m_ui.showGPU, tr("Show GPU Usage"), tr("Unchecked"),
tr("Shows the host's GPU usage in the top-right corner of the display."));
dialog->registerWidgetHelp(m_ui.showGPUStatistics, tr("Show GPU Statistics"), tr("Unchecked"),
tr("Shows information about the emulated GPU in the top-right corner of the display."));
dialog->registerWidgetHelp(
m_ui.showFrameTimes, tr("Show Frame Times"), tr("Unchecked"),
tr("Shows the history of frame rendering times as a graph in the top-right corner of the display."));
dialog->registerWidgetHelp(
m_ui.showInput, tr("Show Controller Input"), tr("Unchecked"),
tr("Shows the current controller state of the system in the bottom-left corner of the display."));
dialog->registerWidgetHelp(m_ui.showInput, tr("Show Settings"), tr("Unchecked"),
tr("Shows a summary of current settings in the bottom-right corner of the display."));
dialog->registerWidgetHelp(m_ui.showStatusIndicators, tr("Show Status Indicators"), tr("Checked"),
tr("Shows indicators on screen when the system is not running in its \"normal\" state. "
"For example, fast forwarding, or being paused."));
// Capture Tab
dialog->registerWidgetHelp(m_ui.screenshotSize, tr("Screenshot Size"), tr("Screen Resolution"),
tr("Determines the resolution at which screenshots will be saved. Internal resolutions "
"preserve more detail at the cost of file size."));
dialog->registerWidgetHelp(
m_ui.screenshotFormat, tr("Screenshot Format"), tr("PNG"),
tr("Selects the format which will be used to save screenshots. JPEG produces smaller files, but loses detail."));
dialog->registerWidgetHelp(m_ui.screenshotQuality, tr("Screenshot Quality"),
QStringLiteral("%1%%").arg(Settings::DEFAULT_DISPLAY_SCREENSHOT_QUALITY),
tr("Selects the quality at which screenshots will be compressed. Higher values preserve "
"more detail for JPEG, and reduce file size for PNG."));
// Texture Replacements Tab
dialog->registerWidgetHelp(m_ui.vramWriteReplacement, tr("Enable VRAM Write Replacement"), tr("Unchecked"),
tr("Enables the replacement of background textures in supported games. <strong>This is "
"not general texture replacement.</strong>"));
dialog->registerWidgetHelp(m_ui.preloadTextureReplacements, tr("Preload Texture Replacements"), tr("Unchecked"),
tr("Loads all replacement texture to RAM, reducing stuttering at runtime."));
dialog->registerWidgetHelp(m_ui.useOldMDECRoutines, tr("Use Old MDEC Routines"), tr("Unchecked"),
tr("Enables the older, less accurate MDEC decoding routines. May be required for old "
"replacement backgrounds to match/load."));
dialog->registerWidgetHelp(m_ui.setVRAMWriteAlphaChannel, tr("Set Alpha Channel"), tr("Checked"),
tr("Clears the mask/transparency bit in VRAM write dumps."));
dialog->registerWidgetHelp(m_ui.vramWriteDumping, tr("Enable VRAM Write Dumping"), tr("Unchecked"),
tr("Writes backgrounds that can be replaced to the dump directory."));
dialog->registerWidgetHelp(m_ui.minDumpedVRAMWriteWidth, tr("Dump Size Threshold"), tr("128px"),
tr("Determines the threshold that triggers a VRAM write to be dumped."));
dialog->registerWidgetHelp(m_ui.minDumpedVRAMWriteHeight, tr("Dump Size Threshold"), tr("128px"),
tr("Determines the threshold that triggers a VRAM write to be dumped."));
// Debugging Tab
dialog->registerWidgetHelp(
m_ui.useDebugDevice, tr("Use Debug Device"), tr("Unchecked"),
tr("Enable debugging when supported by the host's renderer API. <strong>Only for developer use.</strong>"));
dialog->registerWidgetHelp(
m_ui.disableShaderCache, tr("Disable Shader Cache"), tr("Unchecked"),
tr("Forces shaders to be compiled for every run of the program. <strong>Only for developer use.</strong>"));
dialog->registerWidgetHelp(m_ui.disableDualSource, tr("Disable Dual-Source Blending"), tr("Unchecked"),
tr("Prevents dual-source blending from being used. Useful for testing broken graphics "
"drivers. <strong>Only for developer use.</strong>"));
dialog->registerWidgetHelp(m_ui.disableFramebufferFetch, tr("Disable Framebuffer Fetch"), tr("Unchecked"),
tr("Prevents the framebuffer fetch extensions from being used. Useful for testing broken "
"graphics drivers. <strong>Only for developer use.</strong>"));
dialog->registerWidgetHelp(
m_ui.disableTextureBuffers, tr("Disable Texture Buffers"), tr("Unchecked"),
tr("Forces VRAM updates through texture updates, instead of texture buffers and draws. Useful for testing broken "
"graphics drivers. <strong>Only for developer use.</strong>"));
dialog->registerWidgetHelp(m_ui.disableTextureCopyToSelf, tr("Disable Texture Copies To Self"), tr("Unchecked"),
tr("Disables the use of self-copy updates for the VRAM texture. Useful for testing broken "
"graphics drivers. <strong>Only for developer use.</strong>"));
}
GraphicsSettingsWidget::~GraphicsSettingsWidget() = default;
void GraphicsSettingsWidget::setupAdditionalUi()
{
// Rendering Tab
for (u32 i = 0; i < static_cast<u32>(GPURenderer::Count); i++)
{
m_ui.renderer->addItem(QString::fromUtf8(Settings::GetRendererDisplayName(static_cast<GPURenderer>(i))));
}
for (u32 i = 0; i < static_cast<u32>(DisplayAspectRatio::Count); i++)
{
m_ui.displayAspectRatio->addItem(
QString::fromUtf8(Settings::GetDisplayAspectRatioDisplayName(static_cast<DisplayAspectRatio>(i))));
}
for (u32 i = 0; i < static_cast<u32>(DisplayCropMode::Count); i++)
{
m_ui.displayCropMode->addItem(
QString::fromUtf8(Settings::GetDisplayCropModeDisplayName(static_cast<DisplayCropMode>(i))));
}
for (u32 i = 0; i < static_cast<u32>(DisplayScalingMode::Count); i++)
{
m_ui.displayScaling->addItem(
QString::fromUtf8(Settings::GetDisplayScalingDisplayName(static_cast<DisplayScalingMode>(i))));
}
{
if (m_dialog->isPerGameSettings())
m_ui.msaaMode->addItem(tr("Use Global Setting"));
m_ui.msaaMode->addItem(tr("Disabled"), GetMSAAModeValue(1, false));
for (uint i = 2; i <= 32; i *= 2)
m_ui.msaaMode->addItem(tr("%1x MSAA").arg(i), GetMSAAModeValue(i, false));
for (uint i = 2; i <= 32; i *= 2)
m_ui.msaaMode->addItem(tr("%1x SSAA").arg(i), GetMSAAModeValue(i, true));
}
for (u32 i = 0; i < static_cast<u32>(GPUTextureFilter::Count); i++)
{
m_ui.textureFiltering->addItem(
QString::fromUtf8(Settings::GetTextureFilterDisplayName(static_cast<GPUTextureFilter>(i))));
}
for (u32 i = 0; i < static_cast<u32>(GPUDownsampleMode::Count); i++)
{
m_ui.gpuDownsampleMode->addItem(
QString::fromUtf8(Settings::GetDownsampleModeDisplayName(static_cast<GPUDownsampleMode>(i))));
}
// Advanced Tab
for (u32 i = 0; i < static_cast<u32>(DisplayExclusiveFullscreenControl::Count); i++)
{
m_ui.exclusiveFullscreenControl->addItem(QString::fromUtf8(
Settings::GetDisplayExclusiveFullscreenControlDisplayName(static_cast<DisplayExclusiveFullscreenControl>(i))));
}
for (u32 i = 0; i < static_cast<u32>(DisplayAlignment::Count); i++)
{
m_ui.displayAlignment->addItem(
QString::fromUtf8(Settings::GetDisplayAlignmentDisplayName(static_cast<DisplayAlignment>(i))));
}
for (u32 i = 0; i < static_cast<u32>(GPULineDetectMode::Count); i++)
{
m_ui.gpuLineDetectMode->addItem(
QString::fromUtf8(Settings::GetLineDetectModeDisplayName(static_cast<GPULineDetectMode>(i))));
}
for (u32 i = 0; i < static_cast<u32>(GPUWireframeMode::Count); i++)
{
m_ui.gpuWireframeMode->addItem(
QString::fromUtf8(Settings::GetGPUWireframeModeDisplayName(static_cast<GPUWireframeMode>(i))));
}
// Capture Tab
for (u32 i = 0; i < static_cast<u32>(DisplayScreenshotMode::Count); i++)
{
m_ui.screenshotSize->addItem(
QString::fromUtf8(Settings::GetDisplayScreenshotModeDisplayName(static_cast<DisplayScreenshotMode>(i))));
}
for (u32 i = 0; i < static_cast<u32>(DisplayScreenshotFormat::Count); i++)
{
m_ui.screenshotFormat->addItem(
QString::fromUtf8(Settings::GetDisplayScreenshotFormatDisplayName(static_cast<DisplayScreenshotFormat>(i))));
}
}
void GraphicsSettingsWidget::removePlatformSpecificUi()
{
#ifndef _WIN32
m_ui.advancedDisplayOptionsLayout->removeWidget(m_ui.blitSwapChain);
delete m_ui.blitSwapChain;
m_ui.blitSwapChain = nullptr;
#endif
}
GPURenderer GraphicsSettingsWidget::getEffectiveRenderer() const
{
return Settings::ParseRendererName(
m_dialog
->getEffectiveStringValue("GPU", "Renderer", Settings::GetRendererName(Settings::DEFAULT_GPU_RENDERER))
.c_str())
.value_or(Settings::DEFAULT_GPU_RENDERER);
}
bool GraphicsSettingsWidget::effectiveRendererIsHardware() const
{
return (getEffectiveRenderer() != GPURenderer::Software);
}
void GraphicsSettingsWidget::onShowDebugSettingsChanged(bool enabled)
{
m_ui.tabs->setTabVisible(TAB_INDEX_DEBUGGING, enabled);
}
void GraphicsSettingsWidget::updateRendererDependentOptions()
{
const GPURenderer renderer = getEffectiveRenderer();
const RenderAPI render_api = Settings::GetRenderAPIForRenderer(renderer);
const bool is_hardware = (renderer != GPURenderer::Software);
m_ui.resolutionScale->setEnabled(is_hardware);
m_ui.resolutionScaleLabel->setEnabled(is_hardware);
m_ui.msaaMode->setEnabled(is_hardware);
m_ui.msaaModeLabel->setEnabled(is_hardware);
m_ui.textureFiltering->setEnabled(is_hardware);
m_ui.textureFilteringLabel->setEnabled(is_hardware);
m_ui.gpuDownsampleLabel->setEnabled(is_hardware);
m_ui.gpuDownsampleMode->setEnabled(is_hardware);
m_ui.gpuDownsampleScale->setEnabled(is_hardware);
m_ui.trueColor->setEnabled(is_hardware);
m_ui.pgxpEnable->setEnabled(is_hardware);
m_ui.chromaSmoothingFor24Bit->setEnabled(is_hardware);
m_ui.gpuLineDetectMode->setEnabled(is_hardware);
m_ui.gpuLineDetectModeLabel->setEnabled(is_hardware);
m_ui.gpuWireframeMode->setEnabled(is_hardware);
m_ui.gpuWireframeModeLabel->setEnabled(is_hardware);
m_ui.debanding->setEnabled(is_hardware);
m_ui.scaledDithering->setEnabled(is_hardware);
m_ui.useSoftwareRendererForReadbacks->setEnabled(is_hardware);
m_ui.tabs->setTabEnabled(TAB_INDEX_TEXTURE_REPLACEMENTS, is_hardware);
#ifdef _WIN32
m_ui.blitSwapChain->setEnabled(render_api == RenderAPI::D3D11);
#endif
m_ui.gpuThread->setEnabled(!is_hardware);
m_ui.threadedPresentation->setEnabled(render_api == RenderAPI::Vulkan);
m_ui.exclusiveFullscreenLabel->setEnabled(render_api == RenderAPI::D3D11 || render_api == RenderAPI::D3D12 ||
render_api == RenderAPI::Vulkan);
m_ui.exclusiveFullscreenControl->setEnabled(render_api == RenderAPI::Vulkan);
populateGPUAdaptersAndResolutions(render_api);
updatePGXPSettingsEnabled();
}
void GraphicsSettingsWidget::populateGPUAdaptersAndResolutions(RenderAPI render_api)
{
GPUDevice::AdapterAndModeList aml;
switch (render_api)
{
#ifdef _WIN32
case RenderAPI::D3D11:
aml = D3D11Device::StaticGetAdapterAndModeList();
break;
case RenderAPI::D3D12:
aml = D3D12Device::StaticGetAdapterAndModeList();
break;
#endif
#ifdef __APPLE__
case RenderAPI::Metal:
aml = GPUDevice::WrapGetMetalAdapterAndModeList();
break;
#endif
#ifdef ENABLE_VULKAN
case RenderAPI::Vulkan:
aml = VulkanDevice::StaticGetAdapterAndModeList();
break;
#endif
default:
break;
}
{
const std::string current_adapter(m_dialog->getEffectiveStringValue("GPU", "Adapter", ""));
QSignalBlocker blocker(m_ui.adapter);
// add the default entry - we'll fall back to this if the GPU no longer exists, or there's no options
m_ui.adapter->clear();
m_ui.adapter->addItem(tr("(Default)"));
// add the other adapters
for (const std::string& adapter_name : aml.adapter_names)
{
m_ui.adapter->addItem(QString::fromStdString(adapter_name));
if (adapter_name == current_adapter)
m_ui.adapter->setCurrentIndex(m_ui.adapter->count() - 1);
}
// disable it if we don't have a choice
m_ui.adapter->setEnabled(!aml.adapter_names.empty());
}
{
const std::string current_mode(m_dialog->getEffectiveStringValue("GPU", "FullscreenMode", ""));
QSignalBlocker blocker(m_ui.fullscreenMode);
m_ui.fullscreenMode->clear();
m_ui.fullscreenMode->addItem(tr("Borderless Fullscreen"));
m_ui.fullscreenMode->setCurrentIndex(0);
for (const std::string& mode_name : aml.fullscreen_modes)
{
m_ui.fullscreenMode->addItem(QString::fromStdString(mode_name));
if (mode_name == current_mode)
m_ui.fullscreenMode->setCurrentIndex(m_ui.fullscreenMode->count() - 1);
}
// disable it if we don't have a choice
m_ui.fullscreenMode->setEnabled(!aml.fullscreen_modes.empty());
}
// TODO: MSAA modes
}
void GraphicsSettingsWidget::updatePGXPSettingsEnabled()
{
const bool enabled = (effectiveRendererIsHardware() && m_dialog->getEffectiveBoolValue("GPU", "PGXPEnable", false));
const bool tc_enabled = (enabled && m_dialog->getEffectiveBoolValue("GPU", "PGXPTextureCorrection", true));
const bool depth_enabled = (enabled && m_dialog->getEffectiveBoolValue("GPU", "PGXPDepthBuffer", false));
m_ui.tabs->setTabEnabled(TAB_INDEX_PGXP, enabled);
m_ui.pgxpTab->setEnabled(enabled);
m_ui.pgxpCulling->setEnabled(enabled);
m_ui.pgxpTextureCorrection->setEnabled(enabled);
m_ui.pgxpColorCorrection->setEnabled(tc_enabled);
m_ui.pgxpDepthBuffer->setEnabled(enabled);
m_ui.pgxpPreserveProjPrecision->setEnabled(enabled);
m_ui.pgxpCPU->setEnabled(enabled);
m_ui.pgxpVertexCache->setEnabled(enabled);
m_ui.pgxpGeometryTolerance->setEnabled(enabled);
m_ui.pgxpGeometryToleranceLabel->setEnabled(enabled);
m_ui.pgxpDepthClearThreshold->setEnabled(depth_enabled);
m_ui.pgxpDepthClearThresholdLabel->setEnabled(depth_enabled);
}
void GraphicsSettingsWidget::onAdapterChanged()
{
if (m_ui.adapter->currentIndex() == 0)
{
// default
m_dialog->removeSettingValue("GPU", "Adapter");
return;
}
m_dialog->setStringSettingValue("GPU", "Adapter", m_ui.adapter->currentText().toUtf8().constData());
}
void GraphicsSettingsWidget::onAspectRatioChanged()
{
const DisplayAspectRatio ratio =
Settings::ParseDisplayAspectRatio(
m_dialog
->getEffectiveStringValue("Display", "AspectRatio",
Settings::GetDisplayAspectRatioName(Settings::DEFAULT_DISPLAY_ASPECT_RATIO))
.c_str())
.value_or(Settings::DEFAULT_DISPLAY_ASPECT_RATIO);
const bool is_custom = (ratio == DisplayAspectRatio::Custom);
m_ui.customAspectRatioNumerator->setVisible(is_custom);
m_ui.customAspectRatioDenominator->setVisible(is_custom);
m_ui.customAspectRatioSeparator->setVisible(is_custom);
}
void GraphicsSettingsWidget::onMSAAModeChanged()
{
const int index = m_ui.msaaMode->currentIndex();
if (m_dialog->isPerGameSettings() && index == 0)
{
m_dialog->removeSettingValue("GPU", "Multisamples");
m_dialog->removeSettingValue("GPU", "PerSampleShading");
}
else
{
uint multisamples;
bool ssaa;
DecodeMSAAModeValue(m_ui.msaaMode->itemData(index), &multisamples, &ssaa);
m_dialog->setIntSettingValue("GPU", "Multisamples", static_cast<int>(multisamples));
m_dialog->setBoolSettingValue("GPU", "PerSampleShading", ssaa);
}
}
void GraphicsSettingsWidget::onTrueColorChanged()
{
const int resolution_scale = m_ui.resolutionScale->currentIndex();
const bool true_color = m_ui.trueColor->isChecked();
const bool allow_scaled_dithering = (resolution_scale != 1 && !true_color);
const bool allow_debanding = true_color;
m_ui.scaledDithering->setEnabled(allow_scaled_dithering);
m_ui.debanding->setEnabled(allow_debanding);
}
void GraphicsSettingsWidget::onDownsampleModeChanged()
{
const GPUDownsampleMode mode =
Settings::ParseDownsampleModeName(
m_dialog
->getEffectiveStringValue("GPU", "DownsampleMode",
Settings::GetDownsampleModeName(Settings::DEFAULT_GPU_DOWNSAMPLE_MODE))
.c_str())
.value_or(Settings::DEFAULT_GPU_DOWNSAMPLE_MODE);
const bool visible = (mode == GPUDownsampleMode::Box);
if (visible && m_ui.gpuDownsampleLayout->indexOf(m_ui.gpuDownsampleScale) < 0)
{
m_ui.gpuDownsampleScale->setVisible(true);
m_ui.gpuDownsampleLayout->addWidget(m_ui.gpuDownsampleScale, 0);
}
else if (!visible && m_ui.gpuDownsampleLayout->indexOf(m_ui.gpuDownsampleScale) >= 0)
{
m_ui.gpuDownsampleScale->setVisible(false);
m_ui.gpuDownsampleLayout->removeWidget(m_ui.gpuDownsampleScale);
}
}
void GraphicsSettingsWidget::onFullscreenModeChanged()
{
if (m_ui.fullscreenMode->currentIndex() == 0)
{
// default
m_dialog->removeSettingValue("GPU", "FullscreenMode");
return;
}
m_dialog->setStringSettingValue("GPU", "FullscreenMode", m_ui.fullscreenMode->currentText().toUtf8().constData());
}
void GraphicsSettingsWidget::onEnableAnyTextureReplacementsChanged()
{
const bool any_replacements_enabled =
m_dialog->getEffectiveBoolValue("TextureReplacements", "EnableVRAMWriteReplacements", false);
m_ui.preloadTextureReplacements->setEnabled(any_replacements_enabled);
}
void GraphicsSettingsWidget::onEnableVRAMWriteDumpingChanged()
{
const bool enabled = m_dialog->getEffectiveBoolValue("TextureReplacements", "DumpVRAMWrites", false);
m_ui.setVRAMWriteAlphaChannel->setEnabled(enabled);
m_ui.minDumpedVRAMWriteWidth->setEnabled(enabled);
m_ui.minDumpedVRAMWriteHeight->setEnabled(enabled);
m_ui.vramWriteDumpThresholdLabel->setEnabled(enabled);
m_ui.vramWriteDumpThresholdSeparator->setEnabled(enabled);
}

View File

@ -0,0 +1,59 @@
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#pragma once
#include <QtWidgets/QWidget>
#include "ui_graphicssettingswidget.h"
enum class RenderAPI : u32;
enum class GPURenderer : u8;
class SettingsWindow;
class GraphicsSettingsWidget : public QWidget
{
Q_OBJECT
public:
GraphicsSettingsWidget(SettingsWindow* dialog, QWidget* parent);
~GraphicsSettingsWidget();
public Q_SLOTS:
void onShowDebugSettingsChanged(bool enabled);
private Q_SLOTS:
void updateRendererDependentOptions();
void updatePGXPSettingsEnabled();
void onAdapterChanged();
void onAspectRatioChanged();
void onMSAAModeChanged();
void onTrueColorChanged();
void onDownsampleModeChanged();
void onFullscreenModeChanged();
void onEnableAnyTextureReplacementsChanged();
void onEnableVRAMWriteDumpingChanged();
private:
static constexpr int TAB_INDEX_RENDERING = 0;
static constexpr int TAB_INDEX_ADVANCED = 1;
static constexpr int TAB_INDEX_PGXP = 2;
static constexpr int TAB_INDEX_OSD = 3;
static constexpr int TAB_INDEX_CAPTURE = 4;
static constexpr int TAB_INDEX_TEXTURE_REPLACEMENTS = 5;
static constexpr int TAB_INDEX_DEBUGGING = 6;
void setupAdditionalUi();
void removePlatformSpecificUi();
GPURenderer getEffectiveRenderer() const;
bool effectiveRendererIsHardware() const;
void populateGPUAdaptersAndResolutions(RenderAPI render_api);
Ui::GraphicsSettingsWidget m_ui;
SettingsWindow* m_dialog;
};

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,15 @@
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com> // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#include "generalsettingswidget.h" #include "interfacesettingswidget.h"
#include "autoupdaterdialog.h" #include "autoupdaterdialog.h"
#include "generalsettingswidget.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "qtutils.h" #include "qtutils.h"
#include "scmversion/scmversion.h" #include "scmversion/scmversion.h"
#include "settingswindow.h" #include "settingswindow.h"
#include "settingwidgetbinder.h" #include "settingwidgetbinder.h"
const char* GeneralSettingsWidget::THEME_NAMES[] = { const char* InterfaceSettingsWidget::THEME_NAMES[] = {
QT_TRANSLATE_NOOP("MainWindow", "Native"), QT_TRANSLATE_NOOP("MainWindow", "Native"),
QT_TRANSLATE_NOOP("MainWindow", "Fusion"), QT_TRANSLATE_NOOP("MainWindow", "Fusion"),
QT_TRANSLATE_NOOP("MainWindow", "Dark Fusion (Gray)"), QT_TRANSLATE_NOOP("MainWindow", "Dark Fusion (Gray)"),
@ -20,13 +19,13 @@ const char* GeneralSettingsWidget::THEME_NAMES[] = {
nullptr, nullptr,
}; };
const char* GeneralSettingsWidget::THEME_VALUES[] = { const char* InterfaceSettingsWidget::THEME_VALUES[] = {
"", "fusion", "darkfusion", "darkfusionblue", "greymatter", "qdarkstyle", nullptr, "", "fusion", "darkfusion", "darkfusionblue", "greymatter", "qdarkstyle", nullptr,
}; };
const char* GeneralSettingsWidget::DEFAULT_THEME_NAME = "darkfusion"; const char* InterfaceSettingsWidget::DEFAULT_THEME_NAME = "darkfusion";
GeneralSettingsWidget::GeneralSettingsWidget(SettingsWindow* dialog, QWidget* parent) InterfaceSettingsWidget::InterfaceSettingsWidget(SettingsWindow* dialog, QWidget* parent)
: QWidget(parent), m_dialog(dialog) : QWidget(parent), m_dialog(dialog)
{ {
SettingsInterface* sif = dialog->getSettingsInterface(); SettingsInterface* sif = dialog->getSettingsInterface();
@ -57,7 +56,7 @@ GeneralSettingsWidget::GeneralSettingsWidget(SettingsWindow* dialog, QWidget* pa
Settings::DEFAULT_SAVE_STATE_COMPRESSION); Settings::DEFAULT_SAVE_STATE_COMPRESSION);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableDiscordPresence, "Main", "EnableDiscordPresence", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableDiscordPresence, "Main", "EnableDiscordPresence", false);
connect(m_ui.renderToSeparateWindow, &QCheckBox::stateChanged, this, connect(m_ui.renderToSeparateWindow, &QCheckBox::stateChanged, this,
&GeneralSettingsWidget::onRenderToSeparateWindowChanged); &InterfaceSettingsWidget::onRenderToSeparateWindowChanged);
onRenderToSeparateWindowChanged(); onRenderToSeparateWindowChanged();
@ -124,9 +123,9 @@ GeneralSettingsWidget::GeneralSettingsWidget(SettingsWindow* dialog, QWidget* pa
} }
} }
GeneralSettingsWidget::~GeneralSettingsWidget() = default; InterfaceSettingsWidget::~InterfaceSettingsWidget() = default;
void GeneralSettingsWidget::onRenderToSeparateWindowChanged() void InterfaceSettingsWidget::onRenderToSeparateWindowChanged()
{ {
m_ui.hideMainWindow->setEnabled(m_ui.renderToSeparateWindow->isChecked()); m_ui.hideMainWindow->setEnabled(m_ui.renderToSeparateWindow->isChecked());
} }

View File

@ -1,27 +1,27 @@
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com> // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#pragma once #pragma once
#include <QtWidgets/QWidget> #include <QtWidgets/QWidget>
#include "ui_generalsettingswidget.h" #include "ui_interfacesettingswidget.h"
class SettingsWindow; class SettingsWindow;
class GeneralSettingsWidget : public QWidget class InterfaceSettingsWidget : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit GeneralSettingsWidget(SettingsWindow* dialog, QWidget* parent); explicit InterfaceSettingsWidget(SettingsWindow* dialog, QWidget* parent);
~GeneralSettingsWidget(); ~InterfaceSettingsWidget();
private Q_SLOTS: private Q_SLOTS:
void onRenderToSeparateWindowChanged(); void onRenderToSeparateWindowChanged();
private: private:
Ui::GeneralSettingsWidget m_ui; Ui::InterfaceSettingsWidget m_ui;
SettingsWindow* m_dialog; SettingsWindow* m_dialog;

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>GeneralSettingsWidget</class> <class>InterfaceSettingsWidget</class>
<widget class="QWidget" name="GeneralSettingsWidget"> <widget class="QWidget" name="InterfaceSettingsWidget">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>

View File

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com> // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#include "mainwindow.h" #include "mainwindow.h"
@ -11,7 +11,7 @@
#include "displaywidget.h" #include "displaywidget.h"
#include "gamelistsettingswidget.h" #include "gamelistsettingswidget.h"
#include "gamelistwidget.h" #include "gamelistwidget.h"
#include "generalsettingswidget.h" #include "interfacesettingswidget.h"
#include "logwindow.h" #include "logwindow.h"
#include "memorycardeditorwindow.h" #include "memorycardeditorwindow.h"
#include "qthost.h" #include "qthost.h"
@ -1985,7 +1985,7 @@ void MainWindow::connectSignals()
connect(m_ui.actionFullscreen, &QAction::triggered, g_emu_thread, &EmuThread::toggleFullscreen); connect(m_ui.actionFullscreen, &QAction::triggered, g_emu_thread, &EmuThread::toggleFullscreen);
connect(m_ui.actionSettings, &QAction::triggered, [this]() { doSettings(); }); connect(m_ui.actionSettings, &QAction::triggered, [this]() { doSettings(); });
connect(m_ui.actionSettings2, &QAction::triggered, this, &MainWindow::onSettingsTriggeredFromToolbar); connect(m_ui.actionSettings2, &QAction::triggered, this, &MainWindow::onSettingsTriggeredFromToolbar);
connect(m_ui.actionGeneralSettings, &QAction::triggered, [this]() { doSettings("General"); }); connect(m_ui.actionInterfaceSettings, &QAction::triggered, [this]() { doSettings("Interface"); });
connect(m_ui.actionBIOSSettings, &QAction::triggered, [this]() { doSettings("BIOS"); }); connect(m_ui.actionBIOSSettings, &QAction::triggered, [this]() { doSettings("BIOS"); });
connect(m_ui.actionConsoleSettings, &QAction::triggered, [this]() { doSettings("Console"); }); connect(m_ui.actionConsoleSettings, &QAction::triggered, [this]() { doSettings("Console"); });
connect(m_ui.actionEmulationSettings, &QAction::triggered, [this]() { doSettings("Emulation"); }); connect(m_ui.actionEmulationSettings, &QAction::triggered, [this]() { doSettings("Emulation"); });
@ -1995,8 +1995,7 @@ void MainWindow::connectSignals()
connect(m_ui.actionControllerSettings, &QAction::triggered, connect(m_ui.actionControllerSettings, &QAction::triggered,
[this]() { doControllerSettings(ControllerSettingsWindow::Category::GlobalSettings); }); [this]() { doControllerSettings(ControllerSettingsWindow::Category::GlobalSettings); });
connect(m_ui.actionMemoryCardSettings, &QAction::triggered, [this]() { doSettings("Memory Cards"); }); connect(m_ui.actionMemoryCardSettings, &QAction::triggered, [this]() { doSettings("Memory Cards"); });
connect(m_ui.actionDisplaySettings, &QAction::triggered, [this]() { doSettings("Display"); }); connect(m_ui.actionGraphicsSettings, &QAction::triggered, [this]() { doSettings("Graphics"); });
connect(m_ui.actionEnhancementSettings, &QAction::triggered, [this]() { doSettings("Enhancements"); });
connect(m_ui.actionPostProcessingSettings, &QAction::triggered, [this]() { doSettings("Post-Processing"); }); connect(m_ui.actionPostProcessingSettings, &QAction::triggered, [this]() { doSettings("Post-Processing"); });
connect(m_ui.actionAudioSettings, &QAction::triggered, [this]() { doSettings("Audio"); }); connect(m_ui.actionAudioSettings, &QAction::triggered, [this]() { doSettings("Audio"); });
connect(m_ui.actionAchievementSettings, &QAction::triggered, [this]() { doSettings("Achievements"); }); connect(m_ui.actionAchievementSettings, &QAction::triggered, [this]() { doSettings("Achievements"); });
@ -2120,11 +2119,11 @@ void MainWindow::connectSignals()
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionDebugShowMDECState, "Debug", "ShowMDECState", false); SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionDebugShowMDECState, "Debug", "ShowMDECState", false);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionDebugShowDMAState, "Debug", "ShowDMAState", false); SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionDebugShowDMAState, "Debug", "ShowDMAState", false);
for (u32 i = 0; GeneralSettingsWidget::THEME_NAMES[i]; i++) for (u32 i = 0; InterfaceSettingsWidget::THEME_NAMES[i]; i++)
{ {
const QString key = QString::fromUtf8(GeneralSettingsWidget::THEME_VALUES[i]); const QString key = QString::fromUtf8(InterfaceSettingsWidget::THEME_VALUES[i]);
QAction* action = QAction* action =
m_ui.menuSettingsTheme->addAction(qApp->translate("MainWindow", GeneralSettingsWidget::THEME_NAMES[i])); m_ui.menuSettingsTheme->addAction(qApp->translate("MainWindow", InterfaceSettingsWidget::THEME_NAMES[i]));
action->setCheckable(true); action->setCheckable(true);
action->setData(key); action->setData(key);
connect(action, &QAction::toggled, [this, key](bool) { setTheme(key); }); connect(action, &QAction::toggled, [this, key](bool) { setTheme(key); });
@ -2154,7 +2153,7 @@ void MainWindow::reloadThemeSpecificImages()
void MainWindow::setStyleFromSettings() void MainWindow::setStyleFromSettings()
{ {
const std::string theme(Host::GetBaseStringSettingValue("UI", "Theme", GeneralSettingsWidget::DEFAULT_THEME_NAME)); const std::string theme(Host::GetBaseStringSettingValue("UI", "Theme", InterfaceSettingsWidget::DEFAULT_THEME_NAME));
// setPalette() shouldn't be necessary, as the documentation claims that setStyle() resets the palette, but it // setPalette() shouldn't be necessary, as the documentation claims that setStyle() resets the palette, but it
// is here, to work around a bug in 6.4.x and 6.5.x where the palette doesn't restore after changing themes. // is here, to work around a bug in 6.4.x and 6.5.x where the palette doesn't restore after changing themes.
@ -2471,7 +2470,7 @@ void MainWindow::updateDebugMenuCropMode()
void MainWindow::updateMenuSelectedTheme() void MainWindow::updateMenuSelectedTheme()
{ {
QString theme = QString theme =
QString::fromStdString(Host::GetBaseStringSettingValue("UI", "Theme", GeneralSettingsWidget::DEFAULT_THEME_NAME)); QString::fromStdString(Host::GetBaseStringSettingValue("UI", "Theme", InterfaceSettingsWidget::DEFAULT_THEME_NAME));
for (QObject* obj : m_ui.menuSettingsTheme->children()) for (QObject* obj : m_ui.menuSettingsTheme->children())
{ {
@ -2613,7 +2612,7 @@ void MainWindow::startupUpdateCheck()
void MainWindow::updateDebugMenuVisibility() void MainWindow::updateDebugMenuVisibility()
{ {
const bool visible = Host::GetBaseBoolSettingValue("Main", "ShowDebugMenu", false); const bool visible = QtHost::ShouldShowDebugOptions();
m_ui.menuDebug->menuAction()->setVisible(visible); m_ui.menuDebug->menuAction()->setVisible(visible);
} }

View File

@ -123,14 +123,13 @@
</widget> </widget>
<addaction name="actionViewGameProperties"/> <addaction name="actionViewGameProperties"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionGeneralSettings"/> <addaction name="actionInterfaceSettings"/>
<addaction name="actionGameListSettings"/> <addaction name="actionGameListSettings"/>
<addaction name="actionBIOSSettings"/> <addaction name="actionBIOSSettings"/>
<addaction name="actionConsoleSettings"/> <addaction name="actionConsoleSettings"/>
<addaction name="actionEmulationSettings"/> <addaction name="actionEmulationSettings"/>
<addaction name="actionMemoryCardSettings"/> <addaction name="actionMemoryCardSettings"/>
<addaction name="actionDisplaySettings"/> <addaction name="actionGraphicsSettings"/>
<addaction name="actionEnhancementSettings"/>
<addaction name="actionPostProcessingSettings"/> <addaction name="actionPostProcessingSettings"/>
<addaction name="actionAudioSettings"/> <addaction name="actionAudioSettings"/>
<addaction name="actionAchievementSettings"/> <addaction name="actionAchievementSettings"/>
@ -433,22 +432,13 @@
<string>&amp;Hotkeys</string> <string>&amp;Hotkeys</string>
</property> </property>
</action> </action>
<action name="actionDisplaySettings"> <action name="actionGraphicsSettings">
<property name="icon"> <property name="icon">
<iconset theme="image-fill"> <iconset theme="image-fill">
<normaloff>.</normaloff>.</iconset> <normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>&amp;Display</string> <string>&amp;Graphics</string>
</property>
</action>
<action name="actionEnhancementSettings">
<property name="icon">
<iconset theme="sparkle-fill">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Enhancements</string>
</property> </property>
</action> </action>
<action name="actionPostProcessingSettings"> <action name="actionPostProcessingSettings">
@ -587,13 +577,13 @@
<string>Game List</string> <string>Game List</string>
</property> </property>
</action> </action>
<action name="actionGeneralSettings"> <action name="actionInterfaceSettings">
<property name="icon"> <property name="icon">
<iconset theme="settings-3-line"> <iconset theme="settings-3-line">
<normaloff>.</normaloff>.</iconset> <normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>General</string> <string>&amp;Interface</string>
</property> </property>
</action> </action>
<action name="actionAdvancedSettings"> <action name="actionAdvancedSettings">

View File

@ -1373,7 +1373,7 @@ void EmuThread::saveScreenshot()
return; return;
} }
System::SaveScreenshot(nullptr, true, true); System::SaveScreenshot();
} }
void Host::OnAchievementsLoginRequested(Achievements::LoginRequestReason reason) void Host::OnAchievementsLoginRequested(Achievements::LoginRequestReason reason)
@ -1830,6 +1830,11 @@ void QtHost::QueueSettingsSave()
s_settings_save_timer->start(SETTINGS_SAVE_DELAY); s_settings_save_timer->start(SETTINGS_SAVE_DELAY);
} }
bool QtHost::ShouldShowDebugOptions()
{
return Host::GetBaseBoolSettingValue("Main", "ShowDebugMenu", false);
}
void Host::RequestSystemShutdown(bool allow_confirm, bool save_state) void Host::RequestSystemShutdown(bool allow_confirm, bool save_state)
{ {
if (!System::IsValid()) if (!System::IsValid())

View File

@ -286,6 +286,9 @@ bool DownloadFileFromZip(QWidget* parent, const QString& title, std::string url,
/// Thread-safe settings access. /// Thread-safe settings access.
void QueueSettingsSave(); void QueueSettingsSave();
/// Returns true if the debug menu and functionality should be shown.
bool ShouldShowDebugOptions();
/// VM state, safe to access on UI thread. /// VM state, safe to access on UI thread.
bool IsSystemValid(); bool IsSystemValid();
bool IsSystemPaused(); bool IsSystemPaused();

View File

@ -693,59 +693,6 @@ void OpenURL(QWidget* parent, const char* url)
return OpenURL(parent, QUrl::fromEncoded(QByteArray(url, static_cast<int>(std::strlen(url))))); return OpenURL(parent, QUrl::fromEncoded(QByteArray(url, static_cast<int>(std::strlen(url)))));
} }
void FillComboBoxWithResolutionScales(QComboBox* cb)
{
cb->addItem(qApp->translate("GPUSettingsWidget", "Automatic based on window size"));
cb->addItem(qApp->translate("GPUSettingsWidget", "1x"));
cb->addItem(qApp->translate("GPUSettingsWidget", "2x"));
cb->addItem(qApp->translate("GPUSettingsWidget", "3x (for 720p)"));
cb->addItem(qApp->translate("GPUSettingsWidget", "4x"));
cb->addItem(qApp->translate("GPUSettingsWidget", "5x (for 1080p)"));
cb->addItem(qApp->translate("GPUSettingsWidget", "6x (for 1440p)"));
cb->addItem(qApp->translate("GPUSettingsWidget", "7x"));
cb->addItem(qApp->translate("GPUSettingsWidget", "8x"));
cb->addItem(qApp->translate("GPUSettingsWidget", "9x (for 4K)"));
cb->addItem(qApp->translate("GPUSettingsWidget", "10x"));
cb->addItem(qApp->translate("GPUSettingsWidget", "11x"));
cb->addItem(qApp->translate("GPUSettingsWidget", "12x"));
cb->addItem(qApp->translate("GPUSettingsWidget", "13x"));
cb->addItem(qApp->translate("GPUSettingsWidget", "14x"));
cb->addItem(qApp->translate("GPUSettingsWidget", "15x"));
cb->addItem(qApp->translate("GPUSettingsWidget", "16x"));
}
QVariant GetMSAAModeValue(uint multisamples, bool ssaa)
{
const uint userdata = (multisamples & 0x7FFFFFFFu) | (static_cast<uint>(ssaa) << 31);
return QVariant(userdata);
}
void DecodeMSAAModeValue(const QVariant& userdata, uint* multisamples, bool* ssaa)
{
bool ok;
const uint value = userdata.toUInt(&ok);
if (!ok || value == 0)
{
*multisamples = 1;
*ssaa = false;
return;
}
*multisamples = value & 0x7FFFFFFFu;
*ssaa = (value & (1u << 31)) != 0u;
}
void FillComboBoxWithMSAAModes(QComboBox* cb)
{
cb->addItem(qApp->translate("GPUSettingsWidget", "Disabled"), GetMSAAModeValue(1, false));
for (uint i = 2; i <= 32; i *= 2)
cb->addItem(qApp->translate("GPUSettingsWidget", "%1x MSAA").arg(i), GetMSAAModeValue(i, false));
for (uint i = 2; i <= 32; i *= 2)
cb->addItem(qApp->translate("GPUSettingsWidget", "%1x SSAA").arg(i), GetMSAAModeValue(i, true));
}
std::optional<unsigned> PromptForAddress(QWidget* parent, const QString& title, const QString& label, bool code) std::optional<unsigned> PromptForAddress(QWidget* parent, const QString& title, const QString& label, bool code)
{ {
const QString address_str( const QString address_str(

View File

@ -67,14 +67,6 @@ void OpenURL(QWidget* parent, const QUrl& qurl);
/// Opens a URL string with the default handler. /// Opens a URL string with the default handler.
void OpenURL(QWidget* parent, const char* url); void OpenURL(QWidget* parent, const char* url);
/// Fills a combo box with resolution scale options.
void FillComboBoxWithResolutionScales(QComboBox* cb);
/// Fills a combo box with multisampling options.
QVariant GetMSAAModeValue(uint multisamples, bool ssaa);
void DecodeMSAAModeValue(const QVariant& userdata, uint* multisamples, bool* ssaa);
void FillComboBoxWithMSAAModes(QComboBox* cb);
/// Prompts for an address in hex. /// Prompts for an address in hex.
std::optional<unsigned> PromptForAddress(QWidget* parent, const QString& title, const QString& label, bool code); std::optional<unsigned> PromptForAddress(QWidget* parent, const QString& title, const QString& label, bool code);

View File

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com> // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#include "settingswindow.h" #include "settingswindow.h"
@ -8,13 +8,12 @@
#include "consolesettingswidget.h" #include "consolesettingswidget.h"
#include "achievementsettingswidget.h" #include "achievementsettingswidget.h"
#include "displaysettingswidget.h"
#include "emulationsettingswidget.h" #include "emulationsettingswidget.h"
#include "enhancementsettingswidget.h"
#include "foldersettingswidget.h" #include "foldersettingswidget.h"
#include "gamelistsettingswidget.h" #include "gamelistsettingswidget.h"
#include "gamesummarywidget.h" #include "gamesummarywidget.h"
#include "generalsettingswidget.h" #include "graphicssettingswidget.h"
#include "interfacesettingswidget.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "memorycardsettingswidget.h" #include "memorycardsettingswidget.h"
#include "postprocessingsettingswidget.h" #include "postprocessingsettingswidget.h"
@ -78,9 +77,9 @@ void SettingsWindow::closeEvent(QCloseEvent* event)
void SettingsWindow::addPages() void SettingsWindow::addPages()
{ {
addWidget( addWidget(
m_general_settings = new GeneralSettingsWidget(this, m_ui.settingsContainer), tr("General"), m_general_settings = new InterfaceSettingsWidget(this, m_ui.settingsContainer), tr("Interface"),
QStringLiteral("settings-3-line"), QStringLiteral("settings-3-line"),
tr("<strong>General Settings</strong><hr>These options control how the emulator looks and " tr("<strong>Interface Settings</strong><hr>These options control how the emulator looks and "
"behaves.<br><br>Mouse over an option for additional information, and Shift+Wheel to scroll this panel.")); "behaves.<br><br>Mouse over an option for additional information, and Shift+Wheel to scroll this panel."));
if (!isPerGameSettings()) if (!isPerGameSettings())
@ -112,17 +111,11 @@ void SettingsWindow::addPages()
QStringLiteral("memcard-line"), QStringLiteral("memcard-line"),
tr("<strong>Memory Card Settings</strong><hr>This page lets you control what mode the memory card emulation will " tr("<strong>Memory Card Settings</strong><hr>This page lets you control what mode the memory card emulation will "
"function in, and where the images for these cards will be stored on disk.")); "function in, and where the images for these cards will be stored on disk."));
addWidget( addWidget(m_graphics_settings = new GraphicsSettingsWidget(this, m_ui.settingsContainer), tr("Graphics"),
m_display_settings = new DisplaySettingsWidget(this, m_ui.settingsContainer), tr("Display"), QStringLiteral("image-fill"),
QStringLiteral("image-fill"), tr("<strong>Graphics Settings</strong><hr>These options control how the graphics of the emulated console "
tr("<strong>Display Settings</strong><hr>These options control the how the frames generated by the console are " "are rendered. Not all options are available for the software renderer. Mouse over each option for "
"displayed on the screen.")); "additional information, and Shift+Wheel to scroll this panel."));
addWidget(
m_enhancement_settings = new EnhancementSettingsWidget(this, m_ui.settingsContainer), tr("Enhancements"),
QStringLiteral("sparkle-fill"),
tr("<strong>Enhancement Settings</strong><hr>These options control enhancements which can improve visuals compared "
"to the original console. Mouse over each option for additional information, and Shift+Wheel to scroll this "
"panel."));
addWidget( addWidget(
m_post_processing_settings = new PostProcessingSettingsWidget(this, m_ui.settingsContainer), tr("Post-Processing"), m_post_processing_settings = new PostProcessingSettingsWidget(this, m_ui.settingsContainer), tr("Post-Processing"),
QStringLiteral("sun-fill"), QStringLiteral("sun-fill"),
@ -168,6 +161,9 @@ void SettingsWindow::addPages()
tr("<strong>Advanced Settings</strong><hr>These options control logging and internal behavior of the " tr("<strong>Advanced Settings</strong><hr>These options control logging and internal behavior of the "
"emulator. Mouse over an option for additional information, and Shift+Wheel to scroll this panel.")); "emulator. Mouse over an option for additional information, and Shift+Wheel to scroll this panel."));
connect(m_advanced_settings, &AdvancedSettingsWidget::onShowDebugOptionsChanged, m_graphics_settings,
&GraphicsSettingsWidget::onShowDebugSettingsChanged);
if (isPerGameSettings()) if (isPerGameSettings())
{ {
m_ui.buttonBox->button(QDialogButtonBox::RestoreDefaults)->setVisible(false); m_ui.buttonBox->button(QDialogButtonBox::RestoreDefaults)->setVisible(false);
@ -500,6 +496,14 @@ void SettingsWindow::setStringSettingValue(const char* section, const char* key,
} }
} }
bool SettingsWindow::containsSettingValue(const char* section, const char* key) const
{
if (m_sif)
return m_sif->ContainsValue(section, key);
else
return Host::ContainsBaseSettingValue(section, key);
}
void SettingsWindow::removeSettingValue(const char* section, const char* key) void SettingsWindow::removeSettingValue(const char* section, const char* key)
{ {
if (m_sif) if (m_sif)

View File

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com> // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#pragma once #pragma once
@ -21,14 +21,13 @@ namespace GameDatabase {
struct Entry; struct Entry;
} }
class GeneralSettingsWidget; class InterfaceSettingsWidget;
class BIOSSettingsWidget; class BIOSSettingsWidget;
class GameListSettingsWidget; class GameListSettingsWidget;
class ConsoleSettingsWidget; class ConsoleSettingsWidget;
class EmulationSettingsWidget; class EmulationSettingsWidget;
class MemoryCardSettingsWidget; class MemoryCardSettingsWidget;
class DisplaySettingsWidget; class GraphicsSettingsWidget;
class EnhancementSettingsWidget;
class PostProcessingSettingsWidget; class PostProcessingSettingsWidget;
class AudioSettingsWidget; class AudioSettingsWidget;
class AchievementSettingsWidget; class AchievementSettingsWidget;
@ -51,14 +50,13 @@ public:
ALWAYS_INLINE bool isPerGameSettings() const { return static_cast<bool>(m_sif); } ALWAYS_INLINE bool isPerGameSettings() const { return static_cast<bool>(m_sif); }
ALWAYS_INLINE SettingsInterface* getSettingsInterface() const { return m_sif.get(); } ALWAYS_INLINE SettingsInterface* getSettingsInterface() const { return m_sif.get(); }
ALWAYS_INLINE GeneralSettingsWidget* getGeneralSettingsWidget() const { return m_general_settings; } ALWAYS_INLINE InterfaceSettingsWidget* getGeneralSettingsWidget() const { return m_general_settings; }
ALWAYS_INLINE BIOSSettingsWidget* getBIOSSettingsWidget() const { return m_bios_settings; } ALWAYS_INLINE BIOSSettingsWidget* getBIOSSettingsWidget() const { return m_bios_settings; }
ALWAYS_INLINE ConsoleSettingsWidget* getConsoleSettingsWidget() const { return m_console_settings; } ALWAYS_INLINE ConsoleSettingsWidget* getConsoleSettingsWidget() const { return m_console_settings; }
ALWAYS_INLINE EmulationSettingsWidget* getEmulationSettingsWidget() const { return m_emulation_settings; } ALWAYS_INLINE EmulationSettingsWidget* getEmulationSettingsWidget() const { return m_emulation_settings; }
ALWAYS_INLINE GameListSettingsWidget* getGameListSettingsWidget() const { return m_game_list_settings; } ALWAYS_INLINE GameListSettingsWidget* getGameListSettingsWidget() const { return m_game_list_settings; }
ALWAYS_INLINE MemoryCardSettingsWidget* getMemoryCardSettingsWidget() const { return m_memory_card_settings; } ALWAYS_INLINE MemoryCardSettingsWidget* getMemoryCardSettingsWidget() const { return m_memory_card_settings; }
ALWAYS_INLINE DisplaySettingsWidget* getDisplaySettingsWidget() const { return m_display_settings; } ALWAYS_INLINE GraphicsSettingsWidget* getGraphicsSettingsWidget() const { return m_graphics_settings; }
ALWAYS_INLINE EnhancementSettingsWidget* getEnhancementSettingsWidget() const { return m_enhancement_settings; }
ALWAYS_INLINE AudioSettingsWidget* getAudioSettingsWidget() const { return m_audio_settings; } ALWAYS_INLINE AudioSettingsWidget* getAudioSettingsWidget() const { return m_audio_settings; }
ALWAYS_INLINE AchievementSettingsWidget* getAchievementSettingsWidget() const { return m_achievement_settings; } ALWAYS_INLINE AchievementSettingsWidget* getAchievementSettingsWidget() const { return m_achievement_settings; }
ALWAYS_INLINE AdvancedSettingsWidget* getAdvancedSettingsWidget() const { return m_advanced_settings; } ALWAYS_INLINE AdvancedSettingsWidget* getAdvancedSettingsWidget() const { return m_advanced_settings; }
@ -85,6 +83,7 @@ public:
void setIntSettingValue(const char* section, const char* key, std::optional<int> value); void setIntSettingValue(const char* section, const char* key, std::optional<int> value);
void setFloatSettingValue(const char* section, const char* key, std::optional<float> value); void setFloatSettingValue(const char* section, const char* key, std::optional<float> value);
void setStringSettingValue(const char* section, const char* key, std::optional<const char*> value); void setStringSettingValue(const char* section, const char* key, std::optional<const char*> value);
bool containsSettingValue(const char* section, const char* key) const;
void removeSettingValue(const char* section, const char* key); void removeSettingValue(const char* section, const char* key);
Q_SIGNALS: Q_SIGNALS:
@ -104,7 +103,7 @@ protected:
private: private:
enum : u32 enum : u32
{ {
MAX_SETTINGS_WIDGETS = 13 MAX_SETTINGS_WIDGETS = 12
}; };
void addPages(); void addPages();
@ -115,14 +114,13 @@ private:
std::unique_ptr<SettingsInterface> m_sif; std::unique_ptr<SettingsInterface> m_sif;
GeneralSettingsWidget* m_general_settings = nullptr; InterfaceSettingsWidget* m_general_settings = nullptr;
BIOSSettingsWidget* m_bios_settings = nullptr; BIOSSettingsWidget* m_bios_settings = nullptr;
ConsoleSettingsWidget* m_console_settings = nullptr; ConsoleSettingsWidget* m_console_settings = nullptr;
EmulationSettingsWidget* m_emulation_settings = nullptr; EmulationSettingsWidget* m_emulation_settings = nullptr;
GameListSettingsWidget* m_game_list_settings = nullptr; GameListSettingsWidget* m_game_list_settings = nullptr;
MemoryCardSettingsWidget* m_memory_card_settings = nullptr; MemoryCardSettingsWidget* m_memory_card_settings = nullptr;
DisplaySettingsWidget* m_display_settings = nullptr; GraphicsSettingsWidget* m_graphics_settings = nullptr;
EnhancementSettingsWidget* m_enhancement_settings = nullptr;
PostProcessingSettingsWidget* m_post_processing_settings = nullptr; PostProcessingSettingsWidget* m_post_processing_settings = nullptr;
AudioSettingsWidget* m_audio_settings = nullptr; AudioSettingsWidget* m_audio_settings = nullptr;
AchievementSettingsWidget* m_achievement_settings = nullptr; AchievementSettingsWidget* m_achievement_settings = nullptr;

View File

@ -1,9 +1,9 @@
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>. // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>.
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#include "setupwizarddialog.h" #include "setupwizarddialog.h"
#include "controllersettingwidgetbinder.h" #include "controllersettingwidgetbinder.h"
#include "generalsettingswidget.h" #include "interfacesettingswidget.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "qthost.h" #include "qthost.h"
#include "qtutils.h" #include "qtutils.h"
@ -181,9 +181,9 @@ void SetupWizardDialog::setupUi()
void SetupWizardDialog::setupLanguagePage() void SetupWizardDialog::setupLanguagePage()
{ {
SettingWidgetBinder::BindWidgetToEnumSetting(nullptr, m_ui.theme, "UI", "Theme", GeneralSettingsWidget::THEME_NAMES, SettingWidgetBinder::BindWidgetToEnumSetting(nullptr, m_ui.theme, "UI", "Theme", InterfaceSettingsWidget::THEME_NAMES,
GeneralSettingsWidget::THEME_VALUES, InterfaceSettingsWidget::THEME_VALUES,
GeneralSettingsWidget::DEFAULT_THEME_NAME, "InterfaceSettingsWidget"); InterfaceSettingsWidget::DEFAULT_THEME_NAME, "InterfaceSettingsWidget");
connect(m_ui.theme, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SetupWizardDialog::themeChanged); connect(m_ui.theme, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SetupWizardDialog::themeChanged);
for (const auto& [language, code] : Host::GetAvailableLanguageList()) for (const auto& [language, code] : Host::GetAvailableLanguageList())