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>
44 lines
1.7 KiB
Python
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))
|