Skip to content

feat(menu): the Aspect ratio and Output resolution from the screen's display modes - #2566

Merged
hckrman101 merged 13 commits into
NotRexed:mainfrom
nullifyshot:feat/display-modes
Nov 12, 2026
Merged

hckrman101 merged 13 commits into
NotRexed:mainfrom
nullifyshot:feat/display-modes

Conversation

@nullifyshot

@nullifyshot nullifyshot commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

A player on a 21:9, 16:10 or 4:3 screen can only get a size of that shape by writing output_res= by hand: the Output resolution row offers six fixed sizes, and the Aspect ratio row (#2119) only 16:9 or the monitor's shape. This fills both rows from the screen's own display modes.

#2541 has merged, and this branch is rebased on main after it. Its commit is no longer here. Rebased again on #1864 (the Insert menu in 13 languages): the rows' new texts are in its tables (see Translations below).

What changed

  • Aspect ratio (the same row, saved as ultrawide= as before) is now one list of shapes, narrowest first: every shape the screen's modes have (5:4, 4:3, 3:2, 16:10, 16:9, 21:9, 32:9, ...). There's no separate Monitor's shape value any more. Instead, the shape that matches the monitor is marked, e.g. "16:9 (monitor's)" on a 1080p screen, "21:9 (monitor's)" on a 3440x1440 one, "16:10 (monitor's)" on a Steam Deck-shaped 1280x800. It's still the default. An unusual shape shows as its ratio (1600x1024 is 25:16). The row moves from Screen to the top of Resolution and upscaling, right above the Output resolution whose sizes it now picks.

  • Output resolution lists the sizes of the chosen shape:

    • the screen's display modes (EnumDisplaySettingsW) and its own size, every size once, each side rounded down to 8, only those hos_output_size_valid accepts;
    • the common sizes of each of those shapes the screen doesn't list: 720p, 1080p, 1440p, 1800p, 4K and 5K at 16:9; 1280x800 to 3840x2400 at 16:10; 1024x768 to 2880x2160 at 4:3; 1280x1024 at 5:4; 1920x1280 to 3000x2000 at 3:2; 2560x1080, 3440x1440, 3840x1600 and 5120x2160 at 21:9; 3840x1080 and 5120x1440 at 32:9 (display_modes.h common_sizes). A 1080p screen gets 1440p and 4K without DSR. A shape the screen has none of gets none;
    • the game's own 2048x1152 under 16:9.

    The screen's own size is marked "(native)", rounded the same way, so 1366x768 screens see "1360x768 (native)". Picking a shape takes the screen's own size if it has that shape, else the one whose height is nearest the screen's: 21:9 on a 1080p screen is 2560x1080, and 3:2 there is 1920x1280, not 720x480. Larger sizes stay a choice rather than the default. Hints say whether a size is the screen's own, larger (drawn bigger, then scaled down) or smaller.

  • A screen too big for the game's size limit (e.g. a 7680x2160 32:9 monitor, past 5120x2880's pixels) still gets its shape, at the most pixels a picture of another shape takes (6256x1760 there). A screen whose shape the game can't draw at all (portrait) gets "Monitor's shape" as a value of its own at the end of the row, as on main, and that value saves ultrawide=1.

  • Which monitor gets marked: "(monitor's)", "(native)" and the sizes listed come from the monitor the game window is on (MonitorFromWindow, with that monitor's own modes), or from the primary before the window exists. They also follow it while playing: about every 30 frames the menu checks the window's screen. If the window moved to another monitor or the desktop resolution changed, that screen's new sizes are added after the existing choices, so a choice already made keeps its size, and the Aspect ratio row stays on its shape.

  • A size that isn't 16:9 sets the picture's shape, so the cameras widen or narrow and the HUD stays in the middle 16:9. Before, only a size wider than 32:9 did that, and 2560x1080 with 16:9 was stretched. This uses the same rule in host/hos_main.c and the menu (hos_output_own_shape, 1% off 16:9). It takes precedence over HOS_ASPECT and ultrawide=, which now only shape a 16:9 size.

  • Saved options: ultrawide= stays 0 or 1, with main's default and feat(menu): the Aspect ratio row (was Ultrawide), at the monitor's shape by default #2119's rule for older files. It's checked against the host's screen, the primary, whose shape host/hos_main.c gives a 16:9 size at startup: 1 when that shape is picked, else 0. So the next start draws the shape picked, even when the window is on another monitor. The host's screen and its shape are always in the list. Any other shape comes from output_res's own size, so nothing new is saved. The launcher's own 16:9 / Monitor's shape setting (recomplauncher.json) writes the same key and still works. The old saved numbers (output_res=1 to 5) still load (kOutputs, which nx2/pipeline_share.py mirrors).

  • Linux: a new host call, MkwVkHost.screen_size (MKWVK_API_VERSION 20; main took 19 for the ocarina notes, feat: add separate button mappings for the ocarina notes #1930), gives the menu SDL's primary desktop size, the same one the host shapes the picture from. With it, Linux offers the sizes it offered before, plus the screen's own size and the common sizes of their shapes, and marks the monitor's shape like Windows. With no screen size at all, the old fixed sizes are listed. That includes a windowless start (HOS_HEADLESS), which loads no SDL: hos_sdl_desktop_size now returns "screen unknown" there, where it used to call an empty SDL2 slot (found by mooki000, tests/test_sdl_desktop_size.py).

  • HOS_DISPLAY_MODES=<w>x<h>,... stands in for the screen's modes (with the common sizes of their shapes added), for testing a screen you don't have (documented in docs/development.md).

  • Control bridge: option_set output_res still reaches every size (fix(menu): option_set walks the list rows in the arrows' order to the value asked for #2496). The arrows stay within one shape, so for a size of another shape it moves the Aspect ratio first, as a player would.

  • Code: the rules live in gpu/vk/display_modes.h as plain code, tested by tests/test_display_modes.py. Tests updated for the new layout and numbering: test_output_resolution, test_menu_env_overrides, test_menu_setting_walk, test_menu_sections (the row's new section), test_framegen_preset and test_rumble_menu (stand-ins).

  • Translations (feat: the Insert menu in 13 languages, with Game language and Menu la… #1864): seven of feat: the Insert menu in 13 languages, with Game language and Menu la… #1864's entries were this branch's earlier help texts (the old Aspect ratio help and the "The sharpest on a … screen" lines), which the rows no longer show. They're removed from each of the 13 tables, and the rows' current texts are added: the Aspect ratio's help and its four shape lines, the Output resolution's own-size, larger and smaller lines, and "%s (monitor's)". tx_ultrawide prints the mark from that format, so match_format translates "21:9 (monitor's)" and keeps the shape as written. Like the rest of feat: the Insert menu in 13 languages, with Game language and Menu la… #1864's tables, these are machine-made and use each table's own words for Output resolution, HUD and render targets. Speakers are welcome to correct them.

Tested (Windows 11, RTX 5080, a 1920x1080 primary screen whose modes run from 640x480 to 1920x1080)

  • tests/run_all.py (llvm-mingw), at a1eb460 + this branch: 406 passed (test_output_resolution covers the 21:9 primary of the retest from its own modes, the Aspect ratio's values, the bridge's way to 16:9, a 16:9 size kept at the monitor's shape, a window on a 16:9 monitor beside a 32:9 primary, and sizes found while running), 71 skipped, 15 failed. Main alone fails the same 15 on this PC (404 passed; this branch adds test_display_modes and test_sdl_desktop_size). Among them, test_menu_i18n fails on three texts main's menu no longer has, test_framegen_preset and test_rumble_menu on an undeclared temporal_reset_failure in their stand-ins. This branch adds no failures.
  • The menu in German (HOS_LANGUAGE=de, headless): "16:9 (des Monitors)" and the Aspect ratio's help in German. "1920x1080 (native)" stays English, as on main: the size's label is printed with a %s, which the tables don't match.
  • In game, headless, the save loaded through the control bridge. The screen's modes plus the common sizes gave 33 sizes in 7 shapes. Every run used the Upscaler Off at 100%, no window scaling filter and Sharpness 0, and shots at the picture's own size (RX_VK_SHOT_W/H) so they're the raw frame. Each size rendered at exactly that size, with the cameras at its shape (boot: widescreen: picture …, camera ratio …) and nothing stretched:
    • From this screen's modes: 1920x1080 (16:9), 1440x1080 (4:3, camera ratio 1.3333), 1680x1048 (16:10, 1.6031), 1280x1024 (5:4, 1.25).
    • From HOS_DISPLAY_MODES standing in for an ultrawide's list: 2560x1080 and 3440x1440 (21:9, 2.3704 and 2.3889, HUD in the middle 75%), 5120x1440 (32:9, 3.5556, HUD in the middle 50%).
    • Common sizes this 1080p screen doesn't list: 2560x1440 (16:9) and 2560x1600 (16:10, camera ratio 1.6000), each rendered at that size.
  • The Insert menu, headless (RX_VK_MENU_SCRIPT, RX_VK_SHOT_MENU): Aspect ratio stepped through every shape on this screen (5:4 → 1280x1024, 4:3 → 1440x1080, 3:2 → 1920x1280, 25:16 → 1600x1024, 16:10 → 1680x1048, 5:3 → 1280x768, 16:9 (monitor's) → 1920x1080 (native)) and on the simulated ultrawide list (21:9 → 2560x1080, 32:9 → 3840x1080). The Output resolution followed each one with the expected size. Arrows stop at the ends, a shape with a single size shows no arrows, and "Restart needed: Aspect ratio, Output resolution" appears.

Needs testing (help wanted: I have one 16:9 screen)

  • A real ultrawide, 16:10 or 4:3 screen: the list, "(monitor's)" on the right shape and "(native)" on the right size, from the actual modes rather than HOS_DISPLAY_MODES. Also an older options file with ultrawide=1 and a 16:9 output_res there: the row should read "21:9 (monitor's)" (or the screen's shape), the picture should be at the monitor's shape, and saving should keep ultrawide=1.
  • Screens at unusual sizes: 1366x768 (16:9, not a multiple of 8), 1600x900, 3840x1600, 5120x2160, a 7680x2160 32:9 (past the size limit), and a laptop at 3:2 or 16:10. Check the right shape is marked and the default size picked.
  • Common sizes above the screen: 1440p, 4K and 5K on a 1080p screen. They should render at that size and be scaled down to the window, and the hint should say "Larger than your screen".
  • Multi-monitor:
    • The marks and sizes follow the monitor the window is on, while ultrawide= is saved against the primary (see above). Fullscreen (F11) goes borderless on whichever monitor the window is on.
    • Please check the game on a secondary monitor with a different size or shape from the primary (e.g. a 1440p 16:9 primary and a 21:9 secondary). Expected: the secondary's shape is marked "(monitor's)" and its own size "(native)"; picking 16:9 there and restarting gives a 16:9 picture, and picking 21:9 gives 21:9.
    • Also check: dragging the window to the other monitor while running (the log says vk: the window's screen is …: N sizes added, and the marks move); changing which monitor is primary between runs; mixed DPI scaling.
    • Not tested here (one monitor).
  • Window resizing:
    • The picture stays at the Output resolution until a restart. Resizing, maximizing or snapping the window only changes how it's scaled to the window, with bars where the shapes differ (rx_present_fx), never stretched.
    • Please check: a 21:9 or 4:3 Output resolution in a 16:9 window and the other way round; dragging the window to odd shapes (very tall, very wide); maximize and restore; F11 and Alt+Enter in and out of fullscreen at each shape; a window larger than the picture with each Window scaling filter.
    • Also check that the Window scaling filter hint says "Not needed" only when the window is exactly the Output resolution.
  • Display changes while running: changing the desktop resolution, plugging a monitor in or out, or turning DSR on doesn't change the lists until the next start. A saved size the screen no longer offers stays as the player's own choice (as a hand-written output_res= does).
  • DSR / DLDSR: their sizes appear in the list (Windows lists them as modes). Picking a shape shouldn't default to one of them; they should be reachable with the arrows.
  • Upscalers and frame generation at other shapes: DLSS, DLAA, FSR 3.1, FSR 4 and DLSS Frame Generation at 21:9, 32:9, 16:10 and 4:3, checking the Render resolution sizes the row shows and that nothing is cropped or smeared at the edges.
  • The parts of the game outside the 3D at each shape: pause, item and map menus (Ultrawide menus), loading screens, pre-rendered movies, cutscenes, and the HUD at 4:3 and 5:4.
  • Older options files: output_res=1 to 5, a hand-written size of a shape the screen doesn't list, ultrawide=0 from before options version 6 on a 16:10 screen (feat(menu): the Aspect ratio row (was Ultrawide), at the monitor's shape by default #2119's rule), and HOS_ASPECT / HOS_OUTPUT_RES runs (fix(menu): the Aspect ratio's move for older files skips runs with HOS_ASPECT #2541).
  • Handheld profile: both rows are docked only. Check nothing changes in handheld.
  • Linux and the Steam Deck: the menu now gets the screen size from SDL (API 20), so the Deck's 1280x800 should show "16:10 (monitor's)", and 16:9 should be selectable and kept after a restart. Not run on Linux here: CI's Linux build compiles the host side.
  • Desktop resolution changed while playing: e.g. switch the desktop to 2560x1440 with DSR while the game runs. The log should say vk: the window's screen is 2560x1440 …, and the new sizes should appear in the Output resolution while your current choice stays. Not tested here.
  • Portrait screens: their modes are narrower than 5:4, so they're left out. Check the list then falls back sensibly.

Screenshots

From the headless runs above (Windows 11, RTX 5080, 1920x1080 primary screen): Upscaler Off at 100%, no window scaling filter, Sharpness 0, each shot at the picture's own size.

The Graphics tab on this screen: the Aspect ratio at the monitor's own shape, marked "(monitor's)", with the Output resolution at the screen's own size.

Aspect ratio 16:9 (monitor's), Output resolution 1920x1080 (native)

3:2, a shape this screen has only at 720x480. The Output resolution moved to 1920x1280, one of 3:2's common sizes, the one nearest the screen's height. Both rows are marked for the restart.

Aspect ratio 3:2, Output resolution 1920x1280, restart needed

With HOS_DISPLAY_MODES standing in for an ultrawide's list, at a 3440x1440 output: 32:9, with the Output resolution stepped to 5120x1440.

Aspect ratio 32:9, Output resolution 5120x1440 on a simulated ultrawide list

The same spot at all seven sizes, scaled to one height: 16:9, 4:3, 16:10, 5:4, both 21:9 sizes and 32:9. Wider shapes see more at the sides with the HUD in the middle 16:9. Narrower ones keep the height and spread the HUD across their width. Nothing is stretched.

The same spot at 1920x1080, 1440x1080, 1680x1048, 1280x1024, 2560x1080, 3440x1440 and 5120x1440

Full size, 21:9 at 3440x1440 (boot: widescreen: picture 3440x1440, scene 2584x1080, camera ratio 2.3889, HUD and movies in the middle 74.4%):

21:9 at 3440x1440

Full size, 4:3 at 1440x1080 (picture 1440x1080, scene 1080x810, camera ratio 1.3333, HUD and movies in the middle 100.0%):

4:3 at 1440x1080

🤖 Generated with Claude Code

@pmwork-personal

Copy link
Copy Markdown
Contributor

Tested on a real 21:9 screen: Windows 11, RTX 5090, primary monitor 5120x2160 at 125% scaling, plus a 1440x2560 portrait secondary. Build of this branch at a8f7f9d, headless runs (HOS_HEADLESS=1, RX_VK_SHOT_MENU=1, RX_VK_MENU_SCRIPT), no HOS_DISPLAY_MODES.

The screen's modes (EnumDisplaySettingsW(nullptr, i), each size once): 18 sizes, seven of them 21:9: 2560x1080, 3012x1271, 3414x1440, 3440x1440, 3939x1662, 4352x1836, 5120x2160. The others are 4:3, 3:2, 5:4 and 16:9 (up to 3840x2160). No 16:10 or 32:9. The log: the Output resolution's sizes: 32 (the screen's modes), the game's own and no other; shapes 5:4, 4:3, 3:2, 16:9, 21:9.

Works as described

  • First start (no options file): Aspect ratio 21:9 (monitor's). The picture is the monitor's shape (picture 3416x1440, scene 2560x1080, camera ratio 2.3722).
  • Stepping the Aspect ratio: 16:9, 3:2 → 3000x2000, 4:3 → 2880x2160 (the screen's height), 5:4 → 1280x1024. Arrows stop at both ends; no 32:9 (the screen has none). Back at 21:9 the Output resolution reads 5120x2160 (native). "Restart needed" shows for each change.
  • An older options file with ultrawide=1 and a 16:9 output_res=2560x1440: the row reads 21:9 (monitor's), the picture is at the monitor's shape (3416x1440), and saving keeps ultrawide=1.
  • Hand-written 21:9 sizes render at exactly that size, nothing stretched:
    • output_res=3440x1440: picture 3440x1440, scene 2584x1080, camera ratio 2.3889, HUD and movies in the middle 74.4%
    • output_res=5120x2160: picture 5120x2160, scene 3840x1620, camera ratio 2.3704, HUD and movies in the middle 75.0%
    • output_res=2560x1080: picture 2560x1080, scene 1920x810, camera ratio 2.3704

Not as described: 21:9 is the monitor's own shape here, and its list is the 16:9 sizes widened

With the Aspect ratio at 21:9 (monitor's), the Output resolution offers, narrowest first:

1704x720 · 2120x896 · 2560x1080 · 2048x1152 (game's) · 3416x1440 · 4264x1800 · 5120x2160 (native)

Each of these is a 16:9 size at the monitor's shape: 1280x720, 1600x900, 1920x1080, 2560x1440, 3200x1800 (a common 16:9 size, not a mode here) and 3840x2160, widened at their height. The file confirms it: after stepping to 1704x720, output_res=1280x720 was saved. So on this screen:

  • The screen's own 21:9 modes 3440x1440, 3939x1662, 4352x1836 and 3012x1271 are never offered, and neither are the common 21:9 sizes 3440x1440 and 3840x1600. 3414x1440 shows as 3416x1440, the widened 2560x1440, not the mode rounded down to 8 (3408x1440).
  • "no other" in the log: no common sizes were added for any shape.
  • "2048x1152 (game's)" sits in the 21:9 list with its 16:9 numbers, between 2560x1080 and 3416x1440. At 21:9 it draws about 2728x1152.
  • At first start the pair is 21:9 (monitor's) with 2048x1152 (game's). After stepping the shape away and back it becomes 5120x2160 (native), and "Restart needed: Output resolution" shows although the shape is the one the game started with.

My guess is that the monitor's shape still goes through the old Ultrawide rule (ultrawide=1: a 16:9 output_res widened) rather than through the 21:9 shape's own sizes. Your HOS_DISPLAY_MODES run kept a 16:9 primary, where 21:9 is not the monitor's shape, so it took the other path. A test with HOS_DISPLAY_MODES and a 21:9 primary size would need the monitor's size simulated too.

Windowed, on the same PC (picture 3416x1440, the first-start default):

  • Resizing, snapping and maximizing the window: about 98 window sizes, from 2135x900 up to 5409x2121, and never stretched. The game remade its swapchain each time with no errors (mailbox, V-Sync Auto, about 60 fps).
  • The window dragged across both monitors (the 5120-wide primary and the 1440-wide portrait screen; the window reached 6553x2121): the picture kept its 21:9 shape, scaled to the window's height, with black bars at the sides. That is the "bars where the shapes differ, never stretched" you describe. Filling both screens would take an Output resolution of that shape, which isn't one of the primary's modes and is past the 5120x2160-pixel cap anyway.

Not tested yet: F11 and Alt+Enter, the game alone on the portrait monitor, and DLSS / DLSS-G at 21:9.

Two suggestions from playing it

  1. Offer the monitor's own modes, which is this PR's aim, at the monitor's own shape too: on this screen that would be 2560x1080, 3440x1440, 3936x1656, 4352x1832 and 5120x2160 under 21:9, rather than 16:9 sizes widened to it. That's the convenient list for an ultrawide player.
  2. In a window, render at the window's size. When I resize the window or drag it across both monitors, I'd expect the game to fill the window, at whatever shape it is, rather than keep the Output resolution's shape with bars. I know the picture's shape is set at the game's start today (that's why both rows apply after a restart), so following the window live would mean changing the cameras' shape and the render size while it runs. That may be a separate PR, or not possible with how the game sets its widescreen, so I'm just raising it. It would also make spanning three monitors work with no setup: a window stretched across them would just fill them, instead of needing a hand-written surround output_res like feat(video): support 48:9 triple-monitor picture geometry #2052's 7680x1440. (Within the picture's pixel cap: three 1440p screens, 7680x1440, are exactly 5120x2160's pixels; three 4K ones would still be capped.)

nullifyshot added a commit to nullifyshot/Hookshot that referenced this pull request Nov 12, 2026
…ape its size, the game's own as drawn

From a test on a 5120x2160 primary (NotRexed#2566's comment):
- Stepping the Aspect ratio away from the shape the game started with and back took that shape's own pick (5120x2160) and
  asked to restart, though nothing differed from the start. Back at the start's shape it is now the size the game started
  with (output_for_aspect, output_started).
- The game's own size showed its 16:9 2048x1152 in the 21:9 list, though ultrawide=1 draws it at the host's shape: it now
  shows that picture (2728x1152 at a 5120x2160 screen's 21:9), as the game draws it.
- The sizes log said "no other" where no size of the player's own was read, which read as no common sizes: it now says what
  the list holds.

test_output_resolution: that screen's 21:9 modes, a first start at 21:9 (monitor's) with the game's own size: the arrows walk
the 21:9 modes up to 5120x2160 (native), and 16:9 then back keeps the game's own.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nullifyshot

Copy link
Copy Markdown
Contributor Author

@pmwork-personal Thanks, this is exactly the screen I couldn't test. Your build (a8f7f9df) is two commits behind what fixed part of this, so here's where each point stands. 14320fa fixes the rest.

The 21:9 (monitor's) list was 16:9 sizes widened. You were right: the arrows walked the 16:9 sizes from a 16:9 output_res kept at ultrawide=1, which a first start always has with the game's own size.

  • 9cde059: from that state the arrows walk the monitor shape's own sizes.
  • 62f322f: the host's screen (your primary) is always among the sizes too.

On your screen, Right from the first start's game's own size now goes 2560x1080 → 3408x1440 → 3440x1440 → 3936x1656 → 4352x1832 → 5120x2160 (native). test_output_resolution checks exactly that list.

"2048x1152 (game's)" with its 16:9 numbers. 14320fa: it now shows what the game draws at the monitor's shape. That's 2728x1152 on your 5120x2160, the same figure you worked out.

Back at 21:9 gave 5120x2160 and "Restart needed". 14320fa: going back to the shape the game started with now gives back the size it started with, so there's nothing to restart for.

"no other" in the log. That meant "no size of your own", not "no common sizes". Your list did get 16:9's common sizes: 3200x1800 is the 4264x1800 you saw. The line now says the Output resolution's sizes: N (the screen's modes, with the common sizes of their shapes, and the game's own).

Also new since your build:

  • 62f322f: "(monitor's)", "(native)" and the list follow the monitor the window is on. If you drag it to another monitor or change the desktop resolution while playing, that screen's sizes are added and logged (vk: the window's screen is …).
  • ultrawide= is still saved against the primary, which is what host/hos_main.c shapes the picture from at startup.
  • Linux gets the screen size from SDL through a new host call (API 19).

On your setup, the window on the 1440x2560 portrait screen should now show the separate Monitor's shape value. It's still a shape the game can't draw.

Suggestion 2, rendering at the window's size live: I agree it'd be nicer, but it's a different mechanism. The picture's shape is fixed at boot: nx2/oot_wide.py's patches read hos_wide_out once, and the render targets' pool is sized from it. Following the window live would mean reshaping the cameras and reallocating the targets mid-game. I'd rather keep this PR to what the menu offers and pick that up separately, if it's doable at all.

If you have time, a retest at the head on the same screen would cover what changed. Thanks again for the detailed run.

nullifyshot added a commit to nullifyshot/Hookshot that referenced this pull request Nov 12, 2026
…ape its size, the game's own as drawn

From a test on a 5120x2160 primary (NotRexed#2566's comment):
- Stepping the Aspect ratio away from the shape the game started with and back took that shape's own pick (5120x2160) and
  asked to restart, though nothing differed from the start. Back at the start's shape it is now the size the game started
  with (output_for_aspect, output_started).
- The game's own size showed its 16:9 2048x1152 in the 21:9 list, though ultrawide=1 draws it at the host's shape: it now
  shows that picture (2728x1152 at a 5120x2160 screen's 21:9), as the game draws it.
- The sizes log said "no other" where no size of the player's own was read, which read as no common sizes: it now says what
  the list holds.

test_output_resolution: that screen's 21:9 modes, a first start at 21:9 (monitor's) with the game's own size: the arrows walk
the 21:9 modes up to 5120x2160 (native), and 16:9 then back keeps the game's own.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nullifyshot
nullifyshot marked this pull request as draft November 12, 2026 02:57
nullifyshot added a commit to nullifyshot/Hookshot that referenced this pull request Nov 12, 2026
…ape its size, the game's own as drawn

From a test on a 5120x2160 primary (NotRexed#2566's comment):
- Stepping the Aspect ratio away from the shape the game started with and back took that shape's own pick (5120x2160) and
  asked to restart, though nothing differed from the start. Back at the start's shape it is now the size the game started
  with (output_for_aspect, output_started).
- The game's own size showed its 16:9 2048x1152 in the 21:9 list, though ultrawide=1 draws it at the host's shape: it now
  shows that picture (2728x1152 at a 5120x2160 screen's 21:9), as the game draws it.
- The sizes log said "no other" where no size of the player's own was read, which read as no common sizes: it now says what
  the list holds.

test_output_resolution: that screen's 21:9 modes, a first start at 21:9 (monitor's) with the game's own size: the arrows walk
the 21:9 modes up to 5120x2160 (native), and 16:9 then back keeps the game's own.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mooki000

Copy link
Copy Markdown
Contributor

Tested on Linux: Arch, Hyprland 0.56.2 (Wayland), i9-13900K, RTX 4090 with NVIDIA 615.78.08, one 1920x1080 monitor at 60 Hz and scale 1.25, SDL 3.4.18. The runs are on 14320fa7; the branch has since been rebased to bd8fd684, and host/hos_sdl.c and host/rx_backend.c are identical between the two, so the first point applies to the new head as well.

A windowless start crashes on Linux. With HOS_HEADLESS=1, 14320fa7 exits with 139 before the first frame and before any menu key: 0 frames, the log reaches boot and then CRASH: exception 0xc0000005 ... at ?+0, the kernel records the main thread at address 0, and there are no driver lines. The same run on a8f7f9df earlier completed normally (150 s), so it came in with the last commits.

The cause, as far as the evidence goes: the new host screen callback calls hos_sdl_desktop_size, and a windowless start never loads SDL, so version is 0 and the function falls through to the SDL2 branch and calls an empty function pointer. The core shows the jump to 0 but is cut short before the caller's stack, so this is from the code and from a reproduction: those two functions compiled alone with GCC and Clang and an unloaded table fault the same way. With if (!version) return 0; at the top of the helper the same fixture returns "screen unknown" instead. I did not patch the game. Windows takes the GetSystemMetrics branch and is not affected by this path.

With a real window on Wayland it works. 142 s, no crash, no device loss, no driver lines. Stepping both rows by script, the menu offered:

  • 16:9 (monitor's): 1280x720, 1920x1080 (native), 2048x1152 (game's), 2560x1440, 3200x1800, 3840x2160, 5120x2880
  • 32:9: 3840x1080, 5120x1440

The log: the Output resolution's sizes: 9 (the screen's modes, with the common sizes of their shapes, and the game's own); shapes 16:9, 32:9. So on Linux the list is the desktop's size plus the common sizes, not the monitor's whole mode list. The window is 1536x864 in logical units and the swapchain 1920x1080, and 1920x1080 is the one marked native, so the scale of 1.25 is handled. Going back to 16:9 gave back the size the run started with. The last choice was saved as output_res=2048x1152 with ultrawide=1, to apply at the next start. No the window's screen is line appeared, as expected on one unchanged monitor.

Checks: the eight tests this adds or changes pass with GCC 16.2.1 and Clang 23.1.3 (run_all.py --strict). Against main's sources six of them fail as they should and two, which only update stand-ins, pass. The whole suite on 14320fa7: 450 passed, 1 failed, 20 skipped; the one is main's test_env_on of that hour, since fixed by #2575. The Linux build succeeds.

Overlap with #2594 (a typed Custom output size, mine): the two conflict in six places in four files, among them the host callbacks both add (screen_size here, take_text there) and the API version. They fit together: the typed size belongs beside this list. Whichever lands second needs a small rebase; if this lands first I will do it on #2594 and move the typed-size path to your dynamic list.

Not tested: fullscreen (my test harness does not allow it), X11 and other compositors, a second monitor, Windows, and the restart that applies the saved 2048x1152. The windowed run's evidence is the log and the menu's own state, not pictures of the menu.

@pmwork-personal

Copy link
Copy Markdown
Contributor

Retest at bd8fd684 with main merged in, on the same PC: Windows 11, RTX 5090, 5120x2160 primary at 125%, 1440x2560 portrait secondary. Headless (HOS_HEADLESS=1, RX_VK_SHOT_MENU=1, a menu key script), no HOS_DISPLAY_MODES, from a first start with no options file. The windowless start is fine on Windows, as expected from mooki's note on the GetSystemMetrics branch.

All three fixes work on this screen

  • The log: the Output resolution's sizes: 32 (the screen's modes, with the common sizes of their shapes, and the game's own); shapes 5:4, 4:3, 3:2, 16:9, 21:9. The picture is 3416x1440.
  • First start: 21:9 (monitor's) with 2728x1152 (game's).
  • Right from there: 2560x1080 → 3008x1264 → 3408x1440 → 3440x1440 → 3840x1600 → 3936x1656 → 4352x1832. The script stopped at 4352x1832, so I didn't step on to 5120x2160 (native).
  • 21:9 → 16:9 (3840x2160, "Restart needed: Aspect ratio, Output resolution") → back to 21:9 gives 2728x1152 (game's) again, with no restart notice. Saved: ultrawide=1, output_res=2048x1152.

Two small notes on the list. Neither looks wrong to me:

  • On the real screen it has two sizes more than test_output_resolution's list: 3008x1264 (this screen's 3012x1271 mode, rounded down to 8) and 3840x1600 (21:9's common size). Both fit the log line's rule. The test fills output_extras with the six sizes directly, so it doesn't cover these two.
  • "(game's)" comes before 2560x1080, so the first Right goes down a size. That matches what you described; it only reads a little out of order next to the rest.

Merging main. GitHub shows the branch conflicting with main. To build it I merged main (up to a016b7a6) into bd8fd684 locally. All five conflicts are in gpu/vk/vk_menu.cpp, against #1864's Game language row, and each one keeps both sides:

  1. Includes: your display_modes.h, then main's vk_menu_i18n.h.
  2. save(): your ultrawide branch, then main's last branch, which now skips game_lang (that one goes to language.txt):
    } else if (r.value && r.value != &opts.game_lang) {   // (game_lang: language.txt's)
  3. set_row(): main's step line (it only adds a comment), then your output_for_aspect block.
  4. Both new functions: your outputs_follow_screen(), then main's game_lang_tick().
  5. menu_tick(): both calls, outputs_follow_screen(); then game_lang_tick();.

With that:

  • The Windows build succeeds.
  • The menu's row definitions match main's except Aspect ratio and Output resolution.
  • The result also merges with today's main (de866017) with no more conflicts.
  • Of the seven tests this PR adds or changes, five pass here. test_framegen_preset and test_rumble_menu don't compile (temporal_reset_failure undeclared in their stand-ins). They fail the same way on main here (a016b7a6 and de866017), so they're not from this PR.

Not tested yet (these need a real window): the window moved to the portrait screen (the the window's screen is line), F11 and Alt+Enter, and DLSS / DLSS-G at 21:9.

nullifyshot added a commit to nullifyshot/Hookshot that referenced this pull request Nov 12, 2026
…ape its size, the game's own as drawn

From a test on a 5120x2160 primary (NotRexed#2566's comment):
- Stepping the Aspect ratio away from the shape the game started with and back took that shape's own pick (5120x2160) and
  asked to restart, though nothing differed from the start. Back at the start's shape it is now the size the game started
  with (output_for_aspect, output_started).
- The game's own size showed its 16:9 2048x1152 in the 21:9 list, though ultrawide=1 draws it at the host's shape: it now
  shows that picture (2728x1152 at a 5120x2160 screen's 21:9), as the game draws it.
- The sizes log said "no other" where no size of the player's own was read, which read as no common sizes: it now says what
  the list holds.

test_output_resolution: that screen's 21:9 modes, a first start at 21:9 (monitor's) with the game's own size: the arrows walk
the 21:9 modes up to 5120x2160 (native), and 16:9 then back keeps the game's own.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nullifyshot added a commit to nullifyshot/Hookshot that referenced this pull request Nov 12, 2026
…without SDL, not a call through an empty slot

The Insert menu asks the host for the main screen's size at startup and while the game runs (MkwVkHost.screen_size, this
PR's), which on Linux is hos_sdl_desktop_size. A windowless start (HOS_HEADLESS) loads no SDL, so version is 0 and the
function went on to SDL2's branch and called GetDesktopDisplayMode's empty slot: exit 139 before the first frame
(reported on NotRexed#2566 by mooki000, Arch, Hyprland). With no SDL loaded it now says the screen is unknown, and the menu
lists the sizes it does without one. Windows takes GetSystemMetrics and was not affected.

tests/test_sdl_desktop_size.py cuts the function from hos_sdl.c and runs it against stand-ins: no SDL (unknown, which
faulted at address 0 before), SDL3's mode in pixels (1536x864 at a density of 1.25 is 1920x1080), SDL3 with no mode,
and SDL2's mode as given or failed.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nullifyshot added a commit to nullifyshot/Hookshot that referenced this pull request Nov 12, 2026
…them, rounded and with 21:9's common sizes

The 5120x2160 case filled the list with six sizes directly. NotRexed#2566's retest on that screen walked eight: 3008x1264 (its
3012x1271 mode rounded down to 8) and 3840x1600 (21:9's common size) as well. The case now takes the screen's modes
through display_modes.h offered and with_common, as the list does, and walks the same eight sizes the retest saw.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nullifyshot

Copy link
Copy Markdown
Contributor Author

Thanks to both of you. The branch is now rebased on main through #1864 and #2637, and the head has two new commits for your points.

@mooki000 The headless crash on Linux is fixed in 86aa3c4, as you suggested. With no SDL loaded, hos_sdl_desktop_size now returns "screen unknown". Without SDL the menu then lists the sizes it lists when it knows no screen. Before this PR, nothing called the helper before SDL was loaded. The menu now asks at startup and every 30 frames, which is how a windowless start reached the empty SDL2 slot. tests/test_sdl_desktop_size.py cuts the function from hos_sdl.c and runs it with stand-ins. Without the guard it faults at address 0, matching your core. It also checks SDL3's mode in pixels (your 1536x864 at 1.25 is 1920x1080), SDL3 with no mode, and SDL2.

On Linux the list is the desktop's size plus the common sizes of its shapes, as you saw. SDL gives the menu the desktop mode only, not the monitor's whole mode list. #2594: agreed, the typed size belongs beside this list. Whichever lands second takes the rebase, and thanks for offering to do it on yours.

@pmwork-personal Your merge matches the rebase now on the PR: the same five spots in vk_menu.cpp, each keeping both sides. The only difference is the order of the two calls in menu_tick, which don't depend on each other. The rebase also puts the rows' new texts into #1864's tables. "21:9 (monitor's)" now goes through a translatable format, so it shows as "16:9 (des Monitors)" in German, for example.

The two sizes the test didn't cover are in 2e14130. The 21:9 case now takes the screen's modes as Windows lists them, including your 3012x1271, through the same rounding and common-size steps as the list. It walks your eight sizes: 2560x1080 → 3008x1264 → 3408x1440 → 3440x1440 → 3840x1600 → 3936x1656 → 4352x1832 → 5120x2160.

"(game's)" before 2560x1080: that's its place in the list. The game's own size is choice 0, so older saves keep their output_res=0, and the arrows step by list position. At 21:9 it draws 2728x1152, which reads as out of order next to 2560x1080. If you'd rather the arrows reach it at its drawn width, between 2560x1080 and 3008x1264, I can do that. It doesn't change what's saved.

test_framegen_preset and test_rumble_menu fail the same way on main here (temporal_reset_failure in their stand-ins), so they're not from this PR. Of the 15 tests that fail on this PC, main fails the same 15.

nullifyshot added a commit to nullifyshot/Hookshot that referenced this pull request Nov 12, 2026
… shows

At a shape the host widens 16:9 sizes to, the game's own choice shows what the game draws (2728x1152 at a 5120x2160
screen's 21:9) but was walked at its stored 2048x1152, so it came before 2560x1080 and the first Right went down a size
(NotRexed#2566's retest). step_output_choice now orders a shape's choices by picture_for, the size each row shows, and the game's
own is in the walk of the shape it is drawn at, reached from either side: 2560x1080, 2728x1152 (game's), 3008x1264, ...
At 32:9 a kept 1920x1080 (drawn 3840x1080) and the game's own (4096x1152) come before 5120x1440 the same way. What is
saved is the choice, as before (output_res=0 for the game's own); handheld draws nothing wider and keeps the old order.

test_output_resolution walks the 21:9 screen's nine choices up and back down, and the 32:9 one; test_menu_setting_walk's
stand-ins gain picture_for (each choice's own size there).

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nullifyshot

Copy link
Copy Markdown
Contributor Author

@pmwork-personal I made the "(game's)" change in e4caac7. The Output resolution's arrows now go by the size each choice shows. On your screen at 21:9 the order is 2560x1080 → 2728x1152 (game's) → 3008x1264 → …, the same both ways. At 32:9, a kept 1920x1080 (drawn 3840x1080) and the game's own (4096x1152) now come before 5120x1440 as well. Saves don't change: the game's own is still output_res=0. Handheld draws nothing wider, so it keeps the old order. test_output_resolution checks your screen's nine choices up and back down.

nullifyshot added a commit to nullifyshot/Hookshot that referenced this pull request Nov 12, 2026
…ape its size, the game's own as drawn

From a test on a 5120x2160 primary (NotRexed#2566's comment):
- Stepping the Aspect ratio away from the shape the game started with and back took that shape's own pick (5120x2160) and
  asked to restart, though nothing differed from the start. Back at the start's shape it is now the size the game started
  with (output_for_aspect, output_started).
- The game's own size showed its 16:9 2048x1152 in the 21:9 list, though ultrawide=1 draws it at the host's shape: it now
  shows that picture (2728x1152 at a 5120x2160 screen's 21:9), as the game draws it.
- The sizes log said "no other" where no size of the player's own was read, which read as no common sizes: it now says what
  the list holds.

test_output_resolution: that screen's 21:9 modes, a first start at 21:9 (monitor's) with the game's own size: the arrows walk
the 21:9 modes up to 5120x2160 (native), and 16:9 then back keeps the game's own.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nullifyshot added a commit to nullifyshot/Hookshot that referenced this pull request Nov 12, 2026
…without SDL, not a call through an empty slot

The Insert menu asks the host for the main screen's size at startup and while the game runs (MkwVkHost.screen_size, this
PR's), which on Linux is hos_sdl_desktop_size. A windowless start (HOS_HEADLESS) loads no SDL, so version is 0 and the
function went on to SDL2's branch and called GetDesktopDisplayMode's empty slot: exit 139 before the first frame
(reported on NotRexed#2566 by mooki000, Arch, Hyprland). With no SDL loaded it now says the screen is unknown, and the menu
lists the sizes it does without one. Windows takes GetSystemMetrics and was not affected.

tests/test_sdl_desktop_size.py cuts the function from hos_sdl.c and runs it against stand-ins: no SDL (unknown, which
faulted at address 0 before), SDL3's mode in pixels (1536x864 at a density of 1.25 is 1920x1080), SDL3 with no mode,
and SDL2's mode as given or failed.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nullifyshot added a commit to nullifyshot/Hookshot that referenced this pull request Nov 12, 2026
…them, rounded and with 21:9's common sizes

The 5120x2160 case filled the list with six sizes directly. NotRexed#2566's retest on that screen walked eight: 3008x1264 (its
3012x1271 mode rounded down to 8) and 3840x1600 (21:9's common size) as well. The case now takes the screen's modes
through display_modes.h offered and with_common, as the list does, and walks the same eight sizes the retest saw.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nullifyshot added a commit to nullifyshot/Hookshot that referenced this pull request Nov 12, 2026
… shows

At a shape the host widens 16:9 sizes to, the game's own choice shows what the game draws (2728x1152 at a 5120x2160
screen's 21:9) but was walked at its stored 2048x1152, so it came before 2560x1080 and the first Right went down a size
(NotRexed#2566's retest). step_output_choice now orders a shape's choices by picture_for, the size each row shows, and the game's
own is in the walk of the shape it is drawn at, reached from either side: 2560x1080, 2728x1152 (game's), 3008x1264, ...
At 32:9 a kept 1920x1080 (drawn 3840x1080) and the game's own (4096x1152) come before 5120x1440 the same way. What is
saved is the choice, as before (output_res=0 for the game's own); handheld draws nothing wider and keeps the old order.

test_output_resolution walks the 21:9 screen's nine choices up and back down, and the 32:9 one; test_menu_setting_walk's
stand-ins gain picture_for (each choice's own size there).

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nullifyshot added a commit to nullifyshot/Hookshot that referenced this pull request Nov 12, 2026
…ape its size, the game's own as drawn

From a test on a 5120x2160 primary (NotRexed#2566's comment):
- Stepping the Aspect ratio away from the shape the game started with and back took that shape's own pick (5120x2160) and
  asked to restart, though nothing differed from the start. Back at the start's shape it is now the size the game started
  with (output_for_aspect, output_started).
- The game's own size showed its 16:9 2048x1152 in the 21:9 list, though ultrawide=1 draws it at the host's shape: it now
  shows that picture (2728x1152 at a 5120x2160 screen's 21:9), as the game draws it.
- The sizes log said "no other" where no size of the player's own was read, which read as no common sizes: it now says what
  the list holds.

test_output_resolution: that screen's 21:9 modes, a first start at 21:9 (monitor's) with the game's own size: the arrows walk
the 21:9 modes up to 5120x2160 (native), and 16:9 then back keeps the game's own.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nullifyshot added a commit to nullifyshot/Hookshot that referenced this pull request Nov 12, 2026
…without SDL, not a call through an empty slot

The Insert menu asks the host for the main screen's size at startup and while the game runs (MkwVkHost.screen_size, this
PR's), which on Linux is hos_sdl_desktop_size. A windowless start (HOS_HEADLESS) loads no SDL, so version is 0 and the
function went on to SDL2's branch and called GetDesktopDisplayMode's empty slot: exit 139 before the first frame
(reported on NotRexed#2566 by mooki000, Arch, Hyprland). With no SDL loaded it now says the screen is unknown, and the menu
lists the sizes it does without one. Windows takes GetSystemMetrics and was not affected.

tests/test_sdl_desktop_size.py cuts the function from hos_sdl.c and runs it against stand-ins: no SDL (unknown, which
faulted at address 0 before), SDL3's mode in pixels (1536x864 at a density of 1.25 is 1920x1080), SDL3 with no mode,
and SDL2's mode as given or failed.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nullifyshot added a commit to nullifyshot/Hookshot that referenced this pull request Nov 12, 2026
…them, rounded and with 21:9's common sizes

The 5120x2160 case filled the list with six sizes directly. NotRexed#2566's retest on that screen walked eight: 3008x1264 (its
3012x1271 mode rounded down to 8) and 3840x1600 (21:9's common size) as well. The case now takes the screen's modes
through display_modes.h offered and with_common, as the list does, and walks the same eight sizes the retest saw.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nullifyshot added a commit to nullifyshot/Hookshot that referenced this pull request Nov 12, 2026
…ape its size, the game's own as drawn

From a test on a 5120x2160 primary (NotRexed#2566's comment):
- Stepping the Aspect ratio away from the shape the game started with and back took that shape's own pick (5120x2160) and
  asked to restart, though nothing differed from the start. Back at the start's shape it is now the size the game started
  with (output_for_aspect, output_started).
- The game's own size showed its 16:9 2048x1152 in the 21:9 list, though ultrawide=1 draws it at the host's shape: it now
  shows that picture (2728x1152 at a 5120x2160 screen's 21:9), as the game draws it.
- The sizes log said "no other" where no size of the player's own was read, which read as no common sizes: it now says what
  the list holds.

test_output_resolution: that screen's 21:9 modes, a first start at 21:9 (monitor's) with the game's own size: the arrows walk
the 21:9 modes up to 5120x2160 (native), and 16:9 then back keeps the game's own.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nullifyshot added a commit to nullifyshot/Hookshot that referenced this pull request Nov 12, 2026
…without SDL, not a call through an empty slot

The Insert menu asks the host for the main screen's size at startup and while the game runs (MkwVkHost.screen_size, this
PR's), which on Linux is hos_sdl_desktop_size. A windowless start (HOS_HEADLESS) loads no SDL, so version is 0 and the
function went on to SDL2's branch and called GetDesktopDisplayMode's empty slot: exit 139 before the first frame
(reported on NotRexed#2566 by mooki000, Arch, Hyprland). With no SDL loaded it now says the screen is unknown, and the menu
lists the sizes it does without one. Windows takes GetSystemMetrics and was not affected.

tests/test_sdl_desktop_size.py cuts the function from hos_sdl.c and runs it against stand-ins: no SDL (unknown, which
faulted at address 0 before), SDL3's mode in pixels (1536x864 at a density of 1.25 is 1920x1080), SDL3 with no mode,
and SDL2's mode as given or failed.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nullifyshot added a commit to nullifyshot/Hookshot that referenced this pull request Nov 12, 2026
…them, rounded and with 21:9's common sizes

The 5120x2160 case filled the list with six sizes directly. NotRexed#2566's retest on that screen walked eight: 3008x1264 (its
3012x1271 mode rounded down to 8) and 3840x1600 (21:9's common size) as well. The case now takes the screen's modes
through display_modes.h offered and with_common, as the list does, and walks the same eight sizes the retest saw.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nullifyshot added a commit to nullifyshot/Hookshot that referenced this pull request Nov 12, 2026
… shows

At a shape the host widens 16:9 sizes to, the game's own choice shows what the game draws (2728x1152 at a 5120x2160
screen's 21:9) but was walked at its stored 2048x1152, so it came before 2560x1080 and the first Right went down a size
(NotRexed#2566's retest). step_output_choice now orders a shape's choices by picture_for, the size each row shows, and the game's
own is in the walk of the shape it is drawn at, reached from either side: 2560x1080, 2728x1152 (game's), 3008x1264, ...
At 32:9 a kept 1920x1080 (drawn 3840x1080) and the game's own (4096x1152) come before 5120x1440 the same way. What is
saved is the choice, as before (output_res=0 for the game's own); handheld draws nothing wider and keeps the old order.

test_output_resolution walks the 21:9 screen's nine choices up and back down, and the 32:9 one; test_menu_setting_walk's
stand-ins gain picture_for (each choice's own size there).

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mooki000

Copy link
Copy Markdown
Contributor

Linux re-test of the fixed head, as promised above.

Hardware: RTX 4090 24 GB, NVIDIA 615.78.08, i9-13900K, Arch Linux 7.2.15-1-omarchy.
Built ea30380112ac6aebed292627b90f61fff094776f; source checks compared with main ee29dd55b593577ae0a7a6e2f871848ee5e176b4. The head is now d550ea55: the same eleven commits rebased onto main 51da0464 (a range-diff marks all eleven identical). I did not rebuild for the rebase.

The Linux windowless startup crash is gone. Nine starts on this head reached the copied Kokiri Forest save without a crash, fatal error, device loss or kernel driver fault. I captured the title, the loaded save and the Graphics rows. The first start logs:

oe: output resolution 2048x1152 (the game's)
vk: the Output resolution's sizes: 6 (the screen's modes, with the common sizes of their shapes, and the game's own); shapes 16:9, 32:9
vk: no window: presents render offscreen (1920x1080)

That last size is the fixed offscreen extent, not a detected monitor or the chosen output. SDL3 loads later for controller support; there is still no video desktop here.

With the screen unknown, Aspect ratio offers 16:9, 32:9 and Monitor's shape. The outputs are:

  • 16:9 / Monitor's shape: 1920x1080, 2048x1152 (game's), 2560x1440, 3840x2160, 5120x2880.
  • 32:9: 5120x1440.

I selected all six sizes and started a new process at each, checking the output log and same-sized captures. Returning to the starting shape restored the starting size. A menu-selected 1920x1080 survived the next start, with that size in the log and menu and no pending restart notice. The 32:9 start logged picture 5120x1440, scene 3840x1080, camera ratio 3.5556, HUD and movies in the middle 50.0%.

Authored mode lists:

HOS_DISPLAY_MODES Sizes reached in the menu Applied
1280x720,1600x900,1920x1080 1280x720, 1600x896 (the authored 1600x900, rounded down to 8 as the description says), 1920x1080, 2048x1152, 2560x1440, 3200x1800, 3840x2160, 5120x2880 1920x1080
2560x1080,3440x1440,3840x1600,5120x2160 2560x1080, 3440x1440, 3840x1600, 5120x2160 under 21:9; 2048x1152 under 16:9 2560x1080

The 21:9 start logged picture 2560x1080, scene 1920x810, camera ratio 2.3704, HUD and movies in the middle 75.0%; the capture shows the wider view and centred HUD. Larger values in that menu run were selected, not all applied.

An existing custom setting: main 46780503 wrote an options file containing output_res=2400x1600, ultrawide=1. This head read the identical file as 3:2 / 2400x1600, retained the size, and showed the “Your own size” hint without a pending restart. Its boot line says picture 2400x1600, scene 1800x1200, camera ratio 1.5000.

Pictures (windowless captures from this PC, labelled):

A windowless start at the title; the saved 1920x1080 after a restart; the menu with no pending restart; a custom 2400x1600 written by main, read as 3:2

The choices with the screen unknown: Monitor's shape, 32:9 and 16:9 with their sizes

The same spot after a restart at each of the six sizes; 5120x1440 keeps the HUD in the middle 16:9

An authored 16:9 mode list: the eight sizes offered (1600x900 appears as 1600x896, the rounding down to 8 the description states)

An authored 21:9 mode list: its four sizes, and the game's own under Monitor's shape

2560x1080 applied from the authored list: the wider view, the HUD in the middle

Evidence limits: neither authored list supplies a monitor's size, so neither produces a (monitor's) or (native) mark on windowless Linux. Both retain the separate Monitor's shape choice. Also, the unknown-screen fallback really is the old six sizes: the log's generic “screen's modes, with the common sizes” wording does not describe that case literally. Capture dimensions alone are not a source-texture measurement; the output/picture logs are included for that reason.

Checks: all eight changed/new tests pass with GCC 16.2.1 and Clang 23.1.3. Against main, two stand-in updates pass; six fail: the SDL fixture actually faults without the guard, the section check detects the old layout, and four fixtures stop at the absent new header/extraction anchors. Seven C/C++ fixtures pass Windows-target syntax checking, not Windows execution. No full-suite rerun. One virtual-core escape occurred in the heavily loaded first start; these runs make no performance claim.

Not tested: a real window on this head, real ultrawide or other monitor shapes, native marks from a real desktop, multi-monitor/DPI/hotplug changes, fullscreen/window resizing, Windows runtime, handheld mode, or other upscaler/frame-generation combinations.

@mooki000

Copy link
Copy Markdown
Contributor

Follow-up: one run in a real window, for the mark the windowless test could not show.

The real-window follow-up also passes on this monitor: Arch Linux, Hyprland/Wayland, RTX 4090 24 GB, NVIDIA 615.78.08, i9-13900K; 1920x1080 at scale 1.25. Same build ea303801 as above, not a new build of the patch-identical d550ea55 rebase.

One process, 118.2 seconds total. The Graphics menu's own state reports 16:9 (monitor's) and 1920x1080 (native). I stepped the 16:9 outputs through 1280x720, 1920x1080, 2048x1152, 2560x1440, 3200x1800, 3840x2160 and 5120x2880, then selected 32:9 / 3840x1080 and returned to the marked 16:9 / 1920x1080 pair. The larger choices were pending settings, not applied during this process; I did not walk every 32:9 size.

boot: widescreen: a 1.7778 screen is 16:9: the game's own picture
vk: the Output resolution's sizes: 9 (the screen's modes, with the common sizes of their shapes, and the game's own); shapes 16:9, 32:9
vk: swapchain 1920x1080, 4 images, mailbox (V-Sync Auto)

The window was 1536x864 logical pixels; the source picture, content and swapchain were all 1920x1080. Thus the native mark uses the physical size, not the scaled logical window size. No crash, device loss or driver fault; the window did not take focus. No performance claim.

I inspected two 1920x1080 captures made by the game itself. They show the title picture, not the Insert overlay: the marked labels above come from the real menu's state and log, not a desktop screenshot. The first capture has the title over the ranch; the later one has the title over a black background.

Still not tested: other physical monitor shapes, multiple monitors, monitor/DPI/resolution changes, moving or resizing the window, fullscreen transitions, or Windows.

@nullifyshot

Copy link
Copy Markdown
Contributor Author

Thanks, mooki000, for both Linux runs: windowless on the fixed head, and the real window with the "(monitor's)" and "(native)" marks at 125% scaling. Thanks too, Joey-Magnus, for the merge check and the review.

On the two notes for the maintainers:

  • Saved non-16:9 sizes now set the picture's shape: this is intended, and the description says so ("A size that isn't 16:9 sets the picture's shape"). Someone who saved 2560x1080 with 16:9 gets the wider view instead of a stretched one after updating.
  • MKWVK_API_VERSION 20: if feat(menu): text fields in the Insert menu, and a Custom output size typed in it #2594 (or another of the PRs that took 20) merges first, I'll rebase this one and take the next number, so the other PRs don't have to change.

nullifyshot and others added 11 commits November 12, 2026 11:26
…display modes

The Output resolution row offered six fixed sizes, and the Aspect ratio row (NotRexed#2119) only 16:9 or the monitor's shape, so a
21:9, 16:10 or 4:3 size the screen has needed a hand-written output_res. The two rows now list what the screen offers:

- Aspect ratio: 16:9, Monitor's shape (the default, its shape named), then the other shapes of the screen's display modes
  (5:4, 4:3, 16:10, 21:9, 32:9...). It sits right above the Output resolution, whose sizes it chooses.
- Output resolution: the sizes of that shape (each side rounded down to 8, those the game accepts), the screen's own
  marked native, and the game's own 2048x1152 at 16:9. Choosing a shape takes the screen's own size when it has it, else
  the largest no taller than the screen.
- A size more than 1 % off 16:9 sets the picture's shape (cameras, the HUD in the middle 16:9), over HOS_ASPECT and
  ultrawide=, in host/hos_main.c and the menu alike (hos_output_own_shape); ultrawide= shapes a 16:9 size, as before.
- ultrawide= stays 0 or 1 with main's default and its move for older files; another shape is output_res's own. Old
  saved output numbers still load (kOutputs). Where the modes are not known (Linux), the sizes offered before.
  HOS_DISPLAY_MODES=<w>x<h>,... stands in for the screen's modes.
- The control bridge's option_set output_res still reaches every size: one of another shape moves the Aspect ratio
  first, as the arrows keep to one shape.

gpu/vk/display_modes.h holds the rules as plain code; tests/test_display_modes.py checks them. The menu's tests that cut
out the output code follow the new numbering, test_menu_sections has the Aspect ratio above the Output resolution, and
test_menu_setting_walk walks to a size of another shape through the Aspect ratio.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ked; common sizes for each

The Aspect ratio listed 16:9 and Monitor's shape as two values even where they were the same shape (16:9 and "Monitor's
shape (16:9)" on a 16:9 screen). It is now one list of the shapes offered, narrowest first, the one that is the monitor's
own marked "(monitor's)": 16:9 on a 1080p screen, 21:9 on a 3440x1440 one, 16:10 on a 1280x800 one. ultrawide= is still
saved: 1 for the monitor's own shape, else 0, so main's default, its move for older files and the launcher's setting keep
working; where the monitor's shape is not known or not offered (Linux, a portrait screen) it is saved as read.

Each shape the screen has also gets the common sizes the screen does not list (display_modes.h common_sizes): 1440p, 4K
and 5K at 16:9 on a 1080p screen, 16:10's, 4:3's, 3:2's, 21:9's and 32:9's. The screen's own size is always among the
modes, and one past the game's size limit (a 7680x2160 32:9 screen) adds its shape at the most pixels a picture of
another shape takes. "(native)" compares the screen's size rounded to 8 as the game takes it (1366x768: 1360x768).
Choosing a shape takes the screen's own size when it has it, else the one whose height is nearest the screen's (3:2 on a
1080p screen: 1920x1280, not 720x480).

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tions (_CRT_SECURE_NO_WARNINGS)

CI's windows-2022 runner stopped on getenv and sscanf marked deprecated, an error under -Werror, as the other fixtures that include host/hos_wide_size.h define it.

Assisted-by: Claude Opus 5.5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The command line defines it too: redefined under -Werror. Guarded, so either is enough.

Assisted-by: Claude Opus 5.5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nown, the bridge to 16:9, HOS_OUTPUT_RES kept out

- Where the monitor's shape is not known (Linux: the menu has no screen size) or not offered (a portrait screen), the row
  has Monitor's shape as a value of its own after the shapes, as on main, and saves ultrawide= from it. Before, ultrawide=
  was saved as read there, so 16:9 could not be chosen on Linux or the Steam Deck.
- The control bridge's option_set output_res to a 16:9 size from the monitor's 21:9 (or any other shape) moves the row to
  16:9 first (aspect_for_choice), not back to the monitor's shape, which left the walk inside 21:9 and refused (-2).
- A run whose Output resolution HOS_OUTPUT_RES holds saves the player's ultrawide= as read while the row is as it started,
  not the shape of the environment's size.
- A 16:9 size kept from before at the monitor's shape (ultrawide=1) steps into the monitor's own sizes (step_shape), the
  list the row names, instead of the 16:9 list under the monitor's label.
- The shape list is made once per player's size, not at each call; last_output() (custom_index()) and the unused
  hos_output_is_surround are gone.

test_output_resolution checks Monitor's shape as a value, the bridge's way to 16:9 (aspect_for_choice) and the steps of
a 16:9 size at the monitor's shape; test_menu_setting_walk checks menu_setting_set calls aspect_for_choice.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d a resolution changed while playing

The Aspect ratio's "(monitor's)" and the Output resolution's "(native)" were the primary monitor's, read once, and Linux had
no screen size, so the row there showed Monitor's shape as a value of its own.

- The marks, "(native)" and the sizes listed are the monitor the game's window is on (MonitorFromWindow; its own display
  modes, EnumDisplaySettingsW with its device), the primary's before there is a window.
- Followed while playing (every 30 presents): the window moved to another monitor, or the desktop's resolution changed, that
  screen's sizes not offered yet join the Output resolution's choices after the player's own, so the choices' numbers keep
  their sizes; the Aspect ratio row, the run's start value and the restart question's keep their shapes.
- ultrawide= is saved against the host's screen (the primary, whose shape host/hos_main.c gives a 16:9 size at the start):
  1 for its shape, so the next start draws the shape picked even when the window is on another monitor. The host's screen
  and its shape are always among the sizes, so a 16:9 size kept at ultrawide=1 shows the shape it is drawn at.
- Linux: MkwVkHost.screen_size (MKWVK_API_VERSION 20, main took 19 for the ocarina notes), SDL's primary desktop size, as the host shapes the picture from;
  with it the sizes offered before, the screen's own and the common sizes of their shapes. A portrait screen still has
  Monitor's shape as a value: no shape the game draws is its.

test_output_resolution: the window on a 16:9 monitor with a 32:9 primary (marked 16:9, saved for 32:9, a 16:9 size widened
to it), and a size found while running (after the player's own, picked and marked native at its screen).

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ape its size, the game's own as drawn

From a test on a 5120x2160 primary (NotRexed#2566's comment):
- Stepping the Aspect ratio away from the shape the game started with and back took that shape's own pick (5120x2160) and
  asked to restart, though nothing differed from the start. Back at the start's shape it is now the size the game started
  with (output_for_aspect, output_started).
- The game's own size showed its 16:9 2048x1152 in the 21:9 list, though ultrawide=1 draws it at the host's shape: it now
  shows that picture (2728x1152 at a 5120x2160 screen's 21:9), as the game draws it.
- The sizes log said "no other" where no size of the player's own was read, which read as no common sizes: it now says what
  the list holds.

test_output_resolution: that screen's 21:9 modes, a first start at 21:9 (monitor's) with the game's own size: the arrows walk
the 21:9 modes up to 5120x2160 (native), and 16:9 then back keeps the game's own.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…u's 13 languages

NotRexed#1864's tables had this branch's earlier texts (the Aspect ratio's help, the Output resolution's "The sharpest on a ...
screen" lines), which the rows no longer show. Those seven are gone from each table; the rows' texts now are there:
the Aspect ratio's help and its four shapes' lines, the Output resolution's own-size, larger and smaller lines, and
"%s (monitor's)". tx_ultrawide prints the mark from that format, so vk_menu_i18n.cpp's match_format translates
"21:9 (monitor's)" with the shape kept as it is.

Machine-made like the rest of the tables, with each table's own words for the Output resolution, the HUD and the
render targets. test_menu_i18n still fails on main's three texts the menu no longer has (the Controls page's
gamepad line, the mesh shader line, the button prompts' line); this branch adds none.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…without SDL, not a call through an empty slot

The Insert menu asks the host for the main screen's size at startup and while the game runs (MkwVkHost.screen_size, this
PR's), which on Linux is hos_sdl_desktop_size. A windowless start (HOS_HEADLESS) loads no SDL, so version is 0 and the
function went on to SDL2's branch and called GetDesktopDisplayMode's empty slot: exit 139 before the first frame
(reported on NotRexed#2566 by mooki000, Arch, Hyprland). With no SDL loaded it now says the screen is unknown, and the menu
lists the sizes it does without one. Windows takes GetSystemMetrics and was not affected.

tests/test_sdl_desktop_size.py cuts the function from hos_sdl.c and runs it against stand-ins: no SDL (unknown, which
faulted at address 0 before), SDL3's mode in pixels (1536x864 at a density of 1.25 is 1920x1080), SDL3 with no mode,
and SDL2's mode as given or failed.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…them, rounded and with 21:9's common sizes

The 5120x2160 case filled the list with six sizes directly. NotRexed#2566's retest on that screen walked eight: 3008x1264 (its
3012x1271 mode rounded down to 8) and 3840x1600 (21:9's common size) as well. The case now takes the screen's modes
through display_modes.h offered and with_common, as the list does, and walks the same eight sizes the retest saw.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… shows

At a shape the host widens 16:9 sizes to, the game's own choice shows what the game draws (2728x1152 at a 5120x2160
screen's 21:9) but was walked at its stored 2048x1152, so it came before 2560x1080 and the first Right went down a size
(NotRexed#2566's retest). step_output_choice now orders a shape's choices by picture_for, the size each row shows, and the game's
own is in the walk of the shape it is drawn at, reached from either side: 2560x1080, 2728x1152 (game's), 3008x1264, ...
At 32:9 a kept 1920x1080 (drawn 3840x1080) and the game's own (4096x1152) come before 5120x1440 the same way. What is
saved is the choice, as before (output_res=0 for the game's own); handheld draws nothing wider and keeps the old order.

test_output_resolution walks the 21:9 screen's nine choices up and back down, and the 32:9 one; test_menu_setting_walk's
stand-ins gain picture_for (each choice's own size there).

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nullifyshot

Copy link
Copy Markdown
Contributor Author

Windows, real window: passes. RTX 5080, Windows 11 (NVIDIA 621.24), one 1920x1080 screen. Built from head d49f1632. Three windowed starts and one headless; the Insert menu was driven with RX_VK_MENU_SCRIPT, and each row's text was read over the control bridge (option get). The window was captured with PrintWindow, which shows the menu; the game's own shot leaves it out.

  • Start: boot: widescreen: a 1.7778 screen is 16:9: the game's own picture, vk: the Output resolution's sizes: 33 (the screen's modes, with the common sizes of their shapes, and the game's own); shapes 5:4, 4:3, 3:2, 25:16, 16:10, 5:3, 16:9.
  • Marks: Aspect ratio 16:9 (monitor's); Output resolution 2048x1152 (game's) and 1920x1080 (native), with the "your screen's own size" hint.
  • 16:9 sizes: 1280x720, 1360x768, 1600x896, 1920x1080 (native), 2048x1152 (game's), 2560x1440, 3200x1800, 3840x2160, 5120x2880. The arrows stop at both ends.
  • Another shape: Aspect ratio left to 5:3 (1280x768), then 16:10, which picked 1680x1048, the size closest to the screen's height. 16:10's sizes stepped 1680x1048, 1920x1200, 2560x1600. Going back to 16:9 (monitor's) brought back 2048x1152 (game's). The footer said "Restart needed: Aspect ratio, Output resolution".
  • Fullscreen row: On gave display: fullscreen (F11 for a window) and a 1920x1080 swapchain; Off gave display: windowed and a 1280x720 swapchain.
  • Move and resize: the window was moved, then resized from outside (SetWindowPos, not activated) to a 1600x900 client, then 960x540, then back to 1280x720. Each time the swapchain followed (vk: swapchain 1600x900 ..., 960x540, 1280x720) and the menu laid itself out at that size. Moving it logged nothing, as expected with one screen (the window's screen is appears only when the screen changes).
  • No crash, device loss or driver fault in any run.

A crash in the build's shader step (not reproduced). When this head was built, the build's --prepare-shaders run stopped with 0xC0000005, right after the version line and before the Vulkan device line. Started again by hand a few minutes later, it went through to @@done shaders. Three more prepare runs, the headless start and the windowed starts all passed too. This PC's NVIDIA driver changed between the morning's build (621.14) and these runs (621.24), and I couldn't find where the crash happened. Windows has no twin of the Linux windowless crash: on Windows the screen's size and modes come from GetSystemMetrics and EnumDisplaySettingsW, never from SDL. The headless log shows the sizes line with no SDL loaded.

Not covered: two screens or moving the window to another one, display scaling other than this screen's, a desktop resolution change while running, starting with a new size after a restart (Restart now wasn't pressed), and HDR.

hckrman101 added 2 commits November 12, 2026 12:03
…rface, not that its version is 19

The check pinned MKWVK_API_VERSION to 19, so any later interface change (this branch's
screen_size, version 20) failed it. Skip opening is an option id; what the check means is
that it added nothing to MkwVkHost or MkwVkRenderer.
@hckrman101
hckrman101 merged commit 511198c into NotRexed:main Nov 12, 2026
8 of 10 checks passed
polackangry added a commit to polackangry/Hookshot that referenced this pull request Nov 12, 2026
NotRexed#2566 added MkwVkHost.screen_size as API version 20, so this branch's
take_bridge_key and shot_window move to version 21: take_bridge_key after
screen_size, in rx_backend.c's initializer too. tests/test_opening_skip.py
takes main's own fix (no version number in it). docs/tested-configurations.md:
both sides' rows kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Joey-Magnus pushed a commit to Joey-Magnus/Hookshot that referenced this pull request Nov 12, 2026
…NotRexed#2566's choices

NotRexed#2566 made the Output resolution's choices the screen's resolutions and the common sizes, so a choice's
number no longer names a fixed size: Auto's index into the old list (1 for 2560x1440) picked whatever
stood there. Auto now chooses a size, the screen's own where the tier carries its pixels (up to the
game's 2048x1152 any tier, up to 2560x1600 Balanced, up to 4K's pixels High, past them Ultra), and the
menu finds it among its choices; a size it does not offer is the game's own (logged), never the
player's custom size. Screens smaller than the game's own (1080p, 1920x1200, a Steam Deck's 1280x800)
now get their own size at any tier.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
elkarbeenus pushed a commit to elkarbeenus/LakuenRecompBuilder that referenced this pull request Nov 12, 2026
….3.0

Fewer idle threads spinning (NotRexed#2709), bounded waits for shaders still translating (NotRexed#2586), the first start after a
preparation warms the pipeline cache (NotRexed#2865, NotRexed#2869), native float atomics (NotRexed#2306), the 97% squeeze past the allowance
(NotRexed#2585), output choices from the screen's modes (NotRexed#2566), FSR 4 twice as fast on RDNA 2 (NotRexed#2798), the import cap
(NotRexed#2839) and the final NotRexed#2825 (mirror trims settle). Kept: the fork's play() returning the game for Steam's wait (now
through start_scoped's process), the handheld texture caps, the RDNA2 detection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7fdTPXbwDRohew9qanvbp
dazemc added a commit to dazemc/Hookshot-rs that referenced this pull request Nov 12, 2026
…e ownership, Deck preparation and segment heap

Port the six display/menu and builder extras missing from this fork, adapted to its sections, HDR, bug report,
gamepad/ocarina, keyboard and saved options:

- Aspect ratio and Output resolution from the screen's display modes (NotRexed#2566): display_modes.h, the host's
  screen_size (API 20), HOS_DISPLAY_MODES, old numeric output_res values still read, ultrawide= kept 0/1.
- Graphics > Detail > Texture detail (NotRexed#2557): Auto/Full/Medium/Low, mapped in vk_texture.cpp; RX_VK_TEX_* still win.
- Gameplay > Skip opening (NotRexed#2827): host/hos_main.c hos_oot_opening, the Python and Rust lift patches, option 52,
  HOS_SKIP_OPENING, off by default.
- Update ownership (NotRexed#2926): the game no longer checks for updates; the folder's launcher does. A game started
  without its launcher logs one line and never waits on the network. builder_args and WinHTTP are gone.
- Steam Deck shader preparation (NotRexed#2800): nx2/steamdeck_shaders.py and make_game.py --steamdeck, opt-in and
  game-free; the renderer's batch/portable-cache hooks prepare against the Deck driver.
- Segment heap (NotRexed#2895): prepare_workers.h, prepare_cpus, and heapType SegmentHeap in both manifests.

Game-free tests compile the display-mode rules, texture-detail mapping, skip-opening host function, update
ownership, prepare flags and no-game-data checks, and the segment-heap worker count. cargo test --workspace passes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants