73 lines
1.9 KiB
Python
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)
|