BT410 5.3.52: frame rate measured properly -- the missing mech skeleton is the real gap
The pod updates every few seconds. Measured by sampling a head window every
2s (emulator/render-bridge/headrate.py): OURS changed in 5 of 12 samples,
SHIPPED in 1 of 12. So the reconstruction is not slower than the shipped
binary -- the emulated board is just expensive. Caveat recorded with it:
ours was being driven by the throttle hooks while the shipped exe ignores
them and sat parked, so treat those as same-order, not a win.
What did cost us 3x was mine: BT_MECH_LOG/BT_LAUNCH_LOG write per-frame lines
and DEBUG_STREAM=cout is redirected to COM3, so every one goes through an
emulated serial port. Turning them off took the wire from 480 to ~1480
bytes/sec. pod_render_quiet.conf is the conf to use for timing work.
And a correction to my own earlier framing: wire bytes/sec is NOT a frame
rate. Shipped pushes ~8900 B/s against our ~1480 and the difference is
CONTENT, not speed -- shipped submits the mech and we do not:
OURS: L4VIDEO.cpp wrong video resource type for object mad.skl
SHIPPED: (no such line)
The mech's model resource is a SKELETON. The engine's default
MakeEntityRenderables accepts only Object/Rubble and rejects anything else
with exactly that message, because skeletons are the GAME renderer's job. So
our arena renders but the MECH IS ABSENT, and with it the cockpit interior --
one unimplemented path explaining both the missing model and the lower wire
volume.
Next brick is now precisely scoped: answer MechClassID by reading the .SKL
notation pages into a dpl_DCS hierarchy and hanging the per-node .BGF
geometry off it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,20 @@
|
|||||||
|
import sys, time, subprocess
|
||||||
|
from PIL import Image
|
||||||
|
name, label = sys.argv[1], sys.argv[2]
|
||||||
|
def grab(out):
|
||||||
|
subprocess.run(["powershell","-ExecutionPolicy","Bypass","-File","grab.ps1",
|
||||||
|
"-Out",out,"-Match",name], capture_output=True)
|
||||||
|
return Image.open(out).convert("RGB")
|
||||||
|
prev = grab("hr_0.png"); changes = []
|
||||||
|
t0 = time.time()
|
||||||
|
for i in range(1, 13):
|
||||||
|
time.sleep(2)
|
||||||
|
cur = grab("hr_%d.png" % i)
|
||||||
|
pa, pb = prev.load(), cur.load(); w,h = cur.size
|
||||||
|
d = sum(1 for y in range(0,h,4) for x in range(0,w,4) if pa[x,y]!=pb[x,y])
|
||||||
|
changes.append(d)
|
||||||
|
prev = cur
|
||||||
|
moved = sum(1 for c in changes if c > 20)
|
||||||
|
print("%s: %d of %d samples (2s apart) showed change -> ~%.1f s between updates"
|
||||||
|
% (label, moved, len(changes), (len(changes)*2.0)/max(moved,1)))
|
||||||
|
print(" per-sample changed-pixel counts:", changes)
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
[sdl]
|
||||||
|
output=opengl
|
||||||
|
# higher,higher not highest: HIGH_PRIORITY_CLASS starved the host desktop;
|
||||||
|
# with the retry patches a rare dropout self-recovers (see gauge_rio.conf).
|
||||||
|
priority=higher,higher
|
||||||
|
[dosbox]
|
||||||
|
memsize=32
|
||||||
|
machine=svga_s3
|
||||||
|
[cpu]
|
||||||
|
core=dynamic
|
||||||
|
cputype=pentium
|
||||||
|
cycles=max
|
||||||
|
[sblaster]
|
||||||
|
sbtype=sb16
|
||||||
|
sbbase=220
|
||||||
|
irq=5
|
||||||
|
dma=1
|
||||||
|
hdma=5
|
||||||
|
[mixer]
|
||||||
|
# match the EMU8000s' native rate (no resample) and buffer ~60ms so brief
|
||||||
|
# emulation-thread stalls (RIO retry recovery) don't audibly chop
|
||||||
|
rate=44100
|
||||||
|
blocksize=1024
|
||||||
|
prebuffer=60
|
||||||
|
[serial]
|
||||||
|
# RIO on COM1 with the low-latency options (rxpollus/rxburst) so the board's
|
||||||
|
# few-ms ACK deadline is met; plasma display on COM2 (real pod has both).
|
||||||
|
# VWE fork namedpipe backend (com0com/realport retired -- COM1/COM2 gone):
|
||||||
|
# DOSBox = pipe client (retry), vRIO/vPLASMA apps = servers; an unconnected
|
||||||
|
# pipe behaves as an unplugged cable so the mission still runs. serialnamedpipe.h
|
||||||
|
serial1=namedpipe pipe:vrio rxpollus:100 rxburst:16
|
||||||
|
serial2=namedpipe pipe:vplasma
|
||||||
|
|
||||||
|
# live UNBUFFERED game output: DOS char devices are not buffered, so
|
||||||
|
|
||||||
|
# redirecting stdout to COM3 lands every line immediately. A normal
|
||||||
|
|
||||||
|
# '> file' redirect stays 0 bytes until the process exits, which hides
|
||||||
|
|
||||||
|
# all progress on a run that does NOT crash.
|
||||||
|
|
||||||
|
serial3=file file:C:\VWE\TeslaRel410\emulator\render-bridge\podlog.txt
|
||||||
|
[autoexec]
|
||||||
|
mount c "C:\VWE\TeslaRel410\ALPHA_1"
|
||||||
|
c:
|
||||||
|
cd \REL410\BT
|
||||||
|
set VIDEOFORMAT=svga
|
||||||
|
rem production pod card init (PARAMETR.BAT:181-186): DIAGNOSE + AWEUTIL per
|
||||||
|
rem card -- AWEUTIL /S does the EMU8000 bring-up and DRAM detect the HMI SOS
|
||||||
|
rem driver relies on; skipping it left the cards uninitialized (silent).
|
||||||
|
rem aweutil /s SKIPPED for now: it verifies the AWE32 GM ROM, which the
|
||||||
|
rem emulated cards lack (hangs in a retry loop) -- restore once the ROM is
|
||||||
|
rem dumped from a real card. diagnose /s kept (passes, sets mixer config).
|
||||||
|
set BLASTER=A220 I5 D1 H5 P330 T6
|
||||||
|
c:\sb16\diagnose /s
|
||||||
|
set BLASTER=A240 I7 D3 H6 P300 T6
|
||||||
|
c:\sb16\diagnose /s
|
||||||
|
set BLASTER=A220 I5 D1 H5 P330 T6
|
||||||
|
set TEMP=c:\
|
||||||
|
rem arena1 city mission (TESTARN.EGG: map=arena1, time=day) with the RIO
|
||||||
|
rem attached; stdout redirected so mission-load progress survives kills.
|
||||||
|
set BT_FORCE_THROTTLE=0.6
|
||||||
|
set BT_FORCE_TURN=0.25
|
||||||
|
set HEAPSIZE=15000000
|
||||||
|
set L4GAUGE=640x480x16
|
||||||
|
call setenv.bat r s n p
|
||||||
|
32rtm.exe -x
|
||||||
|
BTL4REC.EXE -egg testarn.egg > COM3
|
||||||
|
|
||||||
@@ -56,6 +56,8 @@ rem arena1 city mission (TESTARN.EGG: map=arena1, time=day) with the RIO
|
|||||||
set BLASTER=A240 I7 D3 H6 P300 T6
|
set BLASTER=A240 I7 D3 H6 P300 T6
|
||||||
c:\sb16\diagnose /s
|
c:\sb16\diagnose /s
|
||||||
set BLASTER=A220 I5 D1 H5 P330 T6
|
set BLASTER=A220 I5 D1 H5 P330 T6
|
||||||
|
set TEMP=c:\
|
||||||
|
rem arena1 city mission (TESTARN.EGG: map=arena1, time=day) with the RIO
|
||||||
rem attached; stdout redirected so mission-load progress survives kills.
|
rem attached; stdout redirected so mission-load progress survives kills.
|
||||||
set BT_MECH_LOG=1
|
set BT_MECH_LOG=1
|
||||||
set BT_LAUNCH_LOG=1
|
set BT_LAUNCH_LOG=1
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
BattleTech v4.10
|
BattleTech v4.10
|
||||||
BTL4Application::BTL4Application
|
BTL4Application::BTL4Application
|
||||||
GaugeInterpreter: undefined label 'Initialization'
|
GaugeInterpreter: undefined label 'Initialization'
|
||||||
MakeVehicleSystems hud=0x01150bfc
|
MakeVehicleSystems hud=0x011503f0
|
||||||
Warning: damage zone 'dz_missle' not found!
|
Warning: damage zone 'dz_missle' not found!
|
||||||
Warning: damage zone 'dz_missle' not found!
|
Warning: damage zone 'dz_missle' not found!
|
||||||
Warning: damage zone 'dz_lmissle' not found!
|
Warning: damage zone 'dz_lmissle' not found!
|
||||||
@@ -9,9 +9,7 @@ Warning: damage zone 'dz_rmissle' not found!
|
|||||||
Warning: damage zone 'dz_ftorso' not found!
|
Warning: damage zone 'dz_ftorso' not found!
|
||||||
Warning: damage zone 'dz_btorso' not found!
|
Warning: damage zone 'dz_btorso' not found!
|
||||||
LBE4ControlsManager::Execute, lost RIO analog request
|
LBE4ControlsManager::Execute, lost RIO analog request
|
||||||
iThinkIRQIsOn =1, actual state =1, characters sent =416
|
iThinkIRQIsOn =1, actual state =1, characters sent =713
|
||||||
LBE4ControlsManager::Execute, lost RIO analog request
|
|
||||||
iThinkIRQIsOn =1, actual state =1, characters sent =641
|
|
||||||
BTL4Application::RunMissionMessageHandler
|
BTL4Application::RunMissionMessageHandler
|
||||||
Turning Plasma Score Display On
|
Turning Plasma Score Display On
|
||||||
BTL4Application::RunMissionMessageHandler
|
BTL4Application::RunMissionMessageHandler
|
||||||
|
|||||||
@@ -578,3 +578,46 @@ NEXT: drive it. With controls fed (vRIO is already running in this rig) the
|
|||||||
mech should move and the scene should animate; then the mech's own model and
|
mech should move and the scene should animate; then the mech's own model and
|
||||||
the cockpit-interior renderables are what to verify against the shipped
|
the cockpit-interior renderables are what to verify against the shipped
|
||||||
binary, which is a cheap A/B now (pod_render_shp.conf).
|
binary, which is a cheap A/B now (pod_render_shp.conf).
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
FRAME RATE: measured properly, and what is actually missing from the scene
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
The pod updates roughly once every several seconds. Measured by capturing a
|
||||||
|
head window every 2s and counting changed frames (scratchpad/headrate.py):
|
||||||
|
|
||||||
|
OURS 5 of 12 samples changed (~5s between updates)
|
||||||
|
SHIPPED 1 of 12 samples changed (~24s between updates)
|
||||||
|
|
||||||
|
So the reconstruction is NOT slower than the shipped binary here -- the
|
||||||
|
emulated Division board is simply expensive, and both run the pod at this
|
||||||
|
rate. CAVEAT on that comparison: ours was being driven (BT_FORCE_THROTTLE,
|
||||||
|
speed 14.4, gauges genuinely changing) while the shipped exe ignores those
|
||||||
|
env hooks and sat parked, so it had less to redraw. Treat the two numbers as
|
||||||
|
"same order", not as a win.
|
||||||
|
|
||||||
|
WHAT DID COST US 3x, AND IT WAS MINE: BT_MECH_LOG / BT_LAUNCH_LOG write
|
||||||
|
per-frame [sim]/[mppr] lines, and with DEBUG_STREAM=cout redirected to COM3
|
||||||
|
every one of them goes out through an emulated serial port. Turning them off
|
||||||
|
took the wire from 480 to ~1480 bytes/sec. Keep per-frame logging OFF for
|
||||||
|
anything timing-related -- pod_render_quiet.conf is that conf.
|
||||||
|
|
||||||
|
DO NOT READ WIRE BYTES/SEC AS A FRAME RATE. Shipped pushes ~8900 B/s against
|
||||||
|
our ~1480, and the difference is not speed -- it is CONTENT. Shipped is
|
||||||
|
submitting the mech; we are not:
|
||||||
|
|
||||||
|
OURS: L4VIDEO.cpp wrong video resource type for object mad.skl
|
||||||
|
SHIPPED: (no such line)
|
||||||
|
|
||||||
|
The mech's model resource is a SKELETON (mad.skl). The engine's default
|
||||||
|
MakeEntityRenderables only accepts Object/Rubble resource types and rejects
|
||||||
|
anything else with exactly that message (L4VIDEO.CPP:4265), because handling
|
||||||
|
skeletons is the GAME renderer's job -- RPL4VID.HPP's ReadSKLFile /
|
||||||
|
RecurseSKLFile. So our arena renders but the MECH IS ABSENT, and with it the
|
||||||
|
cockpit interior. That single unimplemented path explains both the missing
|
||||||
|
model and the lower wire volume.
|
||||||
|
|
||||||
|
NEXT BRICK, now precisely scoped: in BTL4VideoRenderer::MakeEntityRenderables
|
||||||
|
answer MechClassID (3001) by reading the .SKL notation pages (VIDEO/*.SKL are
|
||||||
|
in the mount) into a dpl_DCS hierarchy and hanging the per-node .BGF geometry
|
||||||
|
off it -- ReadSKLFile + RecurseSKLFile per the sibling header, content from
|
||||||
|
the BT411 donor.
|
||||||
|
|||||||
Reference in New Issue
Block a user