mirror of https://github.com/PCSX2/pcsx2.git
GS: Allow for widescreen and ultrawide patches to specify their target aspect ratio.
This allows users with monitors of any aspect ratios to use patches made for any other aspect ratio.
For example, if on 32:9 one uses a 21:9 patch, pcsx2 will automatically size the presentation to 21:9 within 32:9.
This also removes some ugly or hardcoded stuff from the code :).
It also opens the door to add a "Custom" user aspect ratio, without the patch needing to specify the aspect ratio, so users could stretch the image to any AR they'd like, but for now there's no need to add that.
(cherry picked from commit 4069752d5f
)
This commit is contained in:
parent
9fe8235eda
commit
5231d5a9ec
|
@ -502,7 +502,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
|
|||
|
||||
dialog->registerWidgetHelp(m_ui.aspectRatio, tr("Aspect Ratio"), tr("Auto Standard (4:3/3:2 Progressive)"),
|
||||
tr("Changes the aspect ratio used to display the console's output to the screen. The default is Auto Standard (4:3/3:2 "
|
||||
"Progressive) which automatically adjusts the aspect ratio to match how a game would be shown on a typical TV of the era."));
|
||||
"Progressive) which automatically adjusts the aspect ratio to match how a game would be shown on a typical TV of the era, and adapts to widescreen/ultrawide game patches."));
|
||||
|
||||
dialog->registerWidgetHelp(m_ui.interlacing, tr("Deinterlacing"), tr("Automatic (Default)"), tr("Determines the deinterlacing method to be used on the interlaced screen of the emulated console. Automatic should be able to correctly deinterlace most games, but if you see visibly shaky graphics, try one of the available options."));
|
||||
|
||||
|
|
|
@ -223,8 +223,8 @@ enum class DebugFunctionScanMode
|
|||
|
||||
enum class AspectRatioType : u8
|
||||
{
|
||||
Stretch,
|
||||
RAuto4_3_3_2,
|
||||
Stretch, // Stretches to the whole window/display size, allowing a custom aspect ratio override if it's set
|
||||
RAuto4_3_3_2, // Automatically scales to the target aspect ratio if there's a widescreen patch
|
||||
R4_3,
|
||||
R16_9,
|
||||
R10_7,
|
||||
|
@ -233,7 +233,7 @@ enum class AspectRatioType : u8
|
|||
|
||||
enum class FMVAspectRatioSwitchType : u8
|
||||
{
|
||||
Off,
|
||||
Off, // Falls back on the selected generic aspect ratio type
|
||||
RAuto4_3_3_2,
|
||||
R4_3,
|
||||
R16_9,
|
||||
|
@ -1324,6 +1324,8 @@ struct Pcsx2Config
|
|||
std::string CurrentIRX;
|
||||
std::string CurrentGameArgs;
|
||||
AspectRatioType CurrentAspectRatio = AspectRatioType::RAuto4_3_3_2;
|
||||
// Fall back aspect ratio for games that have patches (when AspectRatioType::RAuto4_3_3_2) is active.
|
||||
float CurrentCustomAspectRatio = 0.f;
|
||||
bool IsPortableMode = false;
|
||||
|
||||
Pcsx2Config();
|
||||
|
|
|
@ -268,8 +268,25 @@ float GSRenderer::GetModXYOffset()
|
|||
|
||||
static float GetCurrentAspectRatioFloat(bool is_progressive)
|
||||
{
|
||||
static constexpr std::array<float, static_cast<size_t>(AspectRatioType::MaxCount) + 1> ars = {{4.0f / 3.0f, 4.0f / 3.0f, 4.0f / 3.0f, 16.0f / 9.0f, 10.0f / 7.0f, 3.0f / 2.0f}};
|
||||
return ars[static_cast<u32>(GSConfig.AspectRatio) + (3u * (is_progressive && GSConfig.AspectRatio == AspectRatioType::RAuto4_3_3_2))];
|
||||
switch (GSConfig.AspectRatio)
|
||||
{
|
||||
default:
|
||||
// We don't know the AR of the display here, nor we care about it
|
||||
case AspectRatioType::Stretch:
|
||||
case AspectRatioType::RAuto4_3_3_2:
|
||||
if (EmuConfig.CurrentCustomAspectRatio > 0.f)
|
||||
return EmuConfig.CurrentCustomAspectRatio;
|
||||
else if (is_progressive)
|
||||
return 3.0f / 2.0f;
|
||||
else
|
||||
return 4.0f / 3.0f;
|
||||
case AspectRatioType::R4_3:
|
||||
return 4.0f / 3.0f;
|
||||
case AspectRatioType::R16_9:
|
||||
return 16.0f / 9.0f;
|
||||
case AspectRatioType::R10_7:
|
||||
return 10.0f / 7.0f;
|
||||
}
|
||||
}
|
||||
|
||||
static GSVector4 CalculateDrawDstRect(s32 window_width, s32 window_height, const GSVector4i& src_rect, const GSVector2i& src_size, GSDisplayAlignment alignment, bool flip_y, bool is_progressive)
|
||||
|
@ -285,6 +302,9 @@ static GSVector4 CalculateDrawDstRect(s32 window_width, s32 window_height, const
|
|||
targetAr = 3.0f / 2.0f;
|
||||
else
|
||||
targetAr = 4.0f / 3.0f;
|
||||
// Fall back on the custom aspect ratio set by patches (e.g. 16:9, 21:9)
|
||||
if (EmuConfig.CurrentCustomAspectRatio > 0.f)
|
||||
targetAr = EmuConfig.CurrentCustomAspectRatio;
|
||||
}
|
||||
else if (EmuConfig.CurrentAspectRatio == AspectRatioType::R4_3)
|
||||
{
|
||||
|
@ -298,6 +318,10 @@ static GSVector4 CalculateDrawDstRect(s32 window_width, s32 window_height, const
|
|||
{
|
||||
targetAr = 10.0f / 7.0f;
|
||||
}
|
||||
else if (EmuConfig.CurrentCustomAspectRatio > 0.f)
|
||||
{
|
||||
targetAr = EmuConfig.CurrentCustomAspectRatio;
|
||||
}
|
||||
|
||||
const float crop_adjust = (static_cast<float>(src_rect.width()) / static_cast<float>(src_size.x)) /
|
||||
(static_cast<float>(src_rect.height()) / static_cast<float>(src_size.y));
|
||||
|
|
|
@ -111,7 +111,7 @@ namespace Patch
|
|||
struct PatchGroup
|
||||
{
|
||||
std::string name;
|
||||
std::optional<AspectRatioType> override_aspect_ratio;
|
||||
std::optional<float> override_aspect_ratio;
|
||||
std::optional<GSInterlaceMode> override_interlace_mode;
|
||||
std::vector<PatchCommand> patches;
|
||||
std::vector<DynamicPatch> dpatches;
|
||||
|
@ -186,7 +186,7 @@ namespace Patch
|
|||
static EnablePatchList s_just_enabled_cheats;
|
||||
static EnablePatchList s_just_enabled_patches;
|
||||
static u32 s_patches_crc;
|
||||
static std::optional<AspectRatioType> s_override_aspect_ratio;
|
||||
static std::optional<float> s_override_aspect_ratio;
|
||||
static std::optional<GSInterlaceMode> s_override_interlace_mode;
|
||||
|
||||
static const PatchTextTable s_patch_commands[] = {
|
||||
|
@ -797,17 +797,13 @@ void Patch::UpdateActivePatches(bool reload_enabled_list, bool verbose, bool ver
|
|||
|
||||
void Patch::ApplyPatchSettingOverrides()
|
||||
{
|
||||
// Switch to 16:9 if widescreen patches are enabled, and AR is auto.
|
||||
// Switch to 16:9 (or any custom aspect ratio) if widescreen patches are enabled, and AR is auto.
|
||||
if (s_override_aspect_ratio.has_value() && EmuConfig.GS.AspectRatio == AspectRatioType::RAuto4_3_3_2)
|
||||
{
|
||||
// Don't change when reloading settings in the middle of a FMV with switch.
|
||||
if (EmuConfig.CurrentAspectRatio == EmuConfig.GS.AspectRatio)
|
||||
EmuConfig.CurrentAspectRatio = s_override_aspect_ratio.value();
|
||||
EmuConfig.CurrentCustomAspectRatio = s_override_aspect_ratio.value();
|
||||
|
||||
Console.WriteLn(Color_Gray,
|
||||
fmt::format("Patch: Setting aspect ratio to {} by patch request.",
|
||||
Pcsx2Config::GSOptions::AspectRatioNames[static_cast<int>(s_override_aspect_ratio.value())]));
|
||||
EmuConfig.GS.AspectRatio = s_override_aspect_ratio.value();
|
||||
fmt::format("Patch: Setting aspect ratio to {} by patch request.", s_override_aspect_ratio.value()));
|
||||
}
|
||||
|
||||
// Disable interlacing in GS if active.
|
||||
|
@ -821,9 +817,13 @@ void Patch::ApplyPatchSettingOverrides()
|
|||
|
||||
bool Patch::ReloadPatchAffectingOptions()
|
||||
{
|
||||
// Restore the aspect ratio + interlacing setting the user had set before reloading the patch,
|
||||
// as the custom patch settings only apply if the "Auto" settings are selected.
|
||||
|
||||
const AspectRatioType current_ar = EmuConfig.GS.AspectRatio;
|
||||
const GSInterlaceMode current_interlace = EmuConfig.GS.InterlaceMode;
|
||||
|
||||
const float custom_aspect_ratio = EmuConfig.CurrentCustomAspectRatio;
|
||||
|
||||
// This is pretty gross, but we're not using a config layer, so...
|
||||
AspectRatioType new_ar = Pcsx2Config::GSOptions::DEFAULT_ASPECT_RATIO;
|
||||
const std::string ar_value = Host::GetStringSettingValue("EmuCore/GS", "AspectRatio",
|
||||
|
@ -836,15 +836,14 @@ bool Patch::ReloadPatchAffectingOptions()
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (EmuConfig.CurrentAspectRatio == EmuConfig.GS.AspectRatio)
|
||||
EmuConfig.CurrentAspectRatio = new_ar;
|
||||
EmuConfig.GS.AspectRatio = new_ar;
|
||||
EmuConfig.GS.InterlaceMode = static_cast<GSInterlaceMode>(Host::GetIntSettingValue(
|
||||
"EmuCore/GS", "deinterlace_mode", static_cast<int>(Pcsx2Config::GSOptions::DEFAULT_INTERLACE_MODE)));
|
||||
|
||||
ApplyPatchSettingOverrides();
|
||||
|
||||
return (current_ar != EmuConfig.GS.AspectRatio || current_interlace != EmuConfig.GS.InterlaceMode);
|
||||
// Return true if any config setting changed
|
||||
return current_ar != EmuConfig.GS.AspectRatio || custom_aspect_ratio != EmuConfig.CurrentCustomAspectRatio || current_interlace != EmuConfig.GS.InterlaceMode;
|
||||
}
|
||||
|
||||
void Patch::UnloadPatches()
|
||||
|
@ -941,13 +940,22 @@ void Patch::PatchFunc::patch(PatchGroup* group, const std::string_view cmd, cons
|
|||
|
||||
void Patch::PatchFunc::gsaspectratio(PatchGroup* group, const std::string_view cmd, const std::string_view param)
|
||||
{
|
||||
for (u32 i = 0; i < static_cast<u32>(AspectRatioType::MaxCount); i++)
|
||||
std::string str(param);
|
||||
std::istringstream ss(str);
|
||||
uint dividend, divisor;
|
||||
char delimiter;
|
||||
float aspect_ratio = 0.f;
|
||||
|
||||
ss >> dividend >> delimiter >> divisor;
|
||||
if (!ss.fail() && delimiter == ':' && divisor != 0)
|
||||
{
|
||||
if (param == Pcsx2Config::GSOptions::AspectRatioNames[i])
|
||||
{
|
||||
group->override_aspect_ratio = static_cast<AspectRatioType>(i);
|
||||
return;
|
||||
}
|
||||
aspect_ratio = static_cast<float>(dividend) / static_cast<float>(divisor);
|
||||
}
|
||||
|
||||
if (aspect_ratio > 0.f)
|
||||
{
|
||||
group->override_aspect_ratio = aspect_ratio;
|
||||
return;
|
||||
}
|
||||
|
||||
Console.Error(fmt::format("Patch error: {} is an unknown aspect ratio.", param));
|
||||
|
|
|
@ -636,7 +636,7 @@ void Pcsx2Config::CpuOptions::LoadSave(SettingsWrapper& wrap)
|
|||
Recompiler.LoadSave(wrap);
|
||||
}
|
||||
|
||||
const char* Pcsx2Config::GSOptions::AspectRatioNames[] = {
|
||||
const char* Pcsx2Config::GSOptions::AspectRatioNames[(size_t)AspectRatioType::MaxCount + 1] = {
|
||||
"Stretch",
|
||||
"Auto 4:3/3:2",
|
||||
"4:3",
|
||||
|
@ -644,7 +644,7 @@ const char* Pcsx2Config::GSOptions::AspectRatioNames[] = {
|
|||
"10:7",
|
||||
nullptr};
|
||||
|
||||
const char* Pcsx2Config::GSOptions::FMVAspectRatioSwitchNames[] = {
|
||||
const char* Pcsx2Config::GSOptions::FMVAspectRatioSwitchNames[(size_t)FMVAspectRatioSwitchType::MaxCount + 1] = {
|
||||
"Off",
|
||||
"Auto 4:3/3:2",
|
||||
"4:3",
|
||||
|
@ -1983,7 +1983,13 @@ void Pcsx2Config::LoadSaveCore(SettingsWrapper& wrap)
|
|||
|
||||
if (wrap.IsLoading())
|
||||
{
|
||||
// Patches will get re-applied after loading the state so this doesn't matter too much
|
||||
CurrentAspectRatio = GS.AspectRatio;
|
||||
// Don't override it if the user had set it to a custom value
|
||||
if (CurrentAspectRatio == AspectRatioType::RAuto4_3_3_2)
|
||||
{
|
||||
CurrentCustomAspectRatio = 0.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2035,6 +2041,7 @@ void Pcsx2Config::CopyRuntimeConfig(Pcsx2Config& cfg)
|
|||
CurrentIRX = std::move(cfg.CurrentIRX);
|
||||
CurrentGameArgs = std::move(cfg.CurrentGameArgs);
|
||||
CurrentAspectRatio = cfg.CurrentAspectRatio;
|
||||
CurrentCustomAspectRatio = cfg.CurrentCustomAspectRatio;
|
||||
IsPortableMode = cfg.IsPortableMode;
|
||||
|
||||
for (u32 i = 0; i < sizeof(Mcd) / sizeof(Mcd[0]); i++)
|
||||
|
|
|
@ -876,7 +876,9 @@ void VMManager::RequestDisplaySize(float scale /*= 0.0f*/)
|
|||
switch (GSConfig.AspectRatio)
|
||||
{
|
||||
case AspectRatioType::RAuto4_3_3_2:
|
||||
if (GSgetDisplayMode() == GSVideoMode::SDTV_480P)
|
||||
if (EmuConfig.CurrentCustomAspectRatio > 0.f)
|
||||
x_scale = EmuConfig.CurrentCustomAspectRatio / (static_cast<float>(iwidth) / static_cast<float>(iheight));
|
||||
else if (GSgetDisplayMode() == GSVideoMode::SDTV_480P)
|
||||
x_scale = (3.0f / 2.0f) / (static_cast<float>(iwidth) / static_cast<float>(iheight));
|
||||
else
|
||||
x_scale = (4.0f / 3.0f) / (static_cast<float>(iwidth) / static_cast<float>(iheight));
|
||||
|
@ -893,6 +895,8 @@ void VMManager::RequestDisplaySize(float scale /*= 0.0f*/)
|
|||
case AspectRatioType::Stretch:
|
||||
default:
|
||||
x_scale = 1.0f;
|
||||
if (EmuConfig.CurrentCustomAspectRatio > 0.f)
|
||||
x_scale = EmuConfig.CurrentCustomAspectRatio / (static_cast<float>(iwidth) / static_cast<float>(iheight));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue