the visible limp (#78): there was never a jump-jet clip set -- the 'Airborne' drivers ARE the gimp gait machines

The port had FUN_004a5bf8/71f4 fully reconstructed as AdvanceBody/Leg-
AnimationAirborne, gated on (MovementMode()==3||4) && jumpCapable@0x580 and
believed dead ("the test mech never jumps").  The binary says otherwise:
mech+0x40 in that gate is the graphicAlarm LEVEL (3=left-leg gimp, 4=right)
and +0x580 is hasGimpClips, set by the conditional loader block that probes
'wgl' and fills clip slots 22-27 (wgl/wgr/ggr/ggl/gsl/gsr) plus the four
measurements at 0x53c-0x548 (wg entry strides = speed caps, gg cycle strides).
Renamed the five jump* members + both drivers accordingly.

New: GimpBodyClipFinished @004a6344 / GimpLegClipFinished @004a7970 -- the
gimp transition machines, branched from the normal finished-callbacks.  Phase-
correct limp entry (left-gimp enters 0x16/wgl only from a RIGHT step, right-
gimp 0x17/wgr from a LEFT step), gg cycles at gimp cadence, gs exits, and the
demand clamp to the gimped side's speed cap (leg cb writes it back into the
mapper -- the binary's authentic slowdown; the T3 x0.5 stand-in in mechmppr is
retired, BT_GIMP_SPEED now defaults 1.0).  The binary's gimp machines have no
reverse entry -- the "reverse disabled" behavior is now binary-proven.

Reviving the dead drivers replayed two port-glue bugs (gotcha #24): the raw
*(controlSource) mapper read (null -> crash at first engagement) and the
missing alarm->member state re-sync (machine pinned in one run state).  Both
fixed; bench harness gained BT_SELF_DAMAGE_TICKS=<n> to hold a zone past
LegHalfStructure without destroying it.

Bench-verified (madcat, novice, zone 16): crossing -> alarm 4 -> wgr entry
from a left step -> 8k+ frames stable in the ggl limp cycle at cadence 14.77
(vs 18.5 walk / 22+ run) with raw demand still 50.  [T2]

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Joe DiPrima
2026-07-29 15:49:39 -05:00
co-authored by Claude Fable 5
parent 520f6eecd3
commit 36f68718c2
9 changed files with 506 additions and 127 deletions
+9 -5
View File
@@ -974,9 +974,13 @@ void
// attached feed into its drive; the 2007 engine's mover has no feed
// roster, so the same multiplication is applied to the speed demand here.
// speedEffect is the wrapper's live 0..1 output (gear ratio, thermal
// curve, 1 - zone damage); a mech with no Myomers drives at 1.0. While
// GIMPED (mode 3/4) the demand additionally halves -- [T3: the 0.5 is VGL
// Lynx's "roughly 50%" firsthand account, BT_GIMP_SPEED overrides].
// curve, 1 - zone damage); a mech with no Myomers drives at 1.0.
// GIMP slowdown: the binary's real mechanism is the gimp gait machines
// (FUN_004a5bf8/71f4/6344/7970) -- the LIVE demand is clamped to the wg
// clip's speed (GimpLegClipFinished writes it back) and the limp cycle
// cadence enforces it; an EXTRA multiply here would double-slow. The
// earlier T3 0.5 stand-in is therefore retired; BT_GIMP_SPEED remains as
// an optional override multiplier (unset = 1.0 = authentic).
{
extern Scalar BTMyomersDriveOf(void *subsystem);
Scalar drive = 1.0f;
@@ -998,8 +1002,8 @@ void
if (s_gimp < 0.0f)
{
const char *e = getenv("BT_GIMP_SPEED");
s_gimp = (e != 0 && *e != '\0') ? (Scalar)atof(e) : 0.5f;
if (s_gimp < 0.0f || s_gimp > 1.0f) s_gimp = 0.5f;
s_gimp = (e != 0 && *e != '\0') ? (Scalar)atof(e) : 1.0f; // 1.0 = authentic (clamp lives in the gimp SM)
if (s_gimp < 0.0f || s_gimp > 1.0f) s_gimp = 1.0f;
}
drive *= s_gimp;
}