Commit Graph
79 Commits
Author SHA1 Message Date
CydandClaude Fable 5 a1c3363f0b NET-NOTES: console between-missions behavior characterized + host bridge plan
Three-mission live session on net_loop.conf: the pod side is fully
retail-faithful (netnub auto-relaunches on mission end AND console
disconnect, ~60s cycle). Console 4.10's between-missions dead-end is
app-level: its TCP receives FIN+RST from the fresh netnub yet the app
never re-queries; only an app relaunch (endpoints rebuilt from the INI)
recovers it. Selecting a printer in the Chooser makes the app launch
much faster (Printing Manager stalls without one) but does not change
the dead-end. Documented the working operator rhythm and the plan for
bridging the host-side .NET console onto the pod LAN (bridge adapter
IP 200.0.0.1/24, possible Npcap SendToRx for pod->host hairpin).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 10:24:17 -05:00
CydandClaude Fable 5 162fa39117 Death camera: forensics, capture, and probes (fix not yet applied)
Pilot sees the escape-pod/wreck interior at death instead of the portal
ride. Findings (DEATH-SEQUENCE-NOTES.md): two death variants exist --
respawn deaths transit the chain camera to the portal at the origin
(fp_cam's <100m vehicle-distance guard rejects exactly that ride = the
fix target); mission-end deaths (tonight's capture) have no transit on
the wire at all, just the fog fade at the wreck. At death the 0x1f
articulation batches switch to driving origin-anchored nodes = the
portal diorama animating; type-3 view flushes decode as projection+fog
only (hither/yon at floats 12/13). Reference capture
captures/netdeath-20260708.fifodump (full networked mission incl. death)
+ replay probes in probes/.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 00:13:12 -05:00
CydandClaude Fable 5 1b041d5a9e Bridge: frame coalescing -- the view can no longer fall behind real time
The main loop rendered EVERY draw_scene in arrival order, so any render
slowdown played the mission slower than real time and the view drifted
seconds behind the game (user: "renderer fell way out of sync"); the
backpressure hides in the socket, so backlog= stayed 0. Now each pass
slices all complete records, applies every state record in order, and
presents only the newest frame; superseded presents are counted in the
new skipped= report field. Live verdict over a full mission:
frames=10169 skipped=3 backlog=0B -- locked to the wire.

Also from the tuner session: seat trim granularity 0.1 (0.5 was too
jumpy) and a HUD size trim (vrview_gl u_scale + VRVIEW_HUDSCALE env,
live +/- keys) -- tuners stay enabled for pilot feedback; seat trim
turns out to be per-mech (Mad Cat vs Thor want different values).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 00:13:11 -05:00
CydandClaude Fable 5 2233441812 Net: NIC off IRQ 3 (plasma COM2 owns it) -- pod no longer goes deaf in-game
The plasma serial2 addition put COM2 (IRQ 3) in conflict with nicirq=3:
netnub phase worked, then BTL4OPT opened the plasma port and NIC RX died,
so the pod never checked in to the console. NIC now on IRQ 10 in all net
confs + NET.CFG INT 10 (both sides must agree). Verified live: two full
console missions with plasma running.

Also: launch_pod.ps1 prepends the Npcap dir to PATH itself (a bare shell
gave "NO PACKET DRIVER FOUND"); net_diag.conf = packet-stack-only boot
with the NCSA Telnet suite on E: for DOS-side TCP tests; net_loop.conf
promoted to full production parity (sound + plasma + IRQ 10) -- the
GO.BAT-style instant netnub relaunch is also what lets the console
recover its zombie TCP session between missions (see NET-NOTES).
NET-NOTES: full 7/08-09 forensics writeup (TAP RX counter lie, console
IP .10, SBK re-upload measured, zombie-session mechanics).
LAST.EGG = the operator's missions from tonight's runs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 00:13:11 -05:00
CydandClaude Fable 5 419c7d5d63 Pick: authentic per-instance INTERSECT mask replaces the interim gates
Instance body word 9 is the INTERSECT mask (verified live: terrain,
sky, buildings and enemy replicant mechs carry 0xffffffff; the player's
own mech parts, laser beams, missiles and effects carry 0). The raycast
now ANDs it against the query mask from the 0x26 arm -- exactly the
real board's exclusion. The min-range and hidden-until-armed gates
retire: point-blank enemy hulls are targetable again, and own-ordnance
exclusion is authored by the game itself.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 20:46:40 -05:00
CydandClaude Fable 5 c13613e259 GL fog: per-fragment factor -- terrain/cloud no longer escape the fog
Fog was computed per VERTEX; vertices behind the eye clamped to factor
zero, and the terrain/cloud triangles are large enough to span the
camera, so interpolation dragged the whole ground to unfogged (bright
terrain through the pre-drop blackout and the respawn reveal). The
eye-space depth now rides the varying (perspective-correct) and the
factor is computed per fragment, where clipping guarantees valid depth.

Verified offline: pre-drop hold renders solid black + HUD only (matches
the period screenshot exactly); the respawn fade shows the authentic
near-first reveal from the operator's VHS (ground clear, fog wall at
distance, sky still white).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 20:32:38 -05:00
CydandClaude Fable 5 bb8978c127 Retire the near-eye cull by default: the eye-shroud is authentic content
The death sequence re-flushes the view with hither=1/yon=2 -- a thin
render shell that reveals geometry parked around the camera: the
escape-pod interior and the "blue swirly" ring dome (period VHS stills
of a 4.10 death match: violet concentric ripples, drifting center,
static canopy silhouette at the frame edge). Normal play clips the
shroud via the standard hither plane, so nothing leaks; the cull was
only masking authentic content. VRVIEW_NEARCULL=1 re-enables it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 19:53:52 -05:00
CydandClaude Fable 5 7ae11f174c HUD: dpl2d Y grows down -- unflip the whole 2D layer
Period VHS footage of a 4.10 game (operator's capture) shows the twist
dial UNDER the reticle and the range bar filling top-to-bottom; our
mapping of dpl2d Y straight onto GL's Y-up NDC (and the software path's
"y up" projection) rendered the entire HUD vertically flipped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 19:37:29 -05:00
CydandClaude Fable 5 c5659b8d3e Bridge: pre-movement camera, munga yaw fix, fogged background; net conf plasma
- fp_cam works before the first vehicle articulation (a freshly dropped
  mech sends no 0x1f until it moves; bailing out left the raw chain
  convention showing the inside of the mech at every drop)
