four ENG-page lamps were invisible, not missing: the ctors dropped their colour parameters
Playtest report: "generators don't seem to have an Auto setting" / "no auto mode is ever displayed", plus the operator's own memory that the BUS MODE button once stepped through three states. The state machine was NEVER wrong: @004b0abc has exactly two branches (<2 -> Auto(2); ==2 -> detach + Off(0)), Manual(1) is set only by the four SelectGenerator buttons, and the auto-hunt gates on ==2 -- all byte-verified, and the #62 re-attach fires live. Manual is a one-way door out of BUS MODE by design: a single cycle button cannot know WHICH generator manual should mean. Verified on-screen by the operator this session: A-D returns to manual, BUS MODE toggles auto/off thereafter. What was actually broken: the connect-mode lamp -- and three siblings -- never drew a pixel. OneOfSeveralStates (@004c5470) and OneOfSeveralInt (@004c5148) forward caller-supplied background/foreground colours in the binary; the recon dropped both parameters and hardcoded 0,0 into the base. A BitMap-strip lamp draws SetColor(bg) + DrawBitMapOpaque(fg,...), so 0/0 painted colour-0 on colour-0: invisible. Affected: btemode (connect mode, 1x3 -- THE report), btecmode (coolant on/off, 1x2), and both bteseek gear-step lamps (1x4). The cluster call sites pass 0xff/0, byte-verified (@004c866c disasm; part_014.c:1479-1481, :2146-2147). Same dropped-element family as issue #42's MoveToAbsolute. THE TRAP THAT WAS NOT LANDED, recorded so it stays unlanded: with the lamp first made visible, the frames appeared inverted against the levels (art reads AUTO/MANUAL/OFF top-down; levels run OFF/MANUAL/AUTO), and a row=(rows-1)-selected "fix" was proposed. An adversarial workflow proved it wrong: the gauge blit addresses SOURCE rows BOTTOM-UP (Video16BitBuffered::DrawBitMapOpaque, L4VB16.cpp:3846-3850 -- sTop = map_max_y - sTop, rows walked upward), the 1995 blit @0046bdfc performs the identical flip, and the vertical strips are AUTHORED bottom-up to match. Identity level->row therefore draws the pod-correct display; the inversion would have created the very bug it claimed to cure. Two of five investigators (and the first human pass) assumed top-down; the engine source overruled all three. Convention + warning now recorded in context/gauges-hud.md. btecmode doubles as the standing tripwire: a second vertical strip that must show ON when coolant is available -- if it ever reads inverted, the bottom-up verdict is falsified. Also corrected: @004c552c is OneOfSeveralStates' EXECUTE override (clamp >= 0, chain the base draw) -- the port had the body on BecameActive under a wrong label; vtable-diffed against OneOfSeveral (0x518b24 vs 0x518bf0). BecameActive is inherited. Behaviorally inert today (the state source never goes negative), byte-faithful now. README: the "KNOWN ISSUE -- automatic re-attach is not working yet" text is replaced with how power routing actually works (A-D = manual, BUS MODE = auto then off, two presses off / one back to auto). That text shipped in 600, which already contained the #62 fix -- players were being TOLD auto was broken while it worked, which is half of how a painted-out lamp became "no auto mode". Diagnostic kept: BT_GENSEL_TEST=<id> now drives any of the five power-routing message ids (4..8, default 7) and pulses four times, so the whole mode cycle is observable headlessly under BT_FIRE_LOG ([gensel] lines). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
c32d02b3cc
commit
901cf1b459
@@ -654,6 +654,34 @@ Player CALLSIGN labels (kill/damage feed, radar/target tags, score display) are
|
||||
BITMAPS from the egg, not text — format, renderers, and the operator-console generator:
|
||||
[[multiplayer]] §OPERATOR-SET CALLSIGNS.
|
||||
|
||||
## Lamp strips: the BOTTOM-UP source-rect convention (do NOT "fix" the flip) [T0/T1]
|
||||
|
||||
**The gauge blit addresses SOURCE rows bottom-up, and the vertical strip artwork is authored
|
||||
to match.** `Video16BitBuffered::DrawBitMapOpaque` converts the incoming source rect with
|
||||
`sTop = map_max_y - sTop; sBottom = map_max_y - sBottom` and walks rows upward
|
||||
(`engine/MUNGA_L4/L4VB16.cpp:3846-3850`, `UP_BITMAP` :2155) [T0]; the 1995 display blit
|
||||
@0046bdfc performs the IDENTICAL flip [T1 disasm], and the PCC→BitMap loader stores the PCX
|
||||
top scanline at memory row 0 unflipped (`GRAPH2D.cpp:27-174`). Net: in `OneOfSeveral::Execute`
|
||||
`sy0 = row*frameHeight` selects frames counting from the **BOTTOM** of the image as authored.
|
||||
The vertical strips are painted for exactly this: `BTEMODE.PCC` (1×3) reads AUTO/MANUAL/OFF
|
||||
**top-down**, i.e. OFF is the bottom frame = value 0 — so identity level→row draws the pod-
|
||||
correct display (`0=OFF, 1=MANUAL, 2=AUTO`). Horizontal strips (`btebus`/`btpbus`/`bteloop`,
|
||||
rows=1) are insensitive to the convention. **A "row = (rows-1)-selected" correction here is a
|
||||
trap** — it was nearly landed 2026-07-28 on the assumption the blit is top-down; it would
|
||||
invert every vertical lamp. (An adversarial workflow settled this against two of five
|
||||
investigators; the port and the binary agree end-to-end.) Residual [T3]: the `DrawPixelMap8`
|
||||
branch's source-y convention is untraced — verify before authoring any vertical PixMap8 strip.
|
||||
|
||||
**The dropped-colour-parameter family (2026-07-28):** the binary's `OneOfSeveralStates`
|
||||
(@004c5470) and `OneOfSeveralInt` (@004c5148) ctors forward caller-supplied
|
||||
background/foreground colours; the recon dropped both parameters and hardcoded `0,0`, so a
|
||||
BitMap-strip lamp drew `SetColor(0)` + `DrawBitMapOpaque(0,…)` = invisible. Hit every one of:
|
||||
`btemode` (connect mode, 1×3 — reported as "no Auto mode exists"), `btecmode` (coolant on/off,
|
||||
1×2), both `bteseek` gear-step lamps (1×4). Cluster call sites pass `0xff,0`
|
||||
(part_014.c:1479-1481, :2146-2147). Same bug class as issue #42's dropped `MoveToAbsolute`.
|
||||
Also corrected: @004c552c is OneOfSeveralStates' **Execute** override (clamp ≥0, chain base),
|
||||
not `BecameActive` — vtable-diffed.
|
||||
|
||||
## Key Relationships
|
||||
- Full history: `docs/GAUGE_COMPOSITE.md`; reticle recovery: `phases/phase-02-dpl2d-reticle.md`.
|
||||
- Uses: [[attribute-pointer]] + [[reconstruction-gotchas]]; reads [[subsystems]] state.
|
||||
|
||||
Reference in New Issue
Block a user