Files
TeslaRel410/restoration/source410/BT
CydandClaude Fable 5 a87c49c158 BT410 5.3.93: the clip loader runs LIVE -- the Mad Cat measures itself, and a 1995 copy-paste bug ships again on purpose
LoadLocomotionClips + ResolveAnimationClip + MeasureClipStride + LoadClipSlot
reconstructed and WIRED into the ctor's GameModel block.  animationClips[] is
no longer an empty array: every gait slot resolves by the model's animation
prefix, and the locomotion constants are now MEASURED from the authored clips
instead of asserted as bring-up defaults.  First live run, arena mission:

  [mech] clips 'mad': standSpeed=5.23 walkStride=18.51 revStride=56.05
                      revSpeedMax=26.26 gimpSpeedMax=-4.23 gimpStride=-20.26
                      limpSet=1

That line carries three verifications at once: the prefix printing as text
proves the Mech__ModelResource layout is right at +0x40; the reverse figures
come out NEGATIVE exactly as the transition machines expect; and the mission
ran clean to live driving afterwards (703 log lines, no fault).

DRIVING FEEL CHANGED, deliberately: speedDemand at 0.6 throttle went 14.4 ->
26.9, because the placeholder top speed (30) gave way to the measured 56.05.
The Mad Cat is simply faster than the bring-up guess.  Authenticity arriving,
not a regression.

TWO BINARY BEHAVIOURS REPRODUCED ON PURPOSE, both documented at the function:

  The speed caps read keyframeData[keyframeCount] -- one entry PAST the last
  frame.  Fencepost is the binary's own (0x690 + 8 + [0x670]*0xc); whether the
  authored table has count+1 entries is unestablished, but the clips were
  authored against this read and the measured values are sane.

  The reverse-cycle stride is computed from STALE locals.  The decomp is
  unambiguous: bbr and bbl are both measured into local_8/local_c, and the
  divide's second terms come from local_10/local_14 -- still holding the
  RUN-LEFT figures.  gimpStrideLength = -((bbl + rrl_stale)/(...)).  A 1995
  copy-paste bug, shipped in every pod for thirty years, reproduced here with
  a comment pointing at the wwr/wwl block that shows the intended pattern.

  (And an earlier scare resolved: the negation IS in the binary -- the very
  next instruction is 0x350 = -0x350.  My first decomp window cut one line
  short and briefly indicted the donor's minus sign.)

ONE DELIBERATE DIVERGENCE, tagged [T3]: the binary dereferences every resolve
result unguarded -- a model missing a mandatory clip crashes on load.  Here a
miss stores NullResourceID (SelectSequence resolves it to an inert controller)
and the dependent measurement is skipped.  Keeps the boot alive on unverified
clip sets; revisit when the fleet's models are known-good.  Measurement binds
pass a NULL finished-callback (measurement parses, never plays -- the binary's
live pointers can never fire there).

Ctor additionally zero-initializes the whole gait channel -- globalTimeScale
defaulting to 1 specifically, because zero would silence every clip advance --
and fills the clip array with NullResourceID before the loader runs, so the
uninitialized-member class of bug (see 5.3.83) is closed here BEFORE the
consumers arrive.

MECH.HPP: the optional limp set carved out (hasGimpClips + 4 measured limp
figures + gyroRumbleTimer); reservedState 150 -> 140.

Next: the four Advance* entry points -- the last link before the legs move.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 12:23:04 -05:00
..