I now have everything verified against the raw decomp, the engine headers, the CFG, and the sibling reconstructions. Here is the adversarial verdict. --- # ADVERSARIAL VERIFY — SectorDisplay: verdict **APPROVE WITH CORRECTIONS** The spec is structurally sound and its layout corrections over the current (buggy) `btl4gau3.hpp` are **right**. I confirmed sizeof, every ctor offset, the base chain, the Make idiom, the methodDescription row set (against the live CFG), the dtor/BecameActive/Execute structure, and all five systemic-check verdicts. **One substantive error** (a wrong rounding claim with a fabricated justification) and **two confidence downgrades** (disassembly-only claims) must be fixed before implementing. ## What I verified as CORRECT (keep as-is) - **Base = `GraphicGauge`, base ctor `FUN_00444818`, sizeof `0xC4`** — Make allocs `FUN_00402298(0xc4)` (part_014.c:2632). ✓ - **Every ctor offset** vs the raw `param_1[N]` writes (part_014.c:2666–2704): `gridImage@0x94`, `cellWidth@0x98=width/14`, `gridLeft@0x9C=cw*12`, `gridRight@0xA0=cw*13-1`, `gridHeight@0xA4`, `numericColor@0xA8`, `gridColor@0xAC`, both `500`s @0xB0/@0xB4, `numericA@0xBC (x=0)`, `numericB@0xC0 (x=cw*4)`. ✓ - **The header-layout fixes are real bugs in the current header** — it omits `@0xA8` and `@0xB8`, mislabels `@0x90` as `enabled` and `@0xB0/@0xB4` as `baseLine/dirty`, and wrongly gives the ctor **two** image strings (the raw has ONE, `param_9`, used for both grid + font). Spec fixes all of these. ✓ - **`@0x90` = `subject` Entity\* set by `LinkToEntity` (slot 9), NOT `enabled`/`SetEnable`** — well-founded: `FUN_004ca068` is a bare `this[0x24]=param` setter, base slot9 is the empty `LinkToEntity`, and Execute gates on `+0x90 != 0` and reads a *position* from it. This is the correct reinterpretation of the current header. ✓ - **methodDescription 5-row set** (`typeRate, typeModeMask, typeString, typeColor, typeColor`) — matches the Make's DAT_ reads AND the live CFG (`content/GAUGE/L4GAUGE.CFG:5146`): `sectorDisplay(K, ModeAlwaysActive, helv15.pcc, 0, 3)` with `offset=(125,579)` supplied separately. ✓ - **Make/ctor base-chain idiom** — identical to the registered sibling `PilotList` (`btl4gau3.cpp:226–238, 253`): `ParameterDescription *p = methodDescription.parameterList; … GraphicGauge(rate,mode,renderer,0,port,id)`. ✓ - **dtor** (implicit base, release grid, free name, delete numerics), **BecameActive** (dirty=1, ForceUpdate B-then-A, non-inactivating), **Execute** grid blit (`MoveToAbsolute(cw*3,0)`+`SetColor(gridColor@0xAC)`+`DrawBitMap(0,grid,gridLeft,0,gridRight,gridHeight)`) — all match the raw byte-for-byte. ✓ - **Systemic checks all correct**: Execute (slot16) + non-inactivating BecameActive (slot3) both overridden → no `Gauge::Execute` `Fail`→`abort`; the two NumericDisplays are private members drawn directly, not registered children → no child-`GuardedExecute` recursion; no shadow/alias/phantom fields; `subject`-NULL guarded with the viewpoint fallback; single cockpit gauge, not per-mech. ✓ - **`renderer->warehousePointer` is reachable in member methods/dtor** — confirmed by `PlayerStatus::Execute` (`btl4gau3.cpp:673`). Registration line goes before `&BTL4ChainToPrevious` (`btl4grnd.cpp:150`). ✓ ## CHANGES I made (what was wrong) **① CRITICAL — `FUN_004dcd94` is `ROUND`, not truncate.** Confirmed at its definition (`part_015.c:3769`): `local_10 = (undefined4)(longlong)ROUND(in_ST0);` — round-to-nearest (x87 `frndint`, half-to-even). The codebase's own map agrees (`btl4gau3.cpp:36` "FUN_004dcd94 Round"; CLAUDE.md). The spec asserts the **opposite** ("truncate toward zero … RC=chop `or 0xc`, `fistp` … `(long)` not round-to-nearest") — that justification is **fabricated**; there is no `or 0xc`/`fistp` in the function. Fix: the two numerics must **round**, not C-truncate. Use `lrintf` (default FE_TONEAREST == `frndint`) or the engine `Round`, never `(int)(x)`. **② Downgrade the position data-binding to disassembly-sourced / MEDIUM confidence.** The pseudocode Execute (`FUN_004ca07c`, part_014.c:2789–2794) shows **only** `iVar2 = FUN_004dcd94(); iVar3 = FUN_004dcd94();` — the decompiler dropped the x87 operand loads. So the *entire* mapping (that `iVar2 = -Z·0.01`, `iVar3 = +X·0.01`, the `fchs`, and the `0.01` scale) is the reviewer's disassembly, which was **provably wrong on `FUN_004dcd94`**. The `subject != 0` gate + the two `+500` offsets + drawing two numerics are pseudocode-solid; the **which-axis / sign / scale** are not. Keep the mapping as the best structural reconstruction but mark it, and re-disassemble `@0x4ca089–0x4ca0b9` to lock the axis/sign/scale before claiming fidelity. (The read itself — `subject->localOrigin.linearPosition` via the engine `Entity` type — is confirmed as the established radar pattern: `btl4rdr.cpp:150` reads `entity->localOrigin.linearPosition`; `ENTITY.h:140 Origin localOrigin`; entity+0x100 == that per `btl4rdr.cpp:622`.) **③ Unify the `FUN_00442aec` naming to `GetIfAlreadyExists`** (the codebase's established name, `btl4gau3.cpp:128–129 "peek, no AddRef"`). The spec inconsistently modeled the identical call as `bitMapBin.Get` (held) in the ctor but `GetIfAlreadyExists` (peek) in Make/Execute. Use `GetIfAlreadyExists` in all three; keep the dtor `Release` (`FUN_00442c12`, part_014.c:2717) balancing the ctor's held reference and the Make existence-check Release (part_014.c:2640) — that is binary-faithful. **④ Minor:** remove the now-unused static `DAT_0051a2bc/0300/0344` placeholders (`btl4gau3.cpp:69–71`) — the rewired Make reads `methodDescription.parameterList` (same as the PlayerStatus rewire, line 72–73). Drop the redundant `(L4Warehouse*)` cast in Make (`warehousePointer` is already typed, per line 128). Confirm `NumericDisplay::unsignedFormat == 0` (raw format arg is literal `0`); if unsure use `(NumericDisplay::Format)0`. The `offsetX/offsetY` names are misleading (both `500`; A feeds the Z-numeric, B the X-numeric) — rename `sectorBaseA/sectorBaseB` or just comment "both = 500". ## Corrected Execute (the only body that changes) ```cpp // @0x4ca07c -- Execute (slot 16). RAW: iVar2/iVar3 = FUN_004dcd94() = ROUND(ST0) // (part_015.c:3769); the x87 operand loads were dropped by the decompiler, so the // -Z / +X axis assignment, the fchs and the 0.01 scale are DISASSEMBLY-sourced // (@0x4ca089-0x4ca0b9) and MEDIUM-confidence -- re-verify before claiming fidelity. void SectorDisplay::Execute() { Entity *s = subject; // this+0x90 if (s == NULL && application != NULL) // PORT: LinkToEntity broadcast s = (Entity *)application->GetViewpointEntity(); // may be unwired -> fall back if (s == NULL) return; // binary gates purely on subject!=0 const Point3D &pos = s->localOrigin.linearPosition; // engine type (NOT raw +0x100) int vA = (int)lrintf(-pos.z * 0.01f) + sectorBaseA; // ROUND, not (int) truncate int vB = (int)lrintf( pos.x * 0.01f) + sectorBaseB; numericA->Draw(&localView, (Scalar)vA); // FUN_00470430 numericB->Draw(&localView, (Scalar)vB); if (dirty) { // this+0xB8 dirty = 0; BitMap *grid = ((L4Warehouse *)renderer->warehousePointer) ->bitMapBin.GetIfAlreadyExists(gridImage); // FUN_00442aec if (grid != NULL) { localView.MoveToAbsolute(cellWidth * 3, 0); // vtbl+0x24 localView.SetColor(gridColor); // vtbl+0x18 (this+0xAC) localView.DrawBitMap(0, grid, gridLeft, 0, gridRight, gridHeight); // vtbl+0x54 } } } ``` Everything else in the spec (identity table, the `0xC4` overflow-lock, the methodDescription literal, the registration line, ctor/dtor/Make/BecameActive/TestInstance bodies) is **correct as written** — apply only ①–④. ## FINAL CONFIDENCE **HIGH** on structure, layout, registration, and all systemic-check verdicts (pseudocode-verified). **MEDIUM** on the numeric data-binding specifics: the value is a *rounded* `±position·0.01 + 500`, but the exact axis→numeric assignment and the sign of Z are disassembly-only and the reviewer's disassembly was demonstrably unreliable (it inverted the rounding mode). Re-disassemble `@0x4ca089–0x4ca0b9` to lock the axis/sign/scale; nothing else blocks implementation. **Remaining UNKNOWNS (non-blocking):** exact axis/sign/scale of the position read (②); whether `GaugeRenderer::LinkToEntity` is broadcast in the port (the viewpoint fallback makes it LIVE either way); `NumericDisplay::unsignedFormat`'s enum value (raw = `0`).