diff --git a/port/src/input.c b/port/src/input.c index b85afccf..80d5bbc4 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -1081,6 +1081,7 @@ struct aimSlotState { int gepdHeldPrev; /* aim held last tick -> adopt on entry */ int aimHeldPrev; /* was s_aimHeldPrev */ int centreClearTicks; /* was s_centreClearTicks */ + int mouseThisAim; /* mouse moved during this aim hold: keep its position while the stick is used too */ }; static struct aimSlotState s_aimSt[4]; #define AIMS (s_aimSt[(s_slot > 0 && s_slot < 4) ? s_slot : 0]) @@ -2523,6 +2524,7 @@ static unsigned inputComputePadSlot(int idx, signed char *stick_x, signed char * AIMS.centreClearTicks = 2; /* see D194 centre-spring note above */ if (!aimHeld) { AIMS.centreClearTicks = 0; + AIMS.mouseThisAim = 0; /* GEPD adopts the game's current crosshair pos every non-aim * frame so re-entry starts where the game left it. */ AIMS.gepdHeldPrev = 0; @@ -2848,6 +2850,8 @@ static unsigned inputComputePadSlot(int idx, signed char *stick_x, signed char * * driven by the port-supplied turn through the * sub_GAME_7F067FBC hook (see Input.PdMouseAim above). */ aimGepdAccumulate(edx, dyLook); + if (fabs(edx) > 0.01 || fabs(dyLook) > 0.01) + AIMS.mouseThisAim = 1; /* Edge-scroll belongs to the aim position, not to the * crosshair model -- without this the camera stops * following the crosshair at the screen edge. */ @@ -3908,7 +3912,10 @@ int portMouseAimPdActive(void) { /* D337: only while the mouse is the device driving aim -- otherwise the * pad's stick turn (the N64 path, weapon damp) must reach the game. */ - return pdMouseAimEnabled() && mouseGrabbed && s_aimDevMouse; + /* The mouse stays the aim position for the whole hold once it moved (gyro + * sent as mouse); the stick then offsets it (gunfire.c) instead of taking + * over. */ + return pdMouseAimEnabled() && mouseGrabbed && (s_aimDevMouse || s_aimSt[0].mouseThisAim); } int portMouseAimPdGetTurn(f32 *tx, f32 *ty) diff --git a/src/game/gunfire.c b/src/game/gunfire.c index 59d2986e..3dfe2d60 100644 --- a/src/game/gunfire.c +++ b/src/game/gunfire.c @@ -5071,8 +5071,18 @@ void sub_GAME_7F067FBC(f32 turn_x, f32 turn_y) * functions. Identity when Input.PdMouseAim is off, and the N64 build * never sees any of it. Behavioural hook, not the ABI exception: * Rule-2 sign-off given by the maintainer 2026-09-23. */ - if (portMouseAimPdGetTurn(&turn_x, &turn_y)) { - guncrossdamp = 0.01f; + { + f32 mouse_x, mouse_y; + + if (portMouseAimPdGetTurn(&mouse_x, &mouse_y)) { + /* The stick still offsets the crosshair from the mouse position, so + * gyro (sent as mouse) and right-stick aiming combine, as in PD */ + turn_x += mouse_x; + turn_y += mouse_y; + turn_x = (turn_x < -1.0f) ? -1.0f : ((turn_x > 1.0f) ? 1.0f : turn_x); + turn_y = (turn_y < -1.0f) ? -1.0f : ((turn_y > 1.0f) ? 1.0f : turn_y); + guncrossdamp = 0.01f; + } } #endif