Qt: Redesign graphics settings panel
Add screenshot format/type.
This commit is contained in:
@ -2484,7 +2484,7 @@ void FullscreenUI::DrawSettingsWindow()
|
||||
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("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("Advanced Settings")}};
|
||||
|
||||
@ -3898,7 +3898,7 @@ void FullscreenUI::DrawDisplaySettingsPage()
|
||||
MenuHeading(FSUI_CSTR("Rendering"));
|
||||
|
||||
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."),
|
||||
"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,
|
||||
&Settings::GetDisplayScalingName, &Settings::GetDisplayScalingDisplayName, DisplayScalingMode::Count);
|
||||
|
||||
DrawToggleSetting(bsi, FSUI_CSTR("Internal Resolution Screenshots"),
|
||||
FSUI_CSTR("Saves screenshots at internal render resolution and without postprocessing."), "Display",
|
||||
"InternalResolutionScreenshots", false);
|
||||
DrawEnumSetting(bsi, FSUI_CSTR("Screenshot Size"),
|
||||
FSUI_CSTR("Determines the size of screenshots created by DuckStation."), "Display", "ScreenshotMode",
|
||||
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"));
|
||||
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 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 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 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", "Device Settings");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Disable All Enhancements");
|
||||
@ -6754,6 +6766,7 @@ TRANSLATE_NOOP("FullscreenUI", "Genre: %s");
|
||||
TRANSLATE_NOOP("FullscreenUI", "GitHub Repository");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Global Slot {0} - {1}##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 will be enabled on next game restart.");
|
||||
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", "Integration");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Interface Settings");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Internal Resolution Scale");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Internal Resolution Screenshots");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Internal Resolution");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Issue Tracker");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Last Played");
|
||||
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 On Exit");
|
||||
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", "Scaled Dithering");
|
||||
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", "Scanning Subdirectories");
|
||||
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", "Seek Speedup");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Select Device");
|
||||
@ -6942,6 +6956,7 @@ TRANSLATE_NOOP("FullscreenUI", "Select Disc Image");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Select Macro {} Binds");
|
||||
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 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 to use in fullscreen modes.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Selects the view that the game list will open to.");
|
||||
|
||||
105
src/core/gpu.cpp
105
src/core/gpu.cpp
@ -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,
|
||||
bool clear_alpha, bool flip_y, u32 resize_width, u32 resize_height,
|
||||
std::vector<u8> texture_data, u32 texture_data_stride,
|
||||
u8 quality, bool clear_alpha, bool flip_y, u32 resize_width,
|
||||
u32 resize_height, std::vector<u8> texture_data, u32 texture_data_stride,
|
||||
GPUTexture::Format texture_format)
|
||||
{
|
||||
|
||||
@ -1964,12 +1964,13 @@ static bool CompressAndWriteTextureToFile(u32 width, u32 height, std::string fil
|
||||
bool result = false;
|
||||
if (StringUtil::Strcasecmp(extension, ".png") == 0)
|
||||
{
|
||||
// TODO: Use quality... libpng is better.
|
||||
result =
|
||||
(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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -2072,14 +2073,16 @@ bool GPU::WriteDisplayTextureToFile(std::string filename, bool full_resolution /
|
||||
|
||||
if (!compress_on_thread)
|
||||
{
|
||||
return CompressAndWriteTextureToFile(read_width, read_height, std::move(filename), std::move(fp), clear_alpha,
|
||||
flip_y, resize_width, resize_height, std::move(texture_data),
|
||||
texture_data_stride, m_display_texture->GetFormat());
|
||||
return CompressAndWriteTextureToFile(read_width, read_height, std::move(filename), std::move(fp),
|
||||
g_settings.display_screenshot_quality, clear_alpha, flip_y, resize_width,
|
||||
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::move(fp), clear_alpha, flip_y, resize_width, resize_height, std::move(texture_data),
|
||||
texture_data_stride, m_display_texture->GetFormat());
|
||||
std::move(fp), g_settings.display_screenshot_quality, clear_alpha, flip_y, resize_width,
|
||||
resize_height, std::move(texture_data), texture_data_stride,
|
||||
m_display_texture->GetFormat());
|
||||
compress_thread.detach();
|
||||
return true;
|
||||
}
|
||||
@ -2131,53 +2134,61 @@ bool GPU::RenderScreenshotToBuffer(u32 width, u32 height, const Common::Rectangl
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GPU::RenderScreenshotToFile(std::string filename, bool internal_resolution /* = false */,
|
||||
bool compress_on_thread /* = false */)
|
||||
bool GPU::RenderScreenshotToFile(std::string filename, DisplayScreenshotMode mode, u8 quality, bool compress_on_thread)
|
||||
{
|
||||
u32 width = g_gpu_device->GetWindowWidth();
|
||||
u32 height = g_gpu_device->GetWindowHeight();
|
||||
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)
|
||||
{
|
||||
const u32 draw_width = static_cast<u32>(draw_rect.GetWidth());
|
||||
const u32 draw_height = static_cast<u32>(draw_rect.GetHeight());
|
||||
|
||||
// If internal res, scale the computed draw rectangle to the internal res.
|
||||
// We re-use the draw rect because it's already been AR corrected.
|
||||
const float sar =
|
||||
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)
|
||||
if (mode == DisplayScreenshotMode::InternalResolution)
|
||||
{
|
||||
const u32 draw_width = static_cast<u32>(draw_rect.GetWidth());
|
||||
const u32 draw_height = static_cast<u32>(draw_rect.GetHeight());
|
||||
|
||||
// If internal res, scale the computed draw rectangle to the internal res.
|
||||
// We re-use the draw rect because it's already been AR corrected.
|
||||
const float sar =
|
||||
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;
|
||||
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.
|
||||
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.
|
||||
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)
|
||||
{
|
||||
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),
|
||||
pixels_stride, pixels_format);
|
||||
}
|
||||
|
||||
std::thread compress_thread(CompressAndWriteTextureToFile, width, height, std::move(filename), std::move(fp), true,
|
||||
g_gpu_device->UsesLowerLeftOrigin(), width, height, std::move(pixels), pixels_stride,
|
||||
pixels_format);
|
||||
std::thread compress_thread(CompressAndWriteTextureToFile, width, height, std::move(filename), std::move(fp), quality,
|
||||
true, g_gpu_device->UsesLowerLeftOrigin(), width, height, std::move(pixels),
|
||||
pixels_stride, pixels_format);
|
||||
compress_thread.detach();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -209,7 +209,7 @@ public:
|
||||
std::vector<u8>* out_pixels, u32* out_stride, GPUTexture::Format* out_format);
|
||||
|
||||
/// 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.
|
||||
bool PresentDisplay();
|
||||
|
||||
@ -180,6 +180,12 @@ bool Host::RemoveValueFromBaseStringListSetting(const char* section, const char*
|
||||
->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)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
|
||||
@ -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);
|
||||
bool AddValueToBaseStringListSetting(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 CommitBaseSettingChanges();
|
||||
|
||||
|
||||
@ -249,6 +249,18 @@ void Settings::Load(SettingsInterface& si)
|
||||
GetDisplayExclusiveFullscreenControlName(DEFAULT_DISPLAY_EXCLUSIVE_FULLSCREEN_CONTROL))
|
||||
.c_str())
|
||||
.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_active_start_offset = static_cast<s16>(si.GetIntValue("Display", "ActiveStartOffset", 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_enhancements = si.GetBoolValue("Display", "ShowEnhancements", 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);
|
||||
video_sync_enabled = si.GetBoolValue("Display", "VSync", DEFAULT_VSYNC_VALUE);
|
||||
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", "ExclusiveFullscreenControl",
|
||||
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.GetIntValue("Display", "CustomAspectRatioDenominator", display_aspect_ratio_custom_denominator);
|
||||
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", "ShowEnhancements", display_show_enhancements);
|
||||
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", "VSync", video_sync_enabled);
|
||||
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 = {
|
||||
TRANSLATE_NOOP("GPURenderer", "Automatic"),
|
||||
#ifdef _WIN32
|
||||
TRANSLATE_NOOP("GPURenderer", "Hardware (D3D11)"), TRANSLATE_NOOP("GPURenderer", "Hardware (D3D12)"),
|
||||
TRANSLATE_NOOP("GPURenderer", "Direct3D 11"), TRANSLATE_NOOP("GPURenderer", "Direct3D 12"),
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
TRANSLATE_NOOP("GPURenderer", "Hardware (Metal)"),
|
||||
TRANSLATE_NOOP("GPURenderer", "Metal"),
|
||||
#endif
|
||||
#ifdef ENABLE_VULKAN
|
||||
TRANSLATE_NOOP("GPURenderer", "Hardware (Vulkan)"),
|
||||
TRANSLATE_NOOP("GPURenderer", "Vulkan"),
|
||||
#endif
|
||||
#ifdef ENABLE_OPENGL
|
||||
TRANSLATE_NOOP("GPURenderer", "Hardware (OpenGL)"),
|
||||
TRANSLATE_NOOP("GPURenderer", "OpenGL"),
|
||||
#endif
|
||||
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 = {
|
||||
"Nearest", "Bilinear", "BilinearBinAlpha", "JINC2", "JINC2BinAlpha", "xBR", "xBRBinAlpha",
|
||||
};
|
||||
@ -1312,7 +1363,7 @@ static constexpr const std::array s_display_exclusive_fullscreen_mode_names = {
|
||||
"Allowed",
|
||||
};
|
||||
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", "Allowed"),
|
||||
};
|
||||
@ -1342,6 +1393,89 @@ const char* Settings::GetDisplayExclusiveFullscreenControlDisplayName(DisplayExc
|
||||
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 = {
|
||||
"Null",
|
||||
#ifdef ENABLE_CUBEB
|
||||
|
||||
@ -135,6 +135,9 @@ struct Settings
|
||||
DisplayAlignment display_alignment = DEFAULT_DISPLAY_ALIGNMENT;
|
||||
DisplayScalingMode display_scaling = DEFAULT_DISPLAY_SCALING;
|
||||
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_denominator = 0;
|
||||
s16 display_active_start_offset = 0;
|
||||
@ -155,7 +158,6 @@ struct Settings
|
||||
bool display_show_inputs : 1 = false;
|
||||
bool display_show_enhancements : 1 = false;
|
||||
bool display_all_frames : 1 = false;
|
||||
bool display_internal_resolution_screenshots : 1 = false;
|
||||
bool display_stretch_vertically : 1 = false;
|
||||
bool video_sync_enabled = DEFAULT_VSYNC_VALUE;
|
||||
float display_osd_scale = 100.0f;
|
||||
@ -374,6 +376,8 @@ struct Settings
|
||||
static const char* GetRendererName(GPURenderer renderer);
|
||||
static const char* GetRendererDisplayName(GPURenderer renderer);
|
||||
static RenderAPI GetRenderAPIForRenderer(GPURenderer renderer);
|
||||
static GPURenderer GetRendererForRenderAPI(RenderAPI api);
|
||||
static GPURenderer GetAutomaticRenderer();
|
||||
|
||||
static std::optional<GPUTextureFilter> ParseTextureFilterName(const char* str);
|
||||
static const char* GetTextureFilterName(GPUTextureFilter filter);
|
||||
@ -411,6 +415,15 @@ struct Settings
|
||||
static const char* GetDisplayExclusiveFullscreenControlName(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 const char* GetAudioBackendName(AudioBackend backend);
|
||||
static const char* GetAudioBackendDisplayName(AudioBackend backend);
|
||||
@ -473,6 +486,9 @@ struct Settings
|
||||
static constexpr DisplayScalingMode DEFAULT_DISPLAY_SCALING = DisplayScalingMode::BilinearSmooth;
|
||||
static constexpr DisplayExclusiveFullscreenControl DEFAULT_DISPLAY_EXCLUSIVE_FULLSCREEN_CONTROL =
|
||||
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 u8 DEFAULT_CDROM_READAHEAD_SECTORS = 8;
|
||||
|
||||
@ -4306,8 +4306,8 @@ void System::StopDumpingAudio()
|
||||
Host::AddOSDMessage(TRANSLATE_STR("OSDMessage", "Stopped dumping audio."), 5.0f);
|
||||
}
|
||||
|
||||
bool System::SaveScreenshot(const char* filename /* = nullptr */, bool full_resolution /* = true */,
|
||||
bool apply_aspect_ratio /* = true */, bool compress_on_thread /* = true */)
|
||||
bool System::SaveScreenshot(const char* filename, DisplayScreenshotMode mode, DisplayScreenshotFormat format,
|
||||
u8 quality, bool compress_on_thread)
|
||||
{
|
||||
if (!System::IsValid())
|
||||
return false;
|
||||
@ -4316,7 +4316,7 @@ bool System::SaveScreenshot(const char* filename /* = nullptr */, bool full_reso
|
||||
if (!filename)
|
||||
{
|
||||
const auto& code = System::GetGameSerial();
|
||||
const char* extension = "png";
|
||||
const char* extension = Settings::GetDisplayScreenshotFormatExtension(format);
|
||||
if (code.empty())
|
||||
{
|
||||
auto_filename =
|
||||
@ -4337,10 +4337,7 @@ bool System::SaveScreenshot(const char* filename /* = nullptr */, bool full_reso
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool screenshot_saved =
|
||||
g_gpu->RenderScreenshotToFile(filename, g_settings.display_internal_resolution_screenshots, compress_on_thread);
|
||||
|
||||
if (!screenshot_saved)
|
||||
if (!g_gpu->RenderScreenshotToFile(filename, mode, quality, compress_on_thread))
|
||||
{
|
||||
Host::AddFormattedOSDMessage(10.0f, TRANSLATE("OSDMessage", "Failed to save screenshot to '%s'"), filename);
|
||||
return false;
|
||||
|
||||
@ -416,9 +416,10 @@ bool StartDumpingAudio(const char* filename = nullptr);
|
||||
/// Stops dumping audio to file if it has been started.
|
||||
void StopDumpingAudio();
|
||||
|
||||
/// 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 compress_on_thread = true);
|
||||
/// Saves a screenshot to the specified file. If no file name is provided, one will be generated automatically.
|
||||
bool SaveScreenshot(const char* filename = nullptr, DisplayScreenshotMode mode = g_settings.display_screenshot_mode,
|
||||
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.
|
||||
bool LoadCheatList(const char* filename);
|
||||
|
||||
@ -160,6 +160,23 @@ enum class DisplayExclusiveFullscreenControl : u8
|
||||
Count
|
||||
};
|
||||
|
||||
enum class DisplayScreenshotMode : u8
|
||||
{
|
||||
ScreenResolution,
|
||||
InternalResolution,
|
||||
UncorrectedInternalResolution,
|
||||
Count
|
||||
};
|
||||
|
||||
enum class DisplayScreenshotFormat : u8
|
||||
{
|
||||
PNG,
|
||||
JPEG,
|
||||
TGA,
|
||||
BMP,
|
||||
Count
|
||||
};
|
||||
|
||||
enum class AudioBackend : u8
|
||||
{
|
||||
Null,
|
||||
|
||||
Reference in New Issue
Block a user