summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/Widescreen.cpp
diff options
context:
space:
mode:
authorScott Mansell <phiren@gmail.com>2023-01-31 17:58:54 +1300
committerScott Mansell <phiren@gmail.com>2023-02-09 18:36:20 +1300
commit9b5397abdb643b5d40211e71f7a58bb3814c29c4 (patch)
treef03f4cbb0cea40f0229f6ddab3f46ef802ee6e7b /Source/Core/VideoCommon/Widescreen.cpp
parent31cfe8250d5a27bd586136d0b71b09736861ad7d (diff)
Move WidescreenHeuristic to it's own class
It's about the only thing left in renderer
Diffstat (limited to 'Source/Core/VideoCommon/Widescreen.cpp')
-rw-r--r--Source/Core/VideoCommon/Widescreen.cpp113
1 files changed, 113 insertions, 0 deletions
diff --git a/Source/Core/VideoCommon/Widescreen.cpp b/Source/Core/VideoCommon/Widescreen.cpp
new file mode 100644
index 0000000000..ac8fa2fcfd
--- /dev/null
+++ b/Source/Core/VideoCommon/Widescreen.cpp
@@ -0,0 +1,113 @@
+// Copyright 2023 Dolphin Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "VideoCommon/Widescreen.h"
+
+#include "Common/ChunkFile.h"
+#include "Core/Config/SYSCONFSettings.h"
+#include "Core/ConfigManager.h"
+
+#include "VideoCommon/VertexManagerBase.h"
+
+std::unique_ptr<WidescreenManager> g_widescreen;
+
+WidescreenManager::WidescreenManager()
+{
+ Update();
+
+ m_config_changed = ConfigChangedEvent::Register([this](u32 bits) {
+ if (bits & (CONFIG_CHANGE_BIT_ASPECT_RATIO))
+ Update();
+ }, "Widescreen");
+
+ // VertexManager doesn't maintain statistics in Wii mode.
+ if (!SConfig::GetInstance().bWii)
+ {
+ m_update_widescreen =
+ AfterFrameEvent::Register([this] { UpdateWidescreenHeuristic(); }, "WideScreen Heuristic");
+ }
+}
+
+
+void WidescreenManager::Update()
+{
+ if (SConfig::GetInstance().bWii)
+ m_is_game_widescreen = Config::Get(Config::SYSCONF_WIDESCREEN);
+
+ // suggested_aspect_mode overrides SYSCONF_WIDESCREEN
+ if (g_ActiveConfig.suggested_aspect_mode == AspectMode::Analog)
+ m_is_game_widescreen = false;
+ else if (g_ActiveConfig.suggested_aspect_mode == AspectMode::AnalogWide)
+ m_is_game_widescreen = true;
+
+ // If widescreen hack is disabled override game's AR if UI is set to 4:3 or 16:9.
+ if (!g_ActiveConfig.bWidescreenHack)
+ {
+ const auto aspect_mode = g_ActiveConfig.aspect_mode;
+ if (aspect_mode == AspectMode::Analog)
+ m_is_game_widescreen = false;
+ else if (aspect_mode == AspectMode::AnalogWide)
+ m_is_game_widescreen = true;
+ }
+}
+
+// Heuristic to detect if a GameCube game is in 16:9 anamorphic widescreen mode.
+void WidescreenManager::UpdateWidescreenHeuristic()
+{
+ const auto flush_statistics = g_vertex_manager->ResetFlushAspectRatioCount();
+
+ // If suggested_aspect_mode (GameINI) is configured don't use heuristic.
+ if (g_ActiveConfig.suggested_aspect_mode != AspectMode::Auto)
+ return;
+
+ Update();
+
+ // If widescreen hack isn't active and aspect_mode (UI) is 4:3 or 16:9 don't use heuristic.
+ if (!g_ActiveConfig.bWidescreenHack && (g_ActiveConfig.aspect_mode == AspectMode::Analog ||
+ g_ActiveConfig.aspect_mode == AspectMode::AnalogWide))
+ return;
+
+ // Modify the threshold based on which aspect ratio we're already using:
+ // If the game's in 4:3, it probably won't switch to anamorphic, and vice-versa.
+ static constexpr u32 TRANSITION_THRESHOLD = 3;
+
+ const auto looks_normal = [](auto& counts) {
+ return counts.normal_vertex_count > counts.anamorphic_vertex_count * TRANSITION_THRESHOLD;
+ };
+ const auto looks_anamorphic = [](auto& counts) {
+ return counts.anamorphic_vertex_count > counts.normal_vertex_count * TRANSITION_THRESHOLD;
+ };
+
+ const auto& persp = flush_statistics.perspective;
+ const auto& ortho = flush_statistics.orthographic;
+
+ const auto ortho_looks_anamorphic = looks_anamorphic(ortho);
+
+ if (looks_anamorphic(persp) || ortho_looks_anamorphic)
+ {
+ // If either perspective or orthographic projections look anamorphic, it's a safe bet.
+ m_is_game_widescreen = true;
+ }
+ else if (looks_normal(persp) || (m_was_orthographically_anamorphic && looks_normal(ortho)))
+ {
+ // Many widescreen games (or AR/GeckoCodes) use anamorphic perspective projections
+ // with NON-anamorphic orthographic projections.
+ // This can cause incorrect changes to 4:3 when perspective projections are temporarily not
+ // shown. e.g. Animal Crossing's inventory menu.
+ // Unless we were in a situation which was orthographically anamorphic
+ // we won't consider orthographic data for changes from 16:9 to 4:3.
+ m_is_game_widescreen = false;
+ }
+
+ m_was_orthographically_anamorphic = ortho_looks_anamorphic;
+}
+
+void WidescreenManager::DoState(PointerWrap& p)
+{
+ p.Do(m_is_game_widescreen);
+
+ if (p.IsReadMode())
+ {
+ m_was_orthographically_anamorphic = false;
+ }
+} \ No newline at end of file