Files
arcattackandClaude Opus 4.8 4a4ec6855c gauge-complete P4e: SectorDisplay reconstructed + registered -> radar SECTOR X/Z read-out LIVE
The "sectorDisplay" cockpit primitive (Secondary overlay, the radar SECTOR X/Z
coordinate read-out) was PROSE-ONLY in btl4gau3 (placeholder Make, no ctor/
methodDescription/registration) -> the config line was parse-SKIPPED and never built.

Reconstructed byte-verified from the disassembly (ctor @4c9e10, Execute @4ca07c,
methodDescription PE-parse): SectorDisplay : GraphicGauge, sizeof 0xC4. Its Execute
reads the linked mech's world position and shows two 100-unit sector numerics:
  numericA = Round(-localOrigin.z * 0.01) + 500
  numericB = Round( localOrigin.x * 0.01) + 500
(rounding = round-to-nearest == FUN_004dcd94, corrected from the reviewer's wrong
"truncate" claim; 0.01 const PE-verified; -Z/+X axis + fchs confirmed from asm).
Overridden slots: LinkToEntity(9) caches the subject, BecameActive(3, non-inactivating),
Execute(16) -> satisfies the container-Execute rule. Layout overflow-locked
(static_assert sizeof<=0xC4). Make/ctor/dtor mirror the registered PilotList sibling;
the config image name is copied (nameCopy) since Execute reads it per-frame.
Registered in BTL4MethodDescription[].

VERIFIED LIVE (BT_SECTOR_LOG): Make port=1 pos=(125,579) image=helv15.pcc gridCached=1;
Execute -Z=960.4 X=361.6 -> sectorA=510 sectorB=504 (Round(9.6)+500=510, Round(3.6)+500=504
-- authentic 100-unit sectors from live mech position). Gauge composite renders full,
no crash. The skip list is now exactly the two remaining widgets (prepEngr x12, messageBoard).

Also: a permanent BT_GAUGE_SKIP_LOG diagnostic (GAUGREND.cpp, gated) that logs each
unregistered gauge primitive the dev-parse skips -- the tool that pinned this down
(earlier "not built" runs were killed before the lazy gauge-renderer init).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 21:25:48 -05:00

17 lines
769 B
Python

import struct,sys
va=int(sys.argv[1],16)
f=open('content/BTL4OPT.EXE','rb').read()
pe=struct.unpack_from('<I',f,0x3c)[0]
numsec=struct.unpack_from('<H',f,pe+6)[0]; optsz=struct.unpack_from('<H',f,pe+20)[0]
imgbase=struct.unpack_from('<I',f,pe+0x34)[0]; sectab=pe+24+optsz
for i in range(numsec):
o=sectab+i*40; vsz,va2,rsz,ra=struct.unpack_from('<IIII',f,o+8)
if imgbase+va2<=va<imgbase+va2+max(vsz,rsz):
fo=ra+(va-imgbase-va2); raw=f[fo:fo+10]
# 80-bit extended: 64-bit mantissa + 15-bit exp + sign
m=struct.unpack('<Q',raw[0:8])[0]; se=struct.unpack('<H',raw[8:10])[0]
sign=-1 if se&0x8000 else 1; exp=(se&0x7fff)-16383
val=sign*(m/2**63)*2.0**exp
print(f"VA {va:#x} tbyte={raw.hex()} = {val!r}")
break