Phase 3c: fix production vr_sync abort; full game runs through renderer
Root cause: vpx_max_postboot_acks=200, a Phase-2 bring-up guard, capped how many post-boot replies the device would ever feed. A real BattleTech session issues an unbounded stream of sync/frame/render replies and aborted with "velocirender_receive timed out - sends_wo_rcv" at exactly the 200th ack (143 sync + 55 frame-ack + 2 render). Cap is now effectively unlimited (0x7fffffff; override VPX_MAX_ACKS for diagnostics). After the fix the full game (game.conf, RIO disabled, cycles=max) runs indefinitely: 2500+ syncs, 1264+ frame-acks, no abort, into L4VIDEO content load (Thor mech + terrain from ALPHA_1/REL410/BT/VIDEO/GEO -- 841 real .bgf models; test.egg is only mission params). Window still shows background: the game uses the full DPL hierarchy (instance/object/lod/geogroup + DCS transforms) which the flat flyk-tuned scene walk doesn't traverse yet -- that is Phase 3d, documented in PHASE3-PROGRESS.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+61
-14
@@ -1,10 +1,14 @@
|
|||||||
# Phase 3 — Render Backend: Progress
|
# Phase 3 — Render Backend: Progress
|
||||||
|
|
||||||
**Status (2026-07-03): Phase 3a + 3b complete. 3a — the render command stream
|
**Status (2026-07-03): Phase 3a + 3b + 3c complete. 3a — the render command
|
||||||
is fully captured and decoded, and a captured DIVRGB frame reconstructed to
|
stream is fully captured and decoded, and a captured DIVRGB frame
|
||||||
pixels offline. 3b — a live OpenGL window built into the emulated board draws
|
reconstructed to pixels offline. 3b — a live OpenGL window built into the
|
||||||
each frame in real time inside DOSBox-X. First images ever produced from the
|
emulated board draws each frame in real time inside DOSBox-X. 3c — the
|
||||||
Rel 4.10 VPX protocol without a real board.**
|
production `vr_sync` abort is fixed and the full BattleTech v4.10 game now runs
|
||||||
|
indefinitely through the emulated board, drawing 1000s of frames (was hard-
|
||||||
|
capped at 200). First images ever produced from the Rel 4.10 VPX protocol
|
||||||
|
without a real board. Next (3d): traverse the game's DPL hierarchy + DCS
|
||||||
|
transforms so its mechs actually appear.**
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -108,14 +112,57 @@ before its first receive, which the POLL_THRESHOLD gating stalls. This is not
|
|||||||
a 3b issue (the `flyk` clean-launch path renders fine); it is the same
|
a 3b issue (the `flyk` clean-launch path renders fine); it is the same
|
||||||
production-sync item still open from Phase 2.
|
production-sync item still open from Phase 2.
|
||||||
|
|
||||||
## Remaining
|
## 3c. The full game runs through the live renderer (sync abort fixed)
|
||||||
|
|
||||||
1. **Production-path vr_sync timeout** (`sends_wo_rcv`): the game's
|
**The production `vr_sync` abort is fixed, and BattleTech v4.10 now runs
|
||||||
`btdpl.ini`/netnub launch path. Needed before the game itself renders.
|
indefinitely through the emulated board + live renderer.** Root cause was a
|
||||||
2. **Content**: `test.egg` carries no models, so even past sync the game has
|
Phase-2 bring-up guard left in the device: `vpx_max_postboot_acks = 200`
|
||||||
no `buttee.bgf`/`mslr.bgf` geometry to draw — needs a real mission/content
|
capped how many post-boot replies the device would ever feed. A real game
|
||||||
tree from the pod image.
|
session issues an unbounded stream of sync/frame/render replies; the game
|
||||||
3. **DOS/4GW sync variant** for the CYCLE `flyk yip.scn` fixture (Red Planet
|
aborted with `velocirender_receive timed out — sends_wo_rcv` the instant the
|
||||||
|
device fell silent — at *exactly* the 200th ack (measured: 143 sync + 55
|
||||||
|
frame-ack + 2 render = 200). The cap is now effectively unlimited
|
||||||
|
(`0x7fffffff`, override with `VPX_MAX_ACKS`). Same run after the fix: 2500+
|
||||||
|
syncs, 1264+ frame-acks, no abort. The game progresses past sync into
|
||||||
|
`L4VIDEO.cpp` content/entity setup (loading the Thor mech and terrain) and
|
||||||
|
draws continuously.
|
||||||
|
|
||||||
|
Contrary to the earlier note, the content **is** on the production image: 841
|
||||||
|
`.bgf` models under `ALPHA_1/REL410/BT/VIDEO/GEO` (incl. `BUTTEE.BGF`,
|
||||||
|
`MSLR.BGF`, the `THR*` Thor mech). `test.egg` is only mission parameters (as
|
||||||
|
the pod owner said); the geometry loads from `VIDEO/GEO` regardless.
|
||||||
|
|
||||||
|
Game render config: `game.conf` (RIO disabled so the missing cockpit board
|
||||||
|
doesn't stall the control manager; `cycles=max`).
|
||||||
|
|
||||||
|
### What the game's wire stream looks like (vs. flyk)
|
||||||
|
|
||||||
|
The game geometry path is heavier and different from flyk's flat DIVRGB:
|
||||||
|
- **action 26 (0x1A) dominates** — texture texel upload. 32-byte headers
|
||||||
|
`[node][size][w][h]` (`0x1000`=64×64, `0x4000`=128×128 tiles) then 256-byte
|
||||||
|
texel rows. 2880+ of these = the mission texture set streaming in.
|
||||||
|
- action 28 (0x1C): material/light parameter blocks.
|
||||||
|
- actions 23/25 (verts/conns) still carry mesh geometry but are a small
|
||||||
|
fraction of the stream.
|
||||||
|
- The scene graph is the **full DPL hierarchy** — zone → dcs → instance →
|
||||||
|
object → lod → geogroup → geometry — with **DCS transform matrices**
|
||||||
|
positioning each mech/prop. flyk's DIVRGB put geometry directly in
|
||||||
|
geogroups at world coordinates.
|
||||||
|
|
||||||
|
## Remaining (Phase 3d: game geometry on screen)
|
||||||
|
|
||||||
|
The window currently shows only the view background for the game because the
|
||||||
|
live backend's `scene_publish_frame()` walks the *flat* flyk layout
|
||||||
|
(geogroup→geometry at world coords). To draw the game's mechs it must:
|
||||||
|
|
||||||
|
1. **Traverse the full hierarchy** (instance/object/lod/geogroup) and **apply
|
||||||
|
DCS transform matrices** (accumulate the 4×4s down the graph) so each mech
|
||||||
|
lands at its world position; pick a LOD.
|
||||||
|
2. **Arena content search path**: the game logs `couldn't load object
|
||||||
|
thr_tshd.bgf` — that object lives in `VIDEO/GEO/ARENA/` and `…/POLAR/`
|
||||||
|
(arena-specific), not the top `GEO` dir; the geometry search path needs the
|
||||||
|
selected arena subdir (a `setenv`/config detail, not protocol).
|
||||||
|
3. **Texturing** (action 26 texel maps + SVT), lighting, depth/material.
|
||||||
|
Current backend is flat-shaded untextured polys.
|
||||||
|
4. **DOS/4GW sync variant** for the CYCLE `flyk yip.scn` fixture (Red Planet
|
||||||
geometry) — the older action-check sync.
|
geometry) — the older action-check sync.
|
||||||
4. Texturing (`set_texmap_texels`, action 23-data + SVT), lighting, and
|
|
||||||
depth/material niceties; current backend is flat-shaded untextured polys.
|
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
[sdl]
|
||||||
|
output=opengl
|
||||||
|
[dosbox]
|
||||||
|
memsize=32
|
||||||
|
machine=svga_s3
|
||||||
|
[cpu]
|
||||||
|
core=normal
|
||||||
|
cputype=pentium
|
||||||
|
cycles=max
|
||||||
|
[serial]
|
||||||
|
serial1=disabled
|
||||||
|
serial2=disabled
|
||||||
|
[autoexec]
|
||||||
|
mount c "C:\VWE\TeslaRel410\ALPHA_1"
|
||||||
|
c:
|
||||||
|
cd \REL410\BT
|
||||||
|
set VIDEOFORMAT=svga
|
||||||
|
set BLASTER=A220 I5 D1 H5 P330 T6
|
||||||
|
set TEMP=c:\
|
||||||
|
call setenv.bat r s n n
|
||||||
|
32rtm.exe -x
|
||||||
|
btl4opt.exe -egg test.egg
|
||||||
|
32rtm.exe -u
|
||||||
|
echo ALPHA1-RUN-DONE
|
||||||
|
pause
|
||||||
@@ -212,7 +212,13 @@ static void queue_version_request(void) {
|
|||||||
* action code. The post-boot vr_init reply is ignored by the caller
|
* action code. The post-boot vr_init reply is ignored by the caller
|
||||||
* (DPL_HOST.C), so any action != vr_draw_scene_action satisfies it. */
|
* (DPL_HOST.C), so any action != vr_draw_scene_action satisfies it. */
|
||||||
static int postboot_acks = 0;
|
static int postboot_acks = 0;
|
||||||
static int vpx_max_postboot_acks = 200; /* safety cap */
|
/* Post-boot reply cap. This was a Phase-2 bring-up guard against a runaway
|
||||||
|
* reply loop while the protocol was still being reversed. The protocol is now
|
||||||
|
* solid and a real game session issues an unbounded number of sync/frame/
|
||||||
|
* render replies -- BattleTech aborts with "velocirender_receive timed out -
|
||||||
|
* sends_wo_rcv" the instant the device stops answering. Default is now
|
||||||
|
* effectively unlimited; override with VPX_MAX_ACKS only for diagnostics. */
|
||||||
|
static int vpx_max_postboot_acks = 0x7fffffff;
|
||||||
static int empty_polls = 0;
|
static int empty_polls = 0;
|
||||||
static const int POLL_THRESHOLD = 6; /* consecutive empty polls => blocking receive */
|
static const int POLL_THRESHOLD = 6; /* consecutive empty polls => blocking receive */
|
||||||
static void queue_render_ack_node(unsigned char action, unsigned node) {
|
static void queue_render_ack_node(unsigned char action, unsigned node) {
|
||||||
@@ -723,6 +729,8 @@ void VPXLOG_Init(void) {
|
|||||||
vpx_respond = (r && r[0] && r[0] != '0');
|
vpx_respond = (r && r[0] && r[0] != '0');
|
||||||
const char *h = getenv("VPX_HANDSHAKES");
|
const char *h = getenv("VPX_HANDSHAKES");
|
||||||
if (h && atoi(h) > 0) vpx_max_handshakes = atoi(h);
|
if (h && atoi(h) > 0) vpx_max_handshakes = atoi(h);
|
||||||
|
const char *ma = getenv("VPX_MAX_ACKS");
|
||||||
|
if (ma && atoi(ma) > 0) vpx_max_postboot_acks = atoi(ma);
|
||||||
|
|
||||||
const char *fd = getenv("VPX_FIFODUMP");
|
const char *fd = getenv("VPX_FIFODUMP");
|
||||||
if (fd && fd[0]) {
|
if (fd && fd[0]) {
|
||||||
|
|||||||
Reference in New Issue
Block a user