Files
llamamod/tools/stpcwalk.py
T

73 lines
1.9 KiB
Python

#!/usr/bin/env python3
"""Rough STPC walk (boundaries only): models, animsets, flag-0x100 block, then strat code.
Reimplemented from FUN_0042ab50 / FUN_0041f770 / FUN_0041f8b0 (groove.exe)."""
import struct
def u32(d, o):
return struct.unpack_from('<I', d, o)[0]
def u16(d, o):
return struct.unpack_from('<H', d, o)[0]
def models(d, o, n):
hdr = o
o += n * 0x8c
out = []
for i in range(n):
h = hdr + i * 0x8c
start = o
o += u16(d, h + 0x86) * 2
o += u16(d, h + 0x6c) * 0x18
o += u16(d, h + 0x6e) * 0x1c
o += (u16(d, h + 0x78) + u16(d, h + 0x7a) + u16(d, h + 0x7c)) * 0x20
out.append((h, start, o))
return o, out
def animsets(d, o, n):
hdr = o
o += n * 0x20
for i in range(n):
h = hdr + i * 0x20
a0, a1, nfr, a3, a4, a5, a6, a7 = struct.unpack_from('<8I', d, h)
o += a0 * 4
if a3 == 0:
o += nfr * 8
if a4:
o += nfr * 4
o += nfr * 4
for f in range(nfr):
if a4:
if f == 0:
o += a4 * 8
else:
o += a4 * 2 + (2 if a4 & 1 else 0)
o += a6 * 0x40
return o
def walk(d, wfpc):
n = u32(d, 0)
o, mdl = 4, []
for _ in range(n): # FUN_0041f770(&p,1,..) per model: header directly followed by data
o, mm = models(d, o, 1)
mdl += mm
na = u32(d, o); o += 4
for _ in range(na): # FUN_0041f8b0(&p,1,..) per animset
o = animsets(d, o, 1)
extra = []
if wfpc & 0x100:
n3 = u32(d, o); o += 4
for _ in range(n3):
h = o
cnt = u32(d, h + 4)
o = h + 16
if cnt & 0x1fffffff:
o += cnt * 8
o, mm = models(d, o, cnt)
extra.append((h, cnt, mm))
return dict(models=mdl, nanim=na, extra=extra, code=o)