- The FLYK stand-in +90-deg yaw correction no longer applies to munga
  content (it yawed the player's own mech -- and every animated model --
  90 degrees: "looking through the right shoulder")
- With fog on, the clear colour saturates to the fog colour (background
  at infinite distance); the pre-drop hold is FULLY black, as period
  pilots confirm
- net_full.conf: COM2 plasma passthrough + setenv plasma flag

Networked console session verified live: black hold at ready, flash +
fade on console launch, drop-bay doors present, own mech visible, and
the full death sequence captured on the wire (fade-to-black, escape-pod
interior via near-fog exemption, world reload, white flash, blue-violet
respawn fade = the blue swirly's home).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 19:15:04 -05:00
CydandClaude Fable 5 817c3ad4a4 Renderer: VRVIEW_NEARCULL toggle for the near-eye cull A/B
The first-person canopy cull can now be disabled (VRVIEW_NEARCULL=0)
to study the always-armed cockpit/bay assembly from the true chain
eye -- part of the pilot-view attachment investigation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 18:24:23 -05:00
CydandClaude Fable 5 e6ebef071d Pick geometry completeness + the audio crackle root cause
Device raycast/scene parser (vpxlog.cpp):
- Connection lists: accumulate the WHOLE batch before slicing (records
  straddling burst boundaries were dropped + misaligned the rest), do
  not wipe polys per batch header (floor ships tri batch + quad batch;
  only the last survived), keep every loop index (closing-dup drop
  halved each quad). Together these were the "holey ground" the
  range-finder fell through.
- Own-mech exclusion by minimum pick range (15) instead of the
  dcs_parent ancestry walk: sibling link edges made the FLOOR and SKY
  read as the player's subtree, so ground/sky aims never resolved.
  Measured: own barrels/flash live within ~8 of the eye; sky/ground
  are real pickable entities (sky.mod, afloor) -- firing into them
  fires and misses, per the operator's arcade experience.

EMU8000 core (emu8k.cpp): clamp the oscillator output after cubic
interpolation. Crest overshoot on UNFILTERED voices overflowed int32
in the volume multiply and wrapped the crest negative for 1-3 samples
-- the speech/effects crackle (recorded signature: +0.7 flipping to
-0.7 at crests, random phase vs the chunk grid). Filter paths already
clamped; the bypass path now matches.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 15:16:40 -05:00
CydandClaude Fable 5 d88d9212c0 Aim pipeline: all-LODs raycast, always-answer picks, own-mech exclusion
The stale-aim saga, root-caused live with the operator:

- The device raycast walked only lod[0] of each object; BT content is
  authored ADDITIVE_LODS (arena wall = posts lod + panel lod), so the
  aim ray flew BETWEEN the skeleton pieces of whatever was targeted --
  94% miss rate (pick stats now log this).
- Misses fell back to a plain frame ack carrying no sect data, so the
  game kept a seconds-old target: "aim updates every few seconds",
  stationary shots stale. The pick is now answered EVERY armed frame;
  a miss is a valid all-zero reply that clears targetEntity (aiming at
  open sky un-targets -- authentic misfire, not stale fire).
- Raycast walks ALL lod children; own-articulation exclusion via the
  CAM backchannel 7th field (vehicle root DCS) stops mid-volley picks
  of the player's own muzzle flash / arms.

Renderer: same ADDITIVE_LODS fix -- when every LOD switch window is
the degenerate (0,1e9) fallback, draw the union of all lods. The
arena wall ring (user-confirmed live) went from floating post slivers
to the full textured wall. Bridge reports its wire backlog.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 14:33:50 -05:00
CydandClaude Fable 5 351cce26b3 AWE32: VWE_AWE_WAV crackle-hunt recording taps
Three WAVs written from the render thread: per-card PRE-limiter
streams as float32 (clipping baked in upstream shows as flat tops
above full scale) and the POST-limiter int16 mix (what the user
hears). Headers re-patched every second so files survive a hard
kill. launch_pod.ps1 arms it into the work dir by default.

Diagnosis logic: flat tops in a card tap = per-voice clipping inside
the EMU8000 core; clean cards + dirty mix = limiter artifact; all
clean = winmm path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 14:06:11 -05:00
CydandClaude Fable 5 ab4a5b8702 Ravine mission egg + conf (the WALLED arena, per BTL4.RES map decode)
BT411's mapscan (full RES container format) run against our RES settles
the walls question: arena1/arenall and arena2/arenall2 place the open
city set only; the wall1/2/3 segments belong to the RAV map (18+8+5
placements: a canyon maze), and cavern/grass/dbase carry the wall10k
outer ring. Nothing was ever dropped by the renderer.

TESTRAV.EGG = TESTARN.EGG with map=rav; gauge_rav_sound.conf boots it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 13:38:29 -05:00
CydandClaude Fable 5 b2f0becbd4 Document Live Cam + Mission Review architecture (CAMERA-REVIEW-NOTES.md)
Researched from the readable RP MUNGA source (BT shares the engine):
host roles are assigned per-IP in the mission egg (hostType= on each
pilot page); a CameraShip/MissionReview host gets a CameraDirector
player that auto-cuts to the top-ranked pilot every 10s, with manual
flight via the same cockpit hardware as pods (CameraRIOMapper) and
fixed clamped trackside cameras authored in-game into MAPS/<map>.cam.
Mission Review records raw NetworkPackets (SpoolFile -> last.spl) and
replays them through a networkless playback app with timestamp bias --
the replay re-simulates the battle from replication traffic.

Same BTL4OPT.EXE serves every role; standing up Live Cam on the
emulated pod LAN is an egg edit, not a build.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 09:21:46 -05:00
CydandClaude Fable 5 6853b123ed Confs: default L4TIMER to FAST (setenv arg2 s->f, all 14 launch confs)
L4TIMER selects the game clock (L4TIME.CPP): FAST = HMI SOS interrupt
clock at 28 Hz, unset = polled 18.2 Hz BIOS tick. Not a speed switch --
finer time quantum, smoother sim dt and timing cadences.

Per the operator: the flag tracked the deployed fleet's hardware --
original Tesla pods ran Pentium Pro 90s (SLOW), later fleets Pentium
Pro 200s (FAST). The emulated pod has no ISR-headroom constraint, so
FAST is our default from here on.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 09:10:08 -05:00
CydandClaude Fable 5 e7e1d72a66 Move 410console to the TeslaSuite repo
The 4.10 operations-console archive and the BattleTech-port hand-off
spec now live in C:\VWE\TeslaSuite\410console, alongside the
modernized .NET TeslaConsole they feed into.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 00:09:18 -05:00
CydandClaude Fable 5 cbf7015620 Weapon visuals + aim: beams render from the guns; pick self-target fixes
Renderer (dpl3-revive/patha):
- Instance visibility honored at DRAW time (stored word 4 = live
  dpl_SetInstanceVisibility field): laser beams (4-frame pulses) and
  missile models now render; cache tags w3 0/1 instances 'gated'
- PSFX world bursts (dcs=0 muzzle/impact/explosion) rendered; psfx
  storage list-based so one-shot bursts stop collapsing onto one key
- fix_degenerate applied to INSTANCE chains (was camera-only): the
  beam chain rides four rank-2 rig DCSs; composed rank-2 drew beams
  away from the guns. Offline f1635 now shows both arm beams
  converging on the aim point
- First-person canopy cull: the always-armed cockpit model at the
  head drew as a vertical line down screen center (user-confirmed
  fixed live)

Device (vpx-device/vpxlog.cpp):
- CAM backchannel on the fifosock: bridge streams its validated
  camera (+ vehicle root DCS); raycast_pick aims along the player's
  real look instead of the static view-node pose, which had locked
  every missile/beam onto one fixed wrong world point
- raycast_pick skips hidden-until-armed instances and the player's
  own articulation subtree: picking own beams created a target
  feedback loop, picking own missiles retargeted salvos mid-flight,
  and a picked missile's deleted DCS froze the game (arena2 crash)

Sound (vpx-device/vweawe.cpp): stereo-linked peak limiter replaces
the hard output clamp (the "generator out" crackle); VWE_AWE_LOG
reports pre-limit peaks + duck counts, enabled in launch_pod.ps1.
Missile-fire crackle persists: per-voice EMU8000 clamp suspected.

Eggs/confs: TESTAR2.EGG + gauge_arena2_sound.conf (map=arena2 city
variant); cavern.egg (console-era reference); plasma display on COM2
in the gauge confs; gauge_arena_net_sound.conf (slirp net stack).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 00:09:03 -05:00
CydandClaude Opus 4.8 2bb2ff7302 Weapons fire; hat-glance + MFD fixes; windowless bridge
vpx-device/vpxlog.cpp -- WEAPONS FIRE. The game's fire gate is
targetReticle.targetEntity (mech+0x388), filled every frame by a Division-board
reticle pick (dpl_RapidSectPixel) our HLE never answered, so every shot
misfired. The device now casts the camera centre ray against the live scene
(Moller-Trumbore) and returns the full hit -- instance + DCS + geogroup +
geometry -- piggybacked on the draw_scene reply; terrain is a valid target so
you can fire and miss. Sending geogroup=0 was hanging the game (GetAppSpecific
on a null); returning the real geogroup fixed it. Pick is default-on with a
single VPX_NO_PICK escape hatch. Also swaps the upper-left/right MFD explode
windows (screen location only -- decode untouched, real cause TBD on a pod).

dpl3-revive/patha/vrview.py -- HAT-GLANCE fix at the source. One cockpit DCS
(0xa2c) flushes a rank-2 rotation (shifted body -> wrong read window) that
collapsed the camera chain to rank 2 and smeared the head glance onto the wrong
axis (left/right hat read as pitch). chain_matrix(fix_degenerate) treats a
degenerate chain DCS as identity: preserves the look exactly and keeps stick-Y
torso pitch working (an earlier bridge-level yaw/pitch swap broke stick-Y and
was reverted). User-verified live: hat all 4 dirs + stick-Y both correct.

render-bridge/launch_pod.ps1 -- launch the bridge with pyw (windowless) so no
console window parks over the cockpit displays (Start-Process ignores
-WindowStyle once stdout/stderr are redirected).

render-bridge/live_bridge.py -- surface bridge render errors, flush the status
line; reverted glance-swap note.

Also vendored HUD (dpl2d) renderer work in vrboard/vrview_gl and RENDERER-COLLAB
/ RIO notes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 09:53:14 -05:00
CydandClaude Fable 5 c18c253658 RIO: document the board init handshake (test-mode + version) for vRIO
Decoded from L4RIO.CPP/HPP and verified byte-for-byte against a real
v4.2 board tap: CheckRequest 80 -> board must send TestModeChange ENTER
(8C 01 0D), self-test status stream (85 <status> <unit> <ck>), EXIT
(8C 00 0C), then answer VersionRequest 81 with 86 <maj> <min> <ck>.
Full command map 80-8C both directions, ACK/retransmit rules, and the
~1ms/byte 9600-baud pacing requirement. This is the implementation spec
for the user's vRIO (virtual RIO on COM1): its missing 8C packets are
exactly why the game logs 'RIO never came back from check request!'.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:35:37 -05:00
CydandClaude Fable 5 1872799c7a VPX device: dpl3-revive shading port + wire lights; fix game-path yaw mirror
- rt_draw shading replaced with the dpl3-revive software-rasterizer model
  (vrview.py draw(), proven on our own arena captures): lit = sceneAmb +
  sum |N.L|*col double-sided; c = emis + diff*lit (tex*base*1.275 when
  textured); Division 10-bit-DAC gamma 1/1.25 on output. Default light rig
  matches theirs (ambient 0.35 + one 0.65 sun) until wire lights arrive.
- Real wire lights decoded per their SceneCache.rebuild(): lmodel type-6 /
  light type-0xe bodies (dcs @d+12, type @d+16: 2=ambient 3=directional,
  rgb @d+20), directional aim = light DCS +Z row, sanity-clamped; frame
  carries summed ambient + up to 2 suns.
- Projection: the hardcoded post-projection X flip (SMPTE-era) made the
  game view steer mirrored (turn right, view swings left). Game path
  (ydown) now projects without it -- matches dpl3-revive, which has no
  lateral mirror; demo/test path keeps the flip. User-verified: native
  window steering now correct.

Fork source (emulator/src/src/hardware/vpxlog.cpp) in sync; rebuilt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:34:17 -05:00
CydandClaude Fable 5 0f5b2e28da Renderer: vendor live-bridge scripts; GPU backend unblocked (60fps)
- emulator/render-bridge/: the pod->Dave's-renderer live bridge (rescued
  from session scratchpad): live_bridge.py (first-person cam from the 0x1f
  pose, arrow-key eye-height trim), fp/chase offline renders, fifobridge,
  diagnostics, gauge_arena[_sound].conf, and launch_pod.ps1 (one-command
  pod+bridge restart: pentapus VPX_EXPLODE + AWE32 sound + GL bridge).
