"""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. Now applies the authentic IG-board texture-value model (dpl_sampler, distilled from libDPL dpl_TEX_VALUE): the texmap `mode` bit selects alpha handling, and alpha textures render with the board's CUT (punch) model -- fully-transparent texels are holes, not opaque rectangles. 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 the # alpha-cut below so PUNCH holes don't win the depth test. 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,alpha_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] # HxWx4 RGBA # apply the board alpha model (opaque / cut / blend); returns the drawn mask drawmask=composite(img, inside, samp[...,:3], samp[...,3], alpha_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")