render_wide30.py executes the cap7 death-cam capture's raw instruction
packets ({TREEgeZERO_L3 x3 edges, MEMltTREE_L3 z-test, TREEintoMEM_L0
z-write, colour planes, scalar} -- 152 packets found by header scan) through
the named-ISA semantics, vectorized: 85 packets survive edge+z, producing a
recognizable smooth-shaded, depth-correct render of the test-scene object
(wide30_render/depth.png in the session scratchpad). This is geometry drawn
purely by executing the hardware's own instruction stream -- no
geometry-extraction shortcuts.
Known approximations this pass: winding-agnostic edge acceptance, colour
plane word-offsets partly empirical (R channel confirmed Gouraud-correct,
G/B extraction still off), duplicate packets from the wide capture window
z-fight. eof/bars ops still stubbed (per-tile program renders uniform).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
101 lines
3.4 KiB
Python
101 lines
3.4 KiB
Python
"""Render the cap7 test-scene from cap7_wide30.pkl's REAL captured IGC packets.
|
|
Packets = {SETENABS, 3x TREEgeZERO_L3 edges, MEMltTREE_L3 z-test, TREEintoMEM_L0
|
|
z-write, 3x color-plane instrs, scalar}. Executed vectorized (numpy) on a full
|
|
832x512 surface with a persistent 1/w z-buffer (MEMltTREE: keep where old < new
|
|
=> greater 1/w wins = closer wins)."""
|
|
import sys, pickle, struct
|
|
import numpy as np
|
|
|
|
S = r'C:\Users\cyd\AppData\Local\Temp\claude\c--VWE-TeslaRel410\4e848c76-6e89-4034-8047-d8d491cb32d8\scratchpad'
|
|
W, H = 832, 512
|
|
|
|
d = pickle.load(open(S + r'\cap7_wide30.pkl', 'rb'))
|
|
mem = d['mem']
|
|
|
|
def f32(w):
|
|
return struct.unpack('<f', struct.pack('<I', w & 0xffffffff))[0]
|
|
|
|
starts = sorted(a for a, w in mem.items() if w == 0x3ae80d00)
|
|
# packet head = SETENABS right before the first of each edge triple
|
|
# group: consecutive geZERO addresses 16 bytes apart form one packet's 3 edges
|
|
packets = []
|
|
i = 0
|
|
while i < len(starts):
|
|
a = starts[i]
|
|
if i + 2 < len(starts) and starts[i+1] == a + 16 and starts[i+2] == a + 32:
|
|
packets.append(a)
|
|
i += 3
|
|
else:
|
|
i += 1
|
|
print("%d triangle packets" % len(packets))
|
|
|
|
def rdf(a):
|
|
return f32(mem.get(a, 0))
|
|
|
|
def rd(a):
|
|
return mem.get(a, 0)
|
|
|
|
yy, xx = np.mgrid[0:H, 0:W].astype(np.float64)
|
|
zbuf = np.full((H, W), -1e30)
|
|
rgb = np.zeros((H, W, 3))
|
|
drawn = 0
|
|
for a in packets:
|
|
# edges at a, a+16, a+32: {hdr, A, B, C}
|
|
en_pos = np.ones((H, W), bool)
|
|
en_neg = np.ones((H, W), bool)
|
|
for e in range(3):
|
|
ea = a + 16 * e
|
|
A, B, C = rdf(ea + 4), rdf(ea + 8), rdf(ea + 12)
|
|
v = A * xx + B * yy + C
|
|
en_pos &= v >= 0
|
|
en_neg &= v < 0
|
|
en = en_pos | en_neg # winding-agnostic
|
|
if not en.any():
|
|
continue
|
|
# z instr: scan forward from a+48 for the MEMltTREE header (preambles vary)
|
|
za = None
|
|
for off in range(48, 48 + 44, 4):
|
|
if (rd(a + off) & 0xffffff00) == 0x44ea2100:
|
|
za = a + off
|
|
break
|
|
if za is None:
|
|
continue
|
|
A, B, C = rdf(za + 4), rdf(za + 8), rdf(za + 12)
|
|
z = A * xx + B * yy + C
|
|
en &= z > zbuf
|
|
if not en.any():
|
|
continue
|
|
zbuf[en] = z[en]
|
|
# z-write at a+64 (1 word), colors from a+68: three 5-word groups
|
|
# {clmp-hdr, pword, w2, w3, w4} -- empirical: value plane = {B?, A?, C?}
|
|
cols = []
|
|
ca = za + 20
|
|
for c in range(3):
|
|
g = ca + 20 * c
|
|
hdr = rd(g)
|
|
w1, w2, w3, w4 = rd(g + 4), rd(g + 8), rd(g + 12), rd(g + 16)
|
|
# try: the plane floats are the last three words {A?, B?, C?}
|
|
fA, fB, fC = f32(w2), f32(w3), f32(w4)
|
|
cols.append((fA, fB, fC))
|
|
for c, (fA, fB, fC) in enumerate(cols):
|
|
plane = fA * xx + fB * yy + fC
|
|
rgb[..., c][en] = np.clip(plane[en], 0, 255)
|
|
drawn += 1
|
|
|
|
print("drawn: %d packets" % drawn)
|
|
print("rgb range:", rgb.min(), rgb.max())
|
|
# normalize for viewing if the scale is off
|
|
mx = rgb.max() or 1.0
|
|
img = (np.clip(rgb / (mx if mx > 255 else 255), 0, 1) * 255).astype(np.uint8)
|
|
from PIL import Image
|
|
Image.fromarray(img, 'RGB').save(S + r'\wide30_render.png')
|
|
# also a z-buffer visualization (structure check independent of colors)
|
|
zv = zbuf.copy()
|
|
m = zv > -1e29
|
|
if m.any():
|
|
zn = (zv - zv[m].min()) / max(1e-9, (zv[m].max() - zv[m].min()))
|
|
zi = np.zeros((H, W), np.uint8)
|
|
zi[m] = (40 + 215 * zn[m]).astype(np.uint8)
|
|
Image.fromarray(zi, 'L').save(S + r'\wide30_depth.png')
|
|
print("wrote wide30_render.png + wide30_depth.png")
|