59 lines
3.2 KiB
Python
59 lines
3.2 KiB
Python
import sys, glob, os, struct
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
import geomlib as G, mapchunk, lamapaths
|
|
USAGE = 'usage: debugviz_check.py <folder with debug WADs> [<folder with original CD WADs, default $LLAMAMOD_CD/wads>]'
|
|
if len(sys.argv) < 2 or sys.argv[1] in ('-h', '--help'):
|
|
sys.exit(USAGE)
|
|
SRC = lamapaths.need(sys.argv[2] if len(sys.argv) > 2 else lamapaths.CD_WADS, 'CD wads folder',
|
|
'pass it as 2nd argument or set LLAMAMOD_CD') + '/'
|
|
bad = 0
|
|
for f in sorted(glob.glob(sys.argv[1] + '/*.wad')):
|
|
n = os.path.basename(f); err = []
|
|
ch = G.wad_read(f); o = G.wad_read(SRC + n)
|
|
wf = G.wfpc_flags(ch)
|
|
trak = G.parse_trak(G.wad_get(ch, 'TRAK'))
|
|
assert G.build_trak(trak) == G.wad_get(ch, 'TRAK')
|
|
pages, texs = G.parse_text(G.wad_get(ch, 'TEXT'))
|
|
otrak = G.parse_trak(G.wad_get(o, 'TRAK'))
|
|
nt = len(texs)
|
|
for mi, m in enumerate(trak):
|
|
if len(m.verts) > 8000: err.append('model %d %d verts' % (mi, len(m.verts)))
|
|
run = 0
|
|
for k, fc in enumerate(m.faces):
|
|
if fc['tex'] >= nt: err.append('tex idx'); break
|
|
if max(fc['v']) >= len(m.verts): err.append('vert idx'); break
|
|
run = 1 if fc['flags'] & 8 else run + 1
|
|
if run > 256: err.append('batch>256 model %d' % mi); break
|
|
if mi < len(otrak):
|
|
om = otrak[mi]
|
|
if m.coll != om.coll: err.append('COLLISION CHANGED model %d' % mi)
|
|
if m.verts[:len(om.verts)] != om.verts or m.faces[:len(om.faces)] != om.faces:
|
|
err.append('original geometry changed %d' % mi)
|
|
elif any(len(g) for g in m.coll): err.append('new model with collision')
|
|
vc = [len(m.verts) for m in trak]
|
|
mp = mapchunk.parse(G.wad_get(ch, 'MAP'), wf, vc)
|
|
om = mapchunk.parse(G.wad_get(o, 'MAP'), wf, [len(m.verts) for m in otrak])
|
|
if mp['rest'] or mapchunk.build(mp, wf) != G.wad_get(ch, 'MAP'): err.append('MAP roundtrip')
|
|
for k in ('strats', 'nodes', 'list1', 'lights', 'tab32', 'grid', 'alts', 'strat_x', 'paths', 'x200', 'last'):
|
|
if mp[k] != om[k]: err.append('MAP %s changed' % k)
|
|
if mp['tiles'][:len(om['tiles'])] != om['tiles']: err.append('tiles changed')
|
|
W, H = mp['W'], mp['H']
|
|
for t in mp['tiles']:
|
|
if not (0 <= t[0] - 0.5 < W and 0 <= -t[2] - 0.5 < H) or t[4] >= len(trak): err.append('tile out of bounds'); break
|
|
# colour block: nv*frames per tile
|
|
gm = G.parse_map_tiles(G.wad_get(ch, 'MAP'), wf, vc)
|
|
for i, fr in enumerate(gm['cols']):
|
|
if any(len(c) != vc[gm['midx'][i]] for c in fr): err.append('colour block %d' % i); break
|
|
# collision unchanged per tile instance of the original tiles
|
|
for k in ('TEXT',):
|
|
pass
|
|
others = [t for t, _ in ch if t not in ('TRAK', 'MAP ', 'TEXT')]
|
|
for t in others:
|
|
if G.wad_get(ch, t) != G.wad_get(o, t): err.append('chunk %s changed' % t)
|
|
sz = sum(len(G.wad_get(ch, t)) for t in ('TRAK', 'STPC', 'MAP ', 'LGPC'))
|
|
print('%-13s %s maxV %4d maxF %4d models %4d tiles %5d TRAK+STPC+MAP+LGPC %.1f MB' % (
|
|
n, 'OK ' if not err else 'ERROR ' + '; '.join(sorted(set(err))[:4]), max(vc), max(len(m.faces) for m in trak),
|
|
len(trak), len(mp['tiles']), sz / 2**20))
|
|
bad += bool(err)
|
|
print('errors:', bad)
|