BT410 5.3.72: the fault caught in the act; the inside view gets its cockpit

VPX_PF_WATCH (fork, cpu/paging.cpp): on a guest page fault at the watched
linear address, dump guest registers, the last 64 serial RX deliveries with
guest cs:eip at each, the code bytes at the faulting EIP and the stack top.
serialnamedpipe's doReceive feeds the ring.  Armed in podrun.sh and
launch_pod.ps1.

The first catch decoded the residual fault completely: CS:EIP 00FF:000066D4
in the DPMI host, EBX = F000CA60 -- an IVT entry read as a dword, segment
F000 offset CA60, a BIOS default interrupt handler -- and the faulting access
is [EBX+0x3004], whose 0x80000000 segment-base wrap gives exactly cr2
7000FA64.  The host probes a word 0x3004 bytes past a real-mode vector value
treated as a flat pointer: harmless for its own low-memory handlers, a fault
for BIOS F000:xxxx defaults.  The serial ring shows a steady 1-byte/1-3ms
vRIO stream with nothing special at the fault -- the stream determines which
vectors get walked, not the crash itself.  The 0x3004 appears nowhere in
DPMI32VM.OVL or 32RTM.EXE as an immediate, so the probe now also dumps code
bytes at EIP; faulthunt.sh loops runs until the next catch.

Shipped baseline streak: 4/4 clean -- consistent with exposure, not yet
discriminating.

