Wire the HUD reticle into live_render.py

Integrates hud2d_overlay.HudTracker into the live pipeline: fed exactly one
wire record per firmware consumption (synchronized with r.qi, not just queue
arrival, so hud2d_root's view/display-list state matches what the firmware
has actually processed at render time), composited onto each rendered frame
before present.

Verified via the same integration pattern (truncated direct-queue boot, no
socket overhead) against netdeath-20260708.fifodump: the reticle composites
starting at wire command 22906 (frame 22) -- identical resolution point and
visual result to the standalone hud2d_overlay test. A full-mission run
through the live socket path is genuinely slow around this capture's "battle"
content (multi-billion firmware steps per command in that section, pre-
existing and unrelated to this change) but not stalled -- confirmed by
reaching the same cmd/frame numbers via the direct path in 14.7s.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-21 14:48:14 -05:00
co-authored by Claude Opus 4.8
parent ebf0d8c23f
commit 3e766c13c1
@@ -29,6 +29,7 @@ from driver import boot, CpuShim
from vrboard import A from vrboard import A
from texstore import build_texstore from texstore import build_texstore
from gpu_raster import Renderer, W, H from gpu_raster import Renderer, W, H
from hud2d_overlay import HudTracker, composite_hud
ANAME = {int(a): a.name for a in A} ANAME = {int(a): a.name for a in A}
emu860.Mem.log = lambda self, *a, **k: None emu860.Mem.log = lambda self, *a, **k: None
@@ -148,6 +149,7 @@ print("GPU:", g.ctx.info['GL_RENDERER'], flush=True)
recs = list(catchup_recs) # running wire, for the texture store recs = list(catchup_recs) # running wire, for the texture store
tex_dirty = bool(catchup_recs) tex_dirty = bool(catchup_recs)
renderer = Renderer(g.ctx, []) # texlist filled once textures arrive renderer = Renderer(g.ctx, []) # texlist filled once textures arrive
hud = HudTracker() # cockpit reticle/pips (dpl2d overlay)
pinned = False pinned = False
if PIN: if PIN:
renderer.texlist = list(build_texstore(parse_fifodump(PIN)).items()) renderer.texlist = list(build_texstore(parse_fifodump(PIN)).items())
@@ -233,6 +235,7 @@ while not stopped:
tex_dirty = False tex_dirty = False
img = renderer.frame(emu860c.dump_range) img = renderer.frame(emu860c.dump_range)
if img is not None: if img is not None:
composite_hud(img, hud, W, H) # no-op until the reticle resolves
if not present(img, frames): if not present(img, frames):
break break
frames += 1 frames += 1
@@ -251,7 +254,9 @@ while not stopped:
break break
if stopped: if stopped:
break break
if ANAME.get(r.queue[r.qi][0]) == 'draw_scene': act, pl = r.queue[r.qi]
hud.feed(act, pl) # every record, in wire order, exactly
if ANAME.get(act) == 'draw_scene': # once -- matches consumption, not arrival
prev_draw = True prev_draw = True
if h(shim) == 'done': if h(shim) == 'done':
break break