Fixed automatic widescreen adjustment for non-vanilla UI elements like the wheel menu

This commit is contained in:
Eddoursul 2026-08-23 03:42:27 +02:00
parent 3939ba1daa
commit ca5d666b63

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#include <cctype>
// Two independent corrections to the Scaleform scale mode menus are loaded with, both applied // Two independent corrections to the Scaleform scale mode menus are loaded with, both applied
// from the same BSScaleformManager::LoadMovie hook: // from the same BSScaleformManager::LoadMovie hook:
// //
@ -17,6 +19,13 @@
// as the list of menus this patch is allowed to touch at all, so on older runtimes - where the // as the list of menus this patch is allowed to touch at all, so on older runtimes - where the
// engine already passes these very modes - a third-party menu loaded with kNoBorder is left alone. // engine already passes these very modes - a third-party menu loaded with kNoBorder is left alone.
// //
// Enderal's own UI.OpenCustomMenu movies are in the table too. SKSE's CustomMenu hardcodes
// kNoBorder for every custom menu on every runtime (skse64/CustomMenu.cpp), and this hook sees
// those loads as well - the movie name from Papyrus is passed to LoadMovie verbatim. Without the
// clamp the wheel menu at 32:9 renders at 2x with the stage cropped top and bottom. For these
// entries both halves of the patch collapse into the clamp: the caller already passes kNoBorder,
// so restoring the table mode is a no-op on every runtime.
//
// Based on Widescreen Scale Removed by SkyHorizon (GPL-3.0) // Based on Widescreen Scale Removed by SkyHorizon (GPL-3.0)
// https://www.nexusmods.com/skyrimspecialedition/mods/136793 // https://www.nexusmods.com/skyrimspecialedition/mods/136793
namespace MenuAspectRatioFix namespace MenuAspectRatioFix
@ -27,9 +36,25 @@ namespace MenuAspectRatioFix
// that the engine already asks for the modes in the table, so only the clamp has work to do. // that the engine already asks for the modes in the table, so only the clamp has work to do.
inline bool g_restoreScaleModes = false; inline bool g_restoreScaleModes = false;
// Engine call sites pass fixed literals, but custom menu names arrive through BSFixedString,
// which interns case-insensitively and hands out whichever caller's casing got interned first -
// Enderal itself opens the hero menu as both "00E_heromenu" (Papyrus) and "00e_heromenu"
// (HeroMenuPatch). The lookup therefore must not be case sensitive.
struct CaseInsensitiveLess
{
using is_transparent = void;
bool operator()(std::string_view a_lhs, std::string_view a_rhs) const
{
return std::ranges::lexicographical_compare(a_lhs, a_rhs, [](unsigned char a_l, unsigned char a_r) {
return std::tolower(a_l) < std::tolower(a_r);
});
}
};
std::optional<ScaleModeType> GetScaleMode(const char* a_fileName) std::optional<ScaleModeType> GetScaleMode(const char* a_fileName)
{ {
static const std::map<std::string_view, ScaleModeType> modes{ static const std::map<std::string_view, ScaleModeType, CaseInsensitiveLess> modes{
{ "FavoritesMenu"sv, ScaleModeType::kShowAll }, { "FavoritesMenu"sv, ScaleModeType::kShowAll },
{ "HUDMenu"sv, ScaleModeType::kShowAll }, { "HUDMenu"sv, ScaleModeType::kShowAll },
{ "LevelUpMenu"sv, ScaleModeType::kShowAll }, { "LevelUpMenu"sv, ScaleModeType::kShowAll },
@ -58,7 +83,20 @@ namespace MenuAspectRatioFix
{ "TrainingMenu"sv, ScaleModeType::kNoBorder }, { "TrainingMenu"sv, ScaleModeType::kNoBorder },
// Replaces CraftingMenu, https://www.nexusmods.com/skyrimspecialedition/mods/81409 // Replaces CraftingMenu, https://www.nexusmods.com/skyrimspecialedition/mods/81409
{ "ConstructibleObjectMenu"sv, ScaleModeType::kNoBorder } { "ConstructibleObjectMenu"sv, ScaleModeType::kNoBorder },
// Enderal's UI.OpenCustomMenu movies, loaded kNoBorder by SKSE's CustomMenu. The keys
// are the names Papyrus passes; every shipped movie is listed (uidyemenu.psc references
// "dyemenu", but no such movie ships).
{ "00e_heromenu"sv, ScaleModeType::kNoBorder },
{ "listmenu"sv, ScaleModeType::kNoBorder },
{ "magicmenuext"sv, ScaleModeType::kNoBorder },
{ "selectionmenu"sv, ScaleModeType::kNoBorder },
{ "statssheetmenu"sv, ScaleModeType::kNoBorder },
{ "textentrymenu"sv, ScaleModeType::kNoBorder },
{ "uilib/uilib_1_listmenu"sv, ScaleModeType::kNoBorder },
{ "uilib/uilib_1_textinputmenu"sv, ScaleModeType::kNoBorder },
{ "wheelmenu"sv, ScaleModeType::kNoBorder }
}; };
const auto it = modes.find(a_fileName); const auto it = modes.find(a_fileName);