- _backend.py: renderer selection -- vrview_gl.GLRenderer (moderngl) by
  default, VRVIEW_SOFT=1 for the software reference; backend-agnostic
  frame save via last_frame.
- GPU backend runs on side-by-side CPython 3.13 (moderngl/glcontext cp313
  wheels; no MSVC needed): 63fps headless / 60.7 windowed vs 21fps software
  on the same scene, and the GL path also draws the vertex-alpha cloud dome.
- vrview.py: VRVIEW_GAMMA env selects DAC gamma (1.25 live-renderer legacy
  vs 1.7 per the original GAMMA.C) for A/B against the real pod.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:34:02 -05:00
CydandClaude Fable 5 afc3fd839e Vendor dpl3-revive: the Division/DPL3 renderer, now ours
Bring the graphics-dev collaborator's dpl3-revive into the repo as first-class
project code (they've handed it off; it's ours now). This is the proven
Division renderer that our in-process rt_draw has been trying to be.

What's here:
- parser/  B2Z/V2Z/SVT/SCN/SPL/BGF/BMF/BSL decoders (pure Python).
- spec/    reverse-engineered format + the definitive VelociRender wire
           protocol (from the original DIVISION source, matches our live
           VPX node/action tables exactly).
- source-ref/  read-only copies of the original DIVISION C (BIZREAD.C,
           DPLTYPES.H, DPL.H) that define the formats.
