diff --git a/source/Enderal DLL/src/Patches/MenuAspectRatioFix.h b/source/Enderal DLL/src/Patches/MenuAspectRatioFix.h index 020abbf0c..332a8c479 100644 --- a/source/Enderal DLL/src/Patches/MenuAspectRatioFix.h +++ b/source/Enderal DLL/src/Patches/MenuAspectRatioFix.h @@ -1,5 +1,7 @@ #pragma once +#include + // Two independent corrections to the Scaleform scale mode menus are loaded with, both applied // 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 // 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) // https://www.nexusmods.com/skyrimspecialedition/mods/136793 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. 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 GetScaleMode(const char* a_fileName) { - static const std::map modes{ + static const std::map modes{ { "FavoritesMenu"sv, ScaleModeType::kShowAll }, { "HUDMenu"sv, ScaleModeType::kShowAll }, { "LevelUpMenu"sv, ScaleModeType::kShowAll }, @@ -58,7 +83,20 @@ namespace MenuAspectRatioFix { "TrainingMenu"sv, ScaleModeType::kNoBorder }, // 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);