The 72 mouse_direct sites of patches-v143.txt mapped to the 1.2.1 main by enclosing function, each original word
checked: the camera input update, free orbit, Ultrahand and the 16 player camera modes. 1.2.1 keeps some values in
other registers and stack slots (camera input x in s11, orbit angles at sp+0x3c/0x40, Ultrahand x in s9), so the
hooks read a per-version MouseLayout; the 1.4.3 values and behaviour are unchanged.
Where 1.2.1 adds a turn in a shared helper, the degrees go to the store of the helper's result (Aiming's pitch
target, new ROLE_BASE_STORE) or to the turn it is given (Horse yaw). Wakeboard, ShieldSurfing and Tail read the stick
twice (REPEAT on the first read), the dialogue cameras' angle loads are pre-indexed (mov -> add, as ClimbObj).
The player state (ability, bow in hand) is not known on 1.2.1 and reads as not found.
tests/mouse_direct_check.py runs the hooks with both layouts and checks each load-site table against its patch file.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PR #753 unified the cameras at 70/1500 = 0.0467 degrees a count and doubled Ultrahand's rate, which made every
existing mouse_sens turn the free camera 42% slower. The free camera keeps 0.08 degrees a count at mouse_sens 1, every
camera #753 unifies takes the same 0.08, and the held object keeps 0.01 stick units a count over the frame ratio (with
#753's cap of three full tilts a step). A mouse shake now needs 125 counts a swing at sensitivity 1 (10 degrees).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The stick loads returned the sample's pad stick even in a step without mouse motion, which drops anything the game
writes to the camera input's stick after the input update (main has 426 stores to +0x420/+0x424). The base loads added
0 degrees, which turns a -0 into +0. Both now return the loaded value untouched when the step has no mouse motion and no
mouse shake.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The ClimbObj pitch hook replaced the pre-indexed load ldr s1, [x22, #0x88]! and wrote the write-back to x22 from the
host call. The lifter keeps X19-X29 in locals across a call and does not reload them, so the write-back was lost and
the following str s0, [x22] wrote the pitch over the camera object's vtable pointer; the next virtual call crashed
(seen climbing a Stone Talus). The mov x22, x19 before the load is now patched to add x22, x19, #0x88, the hook
performs a plain ldr s1, [x22], and load hooks no longer support write-back loads at all.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Only the free camera took the mouse as degrees. The other camera modes took it as stick input, which their own speeds,
frame time, slow motion and curves reshaped, with the on-foot camera's square-root pitch shaping on top: bow aiming was
far too sensitive vertically on slow movements, abilities and the Purah Pad camera eased their pitch, lock-on turned
27% slower, and climbing, shield surfing and the rest each turned at their own rate.
Each camera mode's update now loads the gamepad's part of the stick where it computes its turn and adds the mouse's
degrees where it adds that turn to its angle (runtime/mouse_direct.c camera_load, the load sites of
recomp/patches-v143.txt): aiming, scope, abilities (and Recall's cursor), horse, Purah Pad camera, lock-on, bow
lock-on, wall and object climbing, the waterfall's turn, shield surfing, wakeboard and the dialogue cameras. Recall's
cursor moves so that its aim turns as many degrees a count. The waterfall's height and the horse's empty lock-on are
not angles and stay stick input, now linear. A step whose mouse motion no hook took is logged with the camera's name.
Holding L to soothe the horse gave the mouse to the ability wheel's virtual cursor, a held stick for the camera: the
mouse goes to the wheel and the D-pad strips only while their screen has the focus (menu_cursor.c
menu_cursor_shortcut). A mouse shake no longer plays a 0.8 s swing after it: the right stick follows the mouse's own
swings and lets go when it rests, and the camera does not turn by that swing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
player_state follows about fifteen pointers from the player root to its action verbs, and each was checked with
plat_mem_readable, a VirtualQuery. That query costs tens of microseconds in this process, so the read stalled the
game thread while the mouse moved. mem_guest_readable answers from the layout for the committed heap and the loaded
modules, where the player and its components live, and asks the OS only for anything else. Together with the same
change in the menu pointer, a Ryzen 5 4500 runs the scene that fell to 50-54 fps at 58-60 fps again.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The game detaches a fused part when the right stick swings left and right a few times. In direct mode the mouse never
reaches that stick, so shaking the mouse did nothing and only the shake key worked. A shake of the mouse while
Ultrahand holds an object (at least three changes of direction within 0.6 s, each swing worth 10 degrees of camera turn
or more) now plays the shake key's right-stick swing. Turning a held object back and forth at an ordinary pace takes
longer and does not count.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The free-orbit camera turned 0.08 degrees per count while the other cameras (the bow, the abilities) took the mouse as
0.01 stick units a count, about 0.023 degrees for yaw and through the camera's signed-square pitch for y, so the bow
turned at half the speed and small vertical moves barely moved it. Every camera now turns 70/1500 = 0.0467 degrees
per count: the stick path gets 0.02 a count for x and the signed square root for y, so pitch is linear and as fast as
yaw. While the player uses an ability (the action verb UseSpecialPower, read from the player actor with the 1.4.3
placement), the ability camera's own linear scales are undone instead. stick_sens is divided out, Ultrahand's held
object gets the camera's stick value a count (at most three full tilts a step), and mouse_aim_scale (0.1 to 3)
scales the mouse while the bow is drawn.
The game's lock-on, recenter and aiming override released the mouse's pitch hold and restored the target from before
it, so after a shot the camera sprang back to that pitch, or to the game's default target. The mouse now lets go
without restoring, and when the override ends (or the camera went 100 ms without a step) it holds the pitch the
camera has then. A gamepad's vertical input still hands the pitch back to the game.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
direct_mode read TOTK_MOUSE_MODE with cfg_get, which is NULL when the player never set it, so a fresh totk.ini kept
stick emulation (and its speed cap) while the menu showed Direct. cfg_value gives the settings table's default.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mouse_mode now defaults to direct: on 1.4.3 the camera turns by the raw mouse motion; 1.1.0 and 1.2.1 have no hooks
and keep stick emulation, and no setting changes the gamepad. The Controls tab gets a "Mouse in the game's menus" row
for menu_cursor, and the mouse rows are in all four catalogs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The camera input's activity hook wrote the flags to +0x418, but the game's next instruction stores w8 over them
(1.4.3 main+0x874d80), so a mouse-only turn still read as idle. The hook now changes w8.
The free-orbit hooks rewrote the camera stick input from the last sample even in steps without mouse motion; they now
take a step only when the mouse moved in it or holds the pitch, so a gamepad-only step reaches the camera as the game
made it.
The mouse shake gesture for detaching parts is gone: three 24-count reversals fire while a held object is turned back
and forth. Arrow keys or the pad's right stick shake as before.
The menu pointer comes only while the keyboard and mouse are the device used last (input_kbm_last): a gamepad player
sees the menus as on the console. Raw mouse travel is counted while the cursor is released too, so moving the mouse
brings the pointer back.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>