mirror of
https://github.com/stenzek/duckstation.git
synced 2024-11-30 17:40:38 +00:00
Support custom and match display aspect ratios
This commit is contained in:
parent
48bc152a63
commit
256f272768
@ -45,6 +45,7 @@
|
||||
</string-array>
|
||||
<string-array name="settings_display_aspect_ratio_names">
|
||||
<item>Auto (Nativo del juego)</item>
|
||||
<item>Auto (Match Display)</item>
|
||||
<item>4:3</item>
|
||||
<item>16:9</item>
|
||||
<item>16:10</item>
|
||||
|
@ -45,6 +45,7 @@
|
||||
</string-array>
|
||||
<string-array name="settings_display_aspect_ratio_names">
|
||||
<item>Auto (Game Native)</item>
|
||||
<item>Auto (Match Display)</item>
|
||||
<item>4:3</item>
|
||||
<item>16:9</item>
|
||||
<item>16:10</item>
|
||||
|
@ -45,6 +45,7 @@
|
||||
</string-array>
|
||||
<string-array name="settings_display_aspect_ratio_names">
|
||||
<item>Auto (Game Native)</item>
|
||||
<item>Auto (Match Display)</item>
|
||||
<item>4:3</item>
|
||||
<item>16:9</item>
|
||||
<item>16:10</item>
|
||||
|
@ -45,6 +45,7 @@
|
||||
</string-array>
|
||||
<string-array name="settings_display_aspect_ratio_names">
|
||||
<item>Auto (Nativo)</item>
|
||||
<item>Auto (Match Display)</item>
|
||||
<item>4:3</item>
|
||||
<item>16:9</item>
|
||||
<item>16:10</item>
|
||||
|
@ -44,8 +44,9 @@
|
||||
<item>Все границы</item>
|
||||
</string-array>
|
||||
<string-array name="settings_display_aspect_ratio_names">
|
||||
<item>Автонастройка (нативное игре)</item>
|
||||
<item>4:3</item>
|
||||
<item>Автонастройка (нативное игре)</item>
|
||||
<item>Auto (Match Display)</item>
|
||||
<item>4:3</item>
|
||||
<item>16:9</item>
|
||||
<item>16:10</item>
|
||||
<item>19:9</item>
|
||||
|
@ -89,6 +89,7 @@
|
||||
</string-array>
|
||||
<string-array name="settings_display_aspect_ratio_names">
|
||||
<item>Auto (Game Native)</item>
|
||||
<item>Auto (Match Display)</item>
|
||||
<item>4:3</item>
|
||||
<item>16:9</item>
|
||||
<item>16:10</item>
|
||||
@ -105,6 +106,7 @@
|
||||
</string-array>
|
||||
<string-array name="settings_display_aspect_ratio_values">
|
||||
<item>Auto (Game Native)</item>
|
||||
<item>Auto (Match Window)</item>
|
||||
<item>4:3</item>
|
||||
<item>16:9</item>
|
||||
<item>16:10</item>
|
||||
|
@ -492,7 +492,7 @@ float GPU::GetDisplayAspectRatio() const
|
||||
}
|
||||
else
|
||||
{
|
||||
return Settings::GetDisplayAspectRatioValue(g_settings.display_aspect_ratio);
|
||||
return g_settings.GetDisplayAspectRatioValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
251
src/core/gte.cpp
251
src/core/gte.cpp
@ -3,10 +3,13 @@
|
||||
#include "common/bitutils.h"
|
||||
#include "common/state_wrapper.h"
|
||||
#include "cpu_core.h"
|
||||
#include "host_display.h"
|
||||
#include "host_interface.h"
|
||||
#include "pgxp.h"
|
||||
#include "settings.h"
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <numeric>
|
||||
|
||||
namespace GTE {
|
||||
|
||||
@ -19,6 +22,11 @@ static constexpr s32 IR0_MAX_VALUE = 0x1000;
|
||||
static constexpr s32 IR123_MIN_VALUE = -(INT64_C(1) << 15);
|
||||
static constexpr s32 IR123_MAX_VALUE = (INT64_C(1) << 15) - 1;
|
||||
|
||||
static DisplayAspectRatio s_aspect_ratio = DisplayAspectRatio::R4_3;
|
||||
static u32 s_custom_aspect_ratio_numerator;
|
||||
static u32 s_custom_aspect_ratio_denominator;
|
||||
static float s_custom_aspect_ratio_f;
|
||||
|
||||
#define REGS CPU::g_state.gte_regs
|
||||
|
||||
ALWAYS_INLINE static u32 CountLeadingBits(u32 value)
|
||||
@ -148,6 +156,7 @@ ALWAYS_INLINE static u32 TruncateRGB(s32 value)
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
UpdateAspectRatio();
|
||||
Reset();
|
||||
}
|
||||
|
||||
@ -162,6 +171,55 @@ bool DoState(StateWrapper& sw)
|
||||
return !sw.HasError();
|
||||
}
|
||||
|
||||
void UpdateAspectRatio()
|
||||
{
|
||||
if (!g_settings.gpu_widescreen_hack)
|
||||
{
|
||||
s_aspect_ratio = DisplayAspectRatio::R4_3;
|
||||
return;
|
||||
}
|
||||
|
||||
s_aspect_ratio = g_settings.display_aspect_ratio;
|
||||
|
||||
u32 num, denom;
|
||||
switch (s_aspect_ratio)
|
||||
{
|
||||
case DisplayAspectRatio::MatchWindow:
|
||||
{
|
||||
const HostDisplay* display = g_host_interface->GetDisplay();
|
||||
if (!display)
|
||||
{
|
||||
s_aspect_ratio = DisplayAspectRatio::R4_3;
|
||||
return;
|
||||
}
|
||||
|
||||
num = display->GetWindowWidth();
|
||||
denom = display->GetWindowHeight();
|
||||
}
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::Custom:
|
||||
{
|
||||
num = g_settings.display_aspect_ratio_custom_numerator;
|
||||
denom = g_settings.display_aspect_ratio_custom_denominator;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// (4 / 3) / (num / denom) => gcd((4 * denom) / (3 * num))
|
||||
const u32 x = 4u * denom;
|
||||
const u32 y = 3u * num;
|
||||
const u32 gcd = std::gcd(x, y);
|
||||
|
||||
s_custom_aspect_ratio_numerator = x / gcd;
|
||||
s_custom_aspect_ratio_denominator = y / gcd;
|
||||
|
||||
s_custom_aspect_ratio_f = static_cast<float>((4.0 / 3.0) / (static_cast<double>(num) / static_cast<double>(denom)));
|
||||
}
|
||||
|
||||
u32 ReadRegister(u32 index)
|
||||
{
|
||||
DebugAssert(index < countof(REGS.r32));
|
||||
@ -614,66 +672,65 @@ static void RTPS(const s16 V[3], u8 shift, bool lm, bool last)
|
||||
const s64 result = static_cast<s64>(ZeroExtend64(UNRDivide(REGS.H, REGS.SZ3)));
|
||||
|
||||
s64 Sx;
|
||||
if (g_settings.gpu_widescreen_hack)
|
||||
switch (s_aspect_ratio)
|
||||
{
|
||||
const DisplayAspectRatio ar = g_settings.display_aspect_ratio;
|
||||
switch (ar)
|
||||
{
|
||||
case DisplayAspectRatio::R16_9:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(3)) / s64(4)) + s64(REGS.OFX));
|
||||
break;
|
||||
case DisplayAspectRatio::R16_9:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(3)) / s64(4)) + s64(REGS.OFX));
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::R16_10:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(5)) / s64(6)) + s64(REGS.OFX));
|
||||
break;
|
||||
case DisplayAspectRatio::R16_10:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(5)) / s64(6)) + s64(REGS.OFX));
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::R19_9:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(12)) / s64(19)) + s64(REGS.OFX));
|
||||
break;
|
||||
case DisplayAspectRatio::R19_9:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(12)) / s64(19)) + s64(REGS.OFX));
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::R20_9:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(3)) / s64(5)) + s64(REGS.OFX));
|
||||
break;
|
||||
case DisplayAspectRatio::R20_9:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(3)) / s64(5)) + s64(REGS.OFX));
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::R21_9:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(9)) / s64(16)) + s64(REGS.OFX));
|
||||
break;
|
||||
case DisplayAspectRatio::R21_9:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(9)) / s64(16)) + s64(REGS.OFX));
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::R32_9:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(3)) / s64(8)) + s64(REGS.OFX));
|
||||
break;
|
||||
case DisplayAspectRatio::R32_9:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(3)) / s64(8)) + s64(REGS.OFX));
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::R8_7:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(7)) / s64(6)) + s64(REGS.OFX));
|
||||
break;
|
||||
case DisplayAspectRatio::R8_7:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(7)) / s64(6)) + s64(REGS.OFX));
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::R5_4:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(16)) / s64(15)) + s64(REGS.OFX));
|
||||
break;
|
||||
case DisplayAspectRatio::R5_4:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(16)) / s64(15)) + s64(REGS.OFX));
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::R3_2:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(8)) / s64(9)) + s64(REGS.OFX));
|
||||
break;
|
||||
case DisplayAspectRatio::R3_2:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(8)) / s64(9)) + s64(REGS.OFX));
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::R2_1:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(2)) / s64(3)) + s64(REGS.OFX));
|
||||
break;
|
||||
case DisplayAspectRatio::R2_1:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(2)) / s64(3)) + s64(REGS.OFX));
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::R1_1:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(7)) / s64(6)) + s64(REGS.OFX));
|
||||
break;
|
||||
case DisplayAspectRatio::R1_1:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(7)) / s64(6)) + s64(REGS.OFX));
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::Auto:
|
||||
case DisplayAspectRatio::R4_3:
|
||||
case DisplayAspectRatio::PAR1_1:
|
||||
default:
|
||||
Sx = (s64(result) * s64(REGS.IR1) + s64(REGS.OFX));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Sx = (s64(result) * s64(REGS.IR1) + s64(REGS.OFX));
|
||||
case DisplayAspectRatio::Custom:
|
||||
case DisplayAspectRatio::MatchWindow:
|
||||
Sx = ((((s64(result) * s64(REGS.IR1)) * s64(s_custom_aspect_ratio_numerator)) /
|
||||
s64(s_custom_aspect_ratio_denominator)) +
|
||||
s64(REGS.OFX));
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::Auto:
|
||||
case DisplayAspectRatio::R4_3:
|
||||
case DisplayAspectRatio::PAR1_1:
|
||||
default:
|
||||
Sx = (s64(result) * s64(REGS.IR1) + s64(REGS.OFX));
|
||||
break;
|
||||
}
|
||||
|
||||
const s64 Sy = s64(result) * s64(REGS.IR2) + s64(REGS.OFY);
|
||||
@ -713,70 +770,68 @@ static void RTPS(const s16 V[3], u8 shift, bool lm, bool last)
|
||||
const float precise_h_div_sz = float(REGS.H) / precise_z;
|
||||
const float fofx = float(REGS.OFX) / float(1 << 16);
|
||||
const float fofy = float(REGS.OFY) / float(1 << 16);
|
||||
float precise_x;
|
||||
if (g_settings.gpu_widescreen_hack)
|
||||
float precise_x = precise_ir1 * precise_h_div_sz;
|
||||
|
||||
switch (s_aspect_ratio)
|
||||
{
|
||||
precise_x = precise_ir1 * precise_h_div_sz;
|
||||
const DisplayAspectRatio ar = g_settings.display_aspect_ratio;
|
||||
switch (ar)
|
||||
{
|
||||
case DisplayAspectRatio::R16_9:
|
||||
precise_x = (precise_x * 3.0f) / 4.0f;
|
||||
break;
|
||||
case DisplayAspectRatio::R16_9:
|
||||
precise_x = (precise_x * 3.0f) / 4.0f;
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::R16_10:
|
||||
precise_x = (precise_x * 5.0f) / 6.0f;
|
||||
break;
|
||||
case DisplayAspectRatio::R16_10:
|
||||
precise_x = (precise_x * 5.0f) / 6.0f;
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::R19_9:
|
||||
precise_x = (precise_x * 12.0f) / 19.0f;
|
||||
break;
|
||||
case DisplayAspectRatio::R19_9:
|
||||
precise_x = (precise_x * 12.0f) / 19.0f;
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::R20_9:
|
||||
precise_x = (precise_x * 3.0f) / 5.0f;
|
||||
break;
|
||||
case DisplayAspectRatio::R20_9:
|
||||
precise_x = (precise_x * 3.0f) / 5.0f;
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::R21_9:
|
||||
precise_x = (precise_x * 9.0f) / 16.0f;
|
||||
break;
|
||||
case DisplayAspectRatio::R21_9:
|
||||
precise_x = (precise_x * 9.0f) / 16.0f;
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::R32_9:
|
||||
precise_x = (precise_x * 3.0f) / 8.0f;
|
||||
break;
|
||||
case DisplayAspectRatio::R32_9:
|
||||
precise_x = (precise_x * 3.0f) / 8.0f;
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::R8_7:
|
||||
precise_x = (precise_x * 7.0f) / 6.0f;
|
||||
break;
|
||||
case DisplayAspectRatio::R8_7:
|
||||
precise_x = (precise_x * 7.0f) / 6.0f;
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::R5_4:
|
||||
precise_x = (precise_x * 16.0f) / 15.0f;
|
||||
break;
|
||||
case DisplayAspectRatio::R5_4:
|
||||
precise_x = (precise_x * 16.0f) / 15.0f;
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::R3_2:
|
||||
precise_x = (precise_x * 8.0f) / 9.0f;
|
||||
break;
|
||||
case DisplayAspectRatio::R3_2:
|
||||
precise_x = (precise_x * 8.0f) / 9.0f;
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::R2_1:
|
||||
precise_x = (precise_x * 2.0f) / 3.0f;
|
||||
break;
|
||||
case DisplayAspectRatio::R2_1:
|
||||
precise_x = (precise_x * 2.0f) / 3.0f;
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::R1_1:
|
||||
precise_x = (precise_x * 7.0f) / 6.0f;
|
||||
break;
|
||||
case DisplayAspectRatio::R1_1:
|
||||
precise_x = (precise_x * 7.0f) / 6.0f;
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::Auto:
|
||||
case DisplayAspectRatio::R4_3:
|
||||
case DisplayAspectRatio::PAR1_1:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
precise_x += fofx;
|
||||
}
|
||||
else
|
||||
{
|
||||
precise_x = fofx + (precise_ir1 * precise_h_div_sz);
|
||||
case DisplayAspectRatio::MatchWindow:
|
||||
case DisplayAspectRatio::Custom:
|
||||
precise_x = precise_x * s_custom_aspect_ratio_f;
|
||||
break;
|
||||
|
||||
case DisplayAspectRatio::Auto:
|
||||
case DisplayAspectRatio::R4_3:
|
||||
case DisplayAspectRatio::PAR1_1:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
precise_x += fofx;
|
||||
|
||||
float precise_y = fofy + (precise_ir2 * precise_h_div_sz);
|
||||
|
||||
precise_x = std::clamp<float>(precise_x, -1024.0f, 1023.0f);
|
||||
|
@ -8,6 +8,7 @@ namespace GTE {
|
||||
void Initialize();
|
||||
void Reset();
|
||||
bool DoState(StateWrapper& sw);
|
||||
void UpdateAspectRatio();
|
||||
|
||||
// control registers are offset by +32
|
||||
u32 ReadRegister(u32 index);
|
||||
|
@ -533,6 +533,8 @@ void HostInterface::SetDefaultSettings(SettingsInterface& si)
|
||||
si.SetIntValue("Display", "LineEndOffset", 0);
|
||||
si.SetStringValue("Display", "AspectRatio",
|
||||
Settings::GetDisplayAspectRatioName(Settings::DEFAULT_DISPLAY_ASPECT_RATIO));
|
||||
si.SetIntValue("Display", "CustomAspectRatioNumerator", 4);
|
||||
si.GetIntValue("Display", "CustomAspectRatioDenominator", 3);
|
||||
si.SetBoolValue("Display", "Force4_3For24Bit", false);
|
||||
si.SetBoolValue("Display", "LinearFiltering", true);
|
||||
si.SetBoolValue("Display", "IntegerScaling", false);
|
||||
@ -803,6 +805,14 @@ void HostInterface::CheckForSettingsChanges(const Settings& old_settings)
|
||||
g_gpu->UpdateSettings();
|
||||
}
|
||||
|
||||
if (g_settings.display_aspect_ratio != old_settings.display_aspect_ratio ||
|
||||
(g_settings.display_aspect_ratio == DisplayAspectRatio::Custom &&
|
||||
(g_settings.display_aspect_ratio_custom_numerator != old_settings.display_aspect_ratio_custom_numerator ||
|
||||
g_settings.display_aspect_ratio_custom_denominator != old_settings.display_aspect_ratio_custom_denominator)))
|
||||
{
|
||||
GTE::UpdateAspectRatio();
|
||||
}
|
||||
|
||||
if (g_settings.gpu_pgxp_enable != old_settings.gpu_pgxp_enable ||
|
||||
(g_settings.gpu_pgxp_enable && (g_settings.gpu_pgxp_culling != old_settings.gpu_pgxp_culling ||
|
||||
g_settings.gpu_pgxp_cpu != old_settings.gpu_pgxp_cpu)))
|
||||
@ -899,6 +909,15 @@ void HostInterface::SetUserDirectoryToProgramDirectory()
|
||||
m_user_directory = program_directory;
|
||||
}
|
||||
|
||||
void HostInterface::OnHostDisplayResized()
|
||||
{
|
||||
if (System::IsValid())
|
||||
{
|
||||
if (g_settings.display_aspect_ratio == DisplayAspectRatio::MatchWindow)
|
||||
GTE::UpdateAspectRatio();
|
||||
}
|
||||
}
|
||||
|
||||
std::string HostInterface::GetUserDirectoryRelativePath(const char* format, ...) const
|
||||
{
|
||||
std::va_list ap;
|
||||
|
@ -183,6 +183,9 @@ protected:
|
||||
/// Enables "relative" mouse mode, locking the cursor position and returning relative coordinates.
|
||||
virtual void SetMouseMode(bool relative, bool hide_cursor);
|
||||
|
||||
/// Call when host display size changes, use with "match display" aspect ratio setting.
|
||||
virtual void OnHostDisplayResized();
|
||||
|
||||
/// Sets the user directory to the program directory, i.e. "portable mode".
|
||||
void SetUserDirectoryToProgramDirectory();
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "common/file_system.h"
|
||||
#include "common/make_array.h"
|
||||
#include "common/string_util.h"
|
||||
#include "host_display.h"
|
||||
#include "host_interface.h"
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
@ -222,6 +223,10 @@ void Settings::Load(SettingsInterface& si)
|
||||
ParseDisplayAspectRatio(
|
||||
si.GetStringValue("Display", "AspectRatio", GetDisplayAspectRatioName(DEFAULT_DISPLAY_ASPECT_RATIO)).c_str())
|
||||
.value_or(DEFAULT_DISPLAY_ASPECT_RATIO);
|
||||
display_aspect_ratio_custom_numerator = static_cast<u16>(
|
||||
std::clamp<int>(si.GetIntValue("Display", "CustomAspectRatioNumerator", 4), 1, std::numeric_limits<u16>::max()));
|
||||
display_aspect_ratio_custom_denominator = static_cast<u16>(
|
||||
std::clamp<int>(si.GetIntValue("Display", "CustomAspectRatioDenominator", 3), 1, std::numeric_limits<u16>::max()));
|
||||
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));
|
||||
@ -395,6 +400,8 @@ void Settings::Save(SettingsInterface& si) const
|
||||
si.SetIntValue("Display", "LineEndOffset", display_line_end_offset);
|
||||
si.SetBoolValue("Display", "Force4_3For24Bit", display_force_4_3_for_24bit);
|
||||
si.SetStringValue("Display", "AspectRatio", GetDisplayAspectRatioName(display_aspect_ratio));
|
||||
si.SetIntValue("Display", "CustomAspectRatioNumerator", display_aspect_ratio_custom_numerator);
|
||||
si.GetIntValue("Display", "CustomAspectRatioDenominator", display_aspect_ratio_custom_denominator);
|
||||
si.SetBoolValue("Display", "LinearFiltering", display_linear_filtering);
|
||||
si.SetBoolValue("Display", "IntegerScaling", display_integer_scaling);
|
||||
si.SetBoolValue("Display", "Stretch", display_stretch);
|
||||
@ -767,12 +774,12 @@ const char* Settings::GetDisplayCropModeDisplayName(DisplayCropMode crop_mode)
|
||||
return s_display_crop_mode_display_names[static_cast<int>(crop_mode)];
|
||||
}
|
||||
|
||||
static std::array<const char*, 14> s_display_aspect_ratio_names = {
|
||||
{TRANSLATABLE("DisplayAspectRatio", "Auto (Game Native)"), "4:3", "16:9", "16:10", "19:9", "20:9", "21:9", "32:9",
|
||||
"8:7", "5:4", "3:2", "2:1 (VRAM 1:1)", "1:1", "PAR 1:1"}};
|
||||
static constexpr std::array<float, 14> s_display_aspect_ratio_values = {
|
||||
{-1.0f, 4.0f / 3.0f, 16.0f / 9.0f, 16.0f / 10.0f, 19.0f / 9.0f, 20.0f / 9.0f, 64.0f / 27.0f, 32.0f / 9.0f,
|
||||
8.0f / 7.0f, 5.0f / 4.0f, 3.0f / 2.0f, 2.0f / 1.0f, 1.0f, -1.0f}};
|
||||
static std::array<const char*, 16> s_display_aspect_ratio_names = {
|
||||
{TRANSLATABLE("DisplayAspectRatio", "Auto (Game Native)"), "Auto (Match Window)", "Custom", "4:3", "16:9", "16:10",
|
||||
"19:9", "20:9", "21:9", "32:9", "8:7", "5:4", "3:2", "2:1 (VRAM 1:1)", "1:1", "PAR 1:1"}};
|
||||
static constexpr std::array<float, 16> s_display_aspect_ratio_values = {
|
||||
{-1.0f, -1.0f, -1.0f, 4.0f / 3.0f, 16.0f / 9.0f, 16.0f / 10.0f, 19.0f / 9.0f, 20.0f / 9.0f, 64.0f / 27.0f,
|
||||
32.0f / 9.0f, 8.0f / 7.0f, 5.0f / 4.0f, 3.0f / 2.0f, 2.0f / 1.0f, 1.0f, -1.0f}};
|
||||
|
||||
std::optional<DisplayAspectRatio> Settings::ParseDisplayAspectRatio(const char* str)
|
||||
{
|
||||
@ -793,9 +800,32 @@ const char* Settings::GetDisplayAspectRatioName(DisplayAspectRatio ar)
|
||||
return s_display_aspect_ratio_names[static_cast<int>(ar)];
|
||||
}
|
||||
|
||||
float Settings::GetDisplayAspectRatioValue(DisplayAspectRatio ar)
|
||||
float Settings::GetDisplayAspectRatioValue() const
|
||||
{
|
||||
return s_display_aspect_ratio_values[static_cast<int>(ar)];
|
||||
switch (display_aspect_ratio)
|
||||
{
|
||||
case DisplayAspectRatio::MatchWindow:
|
||||
{
|
||||
const HostDisplay* display = g_host_interface->GetDisplay();
|
||||
if (!display)
|
||||
return s_display_aspect_ratio_values[static_cast<int>(DEFAULT_DISPLAY_ASPECT_RATIO)];
|
||||
|
||||
const u32 width = display->GetWindowWidth();
|
||||
const u32 height = display->GetWindowHeight() - display->GetDisplayTopMargin();
|
||||
return static_cast<float>(width) / static_cast<float>(height);
|
||||
}
|
||||
|
||||
case DisplayAspectRatio::Custom:
|
||||
{
|
||||
return static_cast<float>(display_aspect_ratio_custom_numerator) /
|
||||
static_cast<float>(display_aspect_ratio_custom_denominator);
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
return s_display_aspect_ratio_values[static_cast<int>(display_aspect_ratio)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static std::array<const char*, 3> s_audio_backend_names = {{
|
||||
|
@ -127,6 +127,8 @@ struct Settings
|
||||
bool gpu_pgxp_depth_buffer = false;
|
||||
DisplayCropMode display_crop_mode = DisplayCropMode::None;
|
||||
DisplayAspectRatio display_aspect_ratio = DisplayAspectRatio::Auto;
|
||||
u16 display_aspect_ratio_custom_numerator = 0;
|
||||
u16 display_aspect_ratio_custom_denominator = 0;
|
||||
s16 display_active_start_offset = 0;
|
||||
s16 display_active_end_offset = 0;
|
||||
s8 display_line_start_offset = 0;
|
||||
@ -256,6 +258,8 @@ struct Settings
|
||||
return audio_output_muted ? 0 : (fast_forwarding ? audio_fast_forward_volume : audio_output_volume);
|
||||
}
|
||||
|
||||
float GetDisplayAspectRatioValue() const;
|
||||
|
||||
bool HasAnyPerGameMemoryCards() const;
|
||||
|
||||
static void CPUOverclockPercentToFraction(u32 percent, u32* numerator, u32* denominator);
|
||||
@ -316,7 +320,6 @@ struct Settings
|
||||
|
||||
static std::optional<DisplayAspectRatio> ParseDisplayAspectRatio(const char* str);
|
||||
static const char* GetDisplayAspectRatioName(DisplayAspectRatio ar);
|
||||
static float GetDisplayAspectRatioValue(DisplayAspectRatio ar);
|
||||
|
||||
static std::optional<AudioBackend> ParseAudioBackend(const char* str);
|
||||
static const char* GetAudioBackendName(AudioBackend backend);
|
||||
|
@ -94,6 +94,8 @@ enum class DisplayCropMode : u8
|
||||
enum class DisplayAspectRatio : u8
|
||||
{
|
||||
Auto,
|
||||
MatchWindow,
|
||||
Custom,
|
||||
R4_3,
|
||||
R16_9,
|
||||
R16_10,
|
||||
|
@ -25,6 +25,10 @@ DisplaySettingsWidget::DisplaySettingsWidget(QtHostInterface* host_interface, QW
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.displayAspectRatio, "Display", "AspectRatio",
|
||||
&Settings::ParseDisplayAspectRatio, &Settings::GetDisplayAspectRatioName,
|
||||
Settings::DEFAULT_DISPLAY_ASPECT_RATIO);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_host_interface, m_ui.customAspectRatioNumerator, "Display",
|
||||
"CustomAspectRatioNumerator", 1);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_host_interface, m_ui.customAspectRatioDenominator, "Display",
|
||||
"CustomAspectRatioDenominator", 1);
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.displayCropMode, "Display", "CropMode",
|
||||
&Settings::ParseDisplayCropMode, &Settings::GetDisplayCropModeName,
|
||||
Settings::DEFAULT_DISPLAY_CROP_MODE);
|
||||
@ -59,10 +63,13 @@ DisplaySettingsWidget::DisplaySettingsWidget(QtHostInterface* host_interface, QW
|
||||
&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);
|
||||
connect(m_ui.displayIntegerScaling, &QCheckBox::stateChanged, this,
|
||||
&DisplaySettingsWidget::onIntegerFilteringChanged);
|
||||
populateGPUAdaptersAndResolutions();
|
||||
onIntegerFilteringChanged();
|
||||
onAspectRatioChanged();
|
||||
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.renderer, tr("Renderer"),
|
||||
@ -283,3 +290,13 @@ void DisplaySettingsWidget::onIntegerFilteringChanged()
|
||||
m_ui.displayLinearFiltering->setEnabled(!m_ui.displayIntegerScaling->isChecked());
|
||||
m_ui.displayStretch->setEnabled(!m_ui.displayIntegerScaling->isChecked());
|
||||
}
|
||||
|
||||
void DisplaySettingsWidget::onAspectRatioChanged()
|
||||
{
|
||||
const bool is_custom =
|
||||
static_cast<DisplayAspectRatio>(m_ui.displayAspectRatio->currentIndex()) == DisplayAspectRatio::Custom;
|
||||
|
||||
m_ui.customAspectRatioNumerator->setVisible(is_custom);
|
||||
m_ui.customAspectRatioDenominator->setVisible(is_custom);
|
||||
m_ui.customAspectRatioSeparator->setVisible(is_custom);
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ private Q_SLOTS:
|
||||
void onGPUAdapterIndexChanged();
|
||||
void onGPUFullscreenModeIndexChanged();
|
||||
void onIntegerFilteringChanged();
|
||||
void onAspectRatioChanged();
|
||||
|
||||
private:
|
||||
void setupAdditionalUi();
|
||||
|
@ -111,7 +111,38 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="displayAspectRatio"/>
|
||||
<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">
|
||||
|
@ -575,6 +575,8 @@ void CommonHostInterface::OnHostDisplayResized()
|
||||
const u32 new_height = m_display ? m_display->GetWindowHeight() : 0;
|
||||
const float new_scale = m_display ? m_display->GetWindowScale() : 1.0f;
|
||||
|
||||
HostInterface::OnHostDisplayResized();
|
||||
|
||||
ImGui::GetIO().DisplaySize.x = static_cast<float>(new_width);
|
||||
ImGui::GetIO().DisplaySize.y = static_cast<float>(new_height);
|
||||
|
||||
|
@ -412,13 +412,13 @@ protected:
|
||||
void UpdateSpeedLimiterState();
|
||||
|
||||
void RecreateSystem() override;
|
||||
void OnHostDisplayResized() override;
|
||||
|
||||
void ApplyGameSettings(bool display_osd_messages);
|
||||
void ApplyControllerCompatibilitySettings(u64 controller_mask, bool display_osd_messages);
|
||||
|
||||
bool CreateHostDisplayResources();
|
||||
void ReleaseHostDisplayResources();
|
||||
void OnHostDisplayResized();
|
||||
|
||||
virtual void DrawImGuiWindows();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user