- patha/   the "virtual VelociRender board": vrboard.py (24-action protocol
           server), vrview.py (numpy software rasterizer, the reference),
           vrview_gl.py (moderngl GPU backend, 832x512@60Hz), plus the
           run/replay/regress tooling and evidence renders. Drives FLYK/BLADE/
           Star Trek demos AND our btl4opt/rpl4opt game binaries.
- viewer/  WebGL archive generators (.py); prebuilt HTML/data regeneratable.
- samples/ small test models/textures.
- bt*.raw.bin  real BTL4OPT arena wire captures (kept for offline renderer
           testing/regression against OUR game).

.gitignore keeps the multi-hundred-MB demo capture dumps + debug logs +
regeneratable viewer bundles out of history (they stay on disk).

Phase 0 of the integration is validated: their board decodes our bt8 capture
with zero errors (3748 nodes, 507 instances, 4 mechs) and renders our arena
(terrain/dome/sky, correct Division DAC gamma). Plan + status in memory;
integration continues in emulator/RENDERER-COLLAB.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 22:06:25 -05:00
CydandClaude Fable 5 9536d4cbc0 NET: full networked mission runs end-to-end; fix blank VDB heads (NIC/VDB port clash)
Console queues a mission -> egg over the wire -> pod loads + runs it -> all
cockpit heads render -> mission ends on the console timer. Four fixes:

