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.
This commit is contained in:
Scott Mansell 2015-07-23 17:39:44 +12:00
parent ed50d61287
commit bb60bcc42d
1 changed files with 17 additions and 0 deletions

View File

@ -9,6 +9,8 @@
#include "Common/BitSet.h" #include "Common/BitSet.h"
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/MathUtil.h" #include "Common/MathUtil.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "VideoCommon/BPMemory.h" #include "VideoCommon/BPMemory.h"
#include "VideoCommon/CPMemory.h" #include "VideoCommon/CPMemory.h"
#include "VideoCommon/RenderBase.h" #include "VideoCommon/RenderBase.h"
@ -417,6 +419,21 @@ void VertexShaderManager::SetConstants()
g_fProjectionMatrix[14] = -1.0f; g_fProjectionMatrix[14] = -1.0f;
g_fProjectionMatrix[15] = 0.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_0, g_fProjectionMatrix[0]);
SETSTAT_FT(stats.gproj_1, g_fProjectionMatrix[1]); SETSTAT_FT(stats.gproj_1, g_fProjectionMatrix[1]);
SETSTAT_FT(stats.gproj_2, g_fProjectionMatrix[2]); SETSTAT_FT(stats.gproj_2, g_fProjectionMatrix[2]);