Torso elevation (pitch aim) wired: the pod stick's Y axis lives

The mechs could always tilt their aim up/down -- Torso models the full
vertical axis (currentElevation, rate, VerticalLimitTop/Bottom,
recenter) and EVERY 1995 control mode routes stickPosition.y into
Torso::SetAnalogElevationAxis -- but the desktop bridge hard-zeroed
stick Y, so the axis was dead on a keyboard rig.  The one pod control
the remap left unwired.

- btinput: JoystickY axis -> elevTarget/elevActive/elevAbsolute
- mech4 shim: sElev integrator (same walk/spring model as the twist;
  X recenters pitch too via gBTElevRecenter)
- mechmppr bridge: feeds stickPosition.y every bridged frame (the old
  unconditional zero removed); both mode branches covered
- CONTROLS.MAP (+ numpad profile + compiled default): R/F = aim
  up/down, pad LeftStickY = elevation (was unused)
- torso.hpp: CurrentElevation()/ElevationVelocity() accessors (diag)
- [mppr] trace gains stickY (note: the trace reads AFTER the next
  frame's device push re-zeroes the stick -- input flows regardless)

Verified live: R held -> torso elevation climbs at the authored rate
and clamps at 0.349066 rad = exactly 20.0 deg (the Blackhawk's
VerticalLimitTop); release holds the aim.  The eyepoint correctly
stays level -- pitch aims the GUNS and reads on the HUD's vertical
elevation tape, as in the pod.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-18 16:44:22 -05:00
co-authored by Claude Fable 5
parent 0a77d8e54b
commit 1271d3bc76
8 changed files with 101 additions and 4 deletions
+51
View File
@@ -654,6 +654,8 @@ static int gBTPinkyKey = 0; // key '4' = the pod's 4th fire butto
int gBTModeCycle = 0; // 'M' edge: cycle the control mode (mapper consumes)
int gBTLookBehind = 0; // 'V' held: the pod's rear-view button (task #68)
float gBTTwistAxis = 0.0f; // Q/E torso-twist deflection (assisted-mode stick X)
float gBTElevAxis = 0.0f; // R/F torso-elevation (pitch aim, stick Y)
int gBTElevRecenter = 0; // X edge: zero the pitch axis
int gBTTorsoRecenter = 0; // 'X' edge: pulse the authentic torso recenter (mapper consumes)
static int gBTConfigKey = 0; // task #6: HOLD 'G' = the weapon-configure button
static int gBTGenSelKey = 0; // task #12: F5..F8 = SelectGeneratorA..D, F9 = mode toggle
@@ -2625,9 +2627,57 @@ void
{
sTwist = 0.0f;
gBTTorsoRecenter = 1; // mapper consumes -> CommandRecenter()
{
extern int gBTElevRecenter;
gBTElevRecenter = 1; // pitch axis zeroes below
}
}
sPrevXT = xtNow;
gBTTwistAxis = sTwist;
// TORSO ELEVATION (pitch aim -- the pod stick's Y
// axis; every 1995 control mode routes it to
// Torso::SetAnalogElevationAxis). Same integrator
// model as the twist: keys walk the axis, release
// springs the RATE to 0 (position holds, the sim's
// vertical limits clamp); a pad stick is absolute.
{
extern float gBTElevAxis;
static float sElev = 0.0f;
if (gBTInput.elevAbsolute)
{
sElev = gBTInput.elevTarget;
}
else if (gBTInput.elevActive)
{
sElev += gBTInput.elevTarget * kStickRate * dt;
if (sElev > 1.0f) sElev = 1.0f;
if (sElev < -1.0f) sElev = -1.0f;
}
else if (sElev != 0.0f)
{
const float estep = kStickCenterRate * dt;
if (sElev > estep) sElev -= estep;
else if (sElev < -estep) sElev += estep;
else sElev = 0.0f;
}
extern int gBTElevRecenter; // set by the X edge above
if (gBTElevRecenter)
{
gBTElevRecenter = 0;
sElev = 0.0f; // X recenters pitch too
}
gBTElevAxis = sElev;
if (getenv("BT_INPUT_LOG"))
{
static float s_eacc = 0.0f; s_eacc += dt;
if (s_eacc >= 1.0f) { s_eacc = 0.0f;
DEBUG_STREAM << "[input] elev tgt="
<< gBTInput.elevTarget << " act="
<< gBTInput.elevActive << " axis="
<< sElev << "\n" << std::flush; }
}
}
}
// gBTDrive.fire = "any weapon trigger down" (feeds the bring-up
// damage dispatcher + the beam-visual keepalive)
@@ -3158,6 +3208,7 @@ void
<< " pre=" << preThrottle
<< " rev=" << mppr->reverseThrust
<< " stickX=" << mppr->stickPosition.x
<< " stickY=" << mppr->stickPosition.y
<< " -> speedDemand=" << mppr->speedDemand
<< " turnDemand=" << mppr->turnDemand
<< " mode=" << mppr->controlMode