The inside view now loads the COCKPIT skeleton: the fleet-wide X-variant
naming convention (MAD->MAX etc., all 64 skeletons present) selects the same
25-joint chain with a single object -- max_cop.bgf, the MAX_COP canopy shell
with the PUNCH-texel windows from the capture forensics.  The donor names the
same mechanism from the decomp side (inside = SkeletonType_A with '_cop'
selection).  Fallback to the body skeleton when no X file exists.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-29 18:09:22 -05:00
co-authored by Claude Fable 5
parent bd1070110b
commit f2687a3146
20 changed files with 3153 additions and 642 deletions
-27
View File
@@ -54,30 +54,3 @@ LOG: ISA Plug & Play BIOS enabled
LOG: VGA ROM BIOS init callback
LOG: pixratio 1.000, dw false, dh false
LOG: Aspect ratio: 640 x 480 xToY=1.333 yToX=0.750
LOG: WARNING: No translation support (to host) for code page 0
LOG: DOS keyboard layout loaded with main language code US for layout us
LOG: XMS: 50 handles allocated for use by the DOS environment
LOG: EMS page frame at 0xe000-0xefff
LOG: COMMAND.COM env size: 720 bytes
LOG: COMMAND.COM environment block: 0x0701 sz=0x002d
LOG: COMMAND.COM main body (PSP): 0x072f sz=0x009a
LOG: COMMAND.COM stack: 0x0749
LOG: pixratio 1.350, dw false, dh false
LOG: Aspect ratio: 720 x 540 xToY=1.333 yToX=0.750
LOG: SHELL:Redirect output to COM3
LOG: VPXLOG: fifosock client connected
VPX lights@f1: type6=0 typeE=0 decoded=0 dir=0 amb(0.00,0.00,0.00)
LOG: 420998823 ERROR MOUSE:Unhandled videomode 79 on reset
LOG: pixratio 1.000, dw false, dh false
LOG: Aspect ratio: 640 x 480 xToY=1.333 yToX=0.750
VPX lightnode t=6 nb=52: [8]00000000/0 [12]00000000/0 [16]00000001/1.4013e-45 [20]3f800000/1 [24]3f800000/1 [28]3f800000/1 [32]64078678/1e+22 [36]64078678/1e+22 [40]00000000/0 [44]3e25a5b9/0.161765 [48]ffffffff/nan
VPX lights@f121: type6=2 typeE=6 decoded=2 dir=1 amb(0.55,0.50,0.65)
L0 dir(0.11,0.77,0.63) col(1.10,0.90,1.00)
VPX lights@f241: type6=2 typeE=6 decoded=2 dir=1 amb(0.55,0.50,0.65)
L0 dir(0.11,0.77,0.63) col(1.10,0.90,1.00)
VPX lights@f361: type6=2 typeE=9 decoded=2 dir=1 amb(0.55,0.50,0.65)
L0 dir(0.11,0.77,0.63) col(1.10,0.90,1.00)
VPX lights@f481: type6=2 typeE=10 decoded=2 dir=1 amb(0.55,0.50,0.65)
L0 dir(0.11,0.77,0.63) col(1.10,0.90,1.00)
VPX lights@f601: type6=2 typeE=10 decoded=2 dir=1 amb(0.55,0.50,0.65)
L0 dir(0.11,0.77,0.63) col(1.10,0.90,1.00)
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash
# Run RIO-live until the watched fault fires (max 6), keep the probe dump.
cd /c/VWE/TeslaRel410/emulator/render-bridge
for i in 1 2 3 4 5 6; do
bash podrun.sh pod_render_rec hunt$i > /dev/null 2>&1
until grep -q "Turning Plasma" podlog.txt 2>/dev/null || grep -qE "illegal address|page you don't own" podlog.txt 2>/dev/null; do sleep 10; done
if grep -q "page you don't own" podlog.txt; then
echo "hunt$i: FAULT -- dump follows"
grep -A40 "VPX_PF_WATCH hit" dosboxlog.txt | head -84
cp dosboxlog.txt logs/faultdump.txt
break
fi
echo "hunt$i: clean"
done
taskkill //F //IM dosbox-x.exe > /dev/null 2>&1
echo "FAULTHUNT DONE"
+1
View File
@@ -54,6 +54,7 @@ $env:VPX_EXPLODE = '1' # pentapus: 7 cockpit displays
$env:VPX_DUMPDIR = $Work
$env:VPX_FIFODUMP = "$Work\live.fifodump" # archival/replay copy
$env:VPX_FIFOSOCK = '8621' # live tee the bridge rides
$env:VPX_PF_WATCH = '7000FA64' # residual load-window fault: dump serial-RX ring on hit
$env:RIO_TAP = "$Work\riotap.txt"
# Dave's bridge is the out-the-window view; the native Division window is a
# decode diagnostic (-ShowNative), cleared black so missing geometry doesn't
@@ -0,0 +1,83 @@
LOG: Early LOG Init complete
LOG: CONFIG: Loaded config file: C:/VWE/TeslaRel410/emulator/render-bridge/pod_render_rec.conf
LOG: DOSBox-X's working directory: C:\VWE\TeslaRel410\emulator\src\src
LOG: Logging init: beginning logging proper. This is the end of the early init logging
LOG: Logging: No logfile was given. All further logging will be discarded.
LOG: DOSBox-X version 2026.06.02 Commit d75a57c (MinGW SDL2 64-bit)
LOG: Prevent capture: 0
LOG: SDL: version 2.32.10, Video windows, Audio directsound
LOG: EXPERIMENTAL: Debugger enabled for MinGW build, DOSBox-X crashes depending on the terminal software you use. Launching from command prompt (cmd.exe) is recommended.
LOG: Windows keyboard layout ID is 0x0409
LOG: Host keyboard layout is now us (US English)
LOG: Mapper keyboard layout is now us (US English)
LOG: SDL2 reports desktop display mode 3440 x 1440
LOG: OpenGL Version : 4.6.0 NVIDIA 610.47
LOG: Configured windowposition: -
LOG: SDL: Current window pixel format: SDL_PIXELFORMAT_RGB888
LOG: SDL: You are running in 24 bpp mode, this will slow down things!
LOG: Releasing keyboard
LOG: SDL: Windows 11 round corners will be disabled.
LOG: Screen report: Method 'Win98base' (3440.000 x 1440.000 pixels) at (0.000 x 0.000) (910.167 x 381.000 mm) (35.833 x 15.000 in) (96.000 x 96.000 DPI)
LOG: ISA BCLK: 8333333.333Hz (25000000/3)
LOG: monopal: green,
LOG: Active save slot: 1 [Empty]
LOG: USING AVI+ZMBV
LOG: Pentium CMPXCHG8B emulation is enabled
LOG: Max 1073741824 sz 32768
LOG: Final 32768
LOG: Final arrangement: Below 4GB = 32768KB, Above 4GB = 0KB
LOG: VPXLOG: fifosock listening on 127.0.0.1:8621
LOG: VPXLOG: live render backend started
LOG: VPXLOG: base 0x150 respond=1 handshakes=3 log='C:\Users\cyd\AppData\Local/Temp/vwe-pod/vpxresp.txt'
LOG: MIDI:Opened device:win32
LOG: mic_input: Selected microphone device: Microphone (Steam Streaming Microphone)
LOG: One joystick reported, initializing with 4axis
LOG: Using joystick Xbox One Controller with 6 axes, 16 buttons and 1 hat(s)
LOG: VOODOO LFB now at d0000000
LOG: Serial1: BASE 3f8h
LOG: Serial1: namedpipe client of \\.\pipe\vrio (poll 0.10ms burst x16)
LOG: Serial1: namedpipe connected to \\.\pipe\vrio
LOG: Serial2: BASE 2f8h
LOG: Serial2: namedpipe client of \\.\pipe\vplasma (poll 1.00ms burst x1)
LOG: Serial2: namedpipe connected to \\.\pipe\vplasma
LOG: Serial3: BASE 3e8h
LOG: Serial: port 3 will write to file C:\VWE\TeslaRel410\emulator\render-bridge\podlog.txt
LOG: Parallel1: BASE 378h
LOG: MPU-401 Registering I/O ports as if IBM PC MPU-401 at base 330h
LOG: Memory I/O complexity optimization enabled aka option 'memory io optimization 1'. If the game or demo is unable to draw to the screen properly, set the option to false.
LOG: The 'scanline render on demand' option is available and may provide a modest boost in video render performance if set to true.
LOG: Allocated APM BIOS pm entry point at f000:ce40
LOG: Writing code to fce40
LOG: Writing code to fce60
LOG: Windows: IID_ITaskbarList3 is available
LOG: ISA Plug & Play BIOS enabled
LOG: VGA ROM BIOS init callback
LOG: pixratio 1.000, dw false, dh false
LOG: Aspect ratio: 640 x 480 xToY=1.333 yToX=0.750
LOG: WARNING: No translation support (to host) for code page 0
LOG: DOS keyboard layout loaded with main language code US for layout us
LOG: XMS: 50 handles allocated for use by the DOS environment
LOG: EMS page frame at 0xe000-0xefff
LOG: COMMAND.COM env size: 720 bytes
LOG: COMMAND.COM environment block: 0x0701 sz=0x002d
LOG: COMMAND.COM main body (PSP): 0x072f sz=0x009a
LOG: COMMAND.COM stack: 0x0749
LOG: pixratio 1.350, dw false, dh false
LOG: Aspect ratio: 720 x 540 xToY=1.333 yToX=0.750
LOG: SHELL:Redirect output to COM3
LOG: VPXLOG: fifosock client connected
VPX lights@f1: type6=0 typeE=0 decoded=0 dir=0 amb(0.00,0.00,0.00)
LOG: 420998823 ERROR MOUSE:Unhandled videomode 79 on reset
LOG: pixratio 1.000, dw false, dh false
LOG: Aspect ratio: 640 x 480 xToY=1.333 yToX=0.750
VPX lightnode t=6 nb=52: [8]00000000/0 [12]00000000/0 [16]00000001/1.4013e-45 [20]3f800000/1 [24]3f800000/1 [28]3f800000/1 [32]64078678/1e+22 [36]64078678/1e+22 [40]00000000/0 [44]3e25a5b9/0.161765 [48]ffffffff/nan
VPX lights@f121: type6=2 typeE=6 decoded=2 dir=1 amb(0.55,0.50,0.65)
L0 dir(0.11,0.77,0.63) col(1.10,0.90,1.00)
VPX lights@f241: type6=2 typeE=6 decoded=2 dir=1 amb(0.55,0.50,0.65)
L0 dir(0.11,0.77,0.63) col(1.10,0.90,1.00)
VPX lights@f361: type6=2 typeE=9 decoded=2 dir=1 amb(0.55,0.50,0.65)
L0 dir(0.11,0.77,0.63) col(1.10,0.90,1.00)
VPX lights@f481: type6=2 typeE=10 decoded=2 dir=1 amb(0.55,0.50,0.65)
L0 dir(0.11,0.77,0.63) col(1.10,0.90,1.00)
VPX lights@f601: type6=2 typeE=10 decoded=2 dir=1 amb(0.55,0.50,0.65)
L0 dir(0.11,0.77,0.63) col(1.10,0.90,1.00)
+586
View File
@@ -0,0 +1,586 @@
BattleTech v4.10
BTL4Application::BTL4Application
RIO never came back from test mode!
GaugeInterpreter: undefined label 'Initialization'
[exp] master player experience=2 simLive=1 heatModelOn=1 advDamage=1
[role] 'Role::Default' lives=1000 killBonus=500 dmgMod=1
[torso] horizJoint 'jointtorso' -> 0x00bf3d58 type=1 enabled=1
[weap] 'AFC100' seg=13 mount=sitelgunport rear=0
[proj] 'AFC100' ammoBinIndex=21 -> AmmoBinAFC100 (rounds=20)
[weap] 'ERLLaser' seg=7 mount=siterugunport rear=0
[weap] 'ERSLaser_1' seg=13 mount=sitelgunport rear=0
[weap] 'ERSLaser_2' seg=8 mount=siterdgunport rear=0
[weap] 'LRM15_1' seg=18 mount=sitelmissleport rear=0
[proj] 'LRM15_1' ammoBinIndex=26 -> AmmoBinLRM15_1 (rounds=16)
[weap] 'LRM15_2' seg=19 mount=sitermissleport rear=0
[proj] 'LRM15_2' ammoBinIndex=28 -> AmmoBinLRM15_2 (rounds=16)
[mech] segment walk done: subsystemCount=32 weaponCount=6
[skel] jointSubsystem=0x009f6d84 jointCount=25
[mech] model params: walkTR=65 runTR=40 maxAcc=20 throttleAdj=0.8 (deg,deg,u/s^2,scale)
[mech] look angles: L=50 R=-50 F=-15 B=0 (deg)
[mech] damage zones streamed: 22 [dz_dtorso,dz_hip,dz_larm,dz_ldleg,dz_ldoor,dz_lfoot,dz_lgun,dz_ltorso,dz_luleg,dz_rarm,dz_rdleg,dz_rdoor,dz_reardtorso,dz_rearltorso,dz_rearrtorso,dz_rearutorso,dz_rfoot,dz_rgun,dz_rtorso,dz_ruleg,dz_searchlight,dz_utorso]
[cyl] table 'madcat' LOADED rows=7
[valve] 'Condenser1' valve=1 flow=0.166667
[valve] 'Condenser2' valve=1 flow=0.166667
[valve] 'Condenser3' valve=1 flow=0.166667
[valve] 'Condenser4' valve=1 flow=0.166667
[valve] 'Condenser5' valve=1 flow=0.166667
[valve] 'Condenser6' valve=1 flow=0.166667
[mapper] ctor id=0 throttleAttr=0x009efd04 controlModeAttr=0x009efd40
[map] 109 streamed mappings for 'L4'
[map] dir sub=0 cls=2012 id=3 grp=1 elem=0
[map] dir sub=0 cls=2012 id=4 grp=0 elem=0
[map] dir sub=0 cls=2012 id=6 grp=3 elem=63
[map] dir sub=17 cls=3013 id=14 grp=3 elem=66
[map] dir sub=0 cls=2012 id=10 grp=3 elem=68
[map] dir sub=0 cls=2012 id=11 grp=3 elem=67
[map] dir sub=0 cls=2012 id=12 grp=3 elem=65
[map] dir sub=22 cls=3021 id=19 grp=3 elem=64
[map] dir sub=23 cls=3016 id=19 grp=3 elem=64
[map] dir sub=24 cls=3016 id=19 grp=3 elem=64
[map] dir sub=25 cls=3016 id=19 grp=3 elem=64
[map] dir sub=27 cls=3024 id=19 grp=3 elem=71
[map] dir sub=29 cls=3024 id=19 grp=3 elem=71
[gau2] cluster slot=14 classID=3011 auxScreen=5 name=Avionics
[gau2] cluster slot=15 classID=3014 auxScreen=6 name=Myomers
[gau2] cluster slot=22 classID=3021 auxScreen=1 name=AFC100
[gau2] cluster slot=23 classID=3016 auxScreen=10 name=ERLLaser
[gau2] cluster slot=24 classID=3016 auxScreen=3 name=ERSLaser_1
[gau2] cluster slot=25 classID=3016 auxScreen=12 name=ERSLaser_2
[gau2] cluster slot=27 classID=3024 auxScreen=2 name=LRM15_1
[gau2] cluster slot=29 classID=3024 auxScreen=9 name=LRM15_2
ColorMapperArmor warning: damage zone dz_missle not found
ColorMapperArmor warning: damage zone dz_missle not found
ColorMapperArmor warning: damage zone dz_lmissle not found
ColorMapperArmor warning: damage zone dz_rmissle not found
ColorMapperArmor warning: damage zone dz_ftorso not found
ColorMapperArmor warning: damage zone dz_btorso not found
ColorMapperCritical warning: subsystem Torso does not exist
ColorMapperHeat warning: subsystem Torso does not exist
[link] InitializePlayerLink -> vehicle playerLink=0x00ad513c
[launch] state=11 minPriorityEmpty=0 ticks=15308
[queues] p0=BUSY p1=BUSY p2=BUSY p3=BUSY p4=- nextReady=1
[posts] id3=416
[launch] state=11 minPriorityEmpty=0 ticks=16322
[queues] p0=BUSY p1=BUSY p2=BUSY p3=BUSY p4=- nextReady=1
[posts] id3=502
[launch] state=11 minPriorityEmpty=0 ticks=17334
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=11 minPriorityEmpty=0 ticks=18344
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=11 minPriorityEmpty=0 ticks=19354
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=20422
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 1 class=3035 view=0 res=0
[mer] 2 class=42 view=0 res=1
[mer] 3 class=42 view=0 res=1
[mer] 4 class=42 view=0 res=1
[mer] 5 class=42 view=0 res=1
[mer] 6 class=42 view=0 res=1
[mer] 7 class=42 view=0 res=1
[mer] 8 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=21430
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 9 class=42 view=0 res=1
[mer] 10 class=42 view=0 res=1
[mer] 11 class=42 view=0 res=1
[mer] 12 class=42 view=0 res=1
[mer] 13 class=42 view=0 res=1
[mer] 14 class=42 view=0 res=1
[mer] 15 class=42 view=0 res=1
[mer] 16 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=22437
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 17 class=42 view=0 res=1
[mer] 18 class=42 view=0 res=1
[mer] 19 class=42 view=0 res=1
[mer] 20 class=42 view=0 res=1
[mer] 21 class=42 view=0 res=1
[mer] 22 class=42 view=0 res=1
[mer] 23 class=42 view=0 res=1
[mer] 24 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=23445
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 25 class=42 view=0 res=1
[mer] 26 class=42 view=0 res=1
[mer] 27 class=42 view=0 res=1
[mer] 28 class=42 view=0 res=1
[mer] 29 class=42 view=0 res=1
[mer] 30 class=42 view=0 res=1
[mer] 31 class=42 view=0 res=1
[mer] 32 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=24453
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 33 class=42 view=0 res=1
[mer] 34 class=42 view=0 res=1
[mer] 35 class=42 view=0 res=1
[mer] 36 class=42 view=0 res=1
[mer] 37 class=42 view=0 res=1
[mer] 38 class=94 view=0 res=1
[mer] 39 class=94 view=0 res=1
[mer] 40 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=25461
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 41 class=94 view=0 res=1
[mer] 42 class=94 view=0 res=1
[mer] 43 class=94 view=0 res=1
[mer] 44 class=94 view=0 res=1
[mer] 45 class=94 view=0 res=1
[mer] 46 class=94 view=0 res=1
[mer] 47 class=94 view=0 res=1
[mer] 48 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=26468
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 49 class=42 view=0 res=1
[mer] 50 class=42 view=0 res=1
[mer] 51 class=42 view=0 res=1
[mer] 52 class=42 view=0 res=1
[mer] 53 class=42 view=0 res=1
[mer] 54 class=94 view=0 res=1
[mer] 55 class=94 view=0 res=1
[mer] 56 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=27476
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 57 class=94 view=0 res=1
[mer] 58 class=42 view=0 res=1
[mer] 59 class=42 view=0 res=1
[mer] 60 class=42 view=0 res=1
[mer] 61 class=42 view=0 res=1
[mer] 62 class=94 view=0 res=1
[mer] 63 class=94 view=0 res=1
[mer] 64 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=28486
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 65 class=94 view=0 res=1
[mer] 66 class=94 view=0 res=1
[mer] 67 class=94 view=0 res=1
[stack] frame at 0x12dee7 drift=0 over 1001 frames ticks=28857 pump=347/1530
[mer] 68 class=42 view=0 res=1
[mer] 69 class=94 view=0 res=1
[mer] 70 class=94 view=0 res=1
[mer] 71 class=94 view=0 res=1
[mer] 72 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=29498
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 73 class=94 view=0 res=1
[mer] 74 class=94 view=0 res=1
[mer] 75 class=94 view=0 res=1
[mer] 76 class=42 view=0 res=1
[mer] 77 class=94 view=0 res=1
[mer] 78 class=42 view=0 res=1
[mer] 79 class=94 view=0 res=1
[mer] 80 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=30506
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 81 class=94 view=0 res=1
[mer] 82 class=94 view=0 res=1
[mer] 83 class=94 view=0 res=1
[mer] 84 class=94 view=0 res=1
[mer] 85 class=42 view=0 res=1
[mer] 86 class=94 view=0 res=1
[mer] 87 class=42 view=0 res=1
[mer] 88 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=31514
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 89 class=42 view=0 res=1
[mer] 90 class=42 view=0 res=1
[mer] 91 class=94 view=0 res=1
[mer] 92 class=94 view=0 res=1
[mer] 93 class=42 view=0 res=1
[mer] 94 class=94 view=0 res=1
[mer] 95 class=94 view=0 res=1
[mer] 96 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=32522
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 97 class=94 view=0 res=1
[mer] 98 class=94 view=0 res=1
[mer] 99 class=42 view=0 res=1
[mer] 100 class=42 view=0 res=1
[mer] 101 class=42 view=0 res=1
[mer] 102 class=94 view=0 res=1
[mer] 103 class=42 view=0 res=1
[mer] 104 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=33530
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 105 class=42 view=0 res=1
[mer] 106 class=42 view=0 res=1
[mer] 107 class=42 view=0 res=1
[mer] 108 class=42 view=0 res=1
[mer] 109 class=42 view=0 res=1
[mer] 110 class=42 view=0 res=1
[mer] 111 class=42 view=0 res=1
[mer] 112 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=34538
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 113 class=42 view=0 res=1
[mer] 114 class=42 view=0 res=1
[mer] 115 class=42 view=0 res=1
[mer] 116 class=42 view=0 res=1
[mer] 117 class=42 view=0 res=1
[mer] 118 class=42 view=0 res=1
[mer] 119 class=42 view=0 res=1
[mer] 120 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=35552
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 121 class=42 view=0 res=1
[mer] 122 class=42 view=0 res=1
[mer] 123 class=42 view=0 res=1
[mer] 124 class=42 view=0 res=1
[mer] 125 class=42 view=0 res=1
[mer] 126 class=42 view=0 res=1
[mer] 127 class=42 view=0 res=1
[mer] 128 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=36563
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 129 class=42 view=0 res=1
[mer] 130 class=42 view=0 res=1
[mer] 131 class=42 view=0 res=1
[mer] 132 class=42 view=0 res=1
[mer] 133 class=42 view=0 res=1
[mer] 134 class=42 view=0 res=1
[mer] 135 class=42 view=0 res=1
[mer] 136 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=37571
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 137 class=42 view=0 res=1
[mer] 138 class=42 view=0 res=1
[mer] 139 class=42 view=0 res=1
[mer] 140 class=42 view=0 res=1
[mer] 141 class=42 view=0 res=1
[mer] 142 class=42 view=0 res=1
[mer] 143 class=94 view=0 res=1
[mer] 144 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=38579
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 145 class=94 view=0 res=1
[mer] 146 class=42 view=0 res=1
[mer] 147 class=94 view=0 res=1
[mer] 148 class=42 view=0 res=1
[mer] 149 class=94 view=0 res=1
[mer] 150 class=94 view=0 res=1
[mer] 151 class=94 view=0 res=1
[mer] 152 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=39589
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 153 class=42 view=0 res=1
[mer] 154 class=42 view=0 res=1
[mer] 155 class=94 view=0 res=1
[mer] 156 class=42 view=0 res=1
[mer] 157 class=42 view=0 res=1
[mer] 158 class=94 view=0 res=1
[mer] 159 class=94 view=0 res=1
[mer] 160 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=40597
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 161 class=42 view=0 res=1
[mer] 162 class=42 view=0 res=1
[mer] 163 class=42 view=0 res=1
[mer] 164 class=94 view=0 res=1
[mer] 165 class=94 view=0 res=1
[mer] 166 class=42 view=0 res=1
[mer] 167 class=94 view=0 res=1
[mer] 168 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=41605
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 169 class=94 view=0 res=1
[mer] 170 class=94 view=0 res=1
[mer] 171 class=42 view=0 res=1
[mer] 172 class=42 view=0 res=1
[mer] 173 class=42 view=0 res=1
[mer] 174 class=94 view=0 res=1
[mer] 175 class=42 view=0 res=1
[mer] 176 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=42613
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 177 class=94 view=0 res=1
[mer] 178 class=94 view=0 res=1
[mer] 179 class=94 view=0 res=1
[mer] 180 class=42 view=0 res=1
[mer] 181 class=42 view=0 res=1
[mer] 182 class=42 view=0 res=1
[mer] 183 class=94 view=0 res=1
[mer] 184 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=43621
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 185 class=42 view=0 res=1
[mer] 186 class=94 view=0 res=1
[mer] 187 class=94 view=0 res=1
[mer] 188 class=94 view=0 res=1
[mer] 189 class=42 view=0 res=1
[mer] 190 class=42 view=0 res=1
[mer] 191 class=94 view=0 res=1
[mer] 192 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=44630
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 193 class=42 view=0 res=1
[mer] 194 class=42 view=0 res=1
[stack] frame at 0x12dee7 drift=0 over 2002 frames ticks=44890 pump=490/2674
[mer] 195 class=42 view=0 res=1
[mer] 196 class=42 view=0 res=1
[mer] 197 class=94 view=0 res=1
[mer] 198 class=94 view=0 res=1
[mer] 199 class=94 view=0 res=1
[mer] 200 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=45640
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 201 class=94 view=0 res=1
[mer] 202 class=94 view=0 res=1
[mer] 203 class=94 view=0 res=1
[mer] 204 class=42 view=0 res=1
[mer] 205 class=94 view=0 res=1
[mer] 206 class=94 view=0 res=1
[mer] 207 class=48 view=0 res=0
[mer] 208 class=3001 view=1 res=1
[vid] type=1 file='mad.skl'
[eye] cockpit eye on 'jointeye' offset=(0,0,0)
[skl] video\mad.skl -> 26 nodes, 19 objects, 1 eye
[launch] state=2 minPriorityEmpty=0 ticks=46648
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=47654
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=48657
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=49769
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=50881
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=51994
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=53106
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=54217
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=55331
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=56443
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=57446
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=58557
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=59670
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=60781
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[stack] frame at 0x12dee7 drift=0 over 3003 frames ticks=60819 pump=633/3818
[launch] state=2 minPriorityEmpty=0 ticks=61894
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=63007
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=64117
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=65227
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=66339
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=67450
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=68560
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=69672
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=70782
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=71892
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 209 class=48 view=0 res=0
[mer] 210 class=48 view=0 res=0
[mer] 211 class=48 view=0 res=0
[launch] state=2 minPriorityEmpty=0 ticks=73007
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 212 class=48 view=0 res=0
[mer] 213 class=48 view=0 res=0
[mer] 214 class=48 view=0 res=0
[mer] 215 class=48 view=0 res=0
[launch] state=2 minPriorityEmpty=0 ticks=74011
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 216 class=48 view=0 res=0
[mer] 217 class=94 view=0 res=1
[mer] 218 class=94 view=0 res=1
[mer] 219 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=75020
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 220 class=94 view=0 res=1
[mer] 221 class=94 view=0 res=1
[mer] 222 class=94 view=0 res=1
[mer] 223 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=76030
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 224 class=94 view=0 res=1
[mer] 225 class=94 view=0 res=1
[mer] 226 class=94 view=0 res=1
[stack] frame at 0x12dee7 drift=0 over 4004 frames ticks=76734 pump=776/4962
[mer] 227 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=77038
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 228 class=94 view=0 res=1
[mer] 229 class=94 view=0 res=1
[mer] 230 class=94 view=0 res=1
[mer] 231 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=78046
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 232 class=94 view=0 res=1
[mer] 233 class=94 view=0 res=1
[mer] 234 class=94 view=0 res=1
[mer] 235 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=79055
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 236 class=94 view=0 res=1
[mer] 237 class=94 view=0 res=1
[mer] 238 class=94 view=0 res=1
[mer] 239 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=80062
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 240 class=94 view=0 res=1
[mer] 241 class=94 view=0 res=1
[mer] 242 class=94 view=0 res=1
[mer] 243 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=81067
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 244 class=94 view=0 res=1
[mer] 245 class=94 view=0 res=1
[mer] 246 class=94 view=0 res=1
[mer] 247 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=82071
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
MapDisplay: operating=1 static=4 moving=0
[mer] 248 class=94 view=0 res=1
[mer] 249 class=94 view=0 res=1
[mer] 250 class=94 view=0 res=1
[mer] 251 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=83076
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 252 class=94 view=0 res=1
[mer] 253 class=94 view=0 res=1
[mer] 254 class=94 view=0 res=1
[mer] 255 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=84082
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 256 class=94 view=0 res=1
[mer] 257 class=94 view=0 res=1
[mer] 258 class=94 view=0 res=1
[mer] 259 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=85089
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 260 class=94 view=0 res=1
[mer] 261 class=94 view=0 res=1
[mer] 262 class=48 view=0 res=0
[mer] 263 class=48 view=0 res=0
[launch] state=2 minPriorityEmpty=0 ticks=86096
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 264 class=48 view=0 res=0
[mer] 265 class=48 view=0 res=0
[launch] state=2 minPriorityEmpty=1 ticks=87101
[queues] p0=- p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
BTL4Application::RunMissionMessageHandler
Turning Plasma Score Display On
BTL4Application::RunMissionMessageHandler
Turning Plasma Score Display On
[tick] roster live (first Sensor frame), radarPercent=1 voltState=4
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDemand=0.0625 torsoElev=0
[euler] 1 this=0x12dbbc matrix=0x12db70 stack=0x12db5b
[sim] pos=(54.6507,20,-652.982) yaw=-0.0742302 spd=14.4 eyePitch=0 eyeYaw=0
[fire] 'ERSLaser_1' LOADED (level=7925.73 T=76.8866)
[fire] 'ERSLaser_2' LOADED (level=7921.56 T=76.847)
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDemand=0.0625 torsoElev=0
[euler] 2 this=0x12dbbc matrix=0x12db70 stack=0x12db5b
[sim] pos=(56.2287,20,-638.527) yaw=-0.142123 spd=14.4 eyePitch=0 eyeYaw=0
[stack] frame at 0x12dee7 drift=0 over 5005 frames ticks=92822 pump=868/6106
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDemand=0.0625 torsoElev=0
[euler] 3 this=0x12dbbc matrix=0x12db70 stack=0x12db5b
[sim] pos=(58.787,20,-624.198) yaw=-0.210107 spd=14.4 eyePitch=0 eyeYaw=0
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDemand=0.0625 torsoElev=0
[euler] 4 this=0x12dbbc matrix=0x12db70 stack=0x12db5b
[sim] pos=(62.301,20,-610.117) yaw=-0.277899 spd=14.4 eyePitch=0 eyeYaw=0
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDemand=0.0625 torsoElev=0
[euler] 5 this=0x12dbbc matrix=0x12db70 stack=0x12db5b
[sim] pos=(66.7461,20,-596.348) yaw=-0.345495 spd=14.4 eyePitch=0 eyeYaw=0
[fire] 'ERLLaser' LOADED (level=7925.74 T=76.0949)
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDemand=0.0625 torsoElev=0
[euler] 6 this=0x12dbbc matrix=0x12db70 stack=0x12db5b
[sim] pos=(72.1168,20,-582.897) yaw=-0.413154 spd=14.4 eyePitch=0 eyeYaw=0
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDemand=0.0625 torsoElev=0
[euler] 7 this=0x12dbbc matrix=0x12db70 stack=0x12db5b
[sim] pos=(78.3914,20,-569.827) yaw=-0.480884 spd=14.4 eyePitch=0 eyeYaw=0
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDemand=0.0625 torsoElev=0
[euler] 8 this=0x12dbbc matrix=0x12db70 stack=0x12db5b
[sim] pos=(85.5135,20,-557.248) yaw=-0.548412 spd=14.4 eyePitch=0 eyeYaw=0
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDemand=0.0625 torsoElev=0
[euler] 9 this=0x12dbbc matrix=0x12db70 stack=0x12db5b
[sim] pos=(93.4932,20,-545.144) yaw=-0.616144 spd=14.4 eyePitch=0 eyeYaw=0
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDemand=0.0625 torsoElev=0
[euler] 10 this=0x12dbbc matrix=0x12db70 stack=0x12db5b
[sim] pos=(102.265,20,-533.618) yaw=-0.683811 spd=14.4 eyePitch=0 eyeYaw=0
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDemand=0.0625 torsoElev=0
[euler] 11 this=0x12dbbc matrix=0x12db70 stack=0x12db5b
[sim] pos=(111.805,20,-522.701) yaw=-0.751545 spd=14.4 eyePitch=0 eyeYaw=0
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDema
+236
View File
@@ -0,0 +1,236 @@
BattleTech v4.10
BTL4Application::BTL4Application
GaugeInterpreter: undefined label 'Initialization'
[exp] master player experience=2 simLive=1 heatModelOn=1 advDamage=1
[role] 'Role::Default' lives=1000 killBonus=500 dmgMod=1
[torso] horizJoint 'jointtorso' -> 0x00a4fe78 type=1 enabled=1
[weap] 'AFC100' seg=13 mount=sitelgunport rear=0
[proj] 'AFC100' ammoBinIndex=21 -> AmmoBinAFC100 (rounds=20)
[weap] 'ERLLaser' seg=7 mount=siterugunport rear=0
[weap] 'ERSLaser_1' seg=13 mount=sitelgunport rear=0
[weap] 'ERSLaser_2' seg=8 mount=siterdgunport rear=0
[weap] 'LRM15_1' seg=18 mount=sitelmissleport rear=0
[proj] 'LRM15_1' ammoBinIndex=26 -> AmmoBinLRM15_1 (rounds=16)
[weap] 'LRM15_2' seg=19 mount=sitermissleport rear=0
[proj] 'LRM15_2' ammoBinIndex=28 -> AmmoBinLRM15_2 (rounds=16)
[mech] segment walk done: subsystemCount=32 weaponCount=6
[skel] jointSubsystem=0x009f6d84 jointCount=25
[mech] model params: walkTR=65 runTR=40 maxAcc=20 throttleAdj=0.8 (deg,deg,u/s^2,scale)
[mech] look angles: L=50 R=-50 F=-15 B=0 (deg)
[mech] damage zones streamed: 22 [dz_dtorso,dz_hip,dz_larm,dz_ldleg,dz_ldoor,dz_lfoot,dz_lgun,dz_ltorso,dz_luleg,dz_rarm,dz_rdleg,dz_rdoor,dz_reardtorso,dz_rearltorso,dz_rearrtorso,dz_rearutorso,dz_rfoot,dz_rgun,dz_rtorso,dz_ruleg,dz_searchlight,dz_utorso]
[cyl] table 'madcat' LOADED rows=7
[valve] 'Condenser1' valve=1 flow=0.166667
[valve] 'Condenser2' valve=1 flow=0.166667
[valve] 'Condenser3' valve=1 flow=0.166667
[valve] 'Condenser4' valve=1 flow=0.166667
[valve] 'Condenser5' valve=1 flow=0.166667
[valve] 'Condenser6' valve=1 flow=0.166667
[mapper] ctor id=0 throttleAttr=0x002c30f8 controlModeAttr=0x002c3134
[map] 109 streamed mappings for 'L4'
[map] dir sub=0 cls=2012 id=3 grp=1 elem=0
[map] dir sub=0 cls=2012 id=4 grp=0 elem=0
[map] dir sub=0 cls=2012 id=6 grp=3 elem=63
[map] dir sub=17 cls=3013 id=14 grp=3 elem=66
[map] dir sub=0 cls=2012 id=10 grp=3 elem=68
[map] dir sub=0 cls=2012 id=11 grp=3 elem=67
[map] dir sub=0 cls=2012 id=12 grp=3 elem=65
[map] dir sub=22 cls=3021 id=19 grp=3 elem=64
[map] dir sub=23 cls=3016 id=19 grp=3 elem=64
[map] dir sub=24 cls=3016 id=19 grp=3 elem=64
[map] dir sub=25 cls=3016 id=19 grp=3 elem=64
[map] dir sub=27 cls=3024 id=19 grp=3 elem=71
[map] dir sub=29 cls=3024 id=19 grp=3 elem=71
[gau2] cluster slot=14 classID=3011 auxScreen=5 name=Avionics
[gau2] cluster slot=15 classID=3014 auxScreen=6 name=Myomers
[gau2] cluster slot=22 classID=3021 auxScreen=1 name=AFC100
[gau2] cluster slot=23 classID=3016 auxScreen=10 name=ERLLaser
[gau2] cluster slot=24 classID=3016 auxScreen=3 name=ERSLaser_1
[gau2] cluster slot=25 classID=3016 auxScreen=12 name=ERSLaser_2
[gau2] cluster slot=27 classID=3024 auxScreen=2 name=LRM15_1
[gau2] cluster slot=29 classID=3024 auxScreen=9 name=LRM15_2
ColorMapperArmor warning: damage zone dz_missle not found
ColorMapperArmor warning: damage zone dz_missle not found
ColorMapperArmor warning: damage zone dz_lmissle not found
ColorMapperArmor warning: damage zone dz_rmissle not found
ColorMapperArmor warning: damage zone dz_ftorso not found
ColorMapperArmor warning: damage zone dz_btorso not found
ColorMapperCritical warning: subsystem Torso does not exist
ColorMapperHeat warning: subsystem Torso does not exist
[link] InitializePlayerLink -> vehicle playerLink=0x00ad513c
[launch] state=11 minPriorityEmpty=0 ticks=10952
[queues] p0=BUSY p1=BUSY p2=BUSY p3=BUSY p4=- nextReady=1
[posts] id3=416
[launch] state=11 minPriorityEmpty=0 ticks=11964
[queues] p0=BUSY p1=BUSY p2=BUSY p3=BUSY p4=- nextReady=1
[posts] id3=502
[launch] state=11 minPriorityEmpty=0 ticks=12974
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=11 minPriorityEmpty=0 ticks=13983
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=11 minPriorityEmpty=0 ticks=14992
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 1 class=3035 view=0 res=0
[mer] 2 class=42 view=0 res=1
[mer] 3 class=42 view=0 res=1
[mer] 4 class=42 view=0 res=1
[mer] 5 class=42 view=0 res=1
[mer] 6 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=16093
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 7 class=42 view=0 res=1
[mer] 8 class=42 view=0 res=1
[mer] 9 class=42 view=0 res=1
[mer] 10 class=42 view=0 res=1
[mer] 11 class=42 view=0 res=1
[mer] 12 class=42 view=0 res=1
[mer] 13 class=42 view=0 res=1
[mer] 14 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=17143
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 15 class=42 view=0 res=1
[mer] 16 class=42 view=0 res=1
[mer] 17 class=42 view=0 res=1
[mer] 18 class=42 view=0 res=1
[mer] 19 class=42 view=0 res=1
[mer] 20 class=42 view=0 res=1
[mer] 21 class=42 view=0 res=1
[mer] 22 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=18204
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 23 class=42 view=0 res=1
[mer] 24 class=42 view=0 res=1
[mer] 25 class=42 view=0 res=1
[mer] 26 class=42 view=0 res=1
[mer] 27 class=42 view=0 res=1
[mer] 28 class=42 view=0 res=1
[mer] 29 class=42 view=0 res=1
[mer] 30 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=19266
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 31 class=42 view=0 res=1
[mer] 32 class=42 view=0 res=1
[mer] 33 class=42 view=0 res=1
[mer] 34 class=42 view=0 res=1
[mer] 35 class=42 view=0 res=1
[mer] 36 class=42 view=0 res=1
[mer] 37 class=42 view=0 res=1
[mer] 38 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=20328
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 39 class=94 view=0 res=1
[mer] 40 class=42 view=0 res=1
[mer] 41 class=94 view=0 res=1
[mer] 42 class=94 view=0 res=1
[mer] 43 class=94 view=0 res=1
[mer] 44 class=94 view=0 res=1
[mer] 45 class=94 view=0 res=1
[mer] 46 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=21390
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 47 class=94 view=0 res=1
[mer] 48 class=94 view=0 res=1
[mer] 49 class=42 view=0 res=1
[mer] 50 class=42 view=0 res=1
[mer] 51 class=42 view=0 res=1
[mer] 52 class=42 view=0 res=1
[mer] 53 class=42 view=0 res=1
[mer] 54 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=22451
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 55 class=94 view=0 res=1
[mer] 56 class=94 view=0 res=1
[mer] 57 class=94 view=0 res=1
[mer] 58 class=42 view=0 res=1
[mer] 59 class=42 view=0 res=1
[mer] 60 class=42 view=0 res=1
[mer] 61 class=42 view=0 res=1
[mer] 62 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=23512
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 63 class=94 view=0 res=1
[mer] 64 class=94 view=0 res=1
[mer] 65 class=94 view=0 res=1
[mer] 66 class=94 view=0 res=1
[mer] 67 class=94 view=0 res=1
[mer] 68 class=42 view=0 res=1
[mer] 69 class=94 view=0 res=1
[mer] 70 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=24573
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 71 class=94 view=0 res=1
[mer] 72 class=94 view=0 res=1
[stack] frame at 0x12dee7 drift=0 over 1001 frames ticks=24846 pump=352/1499
[mer] 73 class=94 view=0 res=1
[mer] 74 class=94 view=0 res=1
[mer] 75 class=94 view=0 res=1
[mer] 76 class=42 view=0 res=1
[mer] 77 class=94 view=0 res=1
[mer] 78 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=25635
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 79 class=94 view=0 res=1
[mer] 80 class=94 view=0 res=1
[mer] 81 class=94 view=0 res=1
[mer] 82 class=94 view=0 res=1
[mer] 83 class=94 view=0 res=1
[mer] 84 class=94 view=0 res=1
[mer] 85 class=42 view=0 res=1
[mer] 86 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=26697
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 87 class=42 view=0 res=1
[mer] 88 class=42 view=0 res=1
[mer] 89 class=42 view=0 res=1
[mer] 90 class=42 view=0 res=1
[mer] 91 class=94 view=0 res=1
[mer] 92 class=94 view=0 res=1
[mer] 93 class=42 view=0 res=1
[mer] 94 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=27759
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 95 class=94 view=0 res=1
[mer] 96 class=94 view=0 res=1
[mer] 97 class=94 view=0 res=1
[mer] 98 class=94 view=0 res=1
[mer] 99 class=42 view=0 res=1
[mer] 100 class=42 view=0 res=1
[mer] 101 class=42 view=0 res=1
[mer] 102 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=28821
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 103 class=42 view=0 res=1
[mer] 104 class=42 view=0 res=1
[mer] 105 class=42 view=0 res=1
[mer] 106 class=42 view=0 res=1
[mer] 107 class=42 view=0 res=1
[mer] 108 class=42 view=0 res=1
[mer] 109 class=42 view=0 res=1
[mer] 110 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=29883
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 111 class=42 view=0 res=1
[mer] 112 class=42 view=0 res=1
[mer] 113 class=42 view=0 res=1
[mer] 114 class=42 view=0 res=1
[mer] 115 class=42 view=0 res=1
[mer] 116 class=42 view=0 res=1
Reference to a page you don't own
PF cr2= 7000 FA64 at 00FF 0000 66D9
Unhandled exception 000E at 00FF 66D9 ErrCode 0004
@@ -0,0 +1,13 @@
LOG: Early LOG Init complete
LOG: CONFIG: Loaded config file: C:/VWE/TeslaRel410/emulator/render-bridge/pod_render_shp.conf
LOG: DOSBox-X's working directory: C:\VWE\TeslaRel410\emulator\src\src
LOG: Logging init: beginning logging proper. This is the end of the early init logging
LOG: Logging: No logfile was given. All further logging will be discarded.
LOG: DOSBox-X version 2026.06.02 Commit d75a57c (MinGW SDL2 64-bit)
LOG: Prevent capture: 0
LOG: SDL: version 2.32.10, Video windows, Audio directsound
LOG: EXPERIMENTAL: Debugger enabled for MinGW build, DOSBox-X crashes depending on the terminal software you use. Launching from command prompt (cmd.exe) is recommended.
LOG: Windows keyboard layout ID is 0x0409
LOG: Host keyboard layout is now us (US English)
LOG: Mapper keyboard layout is now us (US English)
LOG: SDL2 reports desktop display mode 3440 x 1440
-584
View File
@@ -1,586 +1,2 @@
BattleTech v4.10
BTL4Application::BTL4Application
RIO never came back from test mode!
GaugeInterpreter: undefined label 'Initialization'
[exp] master player experience=2 simLive=1 heatModelOn=1 advDamage=1
[role] 'Role::Default' lives=1000 killBonus=500 dmgMod=1
[torso] horizJoint 'jointtorso' -> 0x00bf3d58 type=1 enabled=1
[weap] 'AFC100' seg=13 mount=sitelgunport rear=0
[proj] 'AFC100' ammoBinIndex=21 -> AmmoBinAFC100 (rounds=20)
[weap] 'ERLLaser' seg=7 mount=siterugunport rear=0
[weap] 'ERSLaser_1' seg=13 mount=sitelgunport rear=0
[weap] 'ERSLaser_2' seg=8 mount=siterdgunport rear=0
[weap] 'LRM15_1' seg=18 mount=sitelmissleport rear=0
[proj] 'LRM15_1' ammoBinIndex=26 -> AmmoBinLRM15_1 (rounds=16)
[weap] 'LRM15_2' seg=19 mount=sitermissleport rear=0
[proj] 'LRM15_2' ammoBinIndex=28 -> AmmoBinLRM15_2 (rounds=16)
[mech] segment walk done: subsystemCount=32 weaponCount=6
[skel] jointSubsystem=0x009f6d84 jointCount=25
[mech] model params: walkTR=65 runTR=40 maxAcc=20 throttleAdj=0.8 (deg,deg,u/s^2,scale)
[mech] look angles: L=50 R=-50 F=-15 B=0 (deg)
[mech] damage zones streamed: 22 [dz_dtorso,dz_hip,dz_larm,dz_ldleg,dz_ldoor,dz_lfoot,dz_lgun,dz_ltorso,dz_luleg,dz_rarm,dz_rdleg,dz_rdoor,dz_reardtorso,dz_rearltorso,dz_rearrtorso,dz_rearutorso,dz_rfoot,dz_rgun,dz_rtorso,dz_ruleg,dz_searchlight,dz_utorso]
[cyl] table 'madcat' LOADED rows=7
[valve] 'Condenser1' valve=1 flow=0.166667
[valve] 'Condenser2' valve=1 flow=0.166667
[valve] 'Condenser3' valve=1 flow=0.166667
[valve] 'Condenser4' valve=1 flow=0.166667
[valve] 'Condenser5' valve=1 flow=0.166667
[valve] 'Condenser6' valve=1 flow=0.166667
[mapper] ctor id=0 throttleAttr=0x009efd04 controlModeAttr=0x009efd40
[map] 109 streamed mappings for 'L4'
[map] dir sub=0 cls=2012 id=3 grp=1 elem=0
[map] dir sub=0 cls=2012 id=4 grp=0 elem=0
[map] dir sub=0 cls=2012 id=6 grp=3 elem=63
[map] dir sub=17 cls=3013 id=14 grp=3 elem=66
[map] dir sub=0 cls=2012 id=10 grp=3 elem=68
[map] dir sub=0 cls=2012 id=11 grp=3 elem=67
[map] dir sub=0 cls=2012 id=12 grp=3 elem=65
[map] dir sub=22 cls=3021 id=19 grp=3 elem=64
[map] dir sub=23 cls=3016 id=19 grp=3 elem=64
[map] dir sub=24 cls=3016 id=19 grp=3 elem=64
[map] dir sub=25 cls=3016 id=19 grp=3 elem=64
[map] dir sub=27 cls=3024 id=19 grp=3 elem=71
[map] dir sub=29 cls=3024 id=19 grp=3 elem=71
[gau2] cluster slot=14 classID=3011 auxScreen=5 name=Avionics
[gau2] cluster slot=15 classID=3014 auxScreen=6 name=Myomers
[gau2] cluster slot=22 classID=3021 auxScreen=1 name=AFC100
[gau2] cluster slot=23 classID=3016 auxScreen=10 name=ERLLaser
[gau2] cluster slot=24 classID=3016 auxScreen=3 name=ERSLaser_1
[gau2] cluster slot=25 classID=3016 auxScreen=12 name=ERSLaser_2
[gau2] cluster slot=27 classID=3024 auxScreen=2 name=LRM15_1
[gau2] cluster slot=29 classID=3024 auxScreen=9 name=LRM15_2
ColorMapperArmor warning: damage zone dz_missle not found
ColorMapperArmor warning: damage zone dz_missle not found
ColorMapperArmor warning: damage zone dz_lmissle not found
ColorMapperArmor warning: damage zone dz_rmissle not found
ColorMapperArmor warning: damage zone dz_ftorso not found
ColorMapperArmor warning: damage zone dz_btorso not found
ColorMapperCritical warning: subsystem Torso does not exist
ColorMapperHeat warning: subsystem Torso does not exist
[link] InitializePlayerLink -> vehicle playerLink=0x00ad513c
[launch] state=11 minPriorityEmpty=0 ticks=15308
[queues] p0=BUSY p1=BUSY p2=BUSY p3=BUSY p4=- nextReady=1
[posts] id3=416
[launch] state=11 minPriorityEmpty=0 ticks=16322
[queues] p0=BUSY p1=BUSY p2=BUSY p3=BUSY p4=- nextReady=1
[posts] id3=502
[launch] state=11 minPriorityEmpty=0 ticks=17334
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=11 minPriorityEmpty=0 ticks=18344
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=11 minPriorityEmpty=0 ticks=19354
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=20422
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 1 class=3035 view=0 res=0
[mer] 2 class=42 view=0 res=1
[mer] 3 class=42 view=0 res=1
[mer] 4 class=42 view=0 res=1
[mer] 5 class=42 view=0 res=1
[mer] 6 class=42 view=0 res=1
[mer] 7 class=42 view=0 res=1
[mer] 8 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=21430
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 9 class=42 view=0 res=1
[mer] 10 class=42 view=0 res=1
[mer] 11 class=42 view=0 res=1
[mer] 12 class=42 view=0 res=1
[mer] 13 class=42 view=0 res=1
[mer] 14 class=42 view=0 res=1
[mer] 15 class=42 view=0 res=1
[mer] 16 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=22437
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 17 class=42 view=0 res=1
[mer] 18 class=42 view=0 res=1
[mer] 19 class=42 view=0 res=1
[mer] 20 class=42 view=0 res=1
[mer] 21 class=42 view=0 res=1
[mer] 22 class=42 view=0 res=1
[mer] 23 class=42 view=0 res=1
[mer] 24 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=23445
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 25 class=42 view=0 res=1
[mer] 26 class=42 view=0 res=1
[mer] 27 class=42 view=0 res=1
[mer] 28 class=42 view=0 res=1
[mer] 29 class=42 view=0 res=1
[mer] 30 class=42 view=0 res=1
[mer] 31 class=42 view=0 res=1
[mer] 32 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=24453
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 33 class=42 view=0 res=1
[mer] 34 class=42 view=0 res=1
[mer] 35 class=42 view=0 res=1
[mer] 36 class=42 view=0 res=1
[mer] 37 class=42 view=0 res=1
[mer] 38 class=94 view=0 res=1
[mer] 39 class=94 view=0 res=1
[mer] 40 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=25461
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 41 class=94 view=0 res=1
[mer] 42 class=94 view=0 res=1
[mer] 43 class=94 view=0 res=1
[mer] 44 class=94 view=0 res=1
[mer] 45 class=94 view=0 res=1
[mer] 46 class=94 view=0 res=1
[mer] 47 class=94 view=0 res=1
[mer] 48 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=26468
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 49 class=42 view=0 res=1
[mer] 50 class=42 view=0 res=1
[mer] 51 class=42 view=0 res=1
[mer] 52 class=42 view=0 res=1
[mer] 53 class=42 view=0 res=1
[mer] 54 class=94 view=0 res=1
[mer] 55 class=94 view=0 res=1
[mer] 56 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=27476
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 57 class=94 view=0 res=1
[mer] 58 class=42 view=0 res=1
[mer] 59 class=42 view=0 res=1
[mer] 60 class=42 view=0 res=1
[mer] 61 class=42 view=0 res=1
[mer] 62 class=94 view=0 res=1
[mer] 63 class=94 view=0 res=1
[mer] 64 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=28486
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 65 class=94 view=0 res=1
[mer] 66 class=94 view=0 res=1
[mer] 67 class=94 view=0 res=1
[stack] frame at 0x12dee7 drift=0 over 1001 frames ticks=28857 pump=347/1530
[mer] 68 class=42 view=0 res=1
[mer] 69 class=94 view=0 res=1
[mer] 70 class=94 view=0 res=1
[mer] 71 class=94 view=0 res=1
[mer] 72 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=29498
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 73 class=94 view=0 res=1
[mer] 74 class=94 view=0 res=1
[mer] 75 class=94 view=0 res=1
[mer] 76 class=42 view=0 res=1
[mer] 77 class=94 view=0 res=1
[mer] 78 class=42 view=0 res=1
[mer] 79 class=94 view=0 res=1
[mer] 80 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=30506
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 81 class=94 view=0 res=1
[mer] 82 class=94 view=0 res=1
[mer] 83 class=94 view=0 res=1
[mer] 84 class=94 view=0 res=1
[mer] 85 class=42 view=0 res=1
[mer] 86 class=94 view=0 res=1
[mer] 87 class=42 view=0 res=1
[mer] 88 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=31514
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 89 class=42 view=0 res=1
[mer] 90 class=42 view=0 res=1
[mer] 91 class=94 view=0 res=1
[mer] 92 class=94 view=0 res=1
[mer] 93 class=42 view=0 res=1
[mer] 94 class=94 view=0 res=1
[mer] 95 class=94 view=0 res=1
[mer] 96 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=32522
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 97 class=94 view=0 res=1
[mer] 98 class=94 view=0 res=1
[mer] 99 class=42 view=0 res=1
[mer] 100 class=42 view=0 res=1
[mer] 101 class=42 view=0 res=1
[mer] 102 class=94 view=0 res=1
[mer] 103 class=42 view=0 res=1
[mer] 104 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=33530
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 105 class=42 view=0 res=1
[mer] 106 class=42 view=0 res=1
[mer] 107 class=42 view=0 res=1
[mer] 108 class=42 view=0 res=1
[mer] 109 class=42 view=0 res=1
[mer] 110 class=42 view=0 res=1
[mer] 111 class=42 view=0 res=1
[mer] 112 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=34538
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 113 class=42 view=0 res=1
[mer] 114 class=42 view=0 res=1
[mer] 115 class=42 view=0 res=1
[mer] 116 class=42 view=0 res=1
[mer] 117 class=42 view=0 res=1
[mer] 118 class=42 view=0 res=1
[mer] 119 class=42 view=0 res=1
[mer] 120 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=35552
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 121 class=42 view=0 res=1
[mer] 122 class=42 view=0 res=1
[mer] 123 class=42 view=0 res=1
[mer] 124 class=42 view=0 res=1
[mer] 125 class=42 view=0 res=1
[mer] 126 class=42 view=0 res=1
[mer] 127 class=42 view=0 res=1
[mer] 128 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=36563
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 129 class=42 view=0 res=1
[mer] 130 class=42 view=0 res=1
[mer] 131 class=42 view=0 res=1
[mer] 132 class=42 view=0 res=1
[mer] 133 class=42 view=0 res=1
[mer] 134 class=42 view=0 res=1
[mer] 135 class=42 view=0 res=1
[mer] 136 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=37571
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 137 class=42 view=0 res=1
[mer] 138 class=42 view=0 res=1
[mer] 139 class=42 view=0 res=1
[mer] 140 class=42 view=0 res=1
[mer] 141 class=42 view=0 res=1
[mer] 142 class=42 view=0 res=1
[mer] 143 class=94 view=0 res=1
[mer] 144 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=38579
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 145 class=94 view=0 res=1
[mer] 146 class=42 view=0 res=1
[mer] 147 class=94 view=0 res=1
[mer] 148 class=42 view=0 res=1
[mer] 149 class=94 view=0 res=1
[mer] 150 class=94 view=0 res=1
[mer] 151 class=94 view=0 res=1
[mer] 152 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=39589
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 153 class=42 view=0 res=1
[mer] 154 class=42 view=0 res=1
[mer] 155 class=94 view=0 res=1
[mer] 156 class=42 view=0 res=1
[mer] 157 class=42 view=0 res=1
[mer] 158 class=94 view=0 res=1
[mer] 159 class=94 view=0 res=1
[mer] 160 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=40597
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 161 class=42 view=0 res=1
[mer] 162 class=42 view=0 res=1
[mer] 163 class=42 view=0 res=1
[mer] 164 class=94 view=0 res=1
[mer] 165 class=94 view=0 res=1
[mer] 166 class=42 view=0 res=1
[mer] 167 class=94 view=0 res=1
[mer] 168 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=41605
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 169 class=94 view=0 res=1
[mer] 170 class=94 view=0 res=1
[mer] 171 class=42 view=0 res=1
[mer] 172 class=42 view=0 res=1
[mer] 173 class=42 view=0 res=1
[mer] 174 class=94 view=0 res=1
[mer] 175 class=42 view=0 res=1
[mer] 176 class=42 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=42613
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 177 class=94 view=0 res=1
[mer] 178 class=94 view=0 res=1
[mer] 179 class=94 view=0 res=1
[mer] 180 class=42 view=0 res=1
[mer] 181 class=42 view=0 res=1
[mer] 182 class=42 view=0 res=1
[mer] 183 class=94 view=0 res=1
[mer] 184 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=43621
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 185 class=42 view=0 res=1
[mer] 186 class=94 view=0 res=1
[mer] 187 class=94 view=0 res=1
[mer] 188 class=94 view=0 res=1
[mer] 189 class=42 view=0 res=1
[mer] 190 class=42 view=0 res=1
[mer] 191 class=94 view=0 res=1
[mer] 192 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=44630
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 193 class=42 view=0 res=1
[mer] 194 class=42 view=0 res=1
[stack] frame at 0x12dee7 drift=0 over 2002 frames ticks=44890 pump=490/2674
[mer] 195 class=42 view=0 res=1
[mer] 196 class=42 view=0 res=1
[mer] 197 class=94 view=0 res=1
[mer] 198 class=94 view=0 res=1
[mer] 199 class=94 view=0 res=1
[mer] 200 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=45640
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 201 class=94 view=0 res=1
[mer] 202 class=94 view=0 res=1
[mer] 203 class=94 view=0 res=1
[mer] 204 class=42 view=0 res=1
[mer] 205 class=94 view=0 res=1
[mer] 206 class=94 view=0 res=1
[mer] 207 class=48 view=0 res=0
[mer] 208 class=3001 view=1 res=1
[vid] type=1 file='mad.skl'
[eye] cockpit eye on 'jointeye' offset=(0,0,0)
[skl] video\mad.skl -> 26 nodes, 19 objects, 1 eye
[launch] state=2 minPriorityEmpty=0 ticks=46648
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=47654
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=48657
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=49769
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=50881
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=51994
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=53106
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=54217
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=55331
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=56443
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=57446
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=58557
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=59670
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=60781
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[stack] frame at 0x12dee7 drift=0 over 3003 frames ticks=60819 pump=633/3818
[launch] state=2 minPriorityEmpty=0 ticks=61894
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=63007
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=64117
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=65227
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=66339
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=67450
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=68560
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=69672
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=70782
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[launch] state=2 minPriorityEmpty=0 ticks=71892
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 209 class=48 view=0 res=0
[mer] 210 class=48 view=0 res=0
[mer] 211 class=48 view=0 res=0
[launch] state=2 minPriorityEmpty=0 ticks=73007
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 212 class=48 view=0 res=0
[mer] 213 class=48 view=0 res=0
[mer] 214 class=48 view=0 res=0
[mer] 215 class=48 view=0 res=0
[launch] state=2 minPriorityEmpty=0 ticks=74011
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 216 class=48 view=0 res=0
[mer] 217 class=94 view=0 res=1
[mer] 218 class=94 view=0 res=1
[mer] 219 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=75020
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 220 class=94 view=0 res=1
[mer] 221 class=94 view=0 res=1
[mer] 222 class=94 view=0 res=1
[mer] 223 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=76030
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 224 class=94 view=0 res=1
[mer] 225 class=94 view=0 res=1
[mer] 226 class=94 view=0 res=1
[stack] frame at 0x12dee7 drift=0 over 4004 frames ticks=76734 pump=776/4962
[mer] 227 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=77038
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 228 class=94 view=0 res=1
[mer] 229 class=94 view=0 res=1
[mer] 230 class=94 view=0 res=1
[mer] 231 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=78046
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 232 class=94 view=0 res=1
[mer] 233 class=94 view=0 res=1
[mer] 234 class=94 view=0 res=1
[mer] 235 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=79055
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 236 class=94 view=0 res=1
[mer] 237 class=94 view=0 res=1
[mer] 238 class=94 view=0 res=1
[mer] 239 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=80062
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 240 class=94 view=0 res=1
[mer] 241 class=94 view=0 res=1
[mer] 242 class=94 view=0 res=1
[mer] 243 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=81067
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 244 class=94 view=0 res=1
[mer] 245 class=94 view=0 res=1
[mer] 246 class=94 view=0 res=1
[mer] 247 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=82071
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
MapDisplay: operating=1 static=4 moving=0
[mer] 248 class=94 view=0 res=1
[mer] 249 class=94 view=0 res=1
[mer] 250 class=94 view=0 res=1
[mer] 251 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=83076
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 252 class=94 view=0 res=1
[mer] 253 class=94 view=0 res=1
[mer] 254 class=94 view=0 res=1
[mer] 255 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=84082
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 256 class=94 view=0 res=1
[mer] 257 class=94 view=0 res=1
[mer] 258 class=94 view=0 res=1
[mer] 259 class=94 view=0 res=1
[launch] state=2 minPriorityEmpty=0 ticks=85089
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 260 class=94 view=0 res=1
[mer] 261 class=94 view=0 res=1
[mer] 262 class=48 view=0 res=0
[mer] 263 class=48 view=0 res=0
[launch] state=2 minPriorityEmpty=0 ticks=86096
[queues] p0=BUSY p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
[mer] 264 class=48 view=0 res=0
[mer] 265 class=48 view=0 res=0
[launch] state=2 minPriorityEmpty=1 ticks=87101
[queues] p0=- p1=- p2=BUSY p3=- p4=- nextReady=1
[posts] id3=530
BTL4Application::RunMissionMessageHandler
Turning Plasma Score Display On
BTL4Application::RunMissionMessageHandler
Turning Plasma Score Display On
[tick] roster live (first Sensor frame), radarPercent=1 voltState=4
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDemand=0.0625 torsoElev=0
[euler] 1 this=0x12dbbc matrix=0x12db70 stack=0x12db5b
[sim] pos=(54.6507,20,-652.982) yaw=-0.0742302 spd=14.4 eyePitch=0 eyeYaw=0
[fire] 'ERSLaser_1' LOADED (level=7925.73 T=76.8866)
[fire] 'ERSLaser_2' LOADED (level=7921.56 T=76.847)
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDemand=0.0625 torsoElev=0
[euler] 2 this=0x12dbbc matrix=0x12db70 stack=0x12db5b
[sim] pos=(56.2287,20,-638.527) yaw=-0.142123 spd=14.4 eyePitch=0 eyeYaw=0
[stack] frame at 0x12dee7 drift=0 over 5005 frames ticks=92822 pump=868/6106
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDemand=0.0625 torsoElev=0
[euler] 3 this=0x12dbbc matrix=0x12db70 stack=0x12db5b
[sim] pos=(58.787,20,-624.198) yaw=-0.210107 spd=14.4 eyePitch=0 eyeYaw=0
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDemand=0.0625 torsoElev=0
[euler] 4 this=0x12dbbc matrix=0x12db70 stack=0x12db5b
[sim] pos=(62.301,20,-610.117) yaw=-0.277899 spd=14.4 eyePitch=0 eyeYaw=0
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDemand=0.0625 torsoElev=0
[euler] 5 this=0x12dbbc matrix=0x12db70 stack=0x12db5b
[sim] pos=(66.7461,20,-596.348) yaw=-0.345495 spd=14.4 eyePitch=0 eyeYaw=0
[fire] 'ERLLaser' LOADED (level=7925.74 T=76.0949)
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDemand=0.0625 torsoElev=0
[euler] 6 this=0x12dbbc matrix=0x12db70 stack=0x12db5b
[sim] pos=(72.1168,20,-582.897) yaw=-0.413154 spd=14.4 eyePitch=0 eyeYaw=0
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDemand=0.0625 torsoElev=0
[euler] 7 this=0x12dbbc matrix=0x12db70 stack=0x12db5b
[sim] pos=(78.3914,20,-569.827) yaw=-0.480884 spd=14.4 eyePitch=0 eyeYaw=0
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDemand=0.0625 torsoElev=0
[euler] 8 this=0x12dbbc matrix=0x12db70 stack=0x12db5b
[sim] pos=(85.5135,20,-557.248) yaw=-0.548412 spd=14.4 eyePitch=0 eyeYaw=0
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDemand=0.0625 torsoElev=0
[euler] 9 this=0x12dbbc matrix=0x12db70 stack=0x12db5b
[sim] pos=(93.4932,20,-545.144) yaw=-0.616144 spd=14.4 eyePitch=0 eyeYaw=0
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDemand=0.0625 torsoElev=0
[euler] 10 this=0x12dbbc matrix=0x12db70 stack=0x12db5b
[sim] pos=(102.265,20,-533.618) yaw=-0.683811 spd=14.4 eyePitch=0 eyeYaw=0
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDemand=0.0625 torsoElev=0
[euler] 11 this=0x12dbbc matrix=0x12db70 stack=0x12db5b
[sim] pos=(111.805,20,-522.701) yaw=-0.751545 spd=14.4 eyePitch=0 eyeYaw=0
[mppr] thr=0.6 rev=0 stickX=0.25 stickY=0 mode=0 -> speedDemand=14.4 turnDema
+14 -24
View File
@@ -1,7 +1,7 @@
BattleTech v4.10
BTL4Application::BTL4Application
GaugeInterpreter: undefined label 'Initialization'
MakeVehicleSystems hud=0x01158dcc
MakeVehicleSystems hud=0x01157f6c
Warning: damage zone 'dz_missle' not found!
Warning: damage zone 'dz_missle' not found!
Warning: damage zone 'dz_lmissle' not found!
@@ -9,36 +9,26 @@ Warning: damage zone 'dz_rmissle' not found!
Warning: damage zone 'dz_ftorso' not found!
Warning: damage zone 'dz_btorso' not found!
LBE4ControlsManager::Execute, lost RIO analog request
iThinkIRQIsOn =1, actual state =1, characters sent =4252
iThinkIRQIsOn =1, actual state =1, characters sent =373
LBE4ControlsManager::Execute, lost RIO analog request
iThinkIRQIsOn =1, actual state =1, characters sent =4408
iThinkIRQIsOn =1, actual state =1, characters sent =668
LBE4ControlsManager::Execute, lost RIO analog request
iThinkIRQIsOn =1, actual state =1, characters sent =6128
iThinkIRQIsOn =1, actual state =1, characters sent =743
LBE4ControlsManager::Execute, lost RIO analog request
iThinkIRQIsOn =1, actual state =1, characters sent =6417
iThinkIRQIsOn =1, actual state =1, characters sent =747
LBE4ControlsManager::Execute, lost RIO analog request
iThinkIRQIsOn =1, actual state =1, characters sent =6783
iThinkIRQIsOn =1, actual state =1, characters sent =1888
LBE4ControlsManager::Execute, lost RIO analog request
iThinkIRQIsOn =1, actual state =1, characters sent =7185
iThinkIRQIsOn =1, actual state =1, characters sent =1914
LBE4ControlsManager::Execute, lost RIO analog request
iThinkIRQIsOn =1, actual state =1, characters sent =7193
iThinkIRQIsOn =1, actual state =1, characters sent =2158
LBE4ControlsManager::Execute, lost RIO analog request
iThinkIRQIsOn =1, actual state =1, characters sent =4085
LBE4ControlsManager::Execute, lost RIO analog request
iThinkIRQIsOn =1, actual state =1, characters sent =6986
LBE4ControlsManager::Execute, lost RIO analog request
iThinkIRQIsOn =1, actual state =1, characters sent =8237
BTL4Application::RunMissionMessageHandler
Turning Plasma Score Display On
BTL4Application::RunMissionMessageHandler
Turning Plasma Score Display On
LBE4ControlsManager::Execute, lost RIO analog request
iThinkIRQIsOn =1, actual state =1, characters sent =9235
LBE4ControlsManager::Execute, lost RIO analog request
iThinkIRQIsOn =1, actual state =1, characters sent =9240
LBE4ControlsManager::Execute, lost RIO analog request
iThinkIRQIsOn =1, actual state =1, characters sent =11662
LBE4ControlsManager::Execute, lost RIO analog request
iThinkIRQIsOn =1, actual state =1, characters sent =11666
LBE4ControlsManager::Execute, lost RIO analog request
iThinkIRQIsOn =1, actual state =1, characters sent =12328
LBE4ControlsManager::Execute, lost RIO analog request
iThinkIRQIsOn =1, actual state =1, characters sent =12332
LBE4ControlsManager::Execute, lost RIO analog request
iThinkIRQIsOn =1, actual state =1, characters sent =13939
LBE4ControlsManager::Execute, lost RIO analog request
iThinkIRQIsOn =1, actual state =1, characters sent =13943
+6
View File
@@ -89,6 +89,12 @@ export RIO_TAP="$WORK/riotap.txt"
#
export VPX_FIFODUMP="$WORK/live.fifodump"
export VPX_FIFOSOCK=8621
#
# Arm the page-fault watch on the residual load-window fault (cpu/paging.cpp
# VPX_PFWatch). When cr2 hits this address the emulator dumps guest state +
# the last 64 serial RX deliveries to its stderr (dosboxlog.txt).
#
export VPX_PF_WATCH=7000FA64
rm -f "$BR/podlog.txt"
cd /c/VWE/TeslaRel410/emulator/src/src
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
# Four consecutive SHIPPED-exe runs with vRIO live: the exposure baseline.
# Shipped's log goes to podlog_shipped.txt (its conf's serial3).
cd /c/VWE/TeslaRel410/emulator/render-bridge
for i in 1 2 3 4; do
rm -f podlog_shipped.txt
bash podrun.sh pod_render_shp shpstreak$i > /dev/null 2>&1
until grep -q "Turning Plasma" podlog_shipped.txt 2>/dev/null || grep -qE "illegal address|page you don't own" podlog_shipped.txt 2>/dev/null; do sleep 10; done
if grep -q "page you don't own" podlog_shipped.txt; then R=FAULT; else R=CLEAN; fi
echo "shipped run$i: $R"
done
taskkill //F //IM dosbox-x.exe > /dev/null 2>&1
echo "SHIPPED STREAK DONE"
+77
View File
@@ -83,6 +83,33 @@ version control because the DOSBox-X source tree itself
vRIO-over-pipe keeps `namedpipe pipe:vrio`. Confs: `net_loop_rio.conf` /
`net_rp_rio.conf`; `pod-launch --rio`. B0 (pad) LIVE-CONFIRMED 2026-07-22
from the repacked dist; keyboard-field live test pending.
- **`steamlink.cpp` / `steamlink.h`** — the Steam transport core (2026-07-24):
guest Ethernet **frames** over `ISteamNetworkingMessages`, so a private group
can fly missions over the internet. Shared VERBATIM by two consumers — the
fork's `backend=steam` and the host's standalone `vwe-steam-gw.exe`
steam↔pcap gateway — which is why it is a free-function namespace and not a
class. **L2, not L3, is the whole point:** the 1995 mesh dials peers by raw
IP on one flat subnet and ARPs for them, and NAT/hole-punching has nowhere to
put an ARP. Steamworks is bound at RUNTIME (`LoadLibrary`/`GetProcAddress` on
`steam_api64.dll`), exactly as the pcap backend binds `WPCAP.DLL`, so no SDK
is needed to build or link. Load-bearing: everything ships **Reliable +
NoNagle** (WATTCP's DOS-era retransmit timers are multi-second, so an outer
retransmit costs one RTT where an inner one costs seconds — the long
rationale is in the header, read it before "optimizing" to unreliable), and
the API is **not thread-safe by design** (one thread, pumped from the NE2000
tick). Wire format, session file and env handoff are frozen in
`emulator/steam/SESSION-CONTRACT.md`.
- **`ethernet_steam.cpp` / `ethernet_steam.h`** — the `[ne2000] backend=steam`
`EthernetConnection` that plugs `steamlink` into the emulated NIC. `Pump()`
runs at the top of `GetPackets()`, which `NE2000_Poller` calls off a
`TIMER_AddTickHandler` — i.e. once per emulated millisecond — so that tick
**is** the Steam callback pump and there is no new thread or timer anywhere.
RX policy deliberately mirrors the pcap backend's BPF (accept `dst==self` or
broadcast, drop other multicast) so `backend=steam` and `backend=pcap` are
indistinguishable from the guest's side, and `macaddr=` must be a stable
literal — never `random` — because the MAC is what peers route to. Same
power-of-2-throttled `STEAM TX/RX #n` log lines as pcap. Operator runbook:
`emulator/STEAM-NOTES.md`.
## Applying to a DOSBox-X source checkout
@@ -171,6 +198,56 @@ Tested against DOSBox-X `v2026.06.02`, MSYS2 mingw64.
- `src/src/dosbox.cpp`: add `"plasma"` to the `serials[]` allowed-values list.
(The plasma WINDOW is drawn by `vpxlog.cpp` via the `PLASMA_GetFrame` extern
— already in this dir's `vpxlog.cpp`, so it lands with step 1.)
3e. The Steam ethernet backend (`[ne2000] backend=steam` — internet play; see
`../STEAM-NOTES.md` and `../steam/SESSION-CONTRACT.md`). These are `misc/`
files, not `hardware/`: they sit beside the pcap backend they are modelled
on.
```
cp emulator/vpx-device/steamlink.cpp emulator/src/src/misc/
cp emulator/vpx-device/steamlink.h emulator/src/src/misc/
cp emulator/vpx-device/ethernet_steam.cpp emulator/src/src/misc/
cp emulator/vpx-device/ethernet_steam.h emulator/src/src/misc/
```
plus three stock edits (grep for how `ethernet_pcap` appears and copy the
pattern):
- `src/src/misc/Makefile.am`: append `steamlink.cpp ethernet_steam.cpp` to
`libmisc_a_SOURCES` (we put them after `ethernet_nothing.cpp`). The
hand-mirrored generated-Makefile caveat from step 2 does **not** apply
here: `build-mingw-sdl2` re-runs `./autogen.sh` before configuring, so
`Makefile.in`/`Makefile` are regenerated from the `.am`.
- `src/src/misc/ethernet.cpp`: `#include "ethernet_steam.h"`; add the
`backend == "steam"` case to `OpenEthernetConnection()` next to the pcap
one — `new SteamEthernetConnection`, settings from
`control->GetSection("ethernet, steam")` — inside `#ifdef WIN32` (the
transport's DLL loader is Windows-only; keep the guard or a Linux build
breaks at link). Deliberately NOT in the `auto` ladder: steam is only ever
selected explicitly, since an internet session is never how a pod boots by
default. Add the `else if (backend == "steam")` arm to the failure
`LOG_MSG` chain too, otherwise a steam backend that fails to initialize
falls out as "Unknown ethernet backend".
- `src/src/dosbox.cpp`: add `"steam"` to the `backendopts[]` allowed-values
list (without this the config parser refuses the value and silently falls
back to `auto` — same trap as the `serials[]` list in 3b), and register
the settings section next to
`"ethernet, pcap"`:
`secprop = control->AddSection_prop("ethernet, steam", &Null_Init, true);`
with string props `peers`, `lobby`, `session` (all defaulting to `env`)
and int `channel` (0). Those names and defaults are frozen in
SESSION-CONTRACT.md §2 — the fork and the gateway both parse them.
No new `.conf.tmpl` is needed: the backend is selected per session with
`-set "ne2000 backend=steam"` on the DOSBox-X command line (`pod-launch
--steam` appends it), so the existing `net_loop_rio.conf` / `net_rp_rio.conf`
are reused as-is.
**The Steamworks SDK is OPTIONAL.** `steamlink.cpp` compiles by default
against hand-declared ABI structs and binds `steam_api64.dll` at runtime, so
there is nothing to install to build and nothing to link against. To
validate those structs against the real headers, drop the SDK at
`emulator/steamworks/` (git-ignored, same pattern as `emulator/src/`) and
build with `-DVWE_STEAM_USE_SDK_HEADERS` plus the SDK's `public/` dir on the
include path — worth doing once after an SDK bump, then go back to the plain
build. A build made without the SDK still **runs**: `backend=steam` just
fails Init with a readable message when `steam_api64.dll` is missing or
Steam isn't running, exactly the way a missing Npcap fails pcap.
4. Build:
```
cd emulator/src
+202 -4
View File
@@ -26,6 +26,9 @@
#include "support.h" /* strcasecmp */
#include "control.h" /* [ne2000] macaddr for the RX filter */
#include <cstring>
#include <cstdlib> /* getenv/strtoul -- the latency shim's knobs */
#include <chrono>
#include <deque>
extern std::string niclist;
@@ -143,6 +146,149 @@ bool LoadPcapLibrary() {
#endif
/* ---- Phase 0: the latency-tolerance gate --------------------------------
*
* The riskiest assumption in the whole internet-play plan is that the 1995
* stack -- WATTCP + netnub + L4NetworkManager, every one of them tuned for a
* same-switch LAN with sub-millisecond RTT -- still functions at 30-150ms RTT
* with jitter. They are unpatchable 30-year-old binaries, so the answer has to
* be MEASURED on the existing LAN rigs, with zero Steam code, before any
* transport work is committed to. External shapers (clumsy, WinDivert) hook
* the host IP stack and never see Npcap-injected frames at all, so the delay
* has to live inside the backend. Three env knobs, read once at Initialize():
*
* VWE_NET_DELAY_MS fixed one-way delay applied to BOTH TX and RX, so one
* shimmed pod adds 2x delay to every RTT through it.
* VWE_NET_JITTER_MS uniform 0..N ms extra per frame, with release times
* clamped monotonic per queue -- frames NEVER reorder.
* The real transport is Steam's reliable ORDERED channel;
* a reordering shim would be measuring a transport we are
* not going to build.
* VWE_NET_LOSS_PCT drop percentage, default 0. Reliable delivery surfaces
* loss as a delay spike rather than a drop, so this is
* for characterization only and is not part of the gate.
*
* All unset = the shim does not exist: SendPacket/GetPackets run byte-for-byte
* the code they ran before it was added, and not a single extra log line is
* emitted (same convention as VPXLOG). If any of the three IS set, exactly one
* NETSHIM line is always logged -- ACTIVE or INERT -- because a silent run is
* ambiguous with a binary that was built without this file at all.
*
* Timebase is WALL clock, not emulated time -- network latency is wall clock
* and the guest's own timers must stay free to disagree with it. GetPackets()
* is called from NE2000_Poller, a TIMER_AddTickHandler tick, i.e. once per
* emulated millisecond, and that is the drain quantum: no thread and no timer
* is added anywhere. steady_clock rather than GetTickCount64 because the
* latter advances in ~15.6ms steps, which would quantize the 15ms knobs into
* all-or-nothing jumps.
*
* State is file-static rather than class members because ethernet_pcap.h is
* stock DOSBox-X we would rather not fork, and there is only ever one NE2000.
* Test matrix, two-rig topology and the pass/fail gate: emulator/NET-NOTES.md.
*/
enum { SHIM_FRAMEBUF = 1600 }; /* larger than any frame the NE2000 can make */
struct DelayedFrame {
uint64_t release_ms;
int len;
uint8_t data[SHIM_FRAMEBUF];
};
static bool shim_on = false;
static unsigned shim_delay_ms = 0, shim_jitter_ms = 0, shim_loss_pct = 0;
static std::deque<DelayedFrame> shim_txq, shim_rxq;
static uint64_t shim_tx_release = 0, shim_rx_release = 0; /* monotonic clamp */
static unsigned long shim_lost = 0;
static uint32_t shim_rng = 0;
static bool shim_oversize_warned = false;
static uint64_t shim_now_ms() {
using namespace std::chrono;
return (uint64_t)duration_cast<milliseconds>(
steady_clock::now().time_since_epoch()).count();
}
/* Own xorshift instead of rand(): the shim must not perturb the global rand()
* sequence the rest of the emulator draws from. */
static uint32_t shim_rand() {
shim_rng ^= shim_rng << 13;
shim_rng ^= shim_rng >> 17;
shim_rng ^= shim_rng << 5;
return shim_rng;
}
/* Park a frame on `q`. True = the caller must NOT act on the frame now (it was
* queued, or the loss knob ate it). A frame too big for the buffer is passed
* through undelayed instead of truncated -- a truncated frame would be a
* corruption bug wearing a latency finding's clothes. */
static bool shim_hold(std::deque<DelayedFrame>& q, uint64_t& last_release,
const uint8_t* frame, int len)
{
if (len < 0 || len > (int)SHIM_FRAMEBUF) {
if (!shim_oversize_warned) {
shim_oversize_warned = true;
LOG_MSG("NETSHIM: len=%d exceeds the %d-byte queue buffer -- oversize frames pass through undelayed",
len, (int)SHIM_FRAMEBUF);
}
return false;
}
if (shim_loss_pct && (shim_rand() % 100u) < shim_loss_pct) {
shim_lost++;
return true;
}
uint64_t rel = shim_now_ms() + shim_delay_ms;
if (shim_jitter_ms) rel += shim_rand() % (shim_jitter_ms + 1u);
if (rel < last_release) rel = last_release; /* ordered, never reordered */
last_release = rel;
q.push_back(DelayedFrame());
DelayedFrame& f = q.back();
f.release_ms = rel;
f.len = len;
memcpy(f.data, frame, (size_t)len);
return true;
}
/* Read one knob. `present` is set if the variable EXISTS, whatever its value,
* so that (a) an all-zero control run still announces itself and (b) a typo'd
* or non-numeric value is reported instead of quietly measuring nothing --
* strtoul("abc") is 0, which is indistinguishable from "shim not built in".
* Trailing whitespace is tolerated: `set VWE_NET_DELAY_MS=50 ` in a .bat keeps
* the space, and rejecting that would be a trap rather than a check. */
static unsigned shim_knob(const char* name, bool& present) {
const char* e = getenv(name);
if (!e) return 0;
present = true;
const char* p = e;
while (*p == ' ' || *p == '\t') p++;
char* end = NULL;
unsigned long v = strtoul(p, &end, 10);
if (end) while (*end == ' ' || *end == '\t' || *end == '\r' || *end == '\n') end++;
if (end == p || (end && *end) || *p == '-') {
LOG_MSG("NETSHIM: %s=\"%s\" is not a plain non-negative number -- IGNORED (treated as 0)",
name, e);
return 0;
}
if (v > 100000ul) { /* a 100s one-way delay is a typo, not a test point */
LOG_MSG("NETSHIM: %s=%lu is absurd -- clamped to 100000", name, v);
v = 100000ul;
}
return (unsigned)v;
}
/* Queue-depth tail for the throttled TX/RX log lines; empty when off, so an
* unshimmed run's logs are unchanged. */
static const char* shim_qtail() {
static char t[64];
if (!shim_on) return "";
if (shim_loss_pct)
snprintf(t, sizeof(t), " q=%u/%u lost=%lu",
(unsigned)shim_txq.size(), (unsigned)shim_rxq.size(), shim_lost);
else
snprintf(t, sizeof(t), " q=%u/%u",
(unsigned)shim_txq.size(), (unsigned)shim_rxq.size());
return t;
}
PcapEthernetConnection::PcapEthernetConnection()
: EthernetConnection()
{
@@ -314,6 +460,36 @@ bool PcapEthernetConnection::Initialize(Section* config)
LOG_MSG("PCAP RX filter NOT installed (%s) -- promiscuous, expect LAN noise",
have_filter_api ? "no ne2000 macaddr" : "wpcap lacks pcap_compile");
/* Latency-tolerance gate: read the knobs once, and say out loud what was
* applied so a test run's logs are self-describing months later. */
shim_txq.clear(); shim_rxq.clear();
shim_tx_release = shim_rx_release = 0;
shim_lost = 0;
shim_oversize_warned = false;
shim_delay_ms = shim_jitter_ms = shim_loss_pct = 0;
bool shim_env_seen = false;
shim_delay_ms = shim_knob("VWE_NET_DELAY_MS", shim_env_seen);
shim_jitter_ms = shim_knob("VWE_NET_JITTER_MS", shim_env_seen);
shim_loss_pct = shim_knob("VWE_NET_LOSS_PCT", shim_env_seen);
if (shim_loss_pct > 100) shim_loss_pct = 100;
shim_on = (shim_delay_ms || shim_jitter_ms || shim_loss_pct);
if (shim_on) {
shim_rng = (uint32_t)shim_now_ms() | 1u; /* xorshift is stuck at 0 */
LOG_MSG("NETSHIM ACTIVE: delay=%ums each way (+%ums on every RTT through this pod), "
"jitter=0..%ums monotonic, loss=%u%% -- Phase 0 latency gate, see NET-NOTES.md",
shim_delay_ms, shim_delay_ms * 2, shim_jitter_ms, shim_loss_pct);
} else if (shim_env_seen) {
/* All knobs zero is a legitimate control point in the matrix -- but it
* is ALSO exactly what a dosbox-x.exe built WITHOUT this file looks
* like, and vpx-device/ is only the version-controlled copy (it has to
* be copied into src/src/misc/ before `make`). Announcing the inert
* case is what tells the operator the binary really does contain the
* shim: VWE_NET_* set and NO "NETSHIM" line at all means it does not,
* and the whole matrix would otherwise read as "0ms, no effect". */
LOG_MSG("NETSHIM INERT: VWE_NET_* present but every knob is 0 "
"-- baseline/control run, no delay applied (shim IS compiled in)");
}
return true;
}
@@ -321,8 +497,10 @@ void PcapEthernetConnection::SendPacket(const uint8_t* packet, int len)
{
static unsigned long txn = 0;
if (((++txn) & (txn - 1)) == 0) /* powers of 2, avoid spam */
LOG_MSG("PCAP TX #%lu len=%d dst=%02x:%02x:%02x src=%02x:%02x:%02x",
txn, len, packet[0],packet[1],packet[2], packet[6],packet[7],packet[8]);
LOG_MSG("PCAP TX #%lu len=%d dst=%02x:%02x:%02x src=%02x:%02x:%02x%s",
txn, len, packet[0],packet[1],packet[2], packet[6],packet[7],packet[8],
shim_qtail());
if (shim_on && shim_hold(shim_txq, shim_tx_release, packet, len)) return;
int ret = pcap_sendpacket(adhandle, packet, len);
if(ret) LOG_MSG("PCAP error: %s", pcap_geterr(adhandle));
}
@@ -333,15 +511,35 @@ void PcapEthernetConnection::GetPackets(std::function<void(const uint8_t*, int)>
struct pcap_pkthdr *header;
u_char *pkt_data;
static unsigned long rxn = 0;
/* Shim TX first: SendPacket parked these, and this handler is the only
* thing that runs often enough to release them on time. */
if (shim_on) {
uint64_t now = shim_now_ms();
while (!shim_txq.empty() && shim_txq.front().release_ms <= now) {
const DelayedFrame& f = shim_txq.front();
if (pcap_sendpacket(adhandle, f.data, f.len))
LOG_MSG("PCAP error: %s", pcap_geterr(adhandle));
shim_txq.pop_front();
}
}
//#if 0
while((res = pcap_next_ex( adhandle, &header, (const u_char **)&pkt_data)) > 0) {
if (((++rxn) & (rxn - 1)) == 0)
LOG_MSG("PCAP RX #%lu len=%d dst=%02x:%02x:%02x src=%02x:%02x:%02x",
LOG_MSG("PCAP RX #%lu len=%d dst=%02x:%02x:%02x src=%02x:%02x:%02x%s",
rxn, header->len, pkt_data[0],pkt_data[1],pkt_data[2],
pkt_data[6],pkt_data[7],pkt_data[8]);
pkt_data[6],pkt_data[7],pkt_data[8], shim_qtail());
if (shim_on && shim_hold(shim_rxq, shim_rx_release, pkt_data, (int)header->len)) continue;
callback(pkt_data, header->len);
}
//#endif
if (shim_on) {
uint64_t now = shim_now_ms();
while (!shim_rxq.empty() && shim_rxq.front().release_ms <= now) {
const DelayedFrame& f = shim_rxq.front();
callback(f.data, f.len);
shim_rxq.pop_front();
}
}
}
#endif
+477
View File
@@ -0,0 +1,477 @@
/*
* VWE fork: `backend=steam` -- EthernetConnection over the vwesteam:: tunnel.
* See ethernet_steam.h for why this exists, steamlink.h for the wire format,
* and ../steam/SESSION-CONTRACT.md for the session file and env handoff.
*/
#include "config.h"
#ifdef WIN32
#include "ethernet_steam.h"
#include "steamlink.h"
#include "dosbox.h"
#include "logging.h"
#include "support.h" /* strcasecmp */
#include "control.h" /* [ne2000] macaddr -- required here, not optional */
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
/* vwesteam:: logs through a plain function pointer so the gateway can send the
* same diagnostics to stderr; in the fork they belong wherever every other
* device logs. Set before Init() so Init()'s own failures are visible. */
static void SteamLog(const char* msg)
{
LOG_MSG("%s", msg);
}
/* ------------------------------------------------------------------ *
* Session file (SESSION-CONTRACT section 2)
*
* A tolerant hand-rolled reader, deliberately NOT a JSON library: the fork
* has no JSON dependency and this file is machine-written by TeslaLobby in
* one fixed shape, so scanning for the six keys we need is cheaper than
* taking on one. What it will not do is half-read a roster -- a peer that
* silently went missing looks exactly like a peer that never connected, and
* that is the worst thing to be debugging at 9pm. Anything malformed is a
* hard failure naming the file and the key.
* ------------------------------------------------------------------ */
struct SessionPeer {
uint64_t steamId = 0;
uint32_t ip = 0; /* host order; 0 = absent */
uint8_t mac[6] = {};
bool macKnown = false;
int slot = -1;
bool gateway = false;
std::string name;
};
static const char* SkipWs(const char* p, const char* end)
{
while (p < end && (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')) p++;
return p;
}
/* Matching '}' / ']' for the bracket at p. Quote-aware, so a bracket inside a
* pilot name cannot unbalance the walk. */
static const char* MatchBracket(const char* p, const char* end)
{
const char open = *p, close = (open == '{') ? '}' : ']';
int depth = 0;
bool instr = false;
for (; p < end; p++) {
if (instr) {
if (*p == '\\') p++;
else if (*p == '"') instr = false;
continue;
}
if (*p == '"') instr = true;
else if (*p == open) depth++;
else if (*p == close && --depth == 0) return p;
}
return NULL;
}
/* Scalar value of "key" in [p,end), quotes and escapes stripped. Callers bound
* the span to one object, so a flat search cannot wander into a sibling. */
static bool JsonGet(const char* p, const char* end, const char* key, std::string& out)
{
char pat[32];
snprintf(pat, sizeof(pat), "\"%s\"", key);
const size_t klen = strlen(pat);
for (const char* q = p; q < end; q++) {
q = (const char*)memchr(q, '"', (size_t)(end - q));
if (!q) break;
if ((size_t)(end - q) < klen || memcmp(q, pat, klen) != 0) continue;
const char* v = SkipWs(q + klen, end);
if (v >= end || *v != ':') continue;
v = SkipWs(v + 1, end);
out.clear();
if (v < end && *v == '"') {
for (v++; v < end && *v != '"'; v++) {
if (*v == '\\' && v + 1 < end) v++;
out += *v;
}
} else {
while (v < end && *v != ',' && *v != '}' && *v != ']' &&
*v != ' ' && *v != '\t' && *v != '\r' && *v != '\n')
out += *v++;
}
return true;
}
return false;
}
/* Contents of the {object} or [array] value of "key", brackets excluded. */
static bool JsonSpan(const char* p, const char* end, const char* key,
const char*& bo, const char*& eo)
{
char pat[32];
snprintf(pat, sizeof(pat), "\"%s\"", key);
const size_t klen = strlen(pat);
for (const char* q = p; q < end; q++) {
q = (const char*)memchr(q, '"', (size_t)(end - q));
if (!q) break;
if ((size_t)(end - q) < klen || memcmp(q, pat, klen) != 0) continue;
const char* v = SkipWs(q + klen, end);
if (v >= end || *v != ':') continue;
v = SkipWs(v + 1, end);
if (v >= end || (*v != '{' && *v != '[')) continue;
const char* close = MatchBracket(v, end);
if (!close) return false;
bo = v + 1;
eo = close;
return true;
}
return false;
}
/* Next {object} inside an array span, advancing p past it. */
static bool JsonNextObject(const char*& p, const char* end,
const char*& bo, const char*& eo)
{
p = SkipWs(p, end);
while (p < end && *p == ',') p = SkipWs(p + 1, end);
if (p >= end || *p != '{') return false;
const char* close = MatchBracket(p, end);
if (!close) return false;
bo = p + 1;
eo = close;
p = close + 1;
return true;
}
/* The WIDTH-LIMITED %02x is not cosmetic: it is exactly what ne2000.cpp's own
* macaddr parser uses, and the emulated NIC's answer has to be the same six
* bytes this backend filters on and announces in HELLO. Plain %x diverges
* silently on a malformed conf -- measured, not theorised:
*
* macaddr ne2000.cpp (%02x) plain %x
* 02:00:C8:00:00:7100 02:00:c8:00:00:71 02:00:c8:00:00:00 (truncated)
* 02:00:3E7:00:00:70 ac:de:48:88:bb:aa 02:00:e7:00:00:70 (its fallback)
*
* Either row is a pod whose NIC answers to one address while the tunnel routes
* to another: no unicast frame ever arrives and nothing says why. %n + the tail
* check turns the leftover-digits row into a loud refusal instead of a third
* wrong answer. ("02:00:3E7:..." is not hypothetical -- see configure.ps1's own
* warning comment about emitting exactly that.) */
static bool ParseMac(const char* s, uint8_t mac[6])
{
unsigned int m[6];
int n = -1;
if (!s || sscanf(s, "%02x:%02x:%02x:%02x:%02x:%02x%n",
&m[0],&m[1],&m[2],&m[3],&m[4],&m[5], &n) != 6 || n < 0)
return false;
while (s[n] == ' ' || s[n] == '\t' || s[n] == '\r' || s[n] == '\n') n++;
if (s[n] != '\0') return false; /* trailing junk = a MAC nobody meant */
for (int i = 0; i < 6; i++) mac[i] = (uint8_t)m[i];
return true;
}
static bool ParseIp(const char* s, uint32_t& ip)
{
unsigned int a,b,c,d;
if (!s || sscanf(s, "%u.%u.%u.%u", &a,&b,&c,&d) != 4 || (a|b|c|d) > 255)
return false;
ip = (a << 24) | (b << 16) | (c << 8) | d;
return true;
}
static bool ParseId(const std::string& s, uint64_t& id)
{
char* e = NULL;
id = strtoull(s.c_str(), &e, 10);
return id != 0 && e && *e == '\0';
}
/* One peer/self object. `where` names it in errors ("peers[1]", "self"). */
static bool ParsePeerObject(const char* bo, const char* eo, SessionPeer& out,
const std::string& path, const char* where,
std::string& err)
{
std::string v;
if (!JsonGet(bo, eo, "steamId", v) || !ParseId(v, out.steamId)) {
err = path + ": " + where + " has no usable steamId";
return false;
}
if (JsonGet(bo, eo, "ip", v) && !ParseIp(v.c_str(), out.ip)) {
err = path + ": " + where + " has a bad ip \"" + v + "\"";
return false;
}
if (JsonGet(bo, eo, "mac", v)) {
if (!ParseMac(v.c_str(), out.mac)) {
err = path + ": " + where + " has a bad mac \"" + v + "\"";
return false;
}
out.macKnown = true;
}
if (JsonGet(bo, eo, "slot", v)) out.slot = atoi(v.c_str());
if (JsonGet(bo, eo, "gateway", v)) out.gateway = (strcasecmp(v.c_str(), "true") == 0);
JsonGet(bo, eo, "name", out.name);
return true;
}
static bool ParseSessionFile(const std::string& path, SessionPeer& self,
std::vector<SessionPeer>& peers, std::string& err)
{
FILE* f = fopen(path.c_str(), "rb");
if (!f) {
err = path + ": cannot open the session file";
return false;
}
std::string doc;
char buf[4096];
size_t n;
while ((n = fread(buf, 1, sizeof(buf), f)) > 0) doc.append(buf, n);
fclose(f);
if (doc.size() >= 3 && (unsigned char)doc[0] == 0xef) doc.erase(0, 3); /* stray BOM */
const char* p = doc.c_str();
const char* end = p + doc.size();
const char *bo, *eo;
/* self is optional: the MAC that matters comes from [ne2000] anyway, and
* the IP is only diagnostics. peers is not -- without it there is no
* session and no allowlist. */
if (JsonSpan(p, end, "self", bo, eo) &&
!ParsePeerObject(bo, eo, self, path, "self", err))
return false;
if (!JsonSpan(p, end, "peers", bo, eo)) {
err = path + ": no \"peers\" array";
return false;
}
for (const char* q = bo; ; ) {
const char *pb, *pe;
if (!JsonNextObject(q, eo, pb, pe)) break;
SessionPeer peer;
char where[24];
snprintf(where, sizeof(where), "peers[%u]", (unsigned)peers.size());
if (!ParsePeerObject(pb, pe, peer, path, where, err)) return false;
peers.push_back(peer);
}
if (peers.empty()) {
err = path + ": \"peers\" is empty -- nobody to fly with";
return false;
}
return true;
}
/* A conf key left at the literal "env" (the default) defers to `var`. The
* confs are install-static -- configure.ps1 renders them once -- while the
* roster changes every session, so everything per-session arrives by env or
* session file. SESSION-CONTRACT section 2. */
static std::string ConfOrEnv(Section_prop* section, const char* key, const char* var)
{
const char* v = section->Get_string(key);
if (v && *v && strcasecmp(v, "env") != 0) return std::string(v);
const char* e = getenv(var);
return e ? std::string(e) : std::string();
}
static void ParseIdCsv(const std::string& csv, std::vector<uint64_t>& out)
{
size_t i = 0;
while (i < csv.size()) {
size_t j = csv.find_first_of(",; \t", i);
if (j == std::string::npos) j = csv.size();
const std::string tok = csv.substr(i, j - i);
i = j + 1;
if (tok.empty()) continue;
uint64_t id;
if (!ParseId(tok, id)) {
LOG_MSG("STEAM: ignoring unparseable peer id \"%s\"", tok.c_str());
continue;
}
if (std::find(out.begin(), out.end(), id) == out.end()) out.push_back(id);
}
}
SteamEthernetConnection::SteamEthernetConnection()
: EthernetConnection()
{
}
SteamEthernetConnection::~SteamEthernetConnection()
{
/* Only if Init() took: Shutdown() is refcounted and ethernet.cpp deletes
* us when Initialize() fails. */
if (up) vwesteam::Shutdown();
}
bool SteamEthernetConnection::Initialize(Section* config)
{
Section_prop *section = static_cast<Section_prop*>(config);
const std::string sessionpath = ConfOrEnv(section, "session", "VWE_STEAM_SESSION");
const std::string peerscsv = ConfOrEnv(section, "peers", "VWE_STEAM_PEERS");
const std::string lobbystr = ConfOrEnv(section, "lobby", "VWE_STEAM_LOBBY");
// Where pcap only loses its RX filter without a macaddr, the mesh ROUTES
// to this one: peers bind it to our SteamID from the HELLO record and
// address unicast frames by it. "random" would hand every peer a new
// address on every restart -- so refuse to come up rather than half-work.
const char* macstr = NULL;
Section_prop *ne2ksec = control ? static_cast<Section_prop*>(control->GetSection("ne2000")) : NULL;
if (ne2ksec) macstr = ne2ksec->Get_string("macaddr");
if (!ParseMac(macstr, mac)) {
LOG_MSG("STEAM: [ne2000] macaddr is \"%s\" -- backend=steam needs a fixed MAC, "
"exactly six two-digit hex octets (02:00: + the four IP octets, "
"see SESSION-CONTRACT section 1)",
(macstr && *macstr) ? macstr : "unset");
return false;
}
vwesteam::Config cfg;
uint32_t selfip = 0;
uint64_t sessionid = 0;
std::string name;
if (!sessionpath.empty()) {
SessionPeer self;
std::vector<SessionPeer> peers;
std::string err;
if (!ParseSessionFile(sessionpath, self, peers, err)) {
LOG_MSG("STEAM: %s", err.c_str());
return false;
}
selfip = self.ip;
sessionid = self.steamId;
name = self.name;
if (self.macKnown && memcmp(self.mac, mac, 6) != 0)
LOG_MSG("STEAM: session file says our MAC is %02x:%02x:%02x:%02x:%02x:%02x but "
"[ne2000] macaddr is %02x:%02x:%02x:%02x:%02x:%02x -- the conf wins, "
"peers will route to the conf MAC",
self.mac[0],self.mac[1],self.mac[2],self.mac[3],self.mac[4],self.mac[5],
mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
// Peer MACs/IPs are logged but not fed to the transport -- those are
// learned from HELLO, which stays correct when a player relaunches into
// a different slot. The "gateway": true flag IS passed through: it is
// the default route for any unicast we cannot place, which in practice
// means everything bound for TeslaConsole at .10 (a host-LAN NIC MAC
// that can never appear in the peer table). Without it those frames
// would flood, putting the whole egg transfer on every player's uplink.
for (size_t i = 0; i < peers.size(); i++) {
cfg.peers.push_back(peers[i].steamId);
if (peers[i].gateway) {
if (cfg.gateway && cfg.gateway != peers[i].steamId)
LOG_MSG("STEAM: session file marks more than one peer as the "
"gateway; keeping %s", std::to_string(cfg.gateway).c_str());
else
cfg.gateway = peers[i].steamId;
}
LOG_MSG("STEAM: peer slot %d \"%s\" %s ip %u.%u.%u.%u mac %02x:%02x:%02x:%02x:%02x:%02x%s",
peers[i].slot, peers[i].name.c_str(),
std::to_string(peers[i].steamId).c_str(),
(peers[i].ip >> 24) & 0xff, (peers[i].ip >> 16) & 0xff,
(peers[i].ip >> 8) & 0xff, peers[i].ip & 0xff,
peers[i].mac[0],peers[i].mac[1],peers[i].mac[2],
peers[i].mac[3],peers[i].mac[4],peers[i].mac[5],
peers[i].gateway ? " (gateway)" : "");
}
}
// A csv is a union with the session file's roster rather than an override:
// peers is an allowlist, and an operator who names an ID means to admit it.
ParseIdCsv(peerscsv, cfg.peers);
if (!lobbystr.empty() && !ParseId(lobbystr, cfg.lobby))
LOG_MSG("STEAM: ignoring unparseable lobby id \"%s\"", lobbystr.c_str());
cfg.channel = section->Get_int("channel");
const char* envname = getenv("VWE_STEAM_NAME");
cfg.name = (envname && *envname) ? std::string(envname) : name;
if (cfg.peers.empty() && cfg.lobby == 0) {
LOG_MSG("STEAM: no peers -- set [ethernet, steam] session/peers or the "
"VWE_STEAM_SESSION / VWE_STEAM_PEERS environment variables");
return false;
}
// No session file: recover our IP from the MAC. Every VWE MAC is 02:00: +
// the four IP octets (deploy/configure.ps1's formula), so this is exact
// for a configured pod and simply stays 0 ("unknown") for anything else.
if (!selfip && mac[0] == 0x02 && mac[1] == 0x00)
selfip = ((uint32_t)mac[2] << 24) | ((uint32_t)mac[3] << 16) |
((uint32_t)mac[4] << 8) | (uint32_t)mac[5];
vwesteam::SetLog(SteamLog);
std::string err;
if (!vwesteam::Init(cfg, mac, selfip, err)) {
LOG_MSG("STEAM: link did not come up: %s", err.c_str());
return false;
}
up = true;
// Stale session file, or the machine is signed into a different Steam
// account than the lobby handed the roster to: every peer's allowlist will
// refuse us. Say it here, not at mission start when nobody appears.
if (sessionid && vwesteam::SelfSteamID() && sessionid != vwesteam::SelfSteamID())
LOG_MSG("STEAM: session file was written for SteamID %s but this machine is signed in as %s "
"-- peers will refuse us",
std::to_string(sessionid).c_str(), std::to_string(vwesteam::SelfSteamID()).c_str());
LOG_MSG("STEAM: link up -- self %s mac %02x:%02x:%02x:%02x:%02x:%02x ip %u.%u.%u.%u, "
"%u peer(s), channel %d",
std::to_string(vwesteam::SelfSteamID()).c_str(),
mac[0],mac[1],mac[2],mac[3],mac[4],mac[5],
(selfip >> 24) & 0xff, (selfip >> 16) & 0xff, (selfip >> 8) & 0xff, selfip & 0xff,
(unsigned)cfg.peers.size(), cfg.channel);
return true;
}
void SteamEthernetConnection::SendPacket(const uint8_t* packet, int len)
{
static unsigned long txn = 0;
++txn; /* split off: pcap's one-liner form of this is a sequence-point warning */
if ((txn & (txn - 1)) == 0 && len >= 14) /* powers of 2, avoid spam */
LOG_MSG("STEAM TX #%lu len=%d dst=%02x:%02x:%02x src=%02x:%02x:%02x",
txn, len, packet[0],packet[1],packet[2], packet[6],packet[7],packet[8]);
vwesteam::SendFrame(packet, len);
}
void SteamEthernetConnection::GetPackets(std::function<void(const uint8_t*, int)> callback)
{
// The one and only pump site. NE2000_Poller is a TIMER tick handler, so
// this runs once per emulated millisecond -- which is why the Steam link
// needs no thread and no timer of its own anywhere.
vwesteam::Pump();
static unsigned long rxn = 0;
vwesteam::PollFrames([&](const uint8_t* packet, int len) {
// Acceptance mirrors the pcap backend's BPF clause for clause so the
// guest cannot tell the two backends apart.
if (len < 14 || len > vwesteam::VWE_MAX_FRAME) return;
const bool bcast = (packet[0] & packet[1] & packet[2] &
packet[3] & packet[4] & packet[5]) == 0xff;
if (!bcast) {
if (packet[0] & 1) return; /* multicast: the BPF never matched it */
if (memcmp(packet, mac, 6) != 0) return; /* ether dst <self> */
}
// "and not ether src <self>", the BPF's third clause. steamlink.h
// calls this structurally impossible because a peer never echoes;
// the GATEWAY can, though. Its capture filter is bare
// "ether broadcast" until the first HELLO lands (steam-gw
// BuildFilter()), with no "not ether src" clause to build yet -- so
// in that window it captures its own npcap injection of OUR
// broadcast and tunnels it straight back to us. A real NIC never
// hears its own transmit, and a boot-ARP that returns to its sender
// is duplicate-address bait, so drop it here for one memcmp.
if (memcmp(packet + 6, mac, 6) == 0) return;
++rxn;
if ((rxn & (rxn - 1)) == 0)
LOG_MSG("STEAM RX #%lu len=%d dst=%02x:%02x:%02x src=%02x:%02x:%02x",
rxn, len, packet[0],packet[1],packet[2], packet[6],packet[7],packet[8]);
callback(packet, len);
});
}
#endif
+57
View File
@@ -0,0 +1,57 @@
/*
* VWE fork: NE2000 backend that tunnels guest Ethernet frames over Steam
* (`backend=steam`), so a private group can fly missions over the internet.
*
* Why L2 and not an ordinary L3 tunnel: the 1995 mesh (WATTCP + netnub +
* L4NetworkManager) dials peers by raw IP on one flat subnet and ARPs for
* them, so whole FRAMES have to cross the internet for the DOS binaries to
* see the same-switch world they were built for.
*
* All of the transport lives in vwesteam:: (steamlink.h) and is shared
* VERBATIM with the host's steam<->pcap gateway; this class is only the
* EthernetConnection adapter -- config resolution, the receive-side
* acceptance policy, and the log lines. Steamworks is bound at runtime in
* there, exactly as the pcap backend binds WPCAP.DLL, so a build on a machine
* with no SDK still runs and just fails Initialize() with a readable reason.
*
* Only REMOTE players run this. The session host's pod stays on
* backend=pcap and reaches the tunnel through the gateway, which is what
* keeps exactly one process per machine on ISteamNetworkingMessages.
*
* Conf: [ne2000] backend=steam, macaddr=<stable MAC, never "random">
* [ethernet, steam] peers= lobby= session= channel=
* Contracts: ../steam/SESSION-CONTRACT.md (session file, env, addressing).
*/
#ifndef DOSBOX_ETHERNET_STEAM_H
#define DOSBOX_ETHERNET_STEAM_H
#include "config.h"
#ifdef WIN32
#include "ethernet.h"
#include <stdint.h>
/** A Steam-P2P Ethernet connection
* Carries raw Ethernet frames to the other pods in the session over
* SteamNetworkingMessages instead of over a host NIC. Needs Steam running,
* a stable [ne2000] macaddr, and a peer roster (session file, csv or lobby).
*/
class SteamEthernetConnection : public EthernetConnection {
public:
SteamEthernetConnection();
~SteamEthernetConnection();
bool Initialize(Section* config) override;
void SendPacket(const uint8_t* packet, int len) override;
void GetPackets(std::function<void(const uint8_t*, int)> callback) override;
private:
uint8_t mac[6] = {}; /*!< [ne2000] macaddr; the RX filter's "ether dst self" */
bool up = false; /*!< Init() took -- gates the refcounted Shutdown() */
};
#endif
#endif
+6
View File
@@ -229,11 +229,17 @@ void CSerialNamedPipe::pumpPipe() {
inbuf.erase(inbuf.begin(), inbuf.begin() + pos);
}
/* VPX page-fault watch (cpu/paging.cpp): records each delivered RX byte with
* the guest cs:eip at delivery, so a watched fault can say how close it was
* to a serial delivery and where the guest was interrupted. */
extern void VPX_SerialTraceByte(double now, uint8_t b);
bool CSerialNamedPipe::doReceive() {
if (rxq.empty()) pumpPipe();
if (rxq.empty()) return false;
uint8_t b = rxq.front();
rxq.pop_front();
VPX_SerialTraceByte(PIC_FullIndex(), b);
receiveByteEx(b, 0);
return true;
}
File diff suppressed because it is too large Load Diff
+216
View File
@@ -0,0 +1,216 @@
/*
* steamlink.h -- VWE Steam transport core (Ethernet frames over Steam P2P).
*
* Shared VERBATIM by two consumers, which is why it is a free-function
* namespace and not a class:
* * the DOSBox-X fork's `backend=steam` NE2000 backend (ethernet_steam.cpp)
* -- run by every REMOTE player; no Npcap on those machines at all;
* * the session host's standalone steam<->pcap gateway (steam-gw/main.cpp),
* which bridges the tunnel onto the Network Bridge so TeslaConsole
* (200.0.0.10) and the host's own pcap pod can reach the remote pods.
*
* WHY L2: the 1995 mesh (WATTCP + netnub + L4NetworkManager) dials peers by
* raw IP on one flat subnet and ARPs for them. NAT/UDP hole-punching at L3
* cannot carry that; tunnelling whole Ethernet FRAMES preserves the
* same-switch semantics the DOS binaries were built for. See
* ../STEAM-NOTES.md and ../steam/SESSION-CONTRACT.md.
*
* Threading: NOT thread-safe by design. Every entry point is called from a
* single thread -- in the fork that is the emulator thread (GetPackets runs
* off NE2000_Poller, a TIMER tick handler, i.e. once per emulated
* millisecond), in the gateway it is the one service loop. Do not call from
* two threads.
*
* Steamworks is bound at RUNTIME (LoadLibrary/GetProcAddress on
* steam_api64.dll), exactly like the pcap backend binds WPCAP.DLL. A build
* made without the SDK DLL present still runs -- `backend=steam` just fails
* Init() with a readable message, the same way a missing Npcap fails pcap.
*
* Windows-only for now (the whole VWE deployment is), but nothing here is
* structurally Windows-bound apart from the DLL loader.
*/
#ifndef VWE_STEAMLINK_H
#define VWE_STEAMLINK_H
#include <cstdint>
#include <cstddef>
#include <string>
#include <vector>
#include <functional>
namespace vwesteam {
/* ------------------------------------------------------------------ *
* Wire format (channel `Config::channel`, default 0)
*
* One Steam message == one record. First byte is the record type.
*
* 'F' frame : ['F'][raw Ethernet frame, 14..1514 bytes]
* 'H' hello : ['H'][u8 ver=1][u8 mac[6]][u32 ip, BIG-endian][char name[16]]
*
* HELLO is the authoritative SteamID64 <-> MAC binding. It is sent when a
* session comes up and then periodically (fast until the peer has answered,
* slow after) so a peer that restarts its pod is re-learned without any
* lobby round trip. Learning the src MAC off an 'F' frame is the fallback
* for a HELLO that raced past us.
*
* Everything is sent RELIABLE + NoNagle. Rationale (do not "optimize" this
* to unreliable without re-reading it): the payload is guest TCP driven by
* WATTCP's DOS-era retransmit timers, which are multi-second. One dropped
* segment on an unreliable tunnel therefore costs seconds of visible stall,
* whereas the reliable channel's RTT-based retransmit costs one RTT. The
* usual TCP-over-TCP meltdown argument needs an AGGRESSIVE inner
* retransmitter; WATTCP is the opposite. Reliable is also ORDERED (matches
* the no-reorder model the Phase 0 latency gate validated) and fragments
* transparently far past 1514 bytes, which retires MTU as an issue.
* ------------------------------------------------------------------ */
enum : uint8_t {
REC_FRAME = 'F',
REC_HELLO = 'H'
};
/* Largest Ethernet frame we relay (no jumbo; the NE2000 can't make one). */
enum { VWE_MAX_FRAME = 1514 };
struct Config {
/* Allowlist AND initial peer set: SteamID64s of the other pods in this
* session. Steam session requests from an identity that is not in here
* are refused -- with a private lobby that is the whole security story,
* which is adequate for a friends group on app 480. */
std::vector<uint64_t> peers;
/* Optional: a Steam lobby to pull the roster from instead of / in
* addition to `peers` (Phase 3). 0 = don't touch matchmaking. */
uint64_t lobby = 0;
/* The session host, i.e. the peer running the steam<->pcap gateway
* (SESSION-CONTRACT.md section 2: exactly one peer carries
* "gateway": true). 0 = no gateway in this session.
*
* This is the DEFAULT ROUTE. A remote pod's frames for TeslaConsole at
* 200.0.0.10 carry the console's real NIC MAC, which is a host-LAN
* address and will never appear in the peer table, so without a default
* route the only way to deliver them is to flood every peer -- which
* duplicates the whole console<->pod stream (the egg transfer above all)
* to all 7 other players and pays for it on everyone's uplink. */
uint64_t gateway = 0;
/* Steam networking channel. Keep 0 unless two links share a process. */
int channel = 0;
/* Short label announced in HELLO and printed in logs (pilot/slot name).
* Truncated to 15 chars + NUL on the wire. */
std::string name;
};
/* Log sink. The fork points this at LOG_MSG, the gateway at stderr. Set it
* BEFORE Init() if you want to see Init()'s own diagnostics. */
typedef void (*LogFn)(const char* msg);
void SetLog(LogFn fn);
/* Bring the link up.
* self_mac the guest's 6-byte MAC ([ne2000] macaddr). REQUIRED and must be
* stable -- it is what peers route to. A random MAC breaks the
* mesh on every restart.
* self_ip the guest's IPv4 in HOST byte order (diagnostics + the
* gateway's a-priori 02:00:xx:xx:xx:xx sanity check). 0 = unknown.
* err human-readable reason on failure.
* Returns false if steam_api64.dll is missing, Steam isn't running, the user
* isn't logged in, or the SDK rejected init. Refcounted with Shutdown(). */
bool Init(const Config& cfg, const uint8_t self_mac[6], uint32_t self_ip,
std::string& err);
/* Tear down: closes every peer session and releases the SDK. */
void Shutdown();
/* Service Steam: runs the manual-dispatch callback pump (session requests ->
* accept-if-allowlisted, session failures -> log + mark for re-HELLO, lobby
* roster deltas when Config::lobby is set) and re-sends HELLOs when due.
*
* MUST be called regularly -- the fork calls it at the top of GetPackets(),
* i.e. once per emulated ms, which is also why no separate thread or timer is
* needed anywhere. */
void Pump();
/* Queue one Ethernet frame to the peer(s) it is addressed to. Frames shorter
* than 14 or longer than VWE_MAX_FRAME are dropped.
*
* Routing:
* broadcast / multicast -> every peer (ARP has to reach everyone)
* unicast to a learned MAC -> that one peer
* unicast to an unknown MAC -> Config::gateway if set, else every peer
*
* The unknown-unicast case is almost always console-bound traffic, which is
* why the gateway is the default route rather than a flood. Falling back to
* flooding when no gateway is configured keeps a gateway-less session (two
* players, no console) working, and also covers the narrow race where a peer's
* MAC is not yet learned -- narrow because ARP is broadcast, so a peer is
* normally bound before anyone unicasts to it. */
void SendFrame(const uint8_t* frame, int len);
/* Drain received frames, invoking `cb` for each. Returns how many were
* delivered. NOTE: this hands over EVERY frame a peer sent us -- the caller
* applies its own acceptance policy (the fork mimics the NE2000's
* dst==self||broadcast rule so behaviour matches the pcap backend's BPF; the
* gateway injects everything onto the bridge unmodified). The pointer is only
* valid inside the callback. */
int PollFrames(const std::function<void(const uint8_t*, int)>& cb);
/* Our own SteamID64 (0 before a successful Init). */
uint64_t SelfSteamID();
/* Route diagnostics: relayed (SDR/TURN) vs direct P2P, and the switch between
* them. Call AFTER Init; safe to skip entirely.
*
* Why it is a log firehose and not a clean bool: the flag that answers this,
* k_nSteamNetworkConnectionInfoFlags_Relayed, lives in SteamNetConnectionInfo_t
* and needs an HSteamNetConnection to read. ISteamNetworkingMessages never
* gives one out -- the SDK says so at SteamNetworkingMessage_t::m_conn: "Not
* used when using the ISteamNetworkingMessages interface". So the only route
* left is Steam's own debug output, which names the path it chose and logs the
* relay->direct upgrade when it happens.
*
* `level` is Valve's ESteamNetworkingSocketsDebugOutputType: 4 = Warning,
* 5 = Msg (route changes, the useful setting), 6 = Verbose, 7 = Debug,
* 8 = Everything (a wall of per-packet text). Output goes to the same LogFn
* sink as everything else. Degrades to a logged notice if this steam_api64.dll
* has no ISteamNetworkingUtils. */
void SetRouteDiagnostics(int level);
/* --- introspection, for the gateway's BPF and for status lines ---------- */
/* Bumps every time the known set of peer MACs changes (HELLO from a new peer,
* a peer's MAC changing after a pod restart, a session dropping). The gateway
* watches this to know when to recompile + reinstall its pcap filter; polling
* a counter keeps that policy in the gateway instead of in a callback. */
uint32_t PeerEpoch();
struct PeerInfo {
uint64_t steamId;
uint8_t mac[6];
bool macKnown; /* false until HELLO or a learned src MAC */
uint32_t ip; /* host order; 0 if unknown */
char name[16];
bool sessionUp;
bool isGateway; /* the session host; the default route (see Config) */
uint64_t framesTx, framesRx;
};
/* Snapshot of the peer table (for logs, status panels and the gateway's
* filter build). Returns the number written. */
size_t Peers(std::vector<PeerInfo>& out);
/* Add/remove a peer at runtime (lobby deltas, or a launcher that learns a
* late joiner). Adding an already-known peer is a no-op. */
void AddPeer(uint64_t steamId);
void RemovePeer(uint64_t steamId);
/* Aggregate counters, for the throttled "STEAM TX/RX #n" log lines that mirror
* the pcap backend's. */
void Counters(uint64_t& tx, uint64_t& rx, uint64_t& txDropped);
} // namespace vwesteam
#endif // VWE_STEAMLINK_H
+49 -3
View File
@@ -611,11 +611,57 @@ void
// joint DCS -- so the eye sits in the canopy and
// rides torso twist through chain composition).
//
// THE INSIDE VIEW LOADS THE X-VARIANT SKELETON. The
// resource names one skeleton (mad.skl) for both views;
// the cockpit build is derived from it by the fleet-wide
// naming convention -- third letter X: MAD->MAX,
// AVA->AVX, BAT->BAX, BLH->BLX, FIR->FIX, JAK->JAX,
// LOK->LOX, with the numbered chassis following
// (MAD1->MAX1, LOK1->LOX1; all present in VIDEO/). The
// X skeleton carries the SAME 25-joint chain -- so the
// canopy eye and torso twist compose identically -- but
// its only geometry is the cockpit shell (MAX.SKL ->
// max_cop.bgf, the MAX_COP canopy with PUNCH-texel
// windows from the real-pod capture forensics). The
// donor names the same mechanism from the decomp side:
// inside = SkeletonType_A with '_cop' selection
// (btl4vid.hpp:678). Without this, the pilot sits
// inside the OUTSIDE model staring at torso panels.
//
int
eye_count = 0;
ReadSKLFile(entity, root_DCS,
video_object->GetObjectFilename(), view_type,
&eye_count);
const char
*skeleton_name = video_object->GetObjectFilename();
char
inside_name[64];
dpl_DCS
*skl_result = NULL;
if (
view_type == insideEntity &&
strlen(skeleton_name) >= 3 &&
strlen(skeleton_name) < sizeof(inside_name)
)
{
strcpy(inside_name, skeleton_name);
inside_name[2] =
(inside_name[2] >= 'a' && inside_name[2] <= 'z')
? 'x' : 'X';
skl_result = ReadSKLFile(entity, root_DCS,
inside_name, view_type, &eye_count);
if (skl_result == NULL)
{
DEBUG_STREAM << "[skl] no cockpit variant '"
<< inside_name
<< "' -- falling back to the body skeleton\n"
<< flush;
}
}
if (skl_result == NULL)
{
ReadSKLFile(entity, root_DCS,
skeleton_name, view_type, &eye_count);
}
//
// 3. FALLBACK eyepoint only. A skeleton without a
@@ -1559,3 +1559,48 @@ overwrites the ramp with 1.0f -- authored dead weight, preserved as the
binary's shape). recenterActive carved from dynamicsState (class size
unchanged). With 5.3.68's table fix, the RIO/TM twist buttons now land in
these members and move the torso -- and the canopy eye rides the twist chain.
--------------------------------------------------------------------------------
THE RESIDUAL FAULT, CAUGHT IN THE ACT -- AND THE INSIDE VIEW GETS ITS COCKPIT
--------------------------------------------------------------------------------
TWO instruments landed together this session:
1. VPX_PF_WATCH (emulator fork, cpu/paging.cpp): on any guest page fault at
the watched linear address, dump guest registers, the last 64 serial RX
deliveries (time + guest cs:eip at delivery + byte), the code bytes at the
faulting EIP and the stack top. serialnamedpipe's doReceive() feeds the
ring (VPX_SerialTraceByte). Armed via VPX_PF_WATCH=7000FA64 in podrun.sh
and launch_pod.ps1; the dump lands in dosboxlog.txt / pod_err.txt.
FIRST CATCH decoded the fault completely:
CS:EIP = 00FF:000066D4 (the DPMI host, flat selector)
EBX = F000CA60 <- an IVT ENTRY read as a dword: seg F000, off CA60
= a BIOS DEFAULT interrupt handler
access = [EBX+0x3004], and the segment's 0x80000000 base wrap gives
exactly cr2 = 0x7000FA64
So the host reads a probe word 0x3004 bytes past a REAL-MODE VECTOR VALUE
treated as a flat pointer. For the host's own handlers (low memory) that
read lands in mapped conventional memory and is harmless; for a BIOS
F000:xxxx default it lands in unmapped high linear space and faults. The
serial ring shows a steady 1-byte/1-3ms vRIO stream with NOTHING special
at the fault -- the stream only determines WHICH vectors the host walks
and when. The +0x3004 constant appears nowhere in DPMI32VM.OVL or
32RTM.EXE as an immediate, so it is composed at runtime; the probe now
also dumps code bytes at EIP + stack to close that gap on the next catch
(faulthunt.sh loops runs until it fires).
2. SHIPPED BASELINE: 4/4 clean. Consistent with the exposure theory
(expected ~0.6 faults if the hazard is proportional to the load window)
-- not yet discriminating. The probe data is the discriminator now.
THE INSIDE VIEW LOADS THE COCKPIT SKELETON. MAX.SKL solved the own-mech
question the authentic way: the X-variant naming convention (third letter X:
MAD->MAX, AVA->AVX, BAT->BAX, BLH->BLX, FIR->FIX, JAK->JAX, LOK->LOX, plus
numbered MAX1/MAX2 -- all 64 present in VIDEO/) selects a skeleton with the
SAME 25-joint chain but a single object: max_cop.bgf, the MAX_COP canopy
shell with the PUNCH-texel windows from the real-pod capture forensics. The
donor names the same mechanism from the decomp side (inside = SkeletonType_A
with '_cop' selection, btl4vid.hpp:678). Our mech case now derives the
inside name from the resource's skeleton (fallback to the body skeleton if
the X file is missing), so the pilot sits in the authentic cockpit instead
of inside the body model's torso panels.