Skip to content

Native mouse look: turn the player camera from its own update, not a heap search - #1356

Merged
hckrman101 merged 1 commit into
NotRexed:mainfrom
itaskaev2:mouse-camera-hook
Nov 9, 2026
Merged

hckrman101 merged 1 commit into
NotRexed:mainfrom
itaskaev2:mouse-camera-hook

Conversation

@itaskaev2

Copy link
Copy Markdown
Contributor

The Insert menu's Mouse camera: Native turned the camera by finding its controller with a scan of the heap (about a second over 2 GB, on a thread of its own, again after every scene change; the mouse was the right stick until a scan found it) and wrote the angles from the thread that reads the controller.

This hooks the player camera's own update instead.

How

  • f_80644c80 is the player camera's update (a virtual method, the camera in x0). nx2/oot_patches.py (patch_mouse_camera) puts one call at its top: hos_mouse_camera(c->x[0]). It runs on the game's thread, once a frame, while that camera runs.
  • host/mouse_native.c adds the mouse's motion to the camera's yaw (+0x1a4, wrapped at 180) and pitch (+0x18c, kept within the limits at +0x178) before the camera reads its input, 0.1 degrees a count at sensitivity 1, as before. The right stick's turn goes into the same fields, in f_80649c10 (yaw) and f_8064b770 (pitch). I found them with hardware write watchpoints on the two angles in Kokiri Forest.
  • While the hook has run in the last 150 ms, the controller reads leave the motion to the camera. Otherwise (pause menu, cutscenes with another camera, a build the patch did not find its place in) the mouse is the right stick, as before.
  • The heap search, its thread and the give-back path are gone. tests/test_mouse_native.py covers the new flow (the test runs on Linux; it skips on Windows as before).

Tested on Windows 11, RTX 4080 SUPER, Ryzen 7 5800X3D, main 7dbdcdc + this change, Kokiri Forest save. The patch is applied once (in the hot chunk). I fed mouse counts into the window's raw motion and read the camera's angles every 100 ms:

motion Native (this PR) As the stick
300 counts right yaw -30.0 deg, exactly -14.1 deg
600 counts left yaw +60.0 deg, exactly +55.9 deg
still mouse yaw holds yaw holds
Link walking forward 9 s after a turn yaw holds -
  • The camera is found in the first frame after the save loads. There is no search delay and nothing to find again after a scene change.
  • tests/run_all.py: no new failures (test_finish_output.py failed once in the parallel run and passes alone).

Known limit (same as before): while the camera follows Link by itself (its state at +0x204 is 3), the game eases the pitch back to its rest over a couple of seconds. The right stick switches the camera to state 4 (the player's), where a pitch stays put. Setting 4 from the hook does not work: the next frame the game puts the state back and restores the angles with it. Yaw is not affected. Keeping the pitch would need the stick's own "player turned the camera" input in f_80644c80; that could be a follow-up.

…heap search

The Insert menu's Mouse camera (Native) found the camera controller by scanning the 2 GB heap on
a thread (about a second, again after every scene change, the mouse falling back to the stick
until then) and wrote its angles from the controller-read thread.

The player camera's update, f_80644c80 (a virtual method, the camera in x0), now hands its camera
to host/mouse_native.c first, on the game's thread, once a frame (nx2/oot_patches.py,
patch_mouse_camera). The motion goes into the camera's yaw (+0x1a4, wrapped at 180) and pitch
(+0x18c, within the limits at +0x178) before the camera reads its input: the places the right
stick's turn goes in f_80649c10 and f_8064b770, found with hardware write watchpoints. While the
camera has not run for 150 ms (pause menu, other cameras) the mouse is the right stick as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@hckrman101
hckrman101 merged commit 7908e06 into NotRexed:main Nov 9, 2026
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.

1 participant