- dpl2d API fully recovered from the binary recorders (@487f34-488630): opcode model (points/lines/polyline/circle/color/width/matrix/push-pop), CallList = INLINE include (state persists to caller), centered coordinate frame (unit = half viewport height). game/reconstructed/dpl2d.cpp rework. - BTReticleRenderable ctor @004cc40c transcribed with the authentic calibration (originX .35, originY .25, scaleY .5, 0..1200m right range ladder, bottom heading tape, FUN_004cd938 tick ladders, lock rings, turn arrows); range caret slides from the live target range fed by the mech4 targeting step (BTSetHudTargetRange). - Weapon pips: the binary gate is IsDerivedFrom(0x511830 = MechWeapon::ClassDerivations) [T1: part_014.c:5386 hard-aborts on missing weapon attrs; part_012 counts + roster ORs capabilityFlags@+0x334] so ALL 7 BLH weapons register (3 lasers + 2 PPCs + 2 MissileLaunchers). Pip A (lit, authored PipColor) on TargetWithinRange, else dark ring B. - AddWeapon @004cdac0 store map corrected to the verified order (part_014.c:4827-4837); both state attrs are literally named "SimulationState" (strings @51d526/51d577) -> weapon simulationState. - Mech roster this[0x1ef] renamed poweredSubsystems -> weaponRoster (0x511830 is MechWeapon, not PoweredSubsystem=0x50f4bc); derivation-tag table added to context/decomp-reference.md. - Draw hook BTDrawReticle after the 3D scene, cockpit view only. Binary Execute @004cdcf0 is an un-exported gap -> Draw dynamics [T3], tracked in context/open-questions.md with the blx_cop canopy + PNAME pip meshes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
48 lines
1.6 KiB
Python
48 lines
1.6 KiB
Python
import struct, sys
|
|
|
|
VTX_TAGS = {0x80: 12, 0x81: 24, 0x82: 28, 0x88: 20, 0x89: 32, 0x8A: 36}
|
|
CONTAINERS = {0x03, 0x40, 0x41, 0x42, 0x46, 0x48, 0x70} # HEADER OBJECT LOD PATCH PMESH SPHERE_LIST BOUND
|
|
|
|
def bounds(path):
|
|
data = open(path, 'rb').read()
|
|
assert data[:8] == b'DIV-BIZ2', path
|
|
lo = [1e9, 1e9, 1e9]
|
|
hi = [-1e9, -1e9, -1e9]
|
|
nverts = 0
|
|
|
|
def walk(pos, end):
|
|
nonlocal nverts
|
|
while pos < end - 2:
|
|
tagword, = struct.unpack_from('<H', data, pos)
|
|
tag = tagword & 0x2fff
|
|
wide = (tagword >> 14) & 3
|
|
if wide == 1:
|
|
ln, = struct.unpack_from('<H', data, pos + 2)
|
|
hdr = 4
|
|
else:
|
|
ln = data[pos + 2]
|
|
hdr = 3
|
|
payload = pos + hdr
|
|
if tag in VTX_TAGS:
|
|
stride = VTX_TAGS[tag]
|
|
n = ln // stride
|
|
for i in range(n):
|
|
x, y, z = struct.unpack_from('<3f', data, payload + i * stride)
|
|
for a, v in enumerate((x, y, z)):
|
|
if v < lo[a]: lo[a] = v
|
|
if v > hi[a]: hi[a] = v
|
|
nverts += n
|
|
elif tag in CONTAINERS:
|
|
walk(payload, payload + ln)
|
|
pos = payload + ln
|
|
walk(8, len(data))
|
|
print('%-14s verts=%5d X[%7.2f %7.2f] Y[%7.2f %7.2f] Z[%7.2f %7.2f]'
|
|
% (path.split('\\')[-1], nverts, lo[0], hi[0], lo[1], hi[1], lo[2], hi[2]))
|
|
|
|
base = r'C:\git\bt411\content\VIDEO\GEO\%s'
|
|
for f in ['BLX_COP.BGF']:
|
|
try:
|
|
bounds(base % f)
|
|
except Exception as e:
|
|
print(f, 'ERR', e)
|