Four-dossier workflow synthesis: the engine half of BOTH render paths (DPLRenderer/libDPL for the division-card 3D view; the L4 gauge stack for the cockpit instruments) ALREADY compiles and links into btl4opt.exe from the CODE originals, and the emulator's VPX board-side device is EXE-agnostic (pure wire-level). What's missing is game-TU work with complete BT411 donors: the 6 gauge TUs (~302 fns, the first rendered milestone -- diffable against the shipped exe on the same GAUGE content) and then btl4vid (the 3D world renderable factory). Full protocol map, env gates, and the staged plan in RENDER-ROADMAP.NOTES.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
84 lines
4.9 KiB
Markdown
84 lines
4.9 KiB
Markdown
# The render roadmap — from headless to visible (researched 2026-07-24)
|
|
|
|
Four-dossier workflow synthesis (card protocol / video-TU delta / emulator
|
|
side / gauge path). The headline: **the render seam is far closer than
|
|
expected** — the engine half of BOTH render paths already compiles and links
|
|
into our btl4opt.exe from the CODE originals, and the emulator's board-side
|
|
device is EXE-agnostic.
|
|
|
|
## The two independent render paths (either can run without the other)
|
|
|
|
1. **The 3D main view (division card)**: the game speaks dPL — a
|
|
RETAINED-mode scene graph API (never pixels, never transformed polys) —
|
|
through the statically linked libDPL, which frames every call into
|
|
vr_action messages on the INMOS C012 link adapter at port 0x150
|
|
(FIFO fast path: body as REP OUTSW words to 0x154, trailing length word
|
|
to 0x151 commits). Gate: `DPLARG` env (set by SETENV.BAT when
|
|
L4VIDEO != OFF); NULL DPLARG = the headless shape we run today
|
|
(`MakeVideoRenderer()` returns NULL, tolerated).
|
|
- Per-frame submission: **engine code** — `DPLRenderer::
|
|
ExecuteImplementation` (CODE/RP/MUNGA_L4/L4VIDEO.CPP:5065) walks the
|
|
dplRenderableSocket; renderables (L4VIDRND.CPP, ~30 classes) set DCS
|
|
matrices; `dpl_FlushDCSArticulations` = wire action 0x1f (batched
|
|
poses, absolute 3x3+T or [sin,cos] joint records); `vr_draw_scene`
|
|
(9) kicks the frame; `velocirender_sync` (0x2d, exe @0x48D220) is the
|
|
ack-less bulk-op fence.
|
|
- **Our build ALREADY COMPILES this whole engine layer** (mungal4.lib:
|
|
l4video/l4vidrnd/l4dplmem + prebuilt 1995 STARTDPL.obj + LIBDPL.LIB;
|
|
see build410 obj logs). The missing piece is GAME code: **btl4vid**
|
|
(BTL4VideoRenderer — MakeEntityRenderables/MakeMechRenderables/
|
|
effects/wreck swap/material substitution; BT411 donor 3039/848 lines
|
|
with per-method @ADDR evidence, binary extent @4cc40c..@4d2bbc; our
|
|
stub Fails at LoadMissionImplementation).
|
|
2. **The gauge path (cockpit instruments)**: completely separate hardware —
|
|
the PC's own SVGA (VESA 0x111, 640x480x16, L4SVGA16.ASM banked blits),
|
|
split across VGA heads by the VDB board (port 0x300, palette groups; the
|
|
octopus-cable 5-mono-MFDs + color-radar decode). Gate: `L4GAUGE` env.
|
|
The plasma readout is a gauge-renderer graphics port (PlasmaDisplay on
|
|
COM2), not a separate renderer.
|
|
- Engine half (GaugeRenderer/L4GaugeRenderer/the 5171-line L4GAUGE
|
|
widget interpreter/GAUGMAP/L4VB16) already compiles + links in
|
|
build410; one documented deviation (interpreter table 46864 -> 262144
|
|
for BT's larger CFG).
|
|
- Missing: the 6 BT gauge TUs — **btl4gaug (130 fn) / btl4gau2 (77) /
|
|
btl4gau3 (46) / btl4rdr (36) / btl4grnd (13, ours is a 4-fn stub) /
|
|
btl4galm** — ~302 functions/~43KB, binary extent 0x4c19fc-0x4cc40c,
|
|
the largest function-count block left in btl4.lib. BT411 donors are
|
|
COMPLETE (semantic .cpp/.hpp with @ADDR evidence, ~5900 donor lines);
|
|
the work is RE-HOSTING onto 1995 engine APIs, not fresh decompilation.
|
|
Class inventory per TU in the dossier (widget primitives / composite
|
|
clusters / MP-HUD / radar MapDisplay / the renderer / alarm manager).
|
|
|
|
## The emulator side is READY and EXE-agnostic
|
|
|
|
The DOSBox-X fork's VPX device (emulator/vpx-device/vpxlog.cpp, ports
|
|
0x150-0x161 + VDB 0x300-0x31A) implements the BOARD side purely at the wire
|
|
level: blind firmware absorb, iserver handshake (VPX_RESPOND=1), generic
|
|
acks, the 0x2d sync echo, draw_scene frame-acks with a REAL raycast reticle
|
|
pick against its own decoded scene, and the GL renderer (VPX_RENDER=1) that
|
|
draws the main view + cockpit windows. It never reads game memory and keys
|
|
only on wire contents — **our reconstructed exe drives it unmodified once it
|
|
emits the same traffic**. The AWE32 pair is mandatory for any timed run
|
|
(SOS FAST clock); gauges also render live on the emulated S3 with the
|
|
shipped exe (GAUGE-NOTES.md: HEAPSIZE=15000000 + granularityInKB=64).
|
|
|
|
## The plan (order of value)
|
|
|
|
1. **Gauges-only first** (decisively cheaper): set `L4GAUGE=640x480x16` (+
|
|
HEAPSIZE), reconstruct the 6 gauge TUs from the BT411 donors. Built-in
|
|
oracle: the shipped exe renders reference output from the SAME GAUGE
|
|
content — per-head diffable. Live instruments need the attribute
|
|
sources, which the 5.3.x waves have largely built (weapon states, heat,
|
|
power, damage, radar).
|
|
2. **Then btl4vid** (the 3D world renderer) + DPLARG on: the engine
|
|
DPLRenderer + libDPL do the wire; btl4vid builds the renderables per
|
|
entity; verify against the VPX device's GL window and the dpl3-revive
|
|
bridge.
|
|
3. The review/playback pair (btl4pb + the BTL4.CPP review branch) closes
|
|
the last absent TUs.
|
|
|
|
Message-id / protocol quick refs: vr_create=1 (host-assigned handles),
|
|
vr_flush=3 (node structs; VIEW proves 832x512), geometry 0x17/0x19/0x1a
|
|
(texel word [pad,B,G,R]), artics 0x1f, draw 9, sync 0x2d, fire 0x23,
|
|
reticle 0x26. DPLARG reference value in emulator/baseline.conf:21.
|