Files
TeslaRel410/emulator/firmware-decomp/emu860c/battle_probe.py
T
CydandClaude Opus 4.8 b4c2337ab1 Battle geometry, rendered honestly: coherent arena floor + horizon + sky
Fixed the readout: the effect packets are 3-4 edge TEXTURED quads (0x2c/0x42/
0x0d edges + z + texz/texu/texv planes -- NO Gouraud colour, confirming the
scene is textured). Two bugs in the first pass: (1) 0x2c edges were treated
as 'accept both sides', turning every quad into a full-plane fill; (2) only
2-edge packets were caught, dropping ~3/4 of the geometry. render_battle.py
applies the render_wide30 polygon-winding rule (inside = all-edges>=0 OR
all<0) -> 78 polygons of 141 setups.

Result (flat-per-polygon + depth): a geometrically coherent first-person
scene -- sky at far depth, a ground plane ramping smoothly from horizon to
foreground, a clean horizon line, upright structures. The perspective is
consistent; this is real scene geometry, not the muddy u/v wedges of the
first attempt. Surfaces still need texels (TXDN/M3) for their skin.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 16:10:49 -05:00

44 lines
1.7 KiB
Python

"""Dump one mid-scene battle draw's effect program for honest inspection."""
import sys, os, struct, pickle
HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, HERE); sys.path.insert(0, os.path.dirname(HERE))
sys.path.insert(0, r'C:\VWE\TeslaRel410\dpl3-revive\patha')
import emu860, emu_main, emu860c
from driver import boot, CpuShim
from vrboard import A
ANAME = {int(a): a.name for a in A}
emu860.Mem.log = lambda self, *a, **k: None
TARGET = int(sys.argv[2]) if len(sys.argv) > 2 else 6234
data = open(sys.argv[1], 'rb').read()
recs=[]; off=0
while True:
i=data.find(b'VPXM',off)
if i<0: break
ln=struct.unpack_from('<I',data,i+4)[0]; body=data[i+8:i+8+ln]; off=i+8+ln
if len(body)>=4:
a=struct.unpack_from('<I',body,0)[0]
if a<0x100: recs.append((a,body[4:]))
r=boot(fw='vrend410', queue=recs); shim=CpuShim()
RECV=emu_main.MAPS['vrend410']['receive']
while r.qi < TARGET:
reason,_=emu860c.run(500_000_000)
if reason==3: continue
pc=emu860c.getstate()['pc']; h=r.hooks.get(pc)
if h is None: break
if pc==RECV and r.qi<len(r.queue) and ANAME.get(r.queue[r.qi][0])=='draw_scene' and r.qi>=TARGET-1:
# run this draw fully, capturing the program region after
h(shim)
while True:
reason,_=emu860c.run(500_000_000)
if reason==3: continue
if emu860c.getstate()['pc']==RECV: break
hh=r.hooks.get(emu860c.getstate()['pc'])
if hh: hh(shim)
else: break
break
if h: h(shim)
prog={a:emu860c.r32(a) for a in range(0x08158000,0x08170000,4) if emu860c.r32(a)}
pickle.dump({'prog':prog,'qi':r.qi}, open(os.path.join(HERE,'battle_prog.pkl'),'wb'))
print("dumped %d prog cells at cmd %d"%(len(prog), r.qi))