410console: BattleTech egress-hold addendum -- issue closed (~3s hold)
Decoded/disassembled finding from the TeslaRel410 side, verified against a live DOSBox BTL4OPT pod driven by this console: the post-mission egress window is a compiled ~3 s (stage-1 timer), not ~30 s, and byte-identical across all four BTL4OPT builds. Marked won't-fix -- the floor egress lamps no longer exist on any surviving cockpit. Console takeaway unchanged: send StopMission promptly at timer end; the pod handles its own (short) close, no egress delay to implement. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
# Addendum: mission-close / egress-hold — decoded + disassembled (2026-07-10)
|
||||
|
||||
From the TeslaRel410 side. Verified against a live DOSBox BTL4OPT pod run
|
||||
BY THIS .NET CONSOLE over the host bridge (it works). Full writeup:
|
||||
TeslaRel410/emulator/NET-NOTES.md.
|
||||
|
||||
> **ISSUE CLOSED 2026-07-10 (won't-fix, operator decision).** The floor
|
||||
> egress lamps no longer exist on any surviving cockpit, so the hold has
|
||||
> no restoration value. FINAL, corrected finding (supersedes the "~30s"
|
||||
> phrasing below): the pod's post-mission egress window is a compiled
|
||||
> **~3 seconds** — the game exits at its stage-1 timer (Step-0 proven:
|
||||
> a no-loop single-shot boot still held 3.9s then the game self-exited),
|
||||
> and the deeper 30s timer is never reached. Byte-identical across all
|
||||
> four BTL4OPT builds, so nothing regressed. **Console takeaway is
|
||||
> unchanged and simple: send StopMission(RunBattleTech) promptly at your
|
||||
> timer end; the pod handles its own (short) close. No egress delay to
|
||||
> implement.** The rest of this file is preserved for the record.
|
||||
|
||||
## Bottom line for TeslaConsole
|
||||
|
||||
**The customer-egress window is a HARDCODED ~30s timer inside the GAME,
|
||||
not the console.** You do NOT need to implement the egress delay. Just
|
||||
send `Application__StopMissionMessage` promptly at mission end with
|
||||
`RunBattleTechExitCodeID` (=3), and the pod runs the whole authentic
|
||||
sequence itself: egress lamps ON -> ~30s hold -> lamps OFF -> exit ->
|
||||
GO.BAT relaunch. The console's only timing responsibility is not to send
|
||||
StopMission too EARLY (let the mission actually end first).
|
||||
|
||||
## The sequence (game side)
|
||||
|
||||
1. Mission end -> game fades to black hold, sends the wrap-up
|
||||
(ConsolePlayerMechScoreUpdate / ConsoleBTTeamScoreUpdate /
|
||||
RankAndScore). Its StateResponse to your 1/s StateQuery flips state
|
||||
0 -> 2 (mission-over/hold). It waits INDEFINITELY here for you.
|
||||
**CAUTION — "mission end" is NOT the pod's own clock.** Bench-confirmed
|
||||
2026-07-09 (12s mission via this console): the pod does NOT self-end;
|
||||
the egg `length=` only drives the cockpit clock DISPLAY, which hits 0
|
||||
and counts back UP while play continues. The console is the game's
|
||||
sole timekeeper — this hold state is only ever entered off the
|
||||
console's close (or an in-game end condition), so in practice steps
|
||||
1-2 collapse: the console's StopMission at ITS timer end triggers the
|
||||
fade/wrap-up/lamps directly (see step 3).
|
||||
2. You send `Application__StopMissionMessage(ExitCodeID)`.
|
||||
3. `StopMissionMessageHandler` (BTL4OPT.EXE @0x47b864, disassembled):
|
||||
- calls mission-shutdown/EndMission (0x44eeb4)
|
||||
- turns the RIO egress lamps ON (routine @0x47bba8, flag=1; lamps
|
||||
0x16/0x17/0x1e = the floor/entry cluster; the "LightsOut" string
|
||||
@0x4fd5ac names this family)
|
||||
- schedules the lights-out+exit for `now + 30.0*timebase + 0.5`
|
||||
(30.0f constant @0x47b8e4) -- the customer-egress hold
|
||||
4. ~30s later the timer fires -> lamps swept off -> game exits with the
|
||||
exit code -> pod's BAT loop dispatches it (RunBattleTech = relaunch).
|
||||
|
||||
## Console message set + exit codes (from CODE/RP/MUNGA/APPMSG.HPP)
|
||||
|
||||
Messages: StateQuery, CheckLoad, RunMission, **StopMission**, KeyCommand,
|
||||
SuspendMission, ResumeMission, LoadMission, Abort.
|
||||
|
||||
`ExitCodeID` (the game's exit status = what the pod's BAT loop runs next):
|
||||
```
|
||||
Null=0, Abort, RunRedPlanet, RunBattleTech, RunSinglePlayerRedPlanet,
|
||||
RunSinglePlayerBattleTech, DisplayMainTestPattern, DisplayAuxTestPattern,
|
||||
TestPlasmaDisplay, ResetRIO, RunAudioTest, RunNortonDiskDoctor,
|
||||
CheckDiskUsage, RefreshRedPlanet, RefreshBattleTech, ChangeScreenMode,
|
||||
SoftwareReset, ClearCrashlog, KillSpoolFile, RunRedPlanetCamera,
|
||||
RunBattleTechCamera, RunRedPlanetMissionReview, RunBattleTechMissionReview
|
||||
```
|
||||
= a whole remote-operations menu the console UI could expose (RIO reset,
|
||||
test patterns, plasma test, disk tools, camera/mission-review launches).
|
||||
|
||||
## Notes / open
|
||||
|
||||
- A configurable *pre*-StopMission delay is still fine to expose, but the
|
||||
~30s customer window itself is the game's and is authentic at 30s.
|
||||
- Measured lamp-on-to-sweep was only ~3.4s in two live runs; that sweep
|
||||
was likely the teardown GeneralReset, with the real 30s timer firing
|
||||
past the tap window. To confirm on the TeslaRel410 side: one mission
|
||||
with a 90s+ RIO serial tap past mission end (btdis2.py found the
|
||||
constant; a live tap confirms wall-time).
|
||||
- Bonus authenticity: the floor lamp is ALSO entry lighting -- on from
|
||||
game-ready until the mission drops (customer climbs in lit).
|
||||
- Bench 2026-07-09 (12s mission): pod clock counted UP past 0 with play
|
||||
continuing until the console's stop — confirms the console is the sole
|
||||
timekeeper and step 1 never fires off the pod's own clock. If a
|
||||
self-end path exists in the binary it wasn't reachable with our egg.
|
||||
- Cross-ref: the BT411 up-port source (engine/MUNGA/APP.cpp ~1634) has a
|
||||
TWO-stage StopMissionMessageHandler (stop#1 while Running -> EndingMission
|
||||
+ lamps; stop#2 while Ending -> Stop()/exit; +30s LightsOut = lamps off
|
||||
only). The shipping BTL4OPT.EXE disassembly above (one stop -> lamps +
|
||||
scheduled exit at +30s) is authoritative for the DOSBox pod; the up-port
|
||||
evidently diverges — worth knowing if BT411-built binaries ever drive a
|
||||
real pod.
|
||||
- A console-side "egress hold delay" (wait between console timer zero and
|
||||
the StopMission send) was prototyped in TeslaConsole 2026-07-09 and
|
||||
REVERTED: since the pod plays until stopped, that window is overtime
|
||||
play, not lamps-on time. The game's own 30s window is the authentic
|
||||
egress hold.
|
||||
- CROSS-BUILD DISASM (TeslaRel410 side, 2026-07-10, stopmission_cmp3.py):
|
||||
the StopMission close is BYTE-IDENTICAL across all four BTL4OPT builds
|
||||
-- BTLIVE (May-96), BTRAVINE (Sep-96), BTDAVE, Rel410 -- so no build
|
||||
regressed it (this settles the operator's "did Rel410 cut the hold?"
|
||||
question: no). Each build's dispatched outer handler (Rel410 @0x47c2c4)
|
||||
is the re-entrant two-stage one and carries BOTH a 3.0f and (via the
|
||||
inner @0x47b864) a 30.0f constant. Confirms the up-port's two-stage
|
||||
structure at the binary level. Whether 30s is honored live is still
|
||||
open: our RIO tap saw only ~3.4s of lamp-on (the 3.0f stage) before the
|
||||
exe recycled -- the 30s LightsOut may be pre-empted by teardown in the
|
||||
loop-conf flow. Not console-actionable either way (prompt StopMission is
|
||||
correct); noted for completeness.
|
||||
Reference in New Issue
Block a user