dolphin icon indicating copy to clipboard operation
dolphin copied to clipboard

[Feature Request] Add an "Aspect Ratio" core option + "Widescreen Hack" doesn't work with D3D11/GLcore

Open bslenul opened this issue 4 years ago • 2 comments

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):

image

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

image

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:

image

vs. how it looks with Vulkan:

image

bslenul avatar Nov 03 '21 17:11 bslenul

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.

bslenul avatar Dec 06 '21 12:12 bslenul

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...

bslenul avatar Jan 28 '22 21:01 bslenul