1. ne2000.cpp: don't BX_PANIC on the TCR inhibit-CRC / auto-tx-disable bits.
   A full production boot runs the packet driver's internal loopback
   self-test, which sets those bits; Bochs' NE2000 aborted the whole
   emulator. Record them in TCR state instead (harmless for an emulated NIC;
   pcap/host does framing+CRC). Also fixes a latent coll_prio bit-4 vs bit-3
   round-trip bug. Committed copy in vpx-device/.

2. Confirmed the mission-load page fault (00FF:219D) was RIO-OFF; booting
   with the RIO live (net_full.conf) loads and runs the mission cleanly.

3. net_loop.conf + net-boot/loop.bat: GO.BAT-style loop so the pod stays
   connected to the console and picks up missions as they're queued (the
   real pod relaunches netnub after each mission/idle disconnect).

4. HEADLINE: blank MFD/radar heads were an I/O port collision. The VDB
   video splitter is hardwired at 0x300-0x31A (palettes 0x300/0x308/0x310);
   the NE2000 at nicbase=300 swallowed the game's VDB palette writes ->
   vdb_pal stayed zero -> pal_draw decoded every head to black. Same VDB
   spam corrupted NIC RX, dropping the console EndMission (mission overran
   its timer). Fix: move the NIC to 0x340 (DOSBox nicbase=340 + DOS NET.CFG
   PORT 340; must agree). VDB keeps 0x300. Config-only, no rebuild.

Adds: net_full.conf, net_loop.conf, net-boot/ (ODI drivers, NET.CFG@340,
loop.bat, README), vpx-device/{ne2000,ethernet_pcap}.cpp; updates NET-NOTES.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 21:18:42 -05:00
CydandClaude Opus 4.8 e12bfe1d3a NET milestone: real console->pod mission egg over the wire (+ mission-load crash)
Captured a real mission egg delivered from the SheepShaver console to the
DOSBox pod on TCP 1501, no -egg bypass: 8x ReceiveEggFileMessage chunks,
7514 bytes, reassembled byte-perfect (declared notationFileLength=7514).
The egg is the operator's own mission (BattleTech / cavern / night /
freeforall, pilot "cyd", vehicle madcat). This closes the networking
workstream end to end.

- net-tools/decode_egg.py: reassemble an egg from a captured console->pod
  TCP payload hex dump (skips interleaved StateQuery polls).
- net-tools/captured_cavern_mission.egg: the delivered egg.
- NET-NOTES.md: milestone writeup + the pod's mission-LOAD crash. The pod
  faults loading the mission (page fault, wild ptr 0xFF008B5B, exception
  000E at game 00FF:219D, NetNub Munga exit 14) -- a game-side bug in the
  mission-load path, separate from networking. Leading suspect: RIO was
  disabled for this run and the player vehicle/control setup derefs null.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 17:41:34 -05:00
