diff --git a/src/game/addresses.h b/src/game/addresses.h index 6409a08..bbb75e5 100644 --- a/src/game/addresses.h +++ b/src/game/addresses.h @@ -148,4 +148,8 @@ constexpr uint32_t kGrannyOrthoPushSequences[] = {0x0040ebc9, 0x0040f5cf, 0x0040 // push 1024: the height push, the width push follows 5 bytes later. constexpr uint32_t kLabelAreaPushes[] = {0x006272f8, 0x0060e940}; +// Cinematic letterbox bars (UI frame 0x7587b0): quads from x = 0 to 1024.0f, +// stored as immediates. +constexpr uint32_t kLetterboxRightImmediates[] = {0x0075895d, 0x007589f0, 0x00758aa5, 0x00758b29}; + } // namespace game::addr diff --git a/src/mods/widescreen.cpp b/src/mods/widescreen.cpp index d1ce9b3..a0e82c4 100644 --- a/src/mods/widescreen.cpp +++ b/src/mods/widescreen.cpp @@ -236,6 +236,16 @@ void PatchLabelArea(int width, int height) { static_cast(std::size(game::addr::kLabelAreaPushes)) * 2); } +// Cinematic bars span the screen width. +void PatchLetterbox(int width) { + int patched = 0; + for (uint32_t site : game::addr::kLetterboxRightImmediates) { + patched += re::PatchInstructionDword(site, FloatBits(1024.0f), FloatBits(static_cast(width))); + } + re::Log("widescreen: %d/%d letterbox immediates patched", patched, + static_cast(std::size(game::addr::kLetterboxRightImmediates))); +} + } // namespace void ApplyRenderSize(game::DxDisplayMode& mode, HWND window) { @@ -287,6 +297,7 @@ void ApplyRenderSize(game::DxDisplayMode& mode, HWND window) { PatchCenterImmediates(width, height); PatchGrannyOrthoPushes(width, height); PatchLabelArea(width, height); + PatchLetterbox(width); } const double scaleX = width / kOriginalWidth; const double scaleY = height / kOriginalHeight;