Files
TeslaRel410/restoration/source410/BT/TORSO.NOTES.md
T
CydandClaude Fable 5 6da6ec89dd BT410 5.3.119: the master gate comes home -- 0xC/0x100 decoded as the engine's own enums, and every [T2] mirror retired
The 'mysterious flag pair' gating every master-only registration was never
BT-specific state waiting on unreconstructed stream builders. It is the
Entity base itself: InstanceBits=2 puts the instance field at mask 0xC
(ReplicantInstance=4), DynamicBit=8 makes DynamicFlag 0x100 -- so the
binary's (flags & 0xC)==0 && (flags & 0x100)!=0 reads 'a master-instance
dynamic entity', spelled MasterInstance + DynamicFlag in the 1995 headers.
Mover::DefaultFlags = DynamicFlag|MasterInstance, ENTITY.CPP:978 seeds
simulationFlags from the MakeMessage's instanceFlags, and our spawn recipe
has passed Mech::DefaultFlags since the boot ladder -- the authentic gate
was live all along. The BT411 donor's 'MasterHeatSinkFlag' name was a
fabrication that made an engine constant look like a missing subsystem
feature (donor drift #12).

Eleven sites flip from the GetInstance() mirror to the binary pair: the
heat-family registrations (x4), powersub (x3), gyro, hud, myomers,
emitter, and the Torso ctor's master/copy selection (@004b6b0c verbatim,
isDamagedCopy set in both branches). The MECHWEAP score-post and MECH view
gates are different families and stay as they are.

Statically proven (DefaultFlags carries both bits) and mission-soaked
clean. No [T2] divergence markers remain in the tree.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 14:10:49 -05:00

5.4 KiB

TORSO.CPP / .HPP — reconstruction notes

Torso (: PowerWatcher) drives torso twist (horizontal) and weapon elevation (vertical). Tuning rates/limits stream from the resource (horizontal/verticalRotationPerSecond, horizontal/verticalLimit*, torsoHorizontalEnabled).

Reconstructed

  • Ctor: streams the base rates (deg→rad) + limits + horizontalEnabled, primes currentTwist/currentElevation/analog axes to 0, and installs TorsoSimulation as the per-frame Performance (the replicant copy is console-driven via TorsoCopySimulation, still staged).
  • analogElevationAxis / analogTwistAxis members + SetAnalogElevationAxis / SetAnalogTwistAxis setters (written by MechControlsMapper::InterpretControls).
  • CurrentTwist() / CurrentElevation() / GetHorizontalEnabled() accessors.
  • TorsoSimulation(Scalar) — per-frame aim integration (authentic core):
    • currentElevation += analogElevationAxis · baseElevationRate · dt, clamped to [verticalLimitBottom, verticalLimitTop];
    • if horizontalEnabled: currentTwist += analogTwistAxis · baseTwistRate · dt, clamped to [horizontalLimitLeft, horizontalLimitRight].

VERIFIED (BT_MECH_LOG [mppr] torsoElev=, forced-input BT_FORCE_ELEV): stick pitch 0.8 slews the elevation up and clamps at the authentic verticalLimitTop = 0.349 rad = 20°. Zero Fail.

Skeleton-joint binding (2026-07-21)

The twist joints are now RESOLVED and BOUND: the ctor calls owner->ResolveJoint(torsoHorizontalJoint / torsoHorizontalShadowJoint) (the skeleton is live — see MECH.NOTES.md), stores them as Joint*, and TorsoSimulation pushes currentTwist onto horizontalJointNode via Joint::SetRotation (hinge → Radian; ball → EulerAngles yaw).

The bring-up TEST.EGG mech has a FIXED torso (horizJoint='', enabled=0), so its twist path is inert — correctly guarded (null joint → no apply, no crash). A torso-twist mech drives the joint. Verified headlessly; the VISUAL rotation needs the renderer.

Elevation does NOT drive a gun joint (corrected 2026-07-21)

Checked BT411 before reconstructing a "gun-elevation joint": no such joint binding exists anywhere in the authentic engine. currentElevation instead composes into Mech::eyepointRotation (the cockpit-eye / weapon-boresight pitch) — see MECH.NOTES.md "PHASE 5.3 INCREMENT 5". TorsoSimulation only needed to keep advancing the scalar state, which it already did; the missing piece was the CONSUMER (Mech::Simulate's eyepoint composition), now reconstructed and verified (torsoElev == eyePitch every frame).

TorsoCopySimulation + ComputeTargetTwist (2026-08-04, 5.3.114)

The replicant (damaged-copy) twist path is real, verified line-by-line against the raw decomp (part_013.c):

  • ComputeTargetTwist @004b6510 (232B): two time bases — settled uses lastPerformance - lastUpdate (the engine Simulation fields at +0x10/+0x14), slewing (a copy whose command stamp lastUpdateTime @0x254 is ahead of the clock) uses lastUpdateTime - lastUpdate. targetTwist = twistAtUpdate + twistRate * elapsed, clamped (left = upper, right = lower). Returns the slewing flag. The decomp's DAT_0052140c divide is Time::operator- (ticks / SystemClock::ticksPerSecond) inlined — NOT a hand-written MsPerSecond conversion.
  • TorsoCopySimulation @004b65f8 (188B): settled → snap to target; slewing → Lerp(current, target, dt / ((lastUpdateTime - lastPerformance) + dt)) — the remaining-time ease that lands exactly when the clock reaches the command stamp. Then the same clamp pair applied to targetTwist again.

Two BT411 donor drifts corrected against the decomp: the donor's ease aged by lastUpdate (+0x14) where the binary reads lastPerformance (+0x10); and the donor calls the joint-write helper (@004b67ec) from the copy sim — the binary does not (port-era addition; our copy sim leaves joints to the master path exactly as 1995 shipped).

Members carved from dynamicsState[16][12]: targetTwist @0x218, twistAtUpdate @0x21C, twistRate @0x238, lastUpdateTime @0x254 (Time, init 0L — plain 0 is ambiguous between the long/float assignment operators under BC4.52). Ctor now registers the copy Performance on replicants (binary PTR @00510c1c). [T2 RETIRED 5.3.119] The gate is now the binary's own pair, decoded as engine enum identities: (flags & 0xC) is the Entity INSTANCE field (InstanceBits=2, ReplicantInstance=4) and 0x100 is Entity::DynamicFlag (DynamicBit=8). Mover::DefaultFlags = DynamicFlag|MasterInstance and ENTITY.CPP seeds simulationFlags from the MakeMessage's instanceFlags, so the authentic gate was live all along -- no stream-builder dependency existed, and the BT411 donor's "MasterHeatSinkFlag" name was a fabrication. The whole registration family (heat x4, powersub x3, gyro, hud, myomers, emitter) flipped with it.

Staged feeders: Read/WriteUpdateRecord (the census remainder in this TU) stamp twistAtUpdate/twistRate/lastUpdateTime from console updates. Zero-init means a copy eases to centre — correct-by-vacuity in single-pod, inert until MP replication lands.

Deferred

  • HUD free-aim slew, the look-button state machine (BTCommitLookState / gBTLookPitch/gBTLookYaw — composes with elevation into the full eyepoint) — still staged.
  • Torso::Read/WriteUpdateRecord — the copy sim's update feeders (see above).