#118 crash fix: the eng-eject page gate moves into the game-thread RIO drain
The page-gated eject query ran in the window-click thread (PadRIO EmitButton) and dereferenced the TU-local application global -- NULL there under the /FORCE duplicate-symbol layout -> c0000005 at mode-manager +0x50 the moment the operator pressed the eng eject key (field crash, live.log [crash] record). Moved into LBE4ControlsManager::ProcessRIOEvent's ButtonPressedEvent branch, where mode_mask is already resolved on the game thread; PadRIO now only queues events. Same gate semantics (armed + that bank's ENG-page mode bits); verified no-crash + no-eject on the quad page. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
bfc072b56f
commit
fa3d634ed3
@@ -2630,6 +2630,32 @@ void
|
||||
// Save 'pressed' mode mask for 'release'
|
||||
//----------------------------------------
|
||||
buttonActivateModeMask[rio_event.Data.Unit] = mode_mask;
|
||||
|
||||
// THE ENG-PAGE EJECT KEY [T3 intent-completion, #118]: side keys
|
||||
// 0x0B/0x23/0x03 are the eng-page EJECT position (engEject lamp 0x85
|
||||
// = kBTEngBankTop-4; the streamed weapon pages route the same key to
|
||||
// EjectAmmo). Eject was UNFINISHED in the 4.10 binary (the armed
|
||||
// mode never rose), so the generator-page press has no authored
|
||||
// route; complete the intent here IN THE DRAIN (game thread --
|
||||
// mode_mask in hand; a first cut queried the mode manager from the
|
||||
// window-click thread and crashed on the unbound TU global): while
|
||||
// PANIC is armed AND that bank shows an ENG page, forward the press
|
||||
// as a pilot-keypad key -- the binary's one armed eject binding.
|
||||
{
|
||||
const int a = rio_event.Data.Unit;
|
||||
unsigned engBits =
|
||||
(a == 0x0B) ? 0x001Eu : // bank 1: eng modes aux 1-4
|
||||
(a == 0x23) ? 0x03C0u : // bank 2: eng modes aux 5-8
|
||||
(a == 0x03) ? 0x7800u : 0u; // bank 3: eng modes aux 9-12
|
||||
if (engBits != 0
|
||||
&& ((unsigned)mode_mask & 0x200000u) != 0
|
||||
&& ((unsigned)mode_mask & engBits) != 0)
|
||||
{
|
||||
ControlsKey eject_key = '0';
|
||||
Check(&keyboardGroup[KeyboardPilot]);
|
||||
keyboardGroup[KeyboardPilot].ForceUpdate(&eject_key, mode_mask);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case RIO::ButtonReleasedEvent:
|
||||
|
||||
@@ -475,30 +475,11 @@ void
|
||||
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);
|
||||
}
|
||||
// (The ENG-PAGE EJECT KEY intent-completion lives in the game-thread RIO
|
||||
// drain -- LBE4ControlsManager::ProcessRIOEvent, ButtonPressedEvent --
|
||||
// where mode_mask is safely in hand. A first cut queried the mode
|
||||
// manager HERE, on the window-click thread, and crashed on the unbound
|
||||
// TU global (field-caught 2026-08-03).)
|
||||
|
||||
RIOEvent event;
|
||||
event.Type = pressed ? ButtonPressedEvent : ButtonReleasedEvent;
|
||||
|
||||
Reference in New Issue
Block a user