Targeting correction: reticle = TORSO BORESIGHT, not a free mouse cursor (task #39)

Colleague flagged that targeting is torso-locked with no fine cursor.
Correct: the pod stick's yaw drove the TORSO TWIST
(MechControlsMapper -> HUD::SetFreeAimSlew(stick_x) @cockpit+0x28C,
gated on torso-horizontal-enabled; hud.hpp:167) and reticlePosition
@HUD+0x1FC is COMPUTED by HudSimulation from the mech pose quaternion +
target geometry, zeroed to centre with no target (part_013.c:5680) --
never a free-floating cursor. The engine Reticle struct is general
(shared with Red Planet); BT drives it from the torso boresight.

Fix:
- Removed the mouse-cursor slew (a mis-sourced stand-in from the
  RP-shared struct). The crosshair is now the torso boresight:
  BTTwistToReticleX(torsoTwist) = tan(twist) projected through the live
  per-axis projection. Dead-centre on the fixed-torso BLH
  (TorsoHorizontalEnabled=0); you aim by steering the whole mech.
- BT_AIM="x y" retained as the headless test harness.

Verified: face-to-face spawn -> HOT lock + aimed zone hits (36);
BT_FORCE_TURN circling -> 31 no-target vs 1 HOT (steering off-target
drops the lock, as it must). KB swept (combat-damage / gauges-hud /
open-questions); checkctx CLEAN.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-08 23:29:42 -05:00
co-authored by Claude Fable 5
parent 24ea7f13af
commit a8a56c57c9
5 changed files with 82 additions and 81 deletions
+18 -38
View File
@@ -1241,12 +1241,18 @@ void
}
sPrevV = vNow;
// RETICLE SLEW (task #36): the pod slewed the target reticle
// with the stick free-aim channel; the dev-box stand-in is the
// MOUSE -- absolute cursor position mapped through the client
// rect into reticle coordinates (centered, +y down, unit =
// half the client height -- the dpl2d frame). BT_AIM="x y"
// pins the crosshair for headless harness runs.
// RETICLE = TORSO BORESIGHT (task #39 correction): the pod had
// NO free-aim cursor -- the binary's HudSimulation computes
// reticlePosition from the mech's POSE quaternions
// (part_013.c:5652+, a rate-limited quat->euler of the torso
// aim), i.e. the crosshair marks where the TORSO GUNS point
// relative to the view, and you aim by steering the mech /
// twisting the torso (the pod's right stick). The earlier
// mouse-cursor slew was a mis-sourced stand-in and is
// REMOVED. Our cockpit view is body-mounted, so the
// crosshair deflection = the torso twist projected to screen
// -- identically ZERO on the fixed-torso BLH (dead-centre
// boresight). BT_AIM="x y" remains as the headless harness.
{
static int sAimEnv = -1;
static float sAimEnvX = 0.0f, sAimEnvY = 0.0f;
@@ -1261,39 +1267,13 @@ void
gBTAimX = sAimEnvX;
gBTAimY = sAimEnvY;
}
else if (focused && pFg != 0)
else
{
typedef int (__stdcall *CurFn)(POINT *);
typedef int (__stdcall *StcFn)(void *, POINT *);
typedef int (__stdcall *CrFn)(void *, RECT *);
static CurFn pCur = 0; static StcFn pStc = 0; static CrFn pCr = 0;
if (pCur == 0)
{
HMODULE u = GetModuleHandleA("user32.dll");
pCur = (CurFn)GetProcAddress(u, "GetCursorPos");
pStc = (StcFn)GetProcAddress(u, "ScreenToClient");
pCr = (CrFn)GetProcAddress(u, "GetClientRect");
}
void *wnd = pFg(); // focused == our window
POINT cp; RECT rc;
if (pCur && pStc && pCr && wnd != 0 &&
pCur(&cp) && pStc(wnd, &cp) && pCr(wnd, &rc) &&
rc.right > rc.left && rc.bottom > rc.top)
{
// client px -> reticle coords through the RENDERER
// (it undoes the backbuffer->client present stretch;
// a raw client-height mapping is only exact for a
// backbuffer-shaped window and skews the pick
// sideways otherwise).
extern void BTClientToReticle(float mx, float my,
float cw, float ch, float *rx, float *ry);
float rx = 0.0f, ry = 0.0f;
BTClientToReticle((float)cp.x, (float)cp.y,
(float)(rc.right - rc.left),
(float)(rc.bottom - rc.top), &rx, &ry);
gBTAimX = rx;
gBTAimY = ry;
}
// boresight = torso twist vs the body-mounted view,
// projected through the live per-axis projection.
extern float BTTwistToReticleX(float twist_rad);
gBTAimX = BTTwistToReticleX(gBTHudTwist); // BLH: 0
gBTAimY = 0.0f;
}
}
}