From 08f71eb471332aa023afbb1a87e694d4e746bb85 Mon Sep 17 00:00:00 2001 From: Cyd Date: Fri, 3 Jul 2026 17:13:46 -0500 Subject: [PATCH] Phase 3f: lighting from wire normals; defuse shipped-in debug crash Lighting: stride-8/9 vertices carry a normal (floats 3-5, uv at 6-7). The backend transforms normals by the instance rotation and lights with a single directional sun (GL_LIGHT0, smooth, two-sided, GL_COLOR_MATERIAL). Terrain and hulls shade instead of reading flat. LOD: the lod flush has no switch distances -- the host keeps the active LOD at the child-list head and re-orders over the wire, so children[0] is right and LOD changes come through as the sim runs. The crash that halted the game once the RIO drove the sim was not ours: fault at 0047E1D1 writing 0xFFFFFFFF is the RIO driver's DISABLE_AND_DIE debug macro (PCSPAK.ASM, DIE_ON_ERROR=1), which deliberately faults on a serial-tx anomaly -- error 3 = body char >0x7F during a RIO packet, i.e. a glitch on a board reset. Release build (DIE_ON_ERROR=0) compiles it out and recovers (and al,07Fh). patch_btl4opt.py NOPs all 12 sites by signature (with .orig backup) = release behavior; game then survives RIO resets (1200+ frames). (ALPHA_1 is git-ignored, so the tool ships, not the patched binary.) Co-Authored-By: Claude Opus 4.8 --- emulator/.gitignore | 1 + emulator/PHASE3-PROGRESS.md | 25 +++++++++++-- emulator/game-live-lit.png | Bin 0 -> 55740 bytes emulator/patch_btl4opt.py | 57 +++++++++++++++++++++++++++++ emulator/vpx-device/vpxlog.cpp | 64 +++++++++++++++++++++++++++++---- 5 files changed, 139 insertions(+), 8 deletions(-) create mode 100644 emulator/game-live-lit.png create mode 100644 emulator/patch_btl4opt.py diff --git a/emulator/.gitignore b/emulator/.gitignore index 0fb37fe..f4f642d 100644 --- a/emulator/.gitignore +++ b/emulator/.gitignore @@ -10,6 +10,7 @@ image/ !game-mech-decoded.png !game-live-gl.png !game-live-textured.png +!game-live-lit.png dbx_out.txt vpx*.txt sweep_*.txt diff --git a/emulator/PHASE3-PROGRESS.md b/emulator/PHASE3-PROGRESS.md index ffdcad5..769dcf1 100644 --- a/emulator/PHASE3-PROGRESS.md +++ b/emulator/PHASE3-PROGRESS.md @@ -175,8 +175,29 @@ uploads it to GL keyed by material, and maps it with the wire UVs (stride-5 verts: floats 3–4; stride-8/9: floats 6–7). Result: the arena renders with the ravine's actual brown dirt textures, live (`game-live-textured.png`). -Still to come: lighting from the wire normals, per-frame articulation once -the RIO holds sync, LOD selection by distance. +### 3f. Lighting + the shipped-in debug crash + +Lighting: stride-8/9 vertices carry a **normal** at floats 3–5 (uv at 6–7). +The backend transforms them by the instance world matrix (rotation only) and +lights with a single directional "sun" (`GL_LIGHT0`, smooth shading, +two-sided, `GL_COLOR_MATERIAL` so texture/material color survives). Terrain +and hulls now shade instead of reading flat. + +LOD note: the `lod` flush carries **no switch distances** — the host game +keeps the active LOD at the head of the object's child list and re-orders it +over the wire, so `children[0]` is correct and LOD changes as the sim runs +come through for free. + +**The crash that halted the game with the RIO in sync was not ours.** Fault +`Exception 0E at 0047E1D1` writing to `0xFFFFFFFF` is a debug landmine the +build shipped with: the RIO serial driver's `DISABLE_AND_DIE` macro +(`PCSPAK.ASM`, gated by `DIE_ON_ERROR equ 1`) deliberately faults on any +serial-transmit anomaly. Error code 3 = a body char > 0x7F during a RIO +packet (`PCSPAK.ASM:1630`) — i.e. a serial glitch during a board reset. The +release build (`DIE_ON_ERROR equ 0`) compiles it out and takes the recovery +path (`and al,07Fh`). `patch_btl4opt.py` finds all 12 sites by their 14-byte +signature and NOPs them — exactly the release behavior — with a `.orig` +backup. After patching, the game survives RIO resets (1200+ frames). ## 3c. The full game runs through the live renderer (sync abort fixed) diff --git a/emulator/game-live-lit.png b/emulator/game-live-lit.png new file mode 100644 index 0000000000000000000000000000000000000000..eab2c514aa284a140829f1a92bc8674283fd7af3 GIT binary patch literal 55740 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 + mov [edx], eax ; write to 0xFFFFFFFF -> Exception 0E + +On the real pod a clean cockpit harness never tripped these; through the +DOSBox-X serial passthrough a RIO glitch (e.g. during a board reset) hits +error 3 (PCSPAK.ASM:1630, "body char > 0x7F") and halts the whole game. The +release build (`DIE_ON_ERROR equ 0`) compiles the macro to nothing and lets +the normal recovery path (`and al,07Fh`) continue. + +This tool finds every DISABLE_AND_DIE site by its exact 14-byte signature and +replaces it with NOPs -- exactly the release-build behavior -- writing a +.orig backup first. Idempotent. + +Usage: patch_btl4opt.py +""" +import re +import sys + +SIG = re.compile( + rb'\x50\x52\xBA\xFF\xFF\xFF\xFF\xB8(.)\x00\x00\x00\x89\x02', re.DOTALL) + + +def main(): + if len(sys.argv) != 2: + raise SystemExit(__doc__) + path = sys.argv[1] + data = bytearray(open(path, 'rb').read()) + sites = list(SIG.finditer(bytes(data))) + if not sites: + print("no DISABLE_AND_DIE sites found (already patched?)") + return + import os + bak = path + '.orig' + if not os.path.exists(bak): + open(bak, 'wb').write(data) + print(f"backup written: {bak}") + for m in sites: + code = m.group(1)[0] + va = 0x401000 + m.start() - 0xe00 # CODE VA 0x401000 @ file 0xe00 + print(f" NOP VA 0x{va:06x} (error code {code})") + data[m.start():m.end()] = b'\x90' * (m.end() - m.start()) + open(path, 'wb').write(data) + print(f"patched {len(sites)} sites") + + +if __name__ == "__main__": + main() diff --git a/emulator/vpx-device/vpxlog.cpp b/emulator/vpx-device/vpxlog.cpp index dfcd404..04a00da 100644 --- a/emulator/vpx-device/vpxlog.cpp +++ b/emulator/vpx-device/vpxlog.cpp @@ -439,6 +439,7 @@ struct VPoly { float rgb[3]; std::vector xyz; /* x,y,z triples */ std::vector uv; /* u,v pairs (empty = untextured) */ + std::vector nrm; /* nx,ny,nz triples (empty = unlit) */ unsigned matkey; /* material name for texture lookup, 0 = none */ VPoly() : matkey(0) {} }; @@ -472,6 +473,7 @@ static struct VScene { std::map type; /* name -> node type */ std::map > verts; /* geometry -> xyz */ std::map > uvs; /* geometry -> u,v */ + std::map > nrms; /* geometry -> nx,ny,nz */ std::map > > polys; std::map mat; /* material -> RGB */ std::map ggmat; /* geogroup -> material */ @@ -512,6 +514,10 @@ static void m16_xform(const M16 &w, const float *v, float *o) { for (int c = 0; c < 3; c++) o[c] = v[0] * w.m[c] + v[1] * w.m[4 + c] + v[2] * w.m[8 + c] + w.m[12 + c]; } +static void m16_xform_dir(const M16 &w, const float *v, float *o) { + for (int c = 0; c < 3; c++) /* rotation only (normals) */ + o[c] = v[0] * w.m[c] + v[1] * w.m[4 + c] + v[2] * w.m[8 + c]; +} /* world transform of a dcs: local * parent_world (row-vector convention) */ static void dcs_world(unsigned dcs, std::map &cache, M16 &out, int depth = 0) { @@ -567,8 +573,22 @@ static void rt_draw(HDC dc, const VFrame &f, int cw, int ch) { glTranslatef(-f.eye[0], -f.eye[1], -f.eye[2]); glEnable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); - glDisable(GL_LIGHTING); - glShadeModel(GL_FLAT); + glShadeModel(GL_SMOOTH); + /* directional sun (world coords; modelview is loaded, so GL maps it + * into eye space). World is y-down: up = -y. */ + { + GLfloat lpos[4] = { 0.35f, -0.85f, 0.40f, 0.0f }; + GLfloat lamb[4] = { 0.45f, 0.45f, 0.45f, 1.0f }; + GLfloat ldif[4] = { 0.80f, 0.80f, 0.78f, 1.0f }; + glLightfv(GL_LIGHT0, GL_POSITION, lpos); + glLightfv(GL_LIGHT0, GL_AMBIENT, lamb); + glLightfv(GL_LIGHT0, GL_DIFFUSE, ldif); + glEnable(GL_LIGHT0); + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1); + glEnable(GL_COLOR_MATERIAL); + glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); + glEnable(GL_NORMALIZE); + } /* upload any new/changed baked material textures */ static std::map gltex; /* matkey -> GL name */ static std::map gltex_ver; @@ -610,14 +630,18 @@ static void rt_draw(HDC dc, const VFrame &f, int cw, int ch) { glDisable(GL_TEXTURE_2D); glColor3f(p.rgb[0], p.rgb[1], p.rgb[2]); } + bool lit = !p.nrm.empty(); + if (lit) glEnable(GL_LIGHTING); else glDisable(GL_LIGHTING); glBegin(GL_POLYGON); for (size_t v = 0; v + 2 < p.xyz.size(); v += 3) { if (tex) glTexCoord2f(p.uv[v / 3 * 2], p.uv[v / 3 * 2 + 1]); + if (lit) glNormal3f(p.nrm[v], p.nrm[v + 1], p.nrm[v + 2]); glVertex3f(p.xyz[v], p.xyz[v + 1], p.xyz[v + 2]); } glEnd(); } glDisable(GL_TEXTURE_2D); + glDisable(GL_LIGHTING); } SwapBuffers(dc); } @@ -740,10 +764,18 @@ static void emit_geogroup(VFrame &f, unsigned gg, const M16 *world) { if (vi == S.verts.end() || pi == S.polys.end()) continue; const std::vector &vv = vi->second; const std::vector *uv = NULL; + const std::vector *nr = NULL; std::map >::const_iterator ui = S.uvs.find(geo); if (ui != S.uvs.end() && ui->second.size() * 3 == vv.size() * 2) uv = &ui->second; + std::map >::const_iterator ni = + S.nrms.find(geo); + if (ni != S.nrms.end() && ni->second.size() == vv.size()) { + /* only meaningful if not all-zero (stride < 8 stores zeros) */ + for (size_t z = 0; z < ni->second.size(); z++) + if (ni->second[z] != 0.0f) { nr = &ni->second; break; } + } for (size_t q = 0; q < pi->second.size(); q++) { const std::vector &idx = pi->second[q]; VPoly poly; @@ -762,7 +794,17 @@ static void emit_geogroup(VFrame &f, unsigned gg, const M16 *world) { poly.uv.push_back((*uv)[(size_t)idx[j] * 2]); poly.uv.push_back((*uv)[(size_t)idx[j] * 2 + 1]); } + if (nr) { + float nout[3]; + if (world) m16_xform_dir(*world, &(*nr)[o], nout); + else { nout[0] = (*nr)[o]; nout[1] = (*nr)[o + 1]; + nout[2] = (*nr)[o + 2]; } + poly.nrm.push_back(nout[0]); + poly.nrm.push_back(nout[1]); + poly.nrm.push_back(nout[2]); + } } + if (poly.nrm.size() != poly.xyz.size()) poly.nrm.clear(); if (poly.xyz.size() >= 9) f.polys.push_back(poly); } } @@ -790,7 +832,10 @@ static void scene_publish_frame(void) { std::map >::const_iterator li = S.children.find(oi->second); if (li == S.children.end() || li->second.empty()) continue; - unsigned lod = li->second[0]; /* highest LOD */ + /* First LOD child: the host maintains the active LOD at the list + * head (the wire lod flush carries no switch distances -- LOD + * selection is host-side). */ + unsigned lod = li->second[0]; std::map >::const_iterator ggi = S.children.find(lod); if (ggi == S.children.end()) continue; @@ -824,11 +869,13 @@ static void scene_burst(const unsigned char *p, size_t n) { if (S.geom_acc.size() >= S.geom_need * S.geom_stride) { std::vector &vl = S.verts[S.geom_node]; std::vector &tl = S.uvs[S.geom_node]; - vl.clear(); tl.clear(); - /* uv offset within a vertex record by stride: 5 = xyz+uv, - * 8/9 = xyz+normal+uv(+extra) */ + std::vector &nl = S.nrms[S.geom_node]; + vl.clear(); tl.clear(); nl.clear(); + /* record layout by stride: 5 = xyz+uv, + * 8/9 = xyz + normal(3..5) + uv(6..7) (+extra) */ size_t uvo = (S.geom_stride >= 8) ? 6 : (S.geom_stride == 5) ? 3 : 0; + bool has_n = S.geom_stride >= 8; for (size_t i = 0; i + 2 < S.geom_need * S.geom_stride; i += S.geom_stride) { vl.push_back(S.geom_acc[i]); @@ -838,6 +885,11 @@ static void scene_burst(const unsigned char *p, size_t n) { tl.push_back(S.geom_acc[i + uvo]); tl.push_back(S.geom_acc[i + uvo + 1]); } else { tl.push_back(0); tl.push_back(0); } + if (has_n && i + 5 < S.geom_acc.size()) { + nl.push_back(S.geom_acc[i + 3]); + nl.push_back(S.geom_acc[i + 4]); + nl.push_back(S.geom_acc[i + 5]); + } else { nl.push_back(0); nl.push_back(0); nl.push_back(0); } } S.geom_acc.clear(); S.geom_active = false;