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>
17 lines
769 B
Python
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
|