Merge remote-tracking branch 'origin/master'
# Conflicts: # game/reconstructed/btl4gau2.cpp
This commit is contained in:
@@ -142,6 +142,22 @@ At the authentic 1e7-unit economy (tasks #9-#10) the Heat MFD is fully dynamic:
|
||||
77→2000 (the authored failure threshold), condensers/generators run 100-1400 under sustained
|
||||
fire, and the bank plateaus ~600 — temperatures, heatLoad and the heat alarms all animate. [T2]
|
||||
|
||||
## Radar view-wedge tracks the torso twist (Gitea issue #1 — FIXED 2026-07-17) [T2]
|
||||
The SECTOR radar's view cone (`MapDisplay::DrawViewWedge` @004c2484, btl4rdr.cpp) reads
|
||||
`viewHorizontalRotation@0x31C`, fed by a per-frame `GaugeConnectionDirectOf<Radian>` the ctor
|
||||
wires from the mech's Torso. The two helpers were NULL stubs, so the connection was never
|
||||
created and the wedge sat at heading 0 (the reported "cone does not track the twist").
|
||||
Reconstructed from the binary: `FindSubObject` (FUN_0041f98c) = a SUBSYSTEM-ROSTER walk
|
||||
(count @+0x124 / array @+0x128) matching the streamed name (sub+0xd4) case-insensitively
|
||||
(FUN_004d4b58 = tolower-strcmp) — the "Torso" sub-object IS the roster Torso subsystem;
|
||||
`GetHorizontalRotation` = torso+0x1D8 = `Torso::currentTwist` (layout-locked), reached via the
|
||||
existing task-#56 bridge `BTGetTorsoTwistAddr` (Radian ≡ {Scalar angle}, exact reinterpret).
|
||||
VERIFIED live (MadCat, Standard mode Q/E): wedge rot tracks twist 0→−2.21 rad in lockstep, and
|
||||
the SEMANTIC test passes — body turned away, torso twisted back onto the enemy → reticle goes
|
||||
green AND the wedge points at the enemy's blip while the scope stays body-fixed. ⚠ Test with a
|
||||
TWISTING mech: the Blackhawk's torso is FIXED (limits ±0.01°) — its wedge authentically never
|
||||
moves. Diag: `BT_RADAR_LOG` ([radar] ctor probe + 1 Hz [radar-wedge] rot trace). [T2]
|
||||
|
||||
## Remaining = DATA FEEDS, not widgets (deferred systems)
|
||||
**✅ The condenser valve CONTROL is LIVE (task #13, 2026-07-11) [T2]:** `MoveValve` (id 4, the
|
||||
Condenser handler table @0x50E52C — exactly one entry) registered + guarded by the REAL
|
||||
|
||||
@@ -29,6 +29,32 @@ authentic path scoped.
|
||||
Remaining: bind the side/down look views to keys (only 'V' look-back is bound); pod look-button
|
||||
mappings for Phase 8.
|
||||
|
||||
## Pod-hardware readiness gaps (Phase 8 assessment, 2026-07-17) [[pod-hardware]]
|
||||
Everything below EXISTS in the tree but has NEVER run against real pod hardware. Mechanism
|
||||
status vs the pod's 7-display / RGB-splitter / dual-sound-card rig:
|
||||
- **CARRIED + plausibly functional (untested on hardware):**
|
||||
- RIO serial controls: real Win32 COM (`L4SERIAL` CreateFileA/SetCommState), the full chain
|
||||
RIO AnalogReply → Ranger → ControlsManager → streamed `.CTL` mappings → mapper traced [T1];
|
||||
keyboard bridge disable = `BT_KEY_BRIDGE=0`. Pod look/config buttons are `.CTL` data-driven.
|
||||
- RGB-splitter channel packing: `L4GraphicsPort::ChannelEnableID` (Red/Green/Blue/All +
|
||||
transparent-zero variants) — each gauge draws into ONE color channel of the shared
|
||||
640x480x16 surface, feeding one monochrome CRT per channel through the splitter. The gauge
|
||||
CONTENT is complete (same `L4GaugeRenderer` verified daily in the `BT_DEV_GAUGES` window).
|
||||
- Multi-output selection: `SVGA16::BuildWindows` (a fullscreen D3D9 device per gauge/MFD
|
||||
surface), adapter env `PRIMGAUGE`/`SECGAUGE`/`MFDGAUGE`/`MFDGAUGE2`/`SPANDISABLE`, MFD span
|
||||
= width x2 across two displays; `content/SETENV.BAT` = the authentic pod env preset.
|
||||
- The `L4PLASMA.cpp` serial plasma-display driver (`L4PLASMA=com2`).
|
||||
- **EXPECTED TO NEED REAL WORK on modern hardware:**
|
||||
1. **Multi-head display management**: the original used TWO video cards; simultaneous
|
||||
exclusive-fullscreen D3D9 devices on multiple heads of one modern GPU is fragile — likely
|
||||
needs a borderless-window-per-head modernization of `BuildWindows`.
|
||||
2. **The REAR sound card is folded away**: the pod ran `AWE_FRONT`/`AWE_REAR` as two physical
|
||||
cards for the 4-speaker front/rear split; our OpenAL opens ONE device (front/rear collapses
|
||||
to stereo). Feasible fix: OpenAL Soft quad output (surround config) or a second device.
|
||||
3. Serial protocol timing/handshake vs a real RIO board (and the intercom path) — unverified.
|
||||
4. `-platform pod` deliberately does NOT auto-enable `L4GAUGE` (each surface needs its own
|
||||
device); the pod bring-up procedure itself is undocumented → the Nick items above.
|
||||
|
||||
## BINARY-COVERAGE AUDIT discoveries (2026-07-13, 6-agent decomp census) [T1 verified-uncited]
|
||||
New unaccounted functionality no prior list knew (addresses verified absent from game/+context/+docs):
|
||||
- **✅ `BTL4VideoRenderer::StartEntityEffectImplementation` @004d097c — DONE (2026-07-13) [T2].**
|
||||
@@ -618,6 +644,10 @@ register. ⚠ The audit also flags the damage-economy item as SELF-CONTRADICTOR
|
||||
LIVENESS audit (does a live call path reach each reconstructed fn?) would catch this class.
|
||||
|
||||
## Rendering follow-ups (non-blocking)
|
||||
- ~~Per-pilot mech PAINT (color/badge/patch)~~ — **DONE 2026-07-17, verified live** (crimson MadCat +
|
||||
yellow VGL emblems + hip hazard stripes). Mechanics + the vehicletable color/badge/patch name
|
||||
tables in [[rendering]] §Per-pilot mech PAINT. Residual nit: eggs saying `color=Red` mean
|
||||
**Crimson** (table has no Red; the binary Fail()ed on it, the port warns + drops).
|
||||
- **.PFX effect-layer polish (deferred 2026-07-08; the layer itself is LIVE + verified).** The
|
||||
reconstructed BT particle layer (L4VIDEO.cpp, see its banner) renders the authentic .PFX content
|
||||
(fire + smoke, premultiplied blend, impact-frame oriented — weapon hits AND damage bands via
|
||||
|
||||
@@ -263,6 +263,11 @@ state transitions: charge/seek loops, snap comparisons, timers compared with `==
|
||||
ucrtbased **abort() dialog** ("Debug Error!"), not an AV — `sxe av` won't break there; the box
|
||||
blocks the event loop (a headless node just "stops logging"). cdb: run with a config that does
|
||||
`g` then `kb 40` — the int3 lands ON the aborting thread. [T2]
|
||||
- **Verify under the USER'S launch flags, not a bare run:** a "30 s regression: stable" check that
|
||||
omits `BT_DEV_GAUGES=1` / `BT_START_INSIDE=1` (the `tools/mp_launch.sh` set) misses any bug on the
|
||||
gauge/cockpit paths those flags gate. The task-#7 gauge crash was DORMANT for a day because every
|
||||
post-commit check ran flagless; it surfaced the instant the pod launch config was used. Reproduce
|
||||
with the real launcher's env, and drive (`-net` keyboard) — not just spawn-and-look. [T2]
|
||||
|
||||
---
|
||||
|
||||
@@ -358,6 +363,36 @@ hundreds of pixels off-scope (the radar looked simply "empty"; nothing crashed,
|
||||
decompile) before assigning it an engine method — a wrong-but-plausible identity survives
|
||||
every compile and every "it runs" test.
|
||||
|
||||
## 18. Uninitialized stack-built resource → garbage `simulationFlags` (the "worked for weeks then broke" trap)
|
||||
|
||||
**Symptom:** a subsystem installed from a HAND-BUILT (stack) `*__SubsystemResource` silently stops
|
||||
ticking — `IsNonReplicantExecutable()` returns false because a stray `DontExecuteFlag` (0x2) bit is
|
||||
set. Config-dependent and nondeterministic: it "works for weeks" then an UNRELATED commit that shifts
|
||||
the stack layout before the install flips the garbage bit. Archetype (task #7, 2026-07-17): the RIO
|
||||
controls mapper built on the stack in `btl4app.cpp MakeViewpointEntity` — `Subsystem::Subsystem`
|
||||
copies `model->subsystemFlags` into `simulationFlags`, but the stack struct only set
|
||||
`subsystemName`/`classID`/`subsystemModelSize`, leaving `subsystemFlags`+`segmentIndex` = stack
|
||||
garbage. When the garbage carried 0x2 the mapper froze → `speedDemand` stuck at 0 → no forward motion
|
||||
(MASKED in single-player when the garbage happened to be clean; surfaced in `-net` where the stack
|
||||
differed; the July-16 audio commits shifted the stack and flipped it). **Cause:** partial init of a
|
||||
struct the engine reads in full. **Fix:** `memset(&res, 0, sizeof(res))` before filling ANY
|
||||
stack-built resource — flags 0 = `AlwaysExecute`, the faithful value for a mapper (it MUST tick every
|
||||
frame). **Tell:** a subsystem present in the roster but absent from the executed set; instrument the
|
||||
tick's `!IsNonReplicantExecutable()` branch to name the slot + dump `simulationFlags` (bit 0x2 =
|
||||
DontExecute). **Rule:** zero every hand-built resource struct; never rely on a partially-filled one.
|
||||
[T2]
|
||||
|
||||
**Related — raw numeric attribute index into a GROWING table (same root as gotcha 11):** the dev
|
||||
gauges' `CoolingLoopConnection` reached the cooling master with a RAW `GetAttributePointer(3)` +
|
||||
`*(master+0x1d4)` walk. The July-16 audio work inserted attribute rows (`ReportLeak` etc.), shifting
|
||||
the chained ids — index 3 landed on a scalar, the resolve walked garbage, and the gauge background
|
||||
pass AV'd (only with `BT_DEV_GAUGES=1`, the pod launch flag, ~15 s in when the gauge builds lazily —
|
||||
the cdb stack pinned it to `CoolingLoopConnection::Update`). **Fix:** route through a complete-type
|
||||
bridge reading NAMED members (`heat.cpp BTCoolingLoopFrame`: `linkedSinks.Resolve()` +
|
||||
`Condenser::condenserNumber`) — the databinding rule (gotcha 8), never a raw numeric attribute index.
|
||||
The name-keyed samplers (`PowerSourceConnection`/`GeneratorVoltageConnection`, which look up
|
||||
`"InputVoltage"` by NAME) were unaffected — name lookup survives table growth. [T2]
|
||||
|
||||
---
|
||||
|
||||
## Diagnostic recipe (the standard loop)
|
||||
|
||||
+37
-2
@@ -105,8 +105,43 @@ models is deferred (needs the board's hot-spot semantics). [T2]
|
||||
`.BSL` is a bit-sliced container (6 grayscale sub-images per file); the BMF `0x18 BITSLICE` tag picks
|
||||
the slice. Reading it as RGB overlaid 2-3 gray sheets = the "rainbow/graffiti" bug. Fixed:
|
||||
`image.cpp decodeBSL` slice-decodes; `bgfload` threads the 0x18 channel; a cross-library RAMP registry
|
||||
resolves the mech-skin `softer` ramp (defined in OTHER libs). Every mech renders authentic gray-metal
|
||||
paint now. See [[asset-formats]]. [T2]
|
||||
resolves the mech-skin `softer` ramp (defined in OTHER libs). Every mech renders the authentic BASE
|
||||
gray-metal skin now. See [[asset-formats]]. [T2]
|
||||
|
||||
## Per-pilot mech PAINT (color/badge/patch substitution) — NOT WIRED (2026-07 audit)
|
||||
The "missing warning stripes / coloration" report is the per-pilot paint layer, fully authored but
|
||||
never engaged by the port. Mechanics (all [T1] from the BMF/BGF/vehicletable content + FUN_004d0cc0):
|
||||
- Mech BGFs reference the BASE lib only (`blhskin:gen2_dz_rfoot_mtl` …). The binary rewrites lib
|
||||
prefixes at load via the `vehicletable` resource `[substitute]` templates: `skin:` → `_%color%%serno%:`
|
||||
(`blhskin:` → `blh_wht0:`) and `skin:lgo` → `<<<emblem%serno%:%badge%_%patch%>` (emblem pages →
|
||||
`EMBLEM0.BMF` `lgoN_<patch>_dz_*` materials). Pilot egg values (color/badge/patch) map through the
|
||||
`[color]/[badge]/[patch]` sections to the codes.
|
||||
- The COLOR libs (e.g. `BLH_WHT0.BMF`) are byte-identical to the base lib EXCEPT they add tags
|
||||
`0x23`(diffuse RGB) + `0x24`(ambient RGB) = the pilot color to the ~35 paintable `gen*/mech*_dz_*`
|
||||
materials (base leaves them untinted). 7 colors: wht(.99,.99,.99) red(.90,.11,.10) grn(.63,.83,.52)
|
||||
gry(.65,.60,.65) brn(.60,.44,.28) tan(.65,.55,.43) blk(0,0,0). All 8 sernos are byte-identical
|
||||
(verified: 0 of 193 groups differ) — `%serno%` was future variety, never used. `<mech>SKIN.BMF`
|
||||
(bare) == `<mech>SKIN0.BMF`.
|
||||
- WARNING STRIPES are grayscale hazard-stripe art in the shared `GEN.BSL` pages (slice 1 = `gen2_tex`,
|
||||
top-left), shown through the paintable-zone materials and tinted by the pilot color. `EMBLEM0.BMF`
|
||||
carries `lgoN_<patchcolor>_dz_ld/rdleg` materials (8 patch tints incl. yellow .89,.73,0) over
|
||||
`LGO.BSL` slices 0-5 (slice 5 = VGL winged logo).
|
||||
- **WIRED 2026-07-17 (same-day fix), verified live**: MP MadCat renders crimson with hip hazard
|
||||
stripes + yellow VGL leg emblems; Blackhawk white + emblems; replicants painted on both nodes.
|
||||
The reconstruction: (a) `Mech::resourceNameA/B/C` are real `CString` members (the binary's exact
|
||||
16-byte `CStringRepresentation` {size,len,text@+8,refs@+0xc}; ctor = part_012.c:9841-71, deep-copy
|
||||
bind from the MakeMessage = `CString::operator=(const char*)` == FUN_00402a98 @10427-41, implicit
|
||||
member dtors = 11388-403) with paint-name accessors; (b) `SetupMaterialSubstitutionList` reads them
|
||||
(real egg names; `[paint]` log line); (c) `dpl_SetMaterialNameCallback` is REAL now
|
||||
(L4VIDEO.cpp registry, cleared first in TearDown as FUN_004d11e8 does) and
|
||||
`bgfload MaterialResolver::resolve()` runs every name through `dpl_ApplyMaterialNameCallback`;
|
||||
no mesh-cache issue (LoadObject/LoadBgfFile don't cache — every load resolves fresh). [T2]
|
||||
- DEVIATION (documented, btl4vid.cpp): on a vehicletable miss the binary Fail()ed ("Exiting"
|
||||
@BTL4VID.CPP:0xbeb); the port warns + drops that placeholder (RP analogue). Real case: dev eggs
|
||||
ship `color=Red` but the `[color]` table only has **Crimson** — MP_BHMC.EGG fixed to Crimson;
|
||||
LAST.EGG pilot-2 still says Red (unused slot). The 7 valid egg colors:
|
||||
Black/Brown/Crimson/Green/Grey/Tan/White; badges Davion/Kurita/Liao/Marik/None/Steiner/VGL;
|
||||
patches Black/Blue/Green/Grey/Red/Violet/White/Yellow. [T1]
|
||||
|
||||
## The OLD-STYLE SPECIALFX layer (the weapon-impact action) — RECONSTRUCTED 2026-07-12 (firmware-decoded)
|
||||
The per-weapon impact visuals are fully AUTHORED in `content/BTDPL.INI` `[effects_to_load]`:
|
||||
|
||||
Reference in New Issue
Block a user