feat(video): support 48:9 triple-monitor picture geometry #2052

Merged
Arkex-ai merged 2 commits from feat/triple-monitor-48-9 into main 2026-11-11 02:48:46 +00:00
Arkex-ai commented 2026-11-11 01:14:23 +00:00 (Migrated from github.com)

Summary

On a 48:9 desktop the camera stopped widening at 32:9, and the game rejected custom outputs such as 5760×1080 and 7680×1440. Both settings now give a wider view and keep the HUD in the center 16:9 area.

Addresses the 48:9 request in #1007, originally reported in #2039.

Technical changes

  • Use the same output limits in the host and menu. A custom output above 32:9 selects the camera shape when the OS reports a single 16:9 primary display.
  • Keep the internal pixel budget. 5760×1080 renders at full size, and 7680×1440 uses an aligned 6528×1224 picture at the exact 48:9 ratio.
  • Present with the existing aspect-preserving path. To fill three displays, use a 48:9 logical display or a spanning window.

Validation

  • At 0d5e2981, geometry and output fixtures pass on Windows LLVM-MinGW and Linux GCC. The new four-decimal case fails before the fix (6608x1240) and passes after it (6528x1224). Full local suite: Windows 325 passed / 3 failed / 25 skipped; Linux 330 / 1 / 22. All three Windows failures reproduce on main f915af93; Linux lacks the bake fixture dependency covered by #1954.

  • Current-head upstream source checks fail in finish-output fixtures after main added FSR runtime provisioning; existing #2102 owns the fixture correction. These differ from the local failures. Windows build/package and AppImage passed.

  • At 557542cd on d47206ed, the geometry and output fixtures passed on Windows and Ubuntu. All 11 Windows startup cases also passed. The previous revision also passed the geometry, parser and presentation rectangle checks on Windows and Ubuntu.

  • Native Windows smoke at 9ed2da57 on RTX 5070 Ti used both output settings in a 1920×360 window. Vulkan reported source sizes of 5760×1080 and 6528×1224, with a full 1920×360 destination in both cases. Captures decoded at the two configured output sizes. The HUD stayed in the middle third and the house-to-Kokiri Forest transition completed in both runs.

  • With 7680×1440 configured, maximizing to a 3440×1369 swapchain kept a 3440×645 centered destination. Both runs exited normally and preserved the original checkpoint hashes.

  • The brief black center with visible sides during the opening transition was also reproduced at 32:9 on the pre-change build 600960cd. Linux gameplay, campaign-wide cutscenes and a physical three-monitor span remain untested.

Dev-work claim.

Current-head check (0d5e2981) Result
Linux AppImage Passed
Windows build Passed
Source suite Failed: inherited finish fixtures (#2102); remaining checks pending
## Summary On a 48:9 desktop the camera stopped widening at 32:9, and the game rejected custom outputs such as 5760×1080 and 7680×1440. Both settings now give a wider view and keep the HUD in the center 16:9 area. Addresses the 48:9 request in #1007, originally reported in #2039. ## Technical changes - Use the same output limits in the host and menu. A custom output above 32:9 selects the camera shape when the OS reports a single 16:9 primary display. - Keep the internal pixel budget. 5760×1080 renders at full size, and 7680×1440 uses an aligned **6528×1224** picture at the exact 48:9 ratio. - Present with the existing aspect-preserving path. To fill three displays, use a 48:9 logical display or a spanning window. ## Validation - At `0d5e2981`, geometry and output fixtures pass on Windows LLVM-MinGW and Linux GCC. The new four-decimal case fails before the fix (6608x1240) and passes after it (6528x1224). Full local suite: **Windows 325 passed / 3 failed / 25 skipped; Linux 330 / 1 / 22**. All three Windows failures reproduce on main `f915af93`; Linux lacks the bake fixture dependency covered by #1954. - Current-head upstream source checks fail in finish-output fixtures after main added FSR runtime provisioning; existing #2102 owns the fixture correction. These differ from the local failures. Windows build/package and AppImage passed. - At `557542cd` on `d47206ed`, the geometry and output fixtures passed on Windows and Ubuntu. All 11 Windows startup cases also passed. The previous revision also passed the geometry, parser and presentation rectangle checks on Windows and Ubuntu. - Native Windows smoke at `9ed2da57` on RTX 5070 Ti used both output settings in a **1920×360** window. Vulkan reported source sizes of **5760×1080** and **6528×1224**, with a full 1920×360 destination in both cases. Captures decoded at the two configured output sizes. The HUD stayed in the middle third and the house-to-Kokiri Forest transition completed in both runs. - With 7680×1440 configured, maximizing to a **3440×1369** swapchain kept a **3440×645** centered destination. Both runs exited normally and preserved the original checkpoint hashes. - The brief black center with visible sides during the opening transition was also reproduced at 32:9 on the pre-change build `600960cd`. Linux gameplay, campaign-wide cutscenes and a physical three-monitor span remain untested. [Dev-work claim](https://discord.com/channels/1568810484818378804/1569019786766188665/1569876853261607004). <!-- pr-ci-status --> | Current-head check (`0d5e2981`) | Result | |---|---| | [Linux AppImage](https://github.com/NotRexed/Hookshot/actions/runs/42946975974) | Passed | | [Windows build](https://github.com/NotRexed/Hookshot/actions/runs/42946975794) | Passed | | [Source suite](https://github.com/NotRexed/Hookshot/actions/runs/42946975727) | Failed: inherited finish fixtures (#2102); remaining checks pending | <!-- /pr-ci-status -->
hckrman101 (Migrated from github.com) approved these changes 2026-11-11 02:19:14 +00:00
hckrman101 (Migrated from github.com) left a comment

Looks good to me. The 32:9 and 48:9 limits now live in one place (hos_output_size_valid / hos_output_is_surround in hos_wide_size.h), so the host parser and the menu can't drift apart any more. The host and the menu both force the surround shape for a >32:9 custom output, so the menu's Render resolution rows match what boot picks. The 24-row alignment checks out: 7680x1440 goes over the 3840x2160 budget and comes out at exactly 6528x1224 (48:9), and 5760x1080 fits in the budget at full size. Handheld is unaffected because hos_output_size reports 2560x1440 there. The pool goes to 515 MB and 900 MB as the test expects. Nothing on main since the base touches these files, and CI is green.

A few nits, none blocking:

  • hos_main.c: a surround output now overrides an explicit HOS_ASPECT (see inline).
  • hos_wide_clamp: the 1e-6 snap doesn't catch the 4-decimal form (see inline).
  • vk_menu.cpp picture_for: the doc comment above it still says "with Ultrawide on". A surround output now takes this path with Ultrawide off too, so it's worth a few words there.

The opening-transition black centre is also on the pre-change 32:9 build, so I agree it's not from this PR. A real three-monitor span and Linux are still untested, as the description says.

Looks good to me. The 32:9 and 48:9 limits now live in one place (`hos_output_size_valid` / `hos_output_is_surround` in `hos_wide_size.h`), so the host parser and the menu can't drift apart any more. The host and the menu both force the surround shape for a >32:9 custom output, so the menu's Render resolution rows match what boot picks. The 24-row alignment checks out: 7680x1440 goes over the 3840x2160 budget and comes out at exactly 6528x1224 (48:9), and 5760x1080 fits in the budget at full size. Handheld is unaffected because `hos_output_size` reports 2560x1440 there. The pool goes to 515 MB and 900 MB as the test expects. Nothing on main since the base touches these files, and CI is green. A few nits, none blocking: - `hos_main.c`: a surround output now overrides an explicit `HOS_ASPECT` (see inline). - `hos_wide_clamp`: the 1e-6 snap doesn't catch the 4-decimal form (see inline). - `vk_menu.cpp` `picture_for`: the doc comment above it still says "with Ultrawide on". A surround output now takes this path with Ultrawide off too, so it's worth a few words there. The opening-transition black centre is also on the pre-change 32:9 build, so I agree it's not from this PR. A real three-monitor span and Linux are still untested, as the description says.
@ -1528,4 +1533,3 @@
uint32_t hos_output_size(int height); /* (host/nn_applet.c: the Output resolution's height, 1440 as shipped) */
/* (the height kept, the width at the screen's ratio, at most 3840 x 2160's pixels with the shape kept:
host/hos_wide_size.h, which the Insert menu's Output and Render resolution rows share; issue 1031) */
unsigned ow, oh;
hckrman101 (Migrated from github.com) commented 2026-11-11 02:19:14 +00:00

Nit: this also runs when HOS_ASPECT is set, so HOS_ASPECT=1.7778 (or 0) can't opt out of the surround camera with a 5760x1080/7680x1440 output. The block comment above still says HOS_ASPECT wins. If the override is intended, a word in that comment would do. If not, if (!e && hos_output_is_surround(...)) keeps the env var as the escape hatch. (The menu ignores HOS_ASPECT anyway, so either choice is consistent with it.)

Nit: this also runs when `HOS_ASPECT` is set, so `HOS_ASPECT=1.7778` (or `0`) can't opt out of the surround camera with a 5760x1080/7680x1440 output. The block comment above still says `HOS_ASPECT` wins. If the override is intended, a word in that comment would do. If not, `if (!e && hos_output_is_surround(...))` keeps the env var as the escape hatch. (The menu ignores `HOS_ASPECT` anyway, so either choice is consistent with it.)
@ -6,10 +6,23 @@
#define HOS_WIDE_SIZE_H
hckrman101 (Migrated from github.com) commented 2026-11-11 02:19:14 +00:00

Nit: the 1e-6 tolerance catches 5.333333 but not 5.3333, which is the 4-decimal form the docs use for HOS_ASPECT (2.3889). With HOS_ASPECT=5.3333 at the 1440 output, r isn't exactly 48/9, so hos_wide_size takes the 8-row path and gives 6608x1240 (5.329) instead of 6528x1224. A tolerance like 1e-4 would snap both. Only matters for the env var: the output-derived ratio is exact.

Nit: the 1e-6 tolerance catches `5.333333` but not `5.3333`, which is the 4-decimal form the docs use for `HOS_ASPECT` (`2.3889`). With `HOS_ASPECT=5.3333` at the 1440 output, `r` isn't exactly 48/9, so `hos_wide_size` takes the 8-row path and gives 6608x1240 (5.329) instead of 6528x1224. A tolerance like 1e-4 would snap both. Only matters for the env var: the output-derived ratio is exact.
Arkex-ai commented 2026-11-11 02:35:00 +00:00 (Migrated from github.com)

Addressed the three nits at 0d5e2981. A custom output above 32:9 intentionally takes precedence, keeping startup and menu geometry consistent; both comments now say so. The clamp accepts four-decimal 48:9 input. The added regression fails before the fix (6608x1240) and passes after it (6528x1224). Geometry and output fixtures pass on Windows LLVM-MinGW and Linux GCC. Fresh full-suite/build checks are pending; the description separates them from earlier evidence.

Addressed the three nits at `0d5e2981`. A custom output above 32:9 intentionally takes precedence, keeping startup and menu geometry consistent; both comments now say so. The clamp accepts four-decimal 48:9 input. The added regression fails before the fix (6608x1240) and passes after it (6528x1224). Geometry and output fixtures pass on Windows LLVM-MinGW and Linux GCC. Fresh full-suite/build checks are pending; the description separates them from earlier evidence.
Commenting is not possible because the repository is archived.
No description provided.