Skip to content

fixed like everything on the readme also added some stuff like loader.bat - #2017

Open
mimic-wasm wants to merge 10 commits into
NotRexed:mainfrom
mimic-wasm:mimic-wasm-patch-1
Open

mimic-wasm wants to merge 10 commits into
NotRexed:mainfrom
mimic-wasm:mimic-wasm-patch-1

Conversation

@mimic-wasm

Copy link
Copy Markdown

Improve HUD Aspect Ratio, Graphics Settings and Performance

Summary

This PR introduces several graphics, HUD, and performance improvements to Hookshot.

Changes

HUD

  • Fix HUD stretching on narrower aspect ratios.
  • Preserve 16:9 HUD proportions on 4:3 and 16:10 displays.
  • Maintain proper HUD scaling on ultrawide displays.

Graphics

  • Add a Native 3D Resolution option.
  • Move Texture Streaming Cache into Graphics settings.
  • Add a PS3-style (720p) quality preset.

PS3-style preset

  • 1920×1080 output resolution.
  • Approximately 1280×720 3D rendering.
  • Lanczos upscaling.
  • Reduced sharpness and anisotropic filtering.
  • Native 3D resolution enabled.
  • Texture streaming cache enabled.

Performance

  • Expose texture streaming cache in the Graphics menu.
  • Allow players to use lower rendering resolutions.
  • Preserve frame-generation settings when changing quality presets.

Tests

  • Update widescreen shape tests.
  • Update frame-generation preset tests.
  • Add dedicated HUD aspect-ratio tests.

Expected Results

  • Correct HUD proportions across different display aspect ratios.
  • More control over 3D image sharpness.
  • An additional lower-resolution graphics preset.
  • Potentially fewer texture-streaming stalls when entering new areas.

Testing

The four targeted Python tests passed.

Full hardware validation is still needed.

loader.bat code:

@echo off
set RX_VK_GPU_UNSWIZZLE=1
set RX_VK_BATCH=1
hookshot.exe

@NotRexed NotRexed left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this. The narrow-screen HUD fix is a good catch, and it's already been taken into #2015 (the oot_wide.py vertical squeeze, the hos_main.c lines, and your widescreen tests), with you credited as co-author. It's being checked in game in 4:3 and 16:10 windows before it merges.

The rest can't go in as it is:

  • loader.bat and hookshot_env.txt at the repo root: these look like your local setup. The hookshot_env.txt sets RX_VK_NOOPT=1, a debug switch that turns the game code's optimizer off. Neither belongs in the repository.
  • "Native 3D resolution" defaulting to on: hos_ini_option("native_3d_resolution", 1) changes every player's default from the game's 0.8 scene scale to 1.0, about 25% more pixels to draw, which costs fps for everyone. Defaulting to 0 would keep today's behaviour (HOS_SCENE_NATIVE already turns it on).
  • The "PS3-style (720p)" preset: its help text mentions "GTA V assets", which has nothing to do with this project. Presets are tuned per VRAM size, so a new one needs a reason and measurements.
  • Moving Sampler cache from Debug to Graphics: fine in principle, but it's a separate change. It's easier to review on its own.
  • The description mentions updated frame-generation and widescreen tests, but this branch doesn't include them.

If you'd like to continue: one PR per change, without the local files, each with how you tested it (GPU, resolution, what you saw). The HUD part needs nothing more from you, since #2015 carries it.

🤖 Generated with Claude Code

@mimic-wasm mimic-wasm closed this Nov 10, 2026
@mimic-wasm mimic-wasm reopened this Nov 10, 2026

@hckrman101 hckrman101 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked this one for anything risky first, since the title doesn't match the diff (nothing in the README changes). It's clean: nothing downloads or runs remote code, there are no binaries or obfuscated content, no workflow or release/update URL changes, and nothing touches credentials. loader.bat only sets two env vars and starts the local hookshot.exe.

NotRexed's review covers the rest, and I agree with all of it. The HUD part is already carried by #2015. loader.bat and hookshot_env.txt are local setup (RX_VK_NOOPT=1 turns the optimizer off). Native 3D resolution defaulting to on changes everyone's default. The PS3 preset's hint mentions GTA V and the preset has no measurements behind it. The Sampler cache move should be its own PR, and the tests the description mentions aren't in the branch.

Two more things:

  • The vertical squeeze writes 16 bytes starting at vreg[4] + 4. Each vreg is 16 bytes (uint64_t vreg[32][2]), so that write scales lanes 1-3 of Q4 and lane 0 of Q5. If the row is Q4 lanes 0-3 (the way the horizontal path scales all of Q1), the offset should be 0. If it really is lanes 1-3, the copy should be 12 bytes. #2015 has the same line, so it's worth checking there before it merges (inline note).
  • The branch was made by re-uploading whole files over an older base, so GitHub shows it as conflicting with main, and only the commit-title check ran. A fresh branch from current main per change would sort both out.

The test_env_file.py change (SDL_AUDIO_DRIVER) is fine: SDL_ names already pass the env-file filter.

Comment thread nx2/oot_wide.py
"if (!(_kb & hos_wide_keep_mask)) { float _row[4]; "
"if (_qx > 0.0f && _qx < 1.0f) { memcpy(_row, c->vreg[1], 16); "
"for (int _k = 0; _k < 4; _k++) _row[_k] *= _qx; memcpy(c->vreg[1], _row, 16); } "
"else if (_qy > 0.0f && _qy < 1.0f) { memcpy(_row, (const uint8_t *)c->vreg[4] + 4, 16); "

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c->vreg[4] is one 16-byte Q register, so a 16-byte copy from + 4 reads and writes the first float of Q5 too. Should this be c->vreg[4] with 16 bytes (the whole row, like the Q1 path), or 12 bytes from + 4? The same line is in #2015.

Comment thread hookshot_env.txt
@@ -0,0 +1,2 @@
RX_VK_NOOPT=1

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Local debug settings (optimizer off, checkpoints on). Please drop this from the PR, as NotRexed said.

Comment thread loader.bat
@@ -0,0 +1,4 @@
@echo off

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Harmless (it sets two env vars and starts the local exe), but it's a personal launcher. Please drop it too. hookshot_env.txt beside the exe already does the same job.

@hckrman101

Copy link
Copy Markdown
Collaborator

Heads-up: this conflicts with main now. Could you rebase onto main and resolve the conflicts? Thanks!

@Joey-Magnus Joey-Magnus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd close this one. The useful part, the vertical HUD squeeze in nx2/oot_wide.py and host/hos_main.c, is carried by #2015 with you as co-author. #2015 is still open on main, and the 16-byte write at vreg[4] + 4 hckrman101 flagged should be checked there.

Nothing else here can go in as it is, and there's been no update since NotRexed's review yesterday:

  • loader.bat and hookshot_env.txt at the repo root are local setup. The env file turns on RX_VK_NOOPT=1, a debug switch.
  • hos_ini_option("native_3d_resolution", 1) changes every player's scene scale from 0.8 to 1.0, about 25% more pixels to draw.
  • The PS3 preset has no measurements behind it, and its hint mentions GTA V.
  • Moving Sampler cache to Graphics is a separate change.
  • hos_main.c still reads HOS_SCENE_NATIVE with atoi, where main now uses env_on (#2042).

The branch also conflicts with main in vk_menu.cpp and hos_main.c, and the title doesn't describe the change. If you want to pursue any of these, a fresh branch from main per change, with how you tested it, is the way forward.

hckrman101 pushed a commit that referenced this pull request Nov 11, 2026
The Graphics tab is one list of 24 settings, with the window, HDR,
upscaling, frame generation and GPU options mixed
together, and about ten more are on their way in open PRs. This puts its
rows under section titles, so the upscaler, frame
generation or HDR can be found without scrolling the whole list. It is
the first step of a menu organization laid out below
for discussion.

**What changed**
- The Graphics rows in six sections, under heading rows like the Debug
tab's Developer (a gold title, never selected,
  nothing to click):
  - Quality preset (first: it sets rows in every section)
- **Resolution and upscaling:** Output resolution, Profile, Upscaler,
DLSS model, Render resolution, Sharpness
- **Frame generation and latency:** Frame generation, Frame pacing, Game
frame rate cap, NVIDIA Reflex, AMD Anti-Lag 2
- **Screen:** Fullscreen, V-Sync, Window scaling filter, Aspect ratio
(#2119), Ultrawide menus
- **HDR:** HDR, HDR paper white, HDR peak brightness, HDR contrast
(#2342), HDR tone mapper (#2481)
  - **Detail:** Anisotropic filtering
- **GPU and memory:** GPU device, VRAM budget (#1859), Mesh shaders
(Robust buffers is on Debug ▸ Developer since #2042)
- Moves only: every row's definition is unchanged, word for word; no row
is renamed and no value or saved key changes, so
options files carry over, and #1864's tables (keyed by the English text)
still find every row. They need the six
  headings.
- No new drawing or input code: the menu already draws heading rows on
any tab, and the keys, the pad and the mouse step
  over them.
- `readme.md`: a sentence on the sections, and the option table in the
new order. (Ultrawide menus and Mesh shaders have
no line yet; #2105 adds them.) The **Frame generation by** row from
#2118 gets its line in the table here too: main's
readme has none yet. So do #1859's **VRAM budget** (under GPU and
memory) and #2342's **HDR contrast** (under HDR).
- `tests/test_upscaler_rows.py`: its order list follows the picture's
path (output, upscaler, render size, sharpening,
then the frame rows, then the window). New
`tests/test_menu_sections.py`: the Graphics sections and which rows they
hold,
and on every tab no section that `row_shown` could leave empty (a title
over nothing on a GPU without Reflex, say).

**The plan this is step 1 of (for discussion)**

Each tab answers one question; a section groups the rows you set
together; a row that depends on another follows it; vendor
rows sit beside their counterpart and hide where they can't run (no
vendor sections, so nothing is left empty on AMD); rows
to touch only when something is wrong go last; moves only, no renames.

| Tab | Holds | Sections |
|---|---|---|
| **Game** (was Gameplay; first, where the menu opens) | how the game
behaves and reads, and Restart and Quit, as a pause menu | flat; Restart
and Quit last |
| Graphics | how the picture is made, and what it costs | Quality preset
· Resolution and upscaling · Frame generation and latency · Detail · GPU
and memory |
| **Display** (new) | how it gets to your screen, and what is drawn over
it | Screen · HDR · Overlays (FPS counter, Menu size, from Game) |
| Audio | sound out and in | + Microphone (from Game: it picks the input
device) |
| Controls | how you play | Camera · Controller · Buttons (optional) |
| Debug | tools and developer switches | Robust buffers in Developer
(#2042, merged) |

Next PRs, one topic each: (2) a Display tab, taking the Screen and HDR
sections over whole and adding Overlays; (3) the
Gameplay tab titled Game, first in the strip, where the menu opens; (4)
Microphone to Audio; (5) optional, sections on
Controls. If a sixth tab is a no, this PR stands on its own.

Open questions:
1. A sixth tab (Display)?
2. V-Sync on Display (the PC convention) or with frame generation (it
changes with it)?
3. Sharpness with the upscaling rows (where players look for it) or with
the window filter (where it runs)?
4. DLSS 5 (#1590) and #1834's Neural rows as a page opened from a
Graphics row, like Motion, rather than a seventh tab?

<details><summary>Where open PRs' rows would go</summary>

- Resolution and upscaling: Sharpening method (#1979), DLSS 5 page
(#1590), Native 3D resolution (#2017)
- Frame generation and latency: Frame generation by (#2118, merged: in
this section now), Frame generation method (#1834)
- Detail: Shadow resolution (#1892), Screen filter and Filter strength
(#1488)
- GPU and memory: Texture streaming cache (#2017), Refresh memory
(#888); VRAM budget (#1859, merged) is in this section now
- Game (was Gameplay): Game language and Menu language (#1864), Skip
title screen (#1560), Amiibo (#1521)
- Controls: Camera speed (#1945)
- #2042 (merged) moved Robust buffers to Debug ▸ Developer.
- #2105: its readme check would read the heading rows as rows; it needs
to skip `{TAB_..., "...", nullptr, 0, 0, 0, ...,
  true}` headings, or this PR adds that if it lands first.

Whichever PR lands second moves one row on rebase; happy to do it for
anyone.

</details>

**Testing**
- `tests/run_all.py` on Windows 11 (llvm-mingw clang, 8 at once) after
merging main at 2dfe901 (with #2119's Aspect ratio, #2481's HDR tone
mapper, #2118's Frame generation by,
#2342's HDR contrast and #1859's VRAM budget): 422 passed, 33 skipped, 2
failed, both outside this PR:
`test_vram_budget_row.py` (fails the same on main's own sources here)
and `test_portable_builder_startup.py` (its
`dotnet publish` needs packages this PC does not have). A build of the
branch compiles. All 81 of main's rows keep
main's definitions word for word; the only additions are the six
headings.
`test_menu_sections.py` fails on main as it stands (no sections) and
passes here; a layout with a section of Reflex and
  Anti-Lag 2 alone fails it.
- A build of this branch (Windows 11, RTX 5090), headless with scripted
menu keys at Small, Medium and Large: 12 Downs
from the Quality preset land on V-Sync and 13 Ups come back past it to
the last row, so every heading is stepped over
both ways and Up from the first row wraps to the last; the help box
always shows the selected row (at the first head,
when Robust buffers was the last row). Again at this head (25feb16,
after #2042, #1859 and #2119): Up from the Quality preset
wraps to Mesh shaders, the last row now, under VRAM budget (the bottom
screenshot).

**Not tested**: in a window with a pad, the mouse wheel and a click just
under a heading (the headless runs drive
the keys); values kept across a restart (no row's saved key changes);
AMD and Intel (their rows hide through `row_shown` as before; the new
check makes sure no section can end up
empty), Linux.

**Screenshots**

The Graphics tab at 1920x1080, Medium menu size: the top, then scrolled
with the keys to V-Sync and to the last row
(the selection steps over every heading; Up from the first row wraps to
the last row). The bottom one is retaken at this
head (25feb16, a 16:9 picture: `HOS_ASPECT=1.7778`, as on a 16:9
monitor); the others are from the first head (634ef65).

![Graphics tab, top: Quality preset, then Resolution and upscaling and
Frame generation and
latency](https://raw.githubusercontent.com/pmwork-personal/Hookshot-pr/pr-screenshots/menu-sections/graphics-sections-medium-1.webp)

![Graphics tab, middle: Frame generation and latency, then Screen,
V-Sync
selected](https://raw.githubusercontent.com/pmwork-personal/Hookshot-pr/pr-screenshots/menu-sections/graphics-sections-medium-2.webp)

![Graphics tab, bottom: Screen with Aspect ratio, HDR, Detail, then GPU
and memory with GPU device, VRAM budget and Mesh shaders, Mesh shaders
selected](https://raw.githubusercontent.com/pmwork-personal/Hookshot-pr/pr-screenshots/menu-sections/graphics-sections-medium-3c.webp)

Small and Large:

![Graphics tab at Small menu
size](https://raw.githubusercontent.com/pmwork-personal/Hookshot-pr/pr-screenshots/menu-sections/graphics-sections-small.webp)

![Graphics tab at Large menu
size](https://raw.githubusercontent.com/pmwork-personal/Hookshot-pr/pr-screenshots/menu-sections/graphics-sections-large.webp)

_Taken from headless runs of this branch (`HOS_HEADLESS=1`,
`RX_VK_SHOT_MENU=1`, the keys from `RX_VK_MENU_SCRIPT`), RTX
5090. Headless, the list never scrolls on main either:
`menu_record_image` leaves `ease_step` at 0, so the build behind
the scrolled shots had one more line there (`ease_step = 1.0f`, hence
"-dirty" in the first head's build label), not part of
this PR.
The windowed menu eases as before._

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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