Win, Lose & Pause
10.1Game-over detection: gmOverCheck
The run fails when the life pool empties or a fatal condition fires.
gmOverCheck (@ 0x1e6b88) runs every active frame inside
commonMapFunc; when it triggers it sets GameCondition 0x204
(game-over bit + emergency brake), which both stops the train and flags the failure. But it
first respects a suppression mask:
| Mask | Bits | Meaning |
|---|---|---|
| 0x7C2 | 1,6,7,8,9,10 | pause · undead (debug) · bit 7 (no setter found) · doors · already-game-over · short-replay — no game-over while any is set |
| 0x204 | 2,9 | the trigger itself: emergency brake + game-over, set together |
GameTask's reaction (see the loop, Chapter 4): on bit 9, gmOverFlg walks
0 → 1 (fade init) → 2 (wait for the train to actually stop, _RunMove == 0) →
setMainMapMode(6) (game-over screen), or mode 8/9 fade for the replay end.
10.2The game-over screen
gameOverMapFunc (mode 6) runs gmOverInit → gmOverFuncMain,
a five-state machine over a dedicated UI-state cluster
(DGF_GameOverUIState, base 0x6D7400) with three dispatch tables
(goFuncMain[5] @ 0x42c300, ttlFunc[4],
curFunc[3]). The screen offers continue / quit; continue copies the
retry snapshot (continueGs, the same 0x36c bytes that live in the save) and calls
setStartScore(1).
setStartScore increments a per-run retry counter; setClearData uses it
to cap the achievable clear rank for the rest of the route; a game-over
permanently costs you the best grade even if you recover. This is the mechanism behind the
game's “one clean run” pressure.10.3The station replay
Every active frame, procSReplay(_RunRoutePos) appends packed controller bits to
a 6000-frame circular buffer with 0x70-byte headers. On arrival, map mode 3
(shortReplayMapFunc, states 0–10) hides the world, shows grade/score/life, and
replays the final approach from a cinematic camera with fast-forward (the same buffer that a
continued run can reuse). The mode-7 state checks the score: pool < 1 →
failure path (clears GameCondition bits 8+10, mask 0x500).
10.4Station stop & event stops
judgeStopLine (Chapter 8) handles the platform stop. Two siblings handle
en-route stops:
eventStopLine(@0x1be6cc) — deadline-driven stop events: when a schedule deadline approaches, it fades a warning in, and if the train passes the point too fast or too late, penalizes and forces the stop. Sets theMAP_DEADLINEcondition bit (0x2000) during its fade sequence. Its stop-line crossing is what callsjudgeStopLine(distStop), observed live: a train parked 13 m short of the line never triggers it; the doors never open and the run waits, because the stop-line event hasn't crossed. Creep forward and the judgment fires with the remaining overshoot asdistStop.eventLimitStop— limit-stop flag (condition bit 0x10000): speed-check gates at fixed track locations.setStopLine(@0x1c40e8) — converts the judged distance into the displayed cm value and stores the verdict for the result screen.
10.5Pause
checkPause (@ 0x1eb3fc) (shown in full in Chapter 4's exhibit) triggers only while driving (mainMapMode==2), not in lecture/replay, on the menu
decide key (bit 0x10 of the menu key, tested as key << 0x14 < 0).
initPause sets GameCondition bit 1 in BOTH copies (immediate, so
the same frame's physics skip); pauseFunc (mode 7) runs the pause menu (resume,
restart station, quit to menu) with fade-alpha animations. TimeCtl freezes game
time while bit 1 (or replay bit 10) is set: the 0x402 mask.
10.6The ending tally
Completing the last station hands over to EndingTask (procID 4), which
tallies the run: total score, penalties per category (the accumulators from
subLifePoint), bonuses, and the final grade, then credits, using the unlocked
movie permits. From there setRsevProc returns to the menu (or loops via the
-gameloop attract flag).