- vrend410.mng: the production firmware, a HARD dependency of the committed
live pipeline (emu_main.py MAPS['vrend410'].fw loads it) -- the repo couldn't
run the live renderer without it.
- txdn_probe.py / texstore_trace.py / texel_trace.py: standalone reverse-
engineering probes (texture-source/DRAM-write/texel tracing) documenting the
texid-binding and texel-format investigations.
- .gitignore: exclude the firmware-decomp run artifacts (emu860c.pyd rebuildable
from source, *.log/*.pkl/*.png renderer outputs + caches), editor junk, and
the game runtime state/logs written by running the pod.
Left untouched deliberately: the parallel Mech session's in-progress
restoration/source410/BT/{EMITTER,BTPLAYER}.CPP edits (theirs to commit) and
the tracked game runtime state (LAST.EGG/CTMIX.CFG etc. -- transient).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
63 lines
2.6 KiB
Python
63 lines
2.6 KiB
Python
"""Find where the production build stores texels: run the battle wire to the
|
|
first sizable set_texmap_texels + its 0x1a bulk run, watching ALL DRAM writes
|
|
during those commands -> the texel destination + layout + format."""
|
|
import sys, os, struct, collections
|
|
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
|
|
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('<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:]))
|
|
# find first set_texmap_texels with header n_texels>0 (mode field) then following 0x1a runs
|
|
def w32(p,o): return struct.unpack_from('<I',p,o)[0]
|
|
tex_idx=None
|
|
for i,(a,p) in enumerate(recs):
|
|
if ANAME.get(a)=='set_texmap_texels' and len(p)>=20:
|
|
h=[w32(p,4*k) for k in range(5)]
|
|
# header: remote, n_texels, u, v, mode
|
|
if h[1]>16 and h[2]*h[3]==h[1]:
|
|
tex_idx=i; hdr=h; break
|
|
print("first real texmap @cmd %d: remote=%#x n=%d u=%d v=%d mode=%d"%((tex_idx,)+tuple(hdr)))
|
|
r=boot(fw='vrend410', queue=recs); shim=CpuShim()
|
|
RECV=emu_main.MAPS['vrend410']['receive']
|
|
# advance to just before tex_idx
|
|
while r.qi < tex_idx:
|
|
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 h: h(shim)
|
|
# now watch writes across tex_idx and the next ~10 commands (the 0x1a bulk)
|
|
emu860c.watch_add(0x08000000, 0x0c000000)
|
|
emu860c.watch_drain()
|
|
stop_qi=tex_idx+12
|
|
while r.qi < stop_qi:
|
|
reason,_=emu860c.run(200_000_000)
|
|
if reason==3: continue
|
|
pc=emu860c.getstate()['pc']; h=r.hooks.get(pc)
|
|
if h is None: break
|
|
if h: h(shim)
|
|
raw=emu860c.watch_drain()
|
|
vals=struct.unpack('<%dI'%(len(raw)//4), raw)
|
|
addrs=vals[0::2]
|
|
pages=collections.Counter(a>>12 for a in addrs)
|
|
print("write pages during texmap upload (top 12):")
|
|
for pg,n in pages.most_common(12):
|
|
print(" %#x000 : %d"%(pg,n))
|
|
# dump a sample of the biggest page's writes to see texel format
|
|
top=pages.most_common(1)[0][0]<<12
|
|
sample=[(addrs[k], vals[2*k+1]) for k in range(len(addrs)) if (addrs[k]>>12)==(top>>12)][:8]
|
|
print("sample writes @%#x:"%top)
|
|
for a,v in sample: print(" %#010x <- %08x"%(a,v))
|