CydandClaude Fable 5 bda2f7b8b3 Networking WORKS: real console <-> real pod over the emulated wire
The emulated SheepShaver console and DOSBox pod now exchange the live
console protocol on TCP 1501. Required chain: rebuild the DOSBox pcap
backend + launch with C:\Windows\System32\Npcap on PATH (npcap DLL
location); a two-TAP Windows bridge (single shared TAP fails); TAP2
MediaStatus=Always-Connected; and binding the pod's pcap to the BRIDGE
MINIPORT (not a member TAP -- member-injected frames aren't re-forwarded),
via realnic=DB5521D (letter-leading GUID fragment; leading-digit is parsed
as an interface index). Captured + decoded the real protocol values
(StateResponse clientID=5/flags=1/host=0/state=1/app=1=BattleTech), which
corrects the earlier synthetic guesses. Full writeup in NET-NOTES.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 17:14:48 -05:00
CydandClaude Fable 5 929b6bc267 Networking: add egg_capture.py — console->pod protocol capture tool
Listens on TCP 1501 as a stand-in pod, logs the console's egg-delivery
bytes, and auto-decodes each NetworkPacket in both byte orders to pin the
framing + PPC/x86 endianness (the two open caveats). Works whether the
console reaches it via a slirp gateway redirect or a bridged segment.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 23:17:15 -05:00
CydandClaude Fable 5 5a2c4b589f Networking: note console VM standup (SheepShaver/OS9.0.4) + TAP bridge plan
Records that Router mode is NAT (won't reach the pod) and the console<->pod
link needs bridged TAP on both ends: console TCP/IP manual 200.0.0.1, pod
DOSBox-X switched from slirp to pcap on the same segment.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 23:11:46 -05:00
CydandClaude Fable 5 b86fea71e0 Networking: determine Console 4.10 OS compatibility from the binary
PEF imports (InterfaceLib/MathLib/ObjectSupportLib only; no AppearanceLib,
no Open Transport libs) plus the resource-fork "MacTCP or OpenTransport"
Gestalt check show it is a classic PPC PowerPlant app: runs System 7.1.2
through Mac OS 9 (practical floor 7.5), classic MacTCP API but happy with
either stack. Recommended SheepShaver target: System 7.5.5/7.6.1 with a
7100/7500/8500 old-world ROM, TCP/IP set to 200.0.0.1.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 22:35:01 -05:00
CydandClaude Fable 5 e1d44251da Networking: decode egg-delivery protocol from source; archive console SW
Decoded the console<->pod message layout from the MUNGA framework headers
(the send/recv impl did not survive -- only headers + a test harness):
NetworkPacket = 16B NetworkPacketHeader + a Receiver::Message; the egg is
delivered as ReceiveEggFileMessage chunks (seq/totalLen/thisLen +
notationData[1000]), a full egg packet = 1040B (matches the VPX nb<=1040
cap). Console splits the mission notation file into <=1000B chunks; pod
reassembles + ACKs. Two bytes-on-the-wire details (stream framing +
PPC/x86 endianness) flagged for the first live capture. Full byte tables
in NET-NOTES.md.

Also moves the extracted console software (Console 4.10 PPC app + per-venue
Console.ini + fonts/logs, resource forks preserved) into
410console/4_10-console-extracted/.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 22:21:06 -05:00
CydandClaude Fable 5 5b44ede702 Networking: console SW extracted, TCP port 1501 found, pod = Puck
Console 4.10 (PowerPC PEF/CodeWarrior) + Console.ini extracted from the
.sit. Console.ini answers the open protocol question: the console<->pod
TCP port is 1501. Full cockpit endpoint roster recorded; our emulated pod
200.0.0.113 is the cockpit Puck. The real 6100 does not boot but is no
longer needed -- run Console 4.10 under SheepShaver. Only remaining
protocol unknown is the on-stream message framing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 22:12:49 -05:00
CydandClaude Fable 5 3e838bd4c7 Networking notes: console emulator = SheepShaver (real HW is a 6100/66)
The ops console is a Power Macintosh 6100/66 (PowerPC) -> SheepShaver, with
the caveat that the 6100 ROM is incompatible (use a 7100/7500/8500 old-world
ROM; PPC apps are ROM-agnostic). Plan to leverage the real 6100: image its
drive for a faithful SheepShaver console and/or bridge it live to the
pcap-pod to capture the real egg protocol.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 22:07:10 -05:00
Cyd 49bc526732 Networking M1: pod boots on the network path (no -egg) under emulation
NE2000 + Novell ODI chain (lsl/NE2000 MLID/odipkt) works against the
emulated card (odipkt at SINT 0x60, Ethernet_II). netnub -f btl4opt spawns
the game as btl4opt
2026-07-04 21:43:00 -05:00
CydandClaude Fable 5 5e0f9c8061 Networking recon: map WATTCP/NetNub pod stack + emulator bring-up plan
The pods do TCP/IP over Ethernet (WATTCP + NetNub real-mode server;
ops console is master, pushes mission eggs to pods over TCP). Pod is a
static host on an isolated 200.0.0.0/24 LAN (200.0.0.113, console
200.0.0.1); -egg is the dev bypass of this path. Fork already has NE2000
+ pcap/slirp backends; since the emulated card is NE2000 not PCI Lance we
skip the Novell ODI chain and load a Crynwr NE2000 packet driver directly.
NET-NOTES.md has the full architecture + milestone plan (headline goal:
host-side stand-in console pushes an egg over the wire, no -egg bypass).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 21:27:10 -05:00
CydandClaude Fable 5 3d5892c00f RIO firmware: build + verify patched image (reply-wedge fix)
make_patch.py applies the two-site fix to RIOv4_2.bin (asserting original
bytes first) -> RIOv4_2_patched.bin (23 bytes changed). Re-disassembling
and diffing confirms the change is confined to $D9DD, $DA21-$DA2E, and the
$DFF0 stub with no downstream desync. Clears the reply-in-progress latch
$2521 on every teardown so a stress collision no longer leaves the board
mute to analog. Flash directly to the DIP-28 W27C512; static verification
only -- dynamic RIO_TAP mash test pending the burned chip.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 21:14:07 -05:00
CydandClaude Fable 5 9fa5d101e7 RIO firmware: drop stray disasm.stderr, ignore *.stderr
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 20:42:49 -05:00
CydandClaude Fable 5 34383f3f2c RIO firmware: disassemble v4.2, find the reply-wedge root cause
68HC11 recursive-descent disassembler (disasm_6811.py, follows the
pointer-based RX/TX state dispatch) + full disassembly + analysis doc.

Root cause of the stress wedge: an orphaned reply-in-progress latch
($2521). It gates every analog request ($D758); it is set when a reply is
generated ($D84C) but the 4-retry give-up path ($D9DD -> $DA2F) tears down
reply state without clearing it, and the success teardown ($DA00) clears
it only conditionally on $2522. Once leaked, all analog requests are
dropped -> board mute, while RX/event stays alive; only the game-start
host-reset command ($C686) clears it -- matching the field button-resync
ritual exactly. Proposed minimal in-place fix (clear $2521 on every
teardown) documented with byte patches and a hardware validation plan;
untested pending a spare EPROM. RIOv4_2-ANALYSIS.md has the details.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 20:42:37 -05:00
CydandClaude Fable 5 d0b53e93dd RIO firmware notes: exact EPROM part (AM27C512-150) + replacement pick
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 20:22:14 -05:00
CydandClaude Fable 5 673cebf3b8 RIO: firmware v4.2 dump (Toshiba TMP68HC11) + first-look analysis
RIOv4_2.bin dumped from our own board EPROM (64KB, code $C000-$FFFF).
Vector table confirms 68HC11: RESET->$C000, SCI serial interrupt->$D630 =
the protocol state machine entry for the planned disassembly. Board patch
plan steps 1-2 done (RIO-NOTES.md updated); next: disassemble from the
SCI handler, find the reply-path wedge (button/event path survives it),
patch, burn to a fresh EPROM, preserve the original.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 20:21:42 -05:00
CydandClaude Fable 5 db7745fcd0 sda4: commit the Glaze developer hard-drive dump
Un-ignored: the dev drive is the ground truth the restoration and
emulator work constantly reference (DPL3/LIBDPL + VRENDER i860 renderer
source, BT/RP live+dev game trees, VGL_LABS pod boot, scene/audio
content). Kept in-repo for the pod-owner community.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 19:41:15 -05:00
CydandClaude Fable 5 504aef88d4 ALPHA_1: commit the live production-system working tree
Un-ignored: this is the working copy the emulator actually boots (patched
BTL4OPT.EXE v4 lineage + .orig/.nop14/.pre_idle/.pre_limit backups,
TESTARN.EGG arena1 test egg, REL410 BT+RP trees, VGL_LABS pod boot bats,
VWETEST factory test suites, SB16 Creative utilities). The pristine
untouched image remains ALPHA_1.zip.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 19:40:34 -05:00
CydandClaude Fable 5 a0a4260fd4 Sound: dual-AWE32 EMU8000 emulation -- the pod has audio
Vendored 86Box EMU8000 core (GPL-2, emu8k.cpp/.h + shim) plus vweawe.cpp:
two cards at the production addresses (0x620/0x640 register triplets),
rear-card DSP/mixer stub at 0x240, synthesis on an autonomous render
thread with direct winmm output so sustained voices ride through
emulation-thread stalls (RIO staging retries) like the real silicon did.
WC sample-counter interpolation between render chunks keeps HMI SOS
busy-waits fast. VWE_AWE32/VWE_AWE_ROM/VWE_AWE_RAM_KB/VWE_AWE_SHIFT/
VWE_AWE_LEAD_MS/VWE_AWE_DUMP/VWE_AWE_LOG env knobs.

emulator/roms: the AWE32 1MGM GM ROM dumped from our own pod card (SF2)
plus the reconstructed raw image the emulated EMU8000 loads. The HMI
driver refuses the AUDIO*.RES SoundFont upload without it (banks declare
irom=1MGM) -- that was the root cause of the first silent runs; full
debug chain in SOUND-NOTES.md. Repo serves the pod-owner community only.

.gitignore: drop the ROM excludes and un-ignore ALPHA_1/ and sda4/
(committed separately).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 19:40:15 -05:00
CydandClaude Fable 5 dabc204d0d VPX render: port the restoration gallery shading model; renderer collab doc
Device renderer (vpxlog.cpp, commit-copy of the fork source):
- View-flush fog decode (enable/near/far/rgb at d+72.., mode 5 linear,
  garbage-guarded; VPX_NOFOG=1 diagnostic) applied per fragment.
- Full dpl_MATERIAL parse: emissive/ambient/diffuse/opacity/specular/
  shininess (opacity+specular parsed, not yet applied); fixed-offset
  texture/ramp refs with lazy resolution, rebake on material/ramp reflush.
- Gallery shading model (restoration/gallery_template.html) as a GLSL 1.10
  program over the existing immediate-mode path, fixed-function fallback:
  c = (matAmb*sceneAmb + matDiff*mix(ramp.lo,ramp.hi,acc))*tex + matEmis,
  linear fog with immunity knob. Textured polys use an identity light-ramp
  (texels already baked through the material ramp). Newell flat normals for
  polys without wire normals. Interim sun/ambient until the light node is
  decoded: VPX_AMBIENT / VPX_SUN env overrides.

RENDERER-COLLAB.md: shared working doc with the external-renderer team --
verified FIFO action/node tables, struct offsets, scene assembly and
coordinate conventions, available data taps, open questions (incl. the
type-7 object-vs-light flush conflict).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 16:41:16 -05:00
CydandClaude Fable 5 e2005502ff RIO: gauge confs to priority=higher,higher
highest,highest (HIGH_PRIORITY_CLASS) starved the host desktop; with the
v3 idle-window and v4 retry patches a rare dropout self-recovers, so
ABOVE_NORMAL both ways is the better trade.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 16:41:02 -05:00
CydandClaude Fable 5 301f381305 VDB: exploded 7-display desktop mode (VPX_EXPLODE=1)
New layout mode showing every cockpit display as its own desktop
window -- the two MFD heads split into their individual color wires,
which is what the pentapus cable does on the real pod:

- wins 5-9 = the five mono MFDs (win5 LL = HEAD A red, win6 LR =
  HEAD A green, win7 UL = HEAD B red, win8 UC = HEAD B green,
  win9 UR = HEAD B blue), each decoding framebuffer bits 8-15 through
  its head's palette and rendering its single wire as green-phosphor
  brightness (G=v, R=B=v/8).
- Radar (win0) rotated 90 degrees clockwise and shown portrait
  480x640 -- the pod's radar CRT is mounted sideways -- centered
  between the two lower MFDs.
- All displays at native size: MFDs 640x480, uppers at
  (20,20)/(680,20)/(1340,20), lowers at (20,560)/(1340,560) aligned
  under the outer uppers; radar at (760,560); Division main 800x600
  at (2020,20).
- The DOSBox SDL main screen is auto-parked centered under the
  Division window (one-shot EnumWindows by title + SetWindowPos).
- Geometry overridable per window via VPX_WIN<g>/VPX_MAIN as usual;
  win<g>.bmp dumps cover g=5-9, radar dumps rotated as displayed.
  VPX_COCKPIT takes precedence if both modes are set; cockpit and
  debug layouts unchanged (regression-checked).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 00:46:54 -05:00
CydandClaude Fable 5 377047f37d RIO working: serial wire tap, conf tuning, four-patch writeup
The RIO cockpit board now runs sustained sessions with button mashing;
dropouts self-heal in ~1-3s. Documented in RIO-NOTES.md:

- directserial RIO_TAP=<path> (host env): logs every TX/RX byte with
  host-us + emu-ms timestamps, plus config/RTS/DTR/break lines. This
  instrument found every root cause below.
- Confs: rxburst:16 restored (no-burst reply pacing made the game ACK
  ~14ms late -> board dropped on the first long analog stream; the old
  'rxburst corrupts boot' belief was the then-unpatched PCSPAK crash).
  priority=highest,highest (unfocused DOSBox was demoted and blew the
  ACK deadline).
- BTL4OPT.EXE patch lineage (in ALPHA_1/, zip left pristine):
  v2 full DISABLE_AND_DIE NOPs (v1 left the IRQ/RTS-retract prologue
  live -> first protocol error deafened the driver), v3 TXMAXIDLE 4->32
  (kills the button-press ACK-window livelock), v4 analog retry limit
  15s->0.5s (dev value was 0.2s; recovery now near-instant).
- Board firmware patch plan recorded for the EPROM-dump route.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 00:22:14 -05:00
CydandClaude Fable 5 aea8b3eab4 Archive the Mac operations console (410console)
410consoleArchive.sit is the StuffIt archive of the 4.10 operations
console that ran the show floor for both BattleTech and Red Planet on a
classic Mac. Preserved as-is; extraction/porting comes later.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 00:19:35 -05:00
CydandClaude Fable 5 fa895afc0f Preserve ALPHA_1.zip (production-system image); ignore __pycache__
ALPHA_1.zip is the archived resource behind the git-ignored ALPHA_1/
working directory (the patched production hard-drive image the
emulator mounts). Also ignore Python __pycache__/ dirs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 22:35:09 -05:00
CydandClaude Fable 5 7670d40b37 VDB heads: 4-head cockpit layout (VPX_COCKPIT=1), drop exploratory windows
- VPX_COCKPIT=1 places the four VGA heads as borderless windows:
  Division main 800x600 @ 0,0; radar (win0) 640x480 @ 800,0; MFD heads
  win3/win4 640x480 @ 1440,0 / 2080,0 (heads 3+4 are driver-spanned
  into one 1280x480 canvas). VPX_MAIN / VPX_WIN<g> = x,y[,w,h]
  overrides any window without a rebuild; default debug layout kept.
- Remove exploratory win1/win2 (bits 0-7 via static palettes); keep the
  0/3/4 numbering so win<g>.bmp dump names stay stable.
- Sync commit copy with the build tree: per-head palette decode in
  pal_draw() and device-side BMP capture (VPX_DUMPDIR).
- RIO-NOTES: document the PCSPAK DISABLE_AND_DIE patch (error-3 crash
  on RIO resets); restore the terrain-shadow section heading it ate.
- Add gauge_rio{,_log}.conf launch configs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 22:30:33 -05:00
CydandClaude Opus 4.8 12d2952e9f VDB: palette-reload delta probe (test palette-animation hypothesis)
On each palette reload, diff against the previous captured palette and log how
many of the 256 entries changed plus the first few index:old->new. Confirms
the static/dynamic split: pal1/pal2 load once (static base structure -- red in
odd entries, etc.), pal0 is rewritten ~28x. In this capture pal0 is doing the
intro FadeToWhite -- ~216/256 entries ramping in lockstep from 0 to ~60/63 --
i.e. animating the whole display brightness via the palette without redrawing
the framebuffer. Selective per-element flashing (targeted small deltas) would
need an active mission to observe; this probe is the instrument for it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 20:31:51 -05:00