Video: update widescreen heuristic code to never get stuck to specific old values when changing settings
This commit is contained in:
parent
95ee0ac781
commit
48fbbdba7c
|
@ -4,6 +4,7 @@
|
||||||
#include "VideoCommon/Widescreen.h"
|
#include "VideoCommon/Widescreen.h"
|
||||||
|
|
||||||
#include "Common/ChunkFile.h"
|
#include "Common/ChunkFile.h"
|
||||||
|
#include "Common/Logging/Log.h"
|
||||||
#include "Core/Config/SYSCONFSettings.h"
|
#include "Core/Config/SYSCONFSettings.h"
|
||||||
#include "Core/System.h"
|
#include "Core/System.h"
|
||||||
|
|
||||||
|
@ -13,12 +14,34 @@ std::unique_ptr<WidescreenManager> g_widescreen;
|
||||||
|
|
||||||
WidescreenManager::WidescreenManager()
|
WidescreenManager::WidescreenManager()
|
||||||
{
|
{
|
||||||
Update();
|
std::optional<bool> is_game_widescreen = GetWidescreenOverride();
|
||||||
|
if (is_game_widescreen.has_value())
|
||||||
|
m_is_game_widescreen = is_game_widescreen.value();
|
||||||
|
|
||||||
|
// Throw a warning as unsupported aspect ratio modes have no specific behavior to them
|
||||||
|
const bool is_valid_suggested_aspect_mode =
|
||||||
|
g_ActiveConfig.suggested_aspect_mode == AspectMode::Auto ||
|
||||||
|
g_ActiveConfig.suggested_aspect_mode == AspectMode::ForceStandard ||
|
||||||
|
g_ActiveConfig.suggested_aspect_mode == AspectMode::ForceWide;
|
||||||
|
if (!is_valid_suggested_aspect_mode)
|
||||||
|
{
|
||||||
|
WARN_LOG_FMT(VIDEO,
|
||||||
|
"Invalid suggested aspect ratio mode: only Auto, 4:3 and 16:9 are supported");
|
||||||
|
}
|
||||||
|
|
||||||
m_config_changed = ConfigChangedEvent::Register(
|
m_config_changed = ConfigChangedEvent::Register(
|
||||||
[this](u32 bits) {
|
[this](u32 bits) {
|
||||||
if (bits & (CONFIG_CHANGE_BIT_ASPECT_RATIO))
|
if (bits & (CONFIG_CHANGE_BIT_ASPECT_RATIO))
|
||||||
Update();
|
{
|
||||||
|
std::optional<bool> is_game_widescreen = GetWidescreenOverride();
|
||||||
|
// If the widescreen flag isn't being overridden by any settings,
|
||||||
|
// reset it to default if heuristic aren't running or to the last
|
||||||
|
// heuristic value if they were running.
|
||||||
|
if (!is_game_widescreen.has_value())
|
||||||
|
is_game_widescreen = (m_heuristic_state == HeuristicState::Active_Found_Anamorphic);
|
||||||
|
if (is_game_widescreen.has_value())
|
||||||
|
m_is_game_widescreen = is_game_widescreen.value();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Widescreen");
|
"Widescreen");
|
||||||
|
|
||||||
|
@ -31,7 +54,7 @@ WidescreenManager::WidescreenManager()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidescreenManager::Update()
|
std::optional<bool> WidescreenManager::GetWidescreenOverride() const
|
||||||
{
|
{
|
||||||
std::optional<bool> is_game_widescreen;
|
std::optional<bool> is_game_widescreen;
|
||||||
|
|
||||||
|
@ -53,44 +76,33 @@ void WidescreenManager::Update()
|
||||||
is_game_widescreen = false;
|
is_game_widescreen = false;
|
||||||
else if (aspect_mode == AspectMode::ForceWide)
|
else if (aspect_mode == AspectMode::ForceWide)
|
||||||
is_game_widescreen = true;
|
is_game_widescreen = true;
|
||||||
|
|
||||||
// Reset settings to default if heuristics aren't currently running and
|
|
||||||
// the user selected the automatic aspect ratio.
|
|
||||||
if (!is_game_widescreen.has_value() && !m_widescreen_heuristics_active_and_successful &&
|
|
||||||
aspect_mode == AspectMode::Auto)
|
|
||||||
{
|
|
||||||
is_game_widescreen = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_game_widescreen.has_value())
|
return is_game_widescreen;
|
||||||
{
|
|
||||||
m_is_game_widescreen = is_game_widescreen.value();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Heuristic to detect if a GameCube game is in 16:9 anamorphic widescreen mode.
|
// Heuristic to detect if a GameCube game is in 16:9 anamorphic widescreen mode.
|
||||||
// Cheats that change the game aspect ratio to natively unsupported ones won't be recognized here.
|
// Cheats that change the game aspect ratio to natively unsupported ones won't be recognized here.
|
||||||
void WidescreenManager::UpdateWidescreenHeuristic()
|
void WidescreenManager::UpdateWidescreenHeuristic()
|
||||||
{
|
{
|
||||||
|
// Reset to baseline state before the update
|
||||||
const auto flush_statistics = g_vertex_manager->ResetFlushAspectRatioCount();
|
const auto flush_statistics = g_vertex_manager->ResetFlushAspectRatioCount();
|
||||||
|
const bool was_orthographically_anamorphic = m_was_orthographically_anamorphic;
|
||||||
|
m_heuristic_state = HeuristicState::Inactive;
|
||||||
|
m_was_orthographically_anamorphic = false;
|
||||||
|
|
||||||
// If suggested_aspect_mode (GameINI) is configured don't use heuristic.
|
// If suggested_aspect_mode (GameINI) is configured don't use heuristic.
|
||||||
|
// We also don't need to check "GetWidescreenOverride()" in this case as
|
||||||
|
// nothing would have changed there.
|
||||||
if (g_ActiveConfig.suggested_aspect_mode != AspectMode::Auto)
|
if (g_ActiveConfig.suggested_aspect_mode != AspectMode::Auto)
|
||||||
{
|
|
||||||
m_widescreen_heuristics_active_and_successful = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
Update();
|
std::optional<bool> is_game_widescreen = GetWidescreenOverride();
|
||||||
|
|
||||||
m_widescreen_heuristics_active_and_successful = false;
|
|
||||||
|
|
||||||
// If widescreen hack isn't active and aspect_mode (UI) is 4:3 or 16:9 don't use heuristic.
|
// 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::ForceStandard ||
|
if (g_ActiveConfig.bWidescreenHack || (g_ActiveConfig.aspect_mode != AspectMode::ForceStandard &&
|
||||||
g_ActiveConfig.aspect_mode == AspectMode::ForceWide))
|
g_ActiveConfig.aspect_mode != AspectMode::ForceWide))
|
||||||
return;
|
{
|
||||||
|
|
||||||
// Modify the threshold based on which aspect ratio we're already using:
|
// 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.
|
// If the game's in 4:3, it probably won't switch to anamorphic, and vice-versa.
|
||||||
const u32 transition_threshold = g_ActiveConfig.widescreen_heuristic_transition_threshold;
|
const u32 transition_threshold = g_ActiveConfig.widescreen_heuristic_transition_threshold;
|
||||||
|
@ -106,14 +118,15 @@ void WidescreenManager::UpdateWidescreenHeuristic()
|
||||||
const auto& ortho = flush_statistics.orthographic;
|
const auto& ortho = flush_statistics.orthographic;
|
||||||
|
|
||||||
const auto ortho_looks_anamorphic = looks_anamorphic(ortho);
|
const auto ortho_looks_anamorphic = looks_anamorphic(ortho);
|
||||||
|
const auto persp_looks_normal = looks_normal(persp);
|
||||||
|
|
||||||
if (looks_anamorphic(persp) || ortho_looks_anamorphic)
|
if (looks_anamorphic(persp) || ortho_looks_anamorphic)
|
||||||
{
|
{
|
||||||
// If either perspective or orthographic projections look anamorphic, it's a safe bet.
|
// If either perspective or orthographic projections look anamorphic, it's a safe bet.
|
||||||
m_is_game_widescreen = true;
|
is_game_widescreen = true;
|
||||||
m_widescreen_heuristics_active_and_successful = true;
|
m_heuristic_state = HeuristicState::Active_Found_Anamorphic;
|
||||||
}
|
}
|
||||||
else if (looks_normal(persp) || (m_was_orthographically_anamorphic && looks_normal(ortho)))
|
else if (persp_looks_normal || looks_normal(ortho))
|
||||||
{
|
{
|
||||||
// Many widescreen games (or AR/GeckoCodes) use anamorphic perspective projections
|
// Many widescreen games (or AR/GeckoCodes) use anamorphic perspective projections
|
||||||
// with NON-anamorphic orthographic projections.
|
// with NON-anamorphic orthographic projections.
|
||||||
|
@ -121,11 +134,20 @@ void WidescreenManager::UpdateWidescreenHeuristic()
|
||||||
// shown. e.g. Animal Crossing's inventory menu.
|
// shown. e.g. Animal Crossing's inventory menu.
|
||||||
// Unless we were in a situation which was orthographically anamorphic
|
// Unless we were in a situation which was orthographically anamorphic
|
||||||
// we won't consider orthographic data for changes from 16:9 to 4:3.
|
// we won't consider orthographic data for changes from 16:9 to 4:3.
|
||||||
m_is_game_widescreen = false;
|
if (persp_looks_normal || was_orthographically_anamorphic)
|
||||||
m_widescreen_heuristics_active_and_successful = true;
|
is_game_widescreen = false;
|
||||||
|
m_heuristic_state = HeuristicState::Active_Found_Normal;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_heuristic_state = HeuristicState::Active_NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_was_orthographically_anamorphic = ortho_looks_anamorphic;
|
m_was_orthographically_anamorphic = ortho_looks_anamorphic;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_game_widescreen.has_value())
|
||||||
|
m_is_game_widescreen = is_game_widescreen.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidescreenManager::DoState(PointerWrap& p)
|
void WidescreenManager::DoState(PointerWrap& p)
|
||||||
|
@ -135,6 +157,6 @@ void WidescreenManager::DoState(PointerWrap& p)
|
||||||
if (p.IsReadMode())
|
if (p.IsReadMode())
|
||||||
{
|
{
|
||||||
m_was_orthographically_anamorphic = false;
|
m_was_orthographically_anamorphic = false;
|
||||||
m_widescreen_heuristics_active_and_successful = false;
|
m_heuristic_state = HeuristicState::Inactive;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,12 +24,21 @@ public:
|
||||||
void DoState(PointerWrap& p);
|
void DoState(PointerWrap& p);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Update();
|
enum class HeuristicState
|
||||||
|
{
|
||||||
|
Inactive,
|
||||||
|
Active_NotFound,
|
||||||
|
Active_Found_Normal,
|
||||||
|
Active_Found_Anamorphic,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Returns whether the widescreen state wants to change, and its target value
|
||||||
|
std::optional<bool> GetWidescreenOverride() const;
|
||||||
void UpdateWidescreenHeuristic();
|
void UpdateWidescreenHeuristic();
|
||||||
|
|
||||||
bool m_is_game_widescreen = false;
|
bool m_is_game_widescreen = false;
|
||||||
bool m_was_orthographically_anamorphic = false;
|
bool m_was_orthographically_anamorphic = false;
|
||||||
bool m_widescreen_heuristics_active_and_successful = false;
|
HeuristicState m_heuristic_state = HeuristicState::Inactive;
|
||||||
|
|
||||||
Common::EventHook m_update_widescreen;
|
Common::EventHook m_update_widescreen;
|
||||||
Common::EventHook m_config_changed;
|
Common::EventHook m_config_changed;
|
||||||
|
|
Loading…
Reference in New Issue