[Feature Request] Add an "Aspect Ratio" core option + "Widescreen Hack" doesn't work with D3D11/GLcore
Hey!
Some games have flickering issues between 4/3 and 16/9, here's 2 examples:
- Killer 7 (it triggers in the middle of the cutscene, then it's stuck to 16/9 until you switch to window/fullscreen to "refresh"):
https://user-images.githubusercontent.com/33353403/140099144-581c4bd9-be82-4952-8144-78fa1548a9b3.mp4
- Wave Race (grabbed from a Reddit user, that looks pretty much unplayable :/):
https://user-images.githubusercontent.com/33353403/140099260-799e4544-6465-4e14-bc30-4dc3e9fe8511.mp4
It happens in standalone as well, however it's easy to fix there as you can simply force an aspect ratio to make it stop.
I tried adding a core option myself, like this (also renamed "Widescreen" option to "Widescreen (Wii)" since it only affects the Wii side):
diff --git a/Source/Core/DolphinLibretro/Boot.cpp b/Source/Core/DolphinLibretro/Boot.cpp
index d65c7e2e5c..663622c64c 100644
--- a/Source/Core/DolphinLibretro/Boot.cpp
+++ b/Source/Core/DolphinLibretro/Boot.cpp
@@ -117,7 +117,7 @@ bool retro_load_game(const struct retro_game_info* game)
Config::SetBase(Config::GFX_WIDESCREEN_HACK, Libretro::Options::WidescreenHack);
Config::SetBase(Config::GFX_EFB_SCALE, Libretro::Options::efbScale);
- Config::SetBase(Config::GFX_ASPECT_RATIO, AspectMode::Stretch);
+ Config::SetBase(Config::GFX_ASPECT_RATIO, Libretro::Options::aspectMode);
Config::SetBase(Config::GFX_BACKEND_MULTITHREADING, false);
Config::SetBase(Config::GFX_SHADER_COMPILATION_MODE, Libretro::Options::shaderCompilationMode);
Config::SetBase(Config::GFX_ENHANCE_MAX_ANISOTROPY, Libretro::Options::maxAnisotropy);
diff --git a/Source/Core/DolphinLibretro/Options.cpp b/Source/Core/DolphinLibretro/Options.cpp
index 7c3fa9bd42..23569ab47d 100644
--- a/Source/Core/DolphinLibretro/Options.cpp
+++ b/Source/Core/DolphinLibretro/Options.cpp
@@ -120,6 +120,11 @@ Option<std::string> renderer("dolphin_renderer", "Renderer", {"Hardware", "Softw
Option<int> efbScale("dolphin_efb_scale", "Internal Resolution", 1,
{"x1 (640 x 528)", "x2 (1280 x 1056)", "x3 (1920 x 1584)", "x4 (2560 x 2112)",
"x5 (3200 x 2640)", "x6 (3840 x 3168)"});
+Option<AspectMode> aspectMode("dolphin_aspect_ratio", "Aspect Ratio",
+ {{"Auto", AspectMode::Auto},
+ {"Force 16:9", AspectMode::AnalogWide},
+ {"Force 4:3", AspectMode::Analog},
+ {"Stretch to Window", AspectMode::Stretch}});
Option<bool> Widescreen("dolphin_widescreen", "Widescreen (Wii)", true);
Option<bool> WidescreenHack("dolphin_widescreen_hack", "WideScreen Hack", false);
Option<ShaderCompilationMode> shaderCompilationMode(
diff --git a/Source/Core/DolphinLibretro/Options.h b/Source/Core/DolphinLibretro/Options.h
index e8f9cf3b73..1d79f5eb3c 100644
--- a/Source/Core/DolphinLibretro/Options.h
+++ b/Source/Core/DolphinLibretro/Options.h
@@ -6,6 +6,7 @@
#include <vector>
#include "Common/Logging/Log.h"
+#include "Core/Config/GraphicsSettings.h"
#include "Core/PowerPC/PowerPC.h"
#include "DiscIO/Enums.h"
#include "VideoCommon/VideoConfig.h"
@@ -91,6 +92,7 @@ private:
extern Option<std::string> renderer;
extern Option<int> efbScale;
+extern Option<AspectMode> aspectMode;
extern Option<bool> Widescreen;
extern Option<bool> WidescreenHack;
extern Option<ShaderCompilationMode> shaderCompilationMode;
But I guess this is much more complicated than this unfortunately, way too much for my VERY limited knowledge 😓 The "Force" options kinda work, as in the flickering stops, but 16/9 is squished vertically with D3D11 and GLcore (4/3 seems fine):

and 4/3 is squished horizontally with Vulkan (16/9 seems fine):

So yeah, I'm guessing more changes are necessary :p Anyway, if someone with the proper skills could implement that properly, it would be much appreciated! ❤️
And while speaking of aspect ratio, the "Widescreen Hack" option doesn't work with D3D11/GLcore, it just stretches the image, nothing else:

vs. how it looks with Vulkan:

A few other titles that would benefit from this core option: Resident Evil, Wario Land, Spider-Man 2, Metal Arms, Mario Party games, Metroid Prime 2, Pokemon XD and Colosseum, Tony Hawk's American Wasteland.
And probably others I'm not aware of... :/ Since this is a known issue for more than a year on standalone, I doubt it'll get fixed anytime soon, so we'd really need that core option.
Tried a different approach:
diff --git a/Source/Core/DolphinLibretro/Main.cpp b/Source/Core/DolphinLibretro/Main.cpp
index d97b4047d5..b8519e95fb 100644
--- a/Source/Core/DolphinLibretro/Main.cpp
+++ b/Source/Core/DolphinLibretro/Main.cpp
@@ -152,7 +152,11 @@ void retro_get_system_av_info(retro_system_av_info* info)
info->geometry.max_width = info->geometry.base_width;
info->geometry.max_height = info->geometry.base_height;
- if (g_renderer)
+ if (Libretro::Options::aspectMode == 1)
+ Libretro::widescreen = true;
+ else if (Libretro::Options::aspectMode == 2)
+ Libretro::widescreen = false;
+ else if (g_renderer)
Libretro::widescreen = g_renderer->IsWideScreen() || g_Config.bWidescreenHack;
else if (SConfig::GetInstance().bWii)
Libretro::widescreen = Config::Get(Config::SYSCONF_WIDESCREEN);
@@ -177,7 +181,6 @@ void retro_run(void)
#endif
SConfig::GetInstance().m_OCFactor = Libretro::Options::cpuClockRate;
SConfig::GetInstance().m_OCEnable = Libretro::Options::cpuClockRate != 1.0;
- g_Config.bWidescreenHack = Libretro::Options::WidescreenHack;
Libretro::Input::Update();
@@ -226,8 +229,10 @@ void retro_run(void)
Libretro::environ_cb(cmd, &info);
}
- if (Libretro::widescreen != (g_renderer->IsWideScreen() || g_Config.bWidescreenHack))
+ if (Libretro::Options::WidescreenHack.Updated() || Libretro::Options::aspectMode.Updated()
+ || (Libretro::Options::aspectMode == 0 && Libretro::widescreen != g_renderer->IsWideScreen()))
{
+ g_Config.bWidescreenHack = Libretro::Options::WidescreenHack;
retro_system_av_info info;
retro_get_system_av_info(&info);
Libretro::environ_cb(RETRO_ENVIRONMENT_SET_GEOMETRY, &info);
diff --git a/Source/Core/DolphinLibretro/Options.cpp b/Source/Core/DolphinLibretro/Options.cpp
index 7c3fa9bd42..a80a786343 100644
--- a/Source/Core/DolphinLibretro/Options.cpp
+++ b/Source/Core/DolphinLibretro/Options.cpp
@@ -120,6 +120,7 @@ Option<std::string> renderer("dolphin_renderer", "Renderer", {"Hardware", "Softw
Option<int> efbScale("dolphin_efb_scale", "Internal Resolution", 1,
{"x1 (640 x 528)", "x2 (1280 x 1056)", "x3 (1920 x 1584)", "x4 (2560 x 2112)",
"x5 (3200 x 2640)", "x6 (3840 x 3168)"});
+Option<int> aspectMode("dolphin_aspect_ratio", "Aspect Ratio", {"Auto", "Force 16:9", "Force 4:3"});
Option<bool> Widescreen("dolphin_widescreen", "Widescreen (Wii)", true);
Option<bool> WidescreenHack("dolphin_widescreen_hack", "WideScreen Hack", false);
Option<ShaderCompilationMode> shaderCompilationMode(
diff --git a/Source/Core/DolphinLibretro/Options.h b/Source/Core/DolphinLibretro/Options.h
index e8f9cf3b73..263ff31b8d 100644
--- a/Source/Core/DolphinLibretro/Options.h
+++ b/Source/Core/DolphinLibretro/Options.h
@@ -91,6 +91,7 @@ private:
extern Option<std::string> renderer;
extern Option<int> efbScale;
+extern Option<int> aspectMode;
extern Option<bool> Widescreen;
extern Option<bool> WidescreenHack;
extern Option<ShaderCompilationMode> shaderCompilationMode;
Works fine for the most part, widescreen hack is still problematic tho: the screen still flickers with it ON with these problematic games, and it still doesn't work with D3D11/GL unless I hardcode some 16:9 values for width/height :/
I noticed that with Vulkan the values of m_backbuffer_width and m_backbuffer_height are the window width and height, but with D3D11/GL their values are EFB_WIDTH * Libretro::Options::efbScale and EFB_HEIGHT * Libretro::Options::efbScale instead. I feel like this is related to why the hack doesn't work with D3D11/GL. I could be completely wrong of course, like I said before I'm clearly not experimented enough for this stuff...