Operator report: "artifacts bleeding over from the radar display into the
MFDs, I have noticed this in the BT411 builds as well, but does not happen
in the original."
MECHANISM (proven from the archive source, not inferred):
The ten cockpit heads are not ten framebuffers -- L4GAUGE.CFG gives each
port a BIT MASK into ONE 16-bit buffer. The colour head is six bits
(sec, 0x003F); the MFDs are bits 8-15 of the same words. A colour-head
defect can therefore only ever surface as MFD garbage, which is exactly
the reported shape.
The two translation-table builders in L4VB16.CPP are asymmetric:
BuildSecondaryTranslation (:5419) writes ONLY the active-bit
combinations -- 1<<numberOfBits entries, so 64 of int
translationTable[256] for this port. Entries 64..255 are never
written.
BuildAuxiliaryTranslation (:5443) nests IncrementInactive inside
IncrementActive and so fills all 256 -- which is why the mono MFD
ports are safe by construction and must NOT be touched.
DrawPixelMap8 (:2708) indexes that table with an 8-BIT source pixel, and
DrawPoint ORs the result in UNMASKED. An out-of-range index therefore
ORs whatever the heap left at translationTable[n] straight into other
ports' planes. The colour head's own art carries out-of-range
sentinels: AVACRIT.PCC is 94% <= 63 with 6% at exactly 231, BTSEC1.PCX
99.8% <= 63 with 0.2% at 254. Transparent draws skip them; OPAQUE draws
put every one through the table.
That it depends on heap CONTENTS rather than drawing logic explains both
the intermittency and why BT411 shows it too: both reconstructions
inherit the same latent read from the archive.
THE CHANGE, via the sanctioned source410-shadows-CODE seam (CODE/ is
untouched): a verbatim copy of CODE/RP/MUNGA_L4/L4GREND.CPP with one
difference -- port construction builds a BTL4GraphicsPort, whose ctor
zeroes translationTable[1<<numberOfBits .. 255] for SECONDARY ports only.
The guard (bit_mask & 0xFF) != 0 is literally the test
BuildSecondaryTranslation itself asserts on. numberOfBits is a popcount
set in the base ctor, so the subclass body sees 6 and the later
SetSecondaryPalette -> BuildSecondaryTranslation refills 0..63 over the
top without disturbing the zeroed tail.
WHAT IS AND IS NOT PROVEN -- the honest scoreboard:
PROVEN non-regressive. Gauge A/B, three boots: unfixed x2 and fixed x1
score identically on every head (Mfd1 132/0, Mfd2 37/7, Mfd3 23/0,
Eng1/2/3 and Comm exact), against a ~6px across-boot noise floor
established by re-booting the same binary.
NOT PROVEN to cure the symptom. The A/B rig captures the boot/attract
cockpit, where the MFD heads already show ZERO extra pixels -- there is
no bleed there to remove. The operator's report is in-mission with the
radar live. This is a hardening change against a real uninitialised
read that matches the symptom exactly; the cure needs a mission-state
capture to confirm.
METHOD NOTE: the first "fixed" capture appeared to regress the MFDs by
~2700px and nearly got the change reverted. It was a bad grab caught
mid-draw -- rebuild-and-rerun matched the unfixed numbers exactly. The
two-agreeing-runs rule earned its keep; a single run would have thrown
away a correct change. Worth noting the noise floor that mattered was
ACROSS boots, not the within-boot floor measured first.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>