The operator's 'many seconds between display updates', run to ground: MECHANISM (verified in source AND the shipped exe bytes): main passes GetTicksPerSecond() as ApplicationManager's frame RATE, so frameDuration is microscopic and RunMissions runs flat-out -- exactly ONE background slot per loop frame, shipped and ours alike (ctor constant @0044f2d8 == 1.0f, read straight out of BTL4OPT.EXE). That slot feeds a 7-task ring; the gauge renderer gets 1/7th of slots, one ACTIVE gauge per slot, and the screen blits once per completed wheel pass. The wheel is 136 gauges -- and the BT_GAUGE_LOG roster dump shows all 136 are real cockpit instruments (26 armor colormappers, leak gauges, cooling loops, weapon clusters...): a Tesla pod shows everything at once, so the roster is AUTHENTIC and must not be trimmed. Per-instrument latency is therefore 7 x 146 / loop_fps -- the loop rate is the only lever. THE DEFECT: build410.sh compiled -O2 alone. The authentic release tier (CODE/BT/OPT.MAK) is -O2 -Ot -Oc -Og -O -Ol -Z -Ob -Oe -Oi -Om -Op -Ov. Adopting it (all 234 TUs clean, no BC4.52 optimizer ICEs) doubled the loop: 16.7 -> ~30 fps wall on the rig. Shipped fifo throughput is still ~2x ours (11.8KB/s vs 6.4KB/s, governor-conflated) -- residual gap is an open question pinned in GAUGE-CADENCE-NOTES.md with the operator A/B ask. Instrumentation kept, cheap and gated: slot/wheel counters on the [stack] line (BT_STACK_LOG), one-shot roster dump (BT_GAUGE_LOG), tick-delta timers compile-gated BT_TICK_PROBES (OFF -- guest tick sums proved to be trap-burst artifacts in the emulator, not costs; wall rates are the only trustworthy measure). New: MUNGA/APPTASK.CPP shadow, fifofps.py (true board fps from a fifodump), pod_render_bgprobe.conf. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
32 lines
956 B
Python
32 lines
956 B
Python
"""Count draw_scene (action 9) records in a fifodump = true board fps.
|
|
py fifofps.py <fifodump> -> total count
|
|
py fifofps.py <fifodump> <secs> -> count now, wait, count again, report fps
|
|
"""
|
|
import sys, time, struct
|
|
|
|
def count_frames(path):
|
|
n = 0
|
|
with open(path, 'rb') as f:
|
|
data = f.read()
|
|
off = 0
|
|
while off + 8 <= len(data):
|
|
if data[off:off+4] != b'VPXM':
|
|
off += 1
|
|
continue
|
|
ln = struct.unpack_from('<I', data, off+4)[0] & 0x00ffffff
|
|
body = data[off+8:off+8+ln]
|
|
off += 8 + ln
|
|
if len(body) >= 4 and struct.unpack_from('<I', body, 0)[0] == 9:
|
|
n += 1
|
|
return n
|
|
|
|
path = sys.argv[1]
|
|
if len(sys.argv) > 2:
|
|
secs = float(sys.argv[2])
|
|
a = count_frames(path)
|
|
time.sleep(secs)
|
|
b = count_frames(path)
|
|
print(f"{a} -> {b} draw_scene in {secs:.0f}s = {(b-a)/secs:.1f} fps")
|
|
else:
|
|
print(count_frames(path), "draw_scene records")
|