Skip to content

fix(input): reseed mouse look after camera handover - #2653

Merged
hckrman101 merged 1 commit into
NotRexed:mainfrom
mooki000:fix/mouse-camera-handover
Nov 12, 2026
Merged

hckrman101 merged 1 commit into
NotRexed:mainfrom
mooki000:fix/mouse-camera-handover

Conversation

@mooki000

Copy link
Copy Markdown
Contributor

What this is for: resume Native mouse look from the game's current camera angles after another camera takes over (current main CI). What is measured: the affected game-free check before and after, with GCC 16.2.1 and Clang 23.1.3 selected, plus one strict full-suite run, as recorded below. Not measured: a game run or Windows execution.

Cause

#2617 retains mouse target angles to prevent drift, but the existing inactive-state guard returns without invalidating that target; the pre-existing handover test then applies movement to old yaw 5 instead of current yaw 0 (host/mouse_native.c:120-148, tests/test_mouse_native.py).

The relevant failure in main's CI log is:

AssertionError: 1 != 0 : FAIL line 134: near(getf(YAW), -1.0f) (pitch 10 yaw 4)

What changed

Clear target_ok when the player camera is inactive; keep immediate stick handback and persistent angles while active. Preserve the original failing yaw assertion, exercise changed pitch and yaw on return to both active states, and document the handover in the readme.

How it was tested

Recorded on 2026-11-11, Linux kernel 7.2.15-1-omarchy, base de866017, head 58c817f7 (version and test records).

  • Untouched main a016b7a6: the affected check fails independently in both compiler environments with the diagnostic above; the branch passes independently in both (python -I -B tests/run_all.py --strict --jobs 1 tests/test_mouse_native.py records).
  • Removing only the target invalidation from an isolated copy restores the wrong-yaw failure with both compilers (two mutation records); the original no-drift and stick-handover assertions remain.
  • One full python -I -B tests/run_all.py --strict: 456 passed, 14 failed, 20 skipped in 178 s (linux, 32 at once), load 33.42 → 81.38 (complete suite output).
  • That run's remaining failures are: test_wayland_libdecor_hint.py, test_display_startup_failure.py, test_texel_buffer_ownership.py, test_audio_aux.py, test_audio_biquad.py, test_dlss_checks.py, test_env_on.py, test_framegen_preset.py, test_hdr_encode.py, test_linux_docker_packages.py, test_menu_i18n.py, test_mods_size_table.py, test_readback_part.py, test_rumble_menu.py (complete suite output). The companion fixture, capture-switch, PPA-parser and hint-catalog branches address their separate causes; feat(vk): FSR 3.1 on the chain keeps the game's native HDR highlights #2614 owns the HDR check and is not duplicated here.

Not tested / risks

The executable fixture runs the actual camera function against authored state, but no game, real mouse/controller, Windows or camera-transition playtest was run.

Overlaps

The inspected #2567 first-person changes and #2630 camera-centering restoration do not contain this handover fix and merge cleanly in the recorded comparison.

Assisted-by: GPT-6 Astra
Co-Authored-By: GPT-6 Astra noreply@openai.com

Invalidate the retained angle target when the player camera is inactive. This restores the existing handover contract after NotRexed#2617 without removing persistent angles while active. Cover pitch and yaw when returning to both active states.

Assisted-by: GPT-6 Astra
Co-Authored-By: GPT-6 Astra <noreply@openai.com>

@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.

Thanks, this is the right fix. I traced it on main: the free-look guard clears target_ok just before the slingshot block, the state(4) frame reseeds from yaw 5, and then the state-0 branch returned without dropping that target, so the first frame back turned from 5 instead of the game's 0 (yaw 4, the CI failure). Clearing it in the not-3/4 branch closes that.

What I checked:

  • Every way back from a non-3/4 state now reseeds yaw and pitch from the game's current angles before the frame's motion is added, so there's no jump on the first frame back. Going 3 to 4 or 4 to 3 doesn't touch it (the stick path still reseeds), and a camera that stays in 3/4 the whole time behaves exactly as before; the no-drift checks still cover that.
  • The loop is a real test both times through: on the first pass the stale target would be yaw 5 / pitch 10, on the second -1 / 20.5, and both differ from the 0 / 20 the game sets, so a stale yaw or pitch fails either way back (3 and 4).

One thing for a follow-up, not this PR: the reseed only happens when the hook runs in another state. If the player camera's update stops running altogether (the pause menu, a scene load) and the camera comes back at the same address in state 3 with new angles, target_ok is still 1 and the old target gets written over them. I haven't checked in game whether that happens. If it does, the fix is just as small: reseed when the hook hasn't run within LIVE_NS (read last_hook_ns before it's overwritten).

Python checks are still running; the rest is green.

@hckrman101
hckrman101 merged commit 0ec31ff into NotRexed:main Nov 12, 2026
9 of 13 checks passed
dazemc added a commit to dazemc/Hookshot-rs that referenced this pull request Nov 12, 2026
Upstream NotRexed/Hookshot 0ec31ff (NotRexed#2653): NotRexed#2617 kept the mouse's
target angles to stop the follow camera drifting the view, but the guard
for a camera the mouse does not own returned without invalidating them.
After a first-person aim or another camera, the next player camera
applied the mouse's motion to the old yaw (5) instead of the game's
current one (0).

Ported into host/mouse_native.c: clear target_ok while the camera is in
any state but 3 or 4, so the next player-camera frame seeds yaw and pitch
from the game's current angles. Immediate stick handback and the held
angles while the camera is active are unchanged. readme.md's Mouse
camera entry describes the handover.

Test: tests/mouse_native_test.c now returns from a first-person camera
(state 0) to both 3 and 4 with the same movement, checking the new yaw
(-1) and pitch (20.5) come from the game's current view, and that
hos_mouse_native reports the camera again. built and run by
builder/rust/tests/host_c_fixtures.rs (POSIX only); it skips without a C
compiler. No game, mouse or Windows run was made.

Assisted-by: opencode (DeepSeek V4.1 Flash 1017)
notquiteog added a commit to notquiteog/Hookshot that referenced this pull request Nov 12, 2026
…seeded, V-Sync Auto with DLSS Frame Gen, NotRexed#2746)

Upstream fixed most of what e3f076a fixed here (NotRexed#2648, NotRexed#2651, NotRexed#2652, NotRexed#2653, NotRexed#2654,
NotRexed#2661), so the conflicts are resolved to upstream's versions: its fixtures, its
menu_i18n.h, its mouse_native.c, and its dlss_checks.h with the two-pixel tolerance it
chose and tests. Kept from the fork: the fixtures' framegen_by_pick stand-in, and
vk_texture.cpp's typed min.

Co-Authored-By: Claude Fable 5.2 <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.

2 participants