From bfc072b56f4975cd432a80260e2497a25b1c7799 Mon Sep 17 00:00:00 2001 From: Joe DiPrima Date: Mon, 3 Aug 2026 20:29:16 -0500 Subject: [PATCH] #118: the ENG-PAGE EJECT KEY ejects -- page-gated intent completion The decode that settles it: the eng-page side-key functions align key-for- key with the engEject lamp map (selectGenA-D = 0xF-0xC, EJECT = 0x0B, GEN-MODE = 0xA, COOLING = 0x9, BACK = 0x8; banks 2/3 at 0x27-/0x7-), and the streamed weapon pages route the same key to EjectAmmo -- so 0x0B/0x23/ 0x03 ARE the authored EJECT position. On generator pages the shipped stream leaves the key with NO live route (msg 9, no handler anywhere): eject was UNFINISHED in 4.10 (the evaluator was dead code -- the arcade never armed panic at all). Intent-completion [T3, marked]: while PANIC is armed AND that bank displays an ENGINEERING page (kBTEngModeMask bits -- the same gating the alarm lamps use), the flashing EJECT key fires the pilot-keypad eject. Any other page: authored function untouched (the two field regressions came from skipping the page gate). Verified: armed + QUAD page + 0x0B press -> no eject (gate holds); panic / numpad / Backspace unchanged. Co-Authored-By: Claude Fable 5 --- engine/MUNGA_L4/L4PADRIO.cpp | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/engine/MUNGA_L4/L4PADRIO.cpp b/engine/MUNGA_L4/L4PADRIO.cpp index 5fe5ac0..ceeea75 100644 --- a/engine/MUNGA_L4/L4PADRIO.cpp +++ b/engine/MUNGA_L4/L4PADRIO.cpp @@ -468,19 +468,38 @@ void // PANIC (0x3D) -> pilot-keypad key. The binary's ONLY pilot-eject input // is keyboardGroup[KeyboardPilot].Add(mode 0x200000, mech, msg 0x19) - // (FUN_004d266c; exhaustive scan: no other 0x200000 consumer, and the - // streamed .CTL tables carry NO 0x200000 records either -- the MFD soft - // keys keep their authored per-page functions even while armed, so they - // must NEVER route here; two field-caught regressions (DISPLAY, then the - // weapon ammo-eject soft key 0x0B) came from over-routing them). The + // (FUN_004d266c; exhaustive scan: no other 0x200000 consumer). The // guarded PANIC key has no button-space consumer anywhere in the image, // so on the pod it reported through the pilot keypad matrix -- this is - // that wire. The flashing engEject soft-key LAMP (0x85 alarm code) is - // the INVITE indicator; the press that ejects is panic / any pilot- - // keypad key while armed. + // that wire. if (address == 0x3D && pressed) EmitKeypad(LBE4ControlsManager::KeyboardPilot, 0); + // THE ENG-PAGE EJECT KEY [T3 intent-completion, 2026-08-03]: physical + // side keys 0x0B / 0x23 / 0x03 are the eng-page EJECT function position + // (engEject lamp 0x85 = kBTEngBankTop - 4; the streamed weapon pages + // route the same key to EjectAmmo msg 0xB, and the lamp-name/function + // columns align key-for-key). On GENERATOR eng pages the shipped stream + // gives this key NO live route (msg 9 -- no handler in any class table): + // eject was UNFINISHED in the 4.10 binary (the permission evaluator was + // dead code, so panic mode never armed in the arcade at all). Complete + // the authored intent: while PANIC mode is armed AND that bank shows an + // ENGINEERING page (kBTEngModeMask bits -- the same per-page gating the + // alarm lamps use), the flashing EJECT key fires the pilot-keypad eject. + // On any other page (quad select, weapon pages) the key keeps its + // authored function -- the two field regressions came from skipping the + // page gate. + if (pressed && (address == 0x0B || address == 0x23 || address == 0x03)) + { + ModeMask mask = application->GetModeManager()->GetModeMask(); + unsigned engBits = + (address == 0x0B) ? 0x001Eu : // bank 1: eng modes aux 1-4 + (address == 0x23) ? 0x03C0u : // bank 2: eng modes aux 5-8 + 0x7800u; // bank 3: eng modes aux 9-12 + if ((mask & 0x200000u) != 0 && ((unsigned)mask & engBits) != 0) + EmitKeypad(LBE4ControlsManager::KeyboardPilot, address & 0xF); + } + RIOEvent event; event.Type = pressed ? ButtonPressedEvent : ButtonReleasedEvent; event.Data.Unit = address;