Files
TeslaRel410/restoration/source410/BT/MECH-LAYOUT.md
T
CydandClaude Fable 5 efc41f165b Mech milestone: reconstruct NameFilter (helper 3/3) -- helpers phase complete
NameFilter is the Mech's mechNameFilter (@0x36c), a small fixed debounce record
the ctor initialises. Reconstructed from FUN_00435a7c: a 10-word (0x28) struct,
Initialize() sets [2]=1 / [8]=[9]=-1 / rest 0 exactly. Header-only. Field
semantics unresolved (only caller is Initialize; reader is the unbuilt HUD) --
names best-effort, but size + init values are binary-exact, which is all the
Mech layout + ctor need.

All 3 missing embedded helper classes now reconstructed + compile-verified under
BC4.52 (AlarmIndicator, SequenceController struct+Init, NameFilter). MECH-LAYOUT.md
step 1 marked done. Next: MechSubsystem base + the subsystem roster, then finalize
MECH.HPP (probe sizeof==0x854), then the ctor + segment-table walk.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 20:56:06 -05:00

128 lines
8.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MECH.HPP staging worksheet (opened 2026-07-19)
The working ledger for growing the literal MECH.HPP alongside the mech-family TU
reconstructions. **The period compiler is the layout authority**: `../layout_probe.cpp`
compiled+run under BC4.52 with the authentic OPT.MAK flags (`-a4` alignment) measures the
1995 base-class sizes from the SURVIVING engine headers.
## Probe results (2026-07-19) — methodology VALIDATED 3/3
| class | sizeof | validation |
|---|---|---|
| Simulation | 0x0D0 | |
| Entity | 0x1C4 | (⇒ Entity-own fields span 0x0D00x1C4: playerLink@0x190 ✓, subsystem roster @0x124/0x128 ✓) |
| Mover | 0x300 | (⇒ Mover-own 0x1C40x300: localOrigin@0x260 ✓) |
| **JointedMover** | **0x328** | **⇒ Mech's own region = 0x3280x854 (0x52C bytes)** |
| Mission | 0x0E4 | BTMission's experienceLevel @+0xE4 = first BT member ✓ |
| BTMission | 0x0FC | **== the binary's `new(0xfc)`** (BTL4Mission alloc) ✓ |
| ModeManager / BTL4ModeManager | 0x00C | **== the binary's `new(0xc)`** ✓ |
| BTRegistry | 0x010 | **== the binary's `new(0x10)`** ✓ |
Three independent allocation-size matches against the shipped binary ⇒ headers + compiler +
flags reproduce 1995 layout exactly. Any future header where the probe disagrees with a
binary alloc size is WRONG and must be fixed before use.
## Consequences for MECH.HPP staging
- Every binary offset **< 0x328 is a BASE-CLASS field**, not a Mech member. The port's
mech.hpp declares several pose members in that range (orientation@0xD0, bodyRotation@0x100,
turretBase@0x1C4, headPitch@0x1CC, torsoTwist@0x1DC, legAngle@0x1F4, hipAngle@0x200,
torsoAim*@0x298/0x2C8, netOrientation@0x2D4) — in the 1995 header these belong to
Simulation/Entity/Mover/JointedMover (or their equivalents) and must be RE-ATTRIBUTED by
checking the surviving engine headers' member lists at those offsets (probe with offsetof
where members are public).
- Mech-own members with binary offsets ≥ 0x328 (from the port/CLASSMAP, to be laid out with
`reserved[]` filler between mapped runs): reduceButton@0x340, forwardCycleRate@0x344,
legCycleSpeed@0x348, reverseStrideLength@0x34C, gimpStrideLength@0x350, mechName@0x360,
masterAlarm@0x39C(+legStateAlarm), legAnimationState@0x3B0, unstablePercentage@0x3F0,
airborne@0x3F4, radar block @0x3F80x40C, rearFiring@0x410, missionReview@0x414,
messageManager@0x434, torsoCache@0x438, lastInflictingID@0x43C, damageLookupTable@0x444,
weaponCount@0x448, collisionTemporaryState@0x44C, heatAlarm@0x4500x464, throttleState@0x4A4,
fallDirection@0x4A8, fallScalar@0x4B4(+collisionSpeed), templateBottomLift@0x4B8,
stabilityAlarm@0x4C40x4D8, standing/duckedTemplateMaxY@0x518/0x51C (≡heatLevel/Capacity —
CONFLICT, resolve), gyroSubsystem@0x528, gait caps @0x52C0x548, look angles @0x5640x570,
turn rates @0x574/0x578, jump flags @0x5800x588, motionEventName@0x598, motionEventArmed@0x5A4,
time scales @0x5A80x5B0, hudSubsystem@0x5B4, cycle rates @0x5B80x5C0, gyroRumbleTimer@0x5C4,
footStepRootJoint@0x5C8, animationClips@0x5CC(+namedClip alias @0x5E0, crash clips
@0x5D40x5DC), gimpBaseClip@0x64C, deathAnimationLatched@0x650, leg/bodyResetLatch@0x654/0x658,
legAnimation@0x65C, controllableSubsystems@0x65C(CONFLICT — one is a chain @0x65C, resolve),
bodyTargetSpeed@0x6B4, bodyCycleSpeed@0x6B8, bodyAnimation@0x6BC(≡watchedSubsystems CONFLICT),
statusAlarm/bodyStateAlarm@0x714, bodyAnimationState@0x728, deadband block @0x7680x770,
creationTime@0x778, poseSyncLatch@0x77C, heatLevelSnapshot@0x780, unstable tuning @0x7840x798,
reverseSpeedMax2@0x7A0, heatableSubsystems@0x7AC, weaponRoster@0x7BC, damageableSubsystems@0x7CC,
sensorSubsystem@0x7DC, telemetryFilter@0x7E0, linearSpeed@0x81C, resource names @0x8440x84C,
deathHandler@0x850, end 0x854.
- The flagged CONFLICTs are port-side double-attributions to untangle against the decomp
before the first staged MECH.HPP is written.
- Real 1995 types to substitute for the port proxies: ReconChain→`ChainOf<Subsystem*>`? /
AlarmIndicator→the engine alarm type / ReconSeq→the SequenceController analog / BTVal→per
case — settle each against the surviving engine headers + sizes via the probe.
## Next actions
1. Extend layout_probe.cpp with offsetof checks on public base members to re-attribute the
sub-0x328 pose fields to their true base classes.
2. Untangle the three offset CONFLICTs above (decomp reads).
3. Write the first staged MECH.HPP (interface + mapped runs + reserved[] filler) and
compile-verify sizeof(Mech)==0x854 with the probe.
---
## ADDENDUM 2026-07-19 (later) — spawn factory reached the Mech ctor; proxy layer resolved
The boot ladder now runs the full spawn factory (CreatePlayerVehicle -> Mech::MakeMessage ->
MakeAndLinkViewpointEntity -> registry -> Mech::Make -> `new Mech` -> JointedMover base
streams the model) and halts at the Mech ctor. So the ctor is the live frontier and this
worksheet is the active blocker.
### Proxy layer resolved (BT411 mechrecon.hpp -> real 1995 types)
Settles the open item in the "Real 1995 types" bullet above:
| BT411 alias | real type | in 4.10 archive? |
|---|---|---|
| ReconAlarm (AlarmIndicator) | AlarmIndicator (multi-level, N levels sets size) | ❌ MISSING |
| ReconSeq | SequenceController (animation sequence) | ❌ MISSING |
| ReconFiltered / FilteredScalar | **AverageOf<Scalar>** (15-sample running avg) | ✅ AVERAGE.HPP |
| ReconFiltered (mechNameFilter) | NameFilter | ❌ MISSING |
| ReconChain<Subsystem*> | ChainOf<Subsystem*> | ✅ CHAIN.HPP |
| ReconMatrix / Matrix34 | AffineMatrix / Matrix | ✅ |
| StateIndicator | StateIndicator | ✅ STATE.HPP |
| Reticle | Reticle | ✅ RETICLE.HPP |
| BTVal (turretBase, mechName, torsoAim*, aimRate, headPitch, torsoTwist) | animated value/quaternion — **UNIDENTIFIED**; BT411 BTVal is a no-op placeholder. Most BTVal members are < 0x328 = BASE-class pose fields (re-attribute per §"Consequences"), so their type is a base concern, not Mech's. |
### CRITICAL new finding — 3 embedded helper classes are missing
`AlarmIndicator`, `SequenceController`, `NameFilter` do **not** exist anywhere in the 4.10
CODE archive (confirmed by full-tree grep; no *alarm*/*filter*/*sequen* headers either).
They are additional helper classes the milestone must reconstruct from BT411's decomp, and
their sizes set the embedded-member offsets. (`AverageOf` was initially flagged missing but
DOES survive — AVERAGE.HPP, same SIGNATURED lineage BT411 preserved — so telemetryFilter[5]'s
type is available.) The alarm sizing: the
`masterAlarm@0x39C`/`heatAlarm@0x450`/`stabilityAlarm@0x4C4`/`statusAlarm@0x714` spacing
DERIVES the AlarmIndicator per-level size (e.g. masterAlarm 33 levels spans 0x39C..0x450 =
0xB4; heatAlarm 3 levels spans 0x450..0x4C4 = 0x74 — a fixed header + N-level array; solve
the two equations for header size + per-level stride). Same method sizes AverageOf from
telemetryFilter[5]@0x7E0..0x81C (0x3C/5 = 0xC each) and SequenceController from the
legAnimation/bodyAnimation spacing.
### Subsystem roster source availability (VDATA 0xBxx ClassIDs)
- Full .CPP/.HPP in 4.10: **GAUSS, PPC, SENSOR**
- .TCP partial survivors (authoritative where present): **AMMOBIN, EMITTER, GNRATOR, HEAT,
MISSILE, PROJTILE, PROJWEAP**
- Decomp-only (BT411): MechSubsystem base, gyro, torso, hud, myomers, mechweap, mislanch,
powersub, + the rest of the "917 missing functions".
### Revised reconstruction order
1. ~~**Helper classes** (block the layout): AlarmIndicator, SequenceController, NameFilter~~
**DONE 2026-07-19** — all 3 reconstructed + compile-verified under BC4.52:
MUNGA/ALARM.HPP (AlarmIndicator = StateIndicator subclass, header-only),
BT/SEQCTL.HPP+CPP (SequenceController struct + Init real; gait methods staged),
BT/NAMEFILT.HPP (NameFilter struct + Initialize, header-only). AverageOf survives.
BTVal is mostly base-class pose fields (re-attribute during layout, not Mech's).
2. **MechSubsystem base + roster** (GAUSS/PPC/SENSOR + .TCP partials + decomp).
3. **Finalize MECH.HPP** per the offset map; probe sizeof(Mech)==0x854.
4. **Mech ctor** (@004a1674): embedded construction + segment-table walk.
5. Per-frame path (mech2/3/4) + damage/weapon handlers.