"""M5 integrate: battle frame with the VERIFIED perspective divide (correct texel scale/tiling) + per-quad texid -> texture (best-effort binding, since the exact texid->handle needs the board texture-RAM model). Real colours from real textures, perspective-correct. Textures decode via the SVT [pad,B,G,R] format (texstore -> RGB); the board texture-value model (wrap + near-black cutout) is applied through dpl_sampler, distilled from libDPL dpl_TEX_VALUE + the real renderer. See IG-SHADING-MODEL.md.""" import pickle, struct, os, sys sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, r'C:\VWE\TeslaRel410\dpl3-revive\patha') import numpy as np from PIL import Image from texstore import build_texstore from dpl_sampler import mode_to_texflags, wrap_index, composite HERE=os.path.dirname(os.path.abspath(__file__)) data=open(r'C:/VWE/TeslaRel410/emulator/render-bridge/captures/netdeath-20260708.fifodump','rb').read() recs=[]; off=0 while True: i=data.find(b'VPXM',off) if i<0: break ln=struct.unpack_from('=4: a=struct.unpack_from('>8)&0xff) in EDGE and len(edges)<6: edges.append((f32(rd(p+4)),f32(rd(p+8)),f32(rd(p+12)))); p+=16 if len(edges)<3: continue ep=np.ones((H,W),bool); en=np.ones((H,W),bool) for A,B,C in edges: v=A*xx+B*yy+C; ep&=v>=0; en&=v<0 inside=ep|en if not inside.any(): continue zp=tzp=up=vp=None; tid=None; q=p for _ in range(70): w=rd(q); op=(w>>8)&0xff; ad=w&0xff if op==0x21 and zp is None: zp=(f32(rd(q+4)),f32(rd(q+8)),f32(rd(q+12))) if op==0x43 and ad==32 and tzp is None: tzp=(f32(rd(q+4)),f32(rd(q+8)),f32(rd(q+12))) if op==0x43 and ad==58 and up is None: up=(f32(rd(q+4)),f32(rd(q+8)),f32(rd(q+12))) if op==0x43 and ad==78 and vp is None: vp=(f32(rd(q+4)),f32(rd(q+8)),f32(rd(q+12))) if op==0xf7 and ad in (141,142) and tid is None: tid=(rd(q+4)>>2)&0x3f q+=4 if zp is None: continue z=zp[0]*xx+zp[1]*yy+zp[2] inside&=z>zbuf if not inside.any(): continue # z is claimed only on pixels the poly actually OWNS (deferred past any cutout) if up and vp and tzp: # best-effort texid -> texture (exact binding = board tex-RAM model, pending) h,(tu,tv,mode,arr)=texlist[(tid or 0)%len(texlist)] wrap_u,wrap_v,cut_mode=mode_to_texflags(mode) tzv=tzp[0]*xx+tzp[1]*yy+tzp[2] tzv=np.where(np.abs(tzv)<1.0, np.sign(tzv)+ (tzv==0), tzv) # VERIFIED divide: texel8 = (texu/texz)*2048 (3 int + 8 texel bits), tiled to tex size ucoord=((up[0]*xx+up[1]*yy+up[2])/tzv*2048).astype(np.int64) vcoord=((vp[0]*xx+vp[1]*yy+vp[2])/tzv*2048).astype(np.int64) ui=wrap_index((ucoord*tu)>>8, tu, wrap_u) # 8-bit texel -> tex-size index vi=wrap_index((vcoord*tv)>>8, tv, wrap_v) samp=arr[vi,ui] # HxWx3 RGB (SVT xbgr -> RGB in texstore) # board texture-value model: opaque, or CUT (near-black keying), see dpl_sampler drawmask=composite(img, inside, samp, cut_mode) else: img[inside]=(60,60,70) drawmask=inside zbuf[drawmask]=z[drawmask] drawn+=1 print("drawn %d quads"%drawn) Image.fromarray(img,'RGB').save(os.path.join(HERE,'battle_final.png')) print("wrote battle_final.png")