33fd921cea4e3eaa56bc48a2b8d285cd1de4312e
9
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
df8c2552d0 |
BT410 5.3.87: OPERATOR-CONFIRMED -- both artifacts gone on a live mission
Full arena1 mission on the pod rig (podrun.sh pod_render_norio, 5.3.83-86 staged), run clean to steady state with no fault. Operator: "the artifact appears to be gone and the bleed from the control mode seems to be gone as well." Both reported symptoms -- the yellow-orange bar on the colour head and the bleed into the MFDs -- from the one uninitialised read, closed by the one zero-fill. WEIGHT OF THE EVIDENCE, stated plainly rather than banked as a win: This is ONE run of an INTERMITTENT, heap-content-dependent artifact. A clean run is exactly what the UNFIXED build also produced on the gauge A/B rig, three boots running, which is the whole reason the fix could not be verified there. So the observation is not logically airtight on its own. What makes it convincing anyway is the shape of the fix rather than the count of runs: after it, no index in 64..255 can return anything but zero, whatever the heap holds. The behaviour is deterministic by construction, where before it was a lottery. Combined with the operator having seen the artifact repeatedly across BOTH this reconstruction and BT411, one clean run on the rig that was showing it is meaningful. Further clean runs strengthen it. A recurrence would mean a SECOND source -- most likely whatever blits the *CRIT/*HEAT silhouettes, still unidentified, still carrying 1500-2500px of index 231 apiece -- and NOT a failed fix. That distinction is worth keeping straight if it ever comes back. Still open and unchanged by this: the 354px runtime-generated cluster, and which widget blits the 231-bearing avatar art. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
902ccf1332 |
BT410 5.3.86: colour-mapper escalation KILLED -- they read palettes, they never blit
5.3.85 raised a hypothesis and explicitly flagged it as unverified: the 1345
colour-mapper entries (656 cmCrit, 662 cmHeat, 27 cmArmor) all sit on port 0,
their mode is ModeSecondaryCritical, and they name adpal.pcc / adpal2.pcc /
heatpal.pcc -- three files the art sweep flags, with ADPAL and ADPAL2 being 2x5
and ENTIRELY index 99. If those pixels were blitted as colour indices, 1345
widgets would each be writing out-of-range on the six-bit head, which would
dwarf the 676px bar and would fire in-mission, exactly where the operator sees
the artifact.
Read the implementation. It does not happen.
ColorMapper::ColorMapper (BTL4GAUG.CPP:389) takes the two names into the
palette8Bin -- not a pixelmap bin, not a bitmap bin -- and the execute path
(:526) is
Palette8 *palette = warehouse->palette8Bin.GetIfAlreadyExists(...);
PaletteTriplet &entry = palette->Color[currentColorIndex];
...
graphicsPort->SetColor(&entry, colorSlot);
It reads the file's VGA PALETTE, lifts one RGB triple, and pushes it into a
hardware colour slot. No pixel of ADPAL ever reaches a framebuffer, so its
index-99 content cannot matter. The palette PAIR is a flash toggle
(paletteToggle alternates per frame), which is also what twoColorMode's
name comparison is for.
NEGATIVE. Recorded as a closed hypothesis rather than deleted, so it does not
get re-raised the next time somebody greps the sweep and sees ADPAL at 100%
out-of-range.
What this leaves: the in-mission exposure, if there is one, is NOT the
mappers. The *CRIT/*HEAT silhouettes still carry 1500-2500px of index 231
each, and which widget blits them is still unestablished. The boot cockpit
does not draw them, which is why it lights only 1030 pixels.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
||
|
|
5a465c2321 |
BT410 5.3.85: the six-bit hazard surveyed -- draw site named, 94 art files inventoried, a 1996 config typo found
Follow-up survey to 5.3.84, written into L4GREND.NOTES.md rather than left as
conversation.
THE DRAW SITE, NAMED. This closes a question that had been open across
several sessions ("which of the three DrawBitMapOpaque sites draws
sentinel-bearing sec art"). Answer: none of them. It is a DrawPixelMap8 --
BTL4GAU2.CPP:1524, the bgPixelMap widget, MoveToAbsolute(0,0) then a
full-image OPAQUE blit. BT_VIS_LOG places it at port=0, the six-bit head.
Every pixel of the colour head's background therefore goes through the
64-entry translation table, sentinels included.
ALSO PROVEN: no drawing operation contains the damage. The opaque inner loop's
Replace case is
*dest = (Word)((*dest & bitmask) | color);
which clears THIS port's bits and then ORs the whole table entry back --
including garbage in other ports' bit positions. Replace leaks exactly like
Or does.
ART INVENTORY. Swept all 428 PCX/PCC under GAUGE (which is all the art there
is -- nothing lives outside it). 94 carry pixels > 63: index 231 in 53 files
(sparse, 4-7%, the 172x217 avatar CRIT/HEAT silhouettes), 255 in 27 (the *HT
heat backgrounds), 226/228/229 as 1-2px specks in QJAK*, and 254 in 2.
BTSEC1.PCX is the only one whose out-of-range region is a SOLID RECTANGLE and
the only one proven to reach the screen -- 676px at (199,526)-(250,538),
rotation 270 mapping screen = (src_y, 479 - src_x), landing exactly on the
measured mask.
WHAT IS STILL OPEN, recorded as open rather than smoothed over:
The 354px cluster. Of the provoke control's 1030 lit pixels, 676 are the
bar; the remaining 33x32 cluster at (67,3)-(99,34) is NOT file-borne -- no
gauge file has a count near 354. So it is generated at runtime. The
obvious suspect CreateMutantPixelmap8 is ruled out: it is an inert stub
returning NULL, so recoloredMech never blits here. Unattributed; the fix
covers it regardless.
A possible second exposure, in-mission. L4GAUGE.CFG carries 1345
colour-mapper entries (656 cmCrit, 662 cmHeat, 27 cmArmor), BT_VIS_LOG puts
ALL of them on port 0, and their mode is ModeSecondaryCritical. They name
adpal/adpal2/heatpal, three of which the sweep flags -- ADPAL and ADPAL2 are
2x5 and ENTIRELY index 99. Whether that matters turns on whether a mapper
blits those pixels or merely reads their VGA palette, which nobody has
checked. Written down as a hypothesis with that caveat attached, NOT as a
finding. If the pixels are used as indices it would dwarf the bar and would
fire in-mission, which is where the operator sees the artifact.
The boot cockpit lighting only 1030 pixels says the avatar/mapper art is not
drawn on THAT screen. It says nothing about a live mission.
A SHIPPED DATA BUG, found in passing and deliberately NOT fixed:
L4GAUGE.CFG:2513-2514 name adpa12.pcc -- digit one for lowercase L. The
file does not exist; adpal2.pcc does. Two of 1345 lines, so the GAUSS and
AFC25 ammo-bin criticals have been loading a missing palette since 1996.
It is the original's bug and the shipped binary lives with it; the archive
is sacred, so we live with it too. Noted so the next person who sees a
warning about adpa12.pcc does not go hunting for a reconstruction defect.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
||
|
|
943219345a |
BT410 5.3.84: the yellow bar and the MFD bleed are ONE bug -- BTSEC1.PCX index 254, and the offender is named
Second operator report, same day: "what is that yellow orange artifact on the
display, it too shows up here and in bt411 but not in the original" -- a
solid vertical bar beside the RANGE readout on the colour head.
It is the same defect as 5.3.83's MFD bleed. Not a similar one: the same
676 pixels.
HOW IT WAS CAUGHT. 5.3.83 shipped a fix that could not be verified, because
the fix makes something INVISIBLE and the A/B rig's boot cockpit already
showed zero MFD extras -- the unfixed build looked perfectly clean. So this
commit adds a POSITIVE CONTROL instead of another argument:
BT_TRANS_PROVOKE fills the colour head's uninitialised
translationTable[64..255] with 0xFF00 -- every high-byte head bit --
rather than the zero the fix installs. Any draw that indexes the tail
then lights ALL the mono heads at once.
On the boot cockpit that lights exactly 1030 pixels: Eng1/Eng2/Eng3 +1030
each, Mfd1 +684, Mfd2 +704, Mfd3 +1074, Comm +676, against 0 extras with the
fix. The bug was firing the whole time. Our heap simply happened to hold
zeros in that tail -- the same luck the shipped binary has been having, which
is exactly why the operator sees the artifact and the A/B rig does not.
THE OFFENDER, NAMED. oormask.py renders which pixels those are and prints
their horizontal run lengths. The mask is a glyph cluster plus 52 runs of
13px -- a SOLID 13x52 BAR at screen (526,228)-(538,279). Solid means a
rectangle in the source art, so decode the art:
BTSEC1.PCX, the colour head's own 480x640 background, contains exactly
ONE out-of-range value in the entire image: index 254, exactly 676
pixels, a solid 52x13 rectangle at (199,526)-(250,538).
The sec port is configured at ROTATION 270, mapping source (x,y) ->
screen (y, 479-x). That puts the rectangle at screen x 526..538,
y 229..280. Measured mask: x 526..538, y 228..279. Same rectangle, to
the pixel.
ONE READ, TWO SYMPTOMS. translationTable[254] is never written (
BuildSecondaryTranslation fills only 1<<numberOfBits = 64 entries), and
DrawPoint ORs the result in unmasked. Whatever the heap left there decides
which symptom the operator sees:
low 6 bits set -> a coloured block on the COLOUR head, beside the RANGE
readout. The yellow-orange bar.
high 8 bits set -> garbage in the MFD / ENG / COMM planes. The bleed.
Both reports, one uninitialised int. It also explains the "not in the
original" asymmetry without needing the original to differ in code: it does
not differ, it is just getting zeros there. And it explains BT411 showing it
too -- both reconstructions inherit the read from the archive.
5.3.83's zero-fill therefore cures both, and turns a heap-lottery into a
guarantee. Still not DIRECTLY observed cured, because no rig we have was
showing the artifact to begin with; that honesty is recorded in the file
header rather than smoothed over.
ALSO IN: oormask.py, barbox.py, vis_provoke.conf, and a README section on
positive controls -- when a fix replaces garbage with a benign value, build
the variant that replaces it with a maximally LOUD value, because that turns
"I see no difference" into a number and separates "the fix works" from "this
screen never exercised the path".
METHOD NOTE, recorded in the README because it nearly cost the fix: three
grabs of one running instance score IDENTICALLY, so the within-boot noise
floor is zero -- and that is the wrong floor. Judging a rebuild needs the
ACROSS-boot floor (~6px on the MFD heads). A single bad grab, caught
mid-draw, read as a 2700px regression and nearly got a correct change
reverted.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
||
|
|
7c3d089d9c |
BT410 5.3.83: MFD-bleed hardening -- the uninitialised half of the 6-bit colour head's translation table
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>
|
||
|
|
0906d1efa6 |
4.10 reconstruction: real l4net standalone path + full BTL4Mission::SetPlayerData
Boot ladder progress (each step verified live under DOSBox-X + 32RTM): - L4NET.CPP v2: real statics (ClassDerivations/MessageHandlers/DefaultData), real single-user ctor (egg NotationFile -> last.egg -> local ReceiveEggFile post), real StartConnecting/Shutdown/CreateConsoleHost single-user branches, all four message handlers (egg assembly, ack, host connect/disconnect), 1995 netnub-guard idiom (Net_Common_Ptr NULL => benign return) throughout; netnub wire primitives remain Fail-staged. Sources: BT411 engine/MUNGA_L4/ L4NET.cpp (preserves the 1995 netnub code as comments beside its Winsock port) cross-checked against the surviving 1995 L4NET.HPP. - BTL4MSSN.CPP: full SetPlayerData reconstruction (vehicle/dropzone/color/ patch/badge/team/experience/advancedDamage/role + score modifiers + plasma badge blit), backdated from BT411's Ghidra-recovered body (@004d2c30); every API pinned to the surviving 1995 headers (NOTATION/MISSION/SCNROLE/ L4GREND/BTMSSN). Boot now runs: banner -> resource load -> app ctor chain -> network manager single-user init -> egg dispatch -> mission creation -> SetPlayerData (parses the real TEST.EGG) -> halts at BTPlayer ctor (next staged brick). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
5b35eb973c |
4.10 reconstruction: BTL4OPT.EXE links clean and BOOTS to the first staged brick
The reconstructed tree now produces a runnable binary with the authentic 1995 toolchain (BC4.52 / tlink32 / DPMI32): - BTL4.CPP main TU reconstructed from the 4.11 Ghidra decomp (FUN_0040109c) + the 4.10 binary's own string pool + surviving RPL4TOOL.CPP house style; probe_main.cpp scaffold retired (BTL4.NOTES.md documents every decoded call) - L4NET.CPP staged: L4NetworkManager ctor/dtor + 10 vtable-pulled virtuals (standalone-benign ones no-op, network ones Fail loudly) + NetNub client globals (Net_Common_Ptr=NULL routes L4File to its plain-DOS path) - build410.sh: libs now built in the AUTHENTIC makefile member order (MUNGA.MAK / mungal4.mak / BT.MAK / BTL4.MAK). Order is load-bearing: tlink emits static-init records in module pull order, and alphabetical order booted into a null-vptr crash (IcomManager::ClassDerivations constructing before parent NetworkClient::ClassDerivations). Also fixed stage_link to the proven 32-bit lib set (SOSDBXC+SOSMBXC, no WATTCPLG) - BOXTREE.HPP MemoryBlock unify, BTL4GRND notify stubs, remaining engine backfills (audio/gauge/resource/stream TUs) that closed the deep ledger Smoke test (DOSBox-X + 32RTM, copy of the pod BT tree, our exe swapped in): BattleTech v4.10 BTL4Application::BTL4Application l4net.cpp(22): L4NetworkManager -- l4net.cpp not yet reconstructed Static init, main, -egg parse, BTL4.RES load (version 1.0.6 check passes), ApplicationManager and the BTL4Application ctor chain all execute real reconstructed code; boot halts at the first staged Fail() as designed. Next brick: the real l4net.cpp body. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
af80d52e22 |
source410: engine COMPLETE (165/165) - link reaches PE emission; deep ledger cut
The tlink32 campaign after the checkpoint: eleven engine bodies back-dated from BT412 (rotation player team explode dropzone terrain cultural receiver subsystm app l4gauge - the Application core included), the WinTesla-ectomy handled by backdate.py's new unwrap rules (accessor-fn statics -> 1995 static objects, decl rewrites, pointer->reference Derivation ctor, 2007 windowed- gauge/console-marshal/idle-pump excisions), staged statics TUs opened for the game classes (MECH/BTPLAYER/BTDIRECT/PROJTILE/MISSILE/BTL4MPPR .CPP + L4APP/ NETWORK engine statics). State: every compiled symbol short of the shallow graph RESOLVED (the 52- and 17-symbol ledgers burned to zero); with 32stub.exe in place the linker reaches full vtable closure and emits the deep ledger (~210 symbols, UNRESOLVED- LEDGER.txt): remaining engine bodies (objstrm cstr gauge/gaugrend graphics pixelmap palette resfile ray scnrole explosion-table), the DOS driver extern layer (_SVGA*/_PCSerial*/_PCSPAK*/joystick/netnub/sosMIDI), the full L4App body, and the real game-TU frontier (Mech::Make et al.). Recipe proven for every category. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
6b216d0643 |
source410: link campaign - entire engine compiles (152/152), first true link,
52-symbol unresolved ledger build410.sh: merged-engine mass compile + BT TUs + tlib + authentic tlink32. Engine closure fixes: boxtree/set/l4gauge/filestrm back-dates, lamp<->gaugrend cycle broken (1995 form), APP.HPP Shutdown default, NetNub include path, DPL vpx shim, SOS 32-bit lib arbitration (SOSDBXC/SOSMBXC; SOSMW*=16-bit), WATTCP excluded (16-bit NetNub TSR side). UNRESOLVED-LEDGER.txt = the measured gap to a linking BTL4OPT.EXE. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |