From bb60bcc42d7e9b4e0dfcb10e2058b4cace5c0508 Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Thu, 23 Jul 2015 17:39:44 +1200 Subject: [PATCH] Heuristic to detect if a gamecube game is rendering 16:9 widescreen. Someone suggested on IRC that we should make a database of memory locations in GameCube games which contain the 'Widescreen' setting so we can automatically detect if the game is in 4:3 or 16:9 mode. But that's hardly optimal, when the game actually tells the gpu what aspect ratio to render in. 10 min and 6 lines of code later, this is the result. Not only does it detect the correct aspect ratio it does so on the fly. I'm a little suprised nobody thought about doing this before. --- Source/Core/VideoCommon/VertexShaderManager.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Source/Core/VideoCommon/VertexShaderManager.cpp b/Source/Core/VideoCommon/VertexShaderManager.cpp index 509974c373..a6bab1aabf 100644 --- a/Source/Core/VideoCommon/VertexShaderManager.cpp +++ b/Source/Core/VideoCommon/VertexShaderManager.cpp @@ -9,6 +9,8 @@ #include "Common/BitSet.h" #include "Common/CommonTypes.h" #include "Common/MathUtil.h" +#include "Core/ConfigManager.h" +#include "Core/Core.h" #include "VideoCommon/BPMemory.h" #include "VideoCommon/CPMemory.h" #include "VideoCommon/RenderBase.h" @@ -417,6 +419,21 @@ void VertexShaderManager::SetConstants() g_fProjectionMatrix[14] = -1.0f; g_fProjectionMatrix[15] = 0.0f; + // Heuristic to detect if a GameCube game is in 16:9 anamorphic widescreen mode. + if (!SConfig::GetInstance().bWii) + { + // Due to the BT.601 standard which the GameCube is based on being a compromise + // between PAL and NTSC, neither standard gets square pixels. They are each off + // by ~9% in opposite directions. + // Just in case any game decides to take this into account, we do these tests + // with a large amount of slop. + float aspect = fabsf(rawProjection[2] / rawProjection[0]); + if (fabsf(aspect - 16.0f/9.0f) < 16.0f/9.0f * 0.11) // within 11% of 16:9 + g_aspect_wide = true; + else if (fabsf(aspect - 4.0f/3.0f) < 4.0f/3.0f * 0.11) // within 11% of 4:3 + g_aspect_wide = false; + } + SETSTAT_FT(stats.gproj_0, g_fProjectionMatrix[0]); SETSTAT_FT(stats.gproj_1, g_fProjectionMatrix[1]); SETSTAT_FT(stats.gproj_2, g_fProjectionMatrix[2]);