#166 mechanism pinned + two input-layer fixes: Oracle's LRM jam = the ammo bin PARKED at Ejecting(3) with rounds aboard (his log: 'NoAmmo (gate2): rounds=18 binState=3', twice; eject tap cleared it exactly as the handler predicts). The MFD/HUD 'desync' is honest: the full green circle is the RECHARGE dial (untouched by the gate2 pin) and the btejam lamp keys only on weaponAlarm 5 (binary @004c9a38) -- state-7 pins show neither, authentically. The parking producer needs an unpaired eject PRESS, which pod hardware cannot make but our glass mouse layer could: (1) WM_CAPTURECHANGED now releases a held panel button when capture is stolen (Steam overlay/popups ate the WM_LBUTTONUP), (2) a new press releases any still-held previous button instead of orphaning it. Forensics: every EJECT message now logs data/bin/ejectState/binState/rounds always-on (ejects are rare) -- Friday names the producer if it recurs. Smoke: BT_EJECTTEST replays the full press/hold/dump receipt chain incl. the authentic mid-eject gate2 pin.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
18fba98298
commit
14c62f184d
@@ -1768,6 +1768,14 @@ static LRESULT CALLBACK
|
||||
}
|
||||
else
|
||||
{
|
||||
// #166: a press must never ORPHAN a previous one -- if a
|
||||
// prior button is still logically down (capture stolen by
|
||||
// an overlay/popup so its WM_LBUTTONUP never arrived),
|
||||
// release it before pressing the new one. An orphaned
|
||||
// press on the ammo-EJECT panel button is a permanent
|
||||
// weapon jam (bin parked at Ejecting).
|
||||
if (pressedAddress >= 0 && pressedAddress != a)
|
||||
PadRIO::SetScreenButton(pressedAddress, 0);
|
||||
pressedAddress = a;
|
||||
SetCapture(window);
|
||||
PadRIO::SetScreenButton(a, 1);
|
||||
@@ -1787,6 +1795,21 @@ static LRESULT CALLBACK
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_CAPTURECHANGED:
|
||||
// #166: mouse capture stolen mid-press (Steam overlay, popups, focus
|
||||
// change) -- WM_LBUTTONUP will never arrive, so release the held
|
||||
// button NOW instead of leaving its control (e.g. ammo EJECT) pressed
|
||||
// forever from the game's point of view.
|
||||
if (pressedAddress >= 0)
|
||||
{
|
||||
DEBUG_STREAM << "[glasswin] capture LOST with button 0x" << std::hex
|
||||
<< pressedAddress << std::dec << " down -- releasing\n" << std::flush;
|
||||
PadRIO::SetScreenButton(pressedAddress, 0);
|
||||
pressedAddress = -1;
|
||||
InvalidateRect(window, NULL, FALSE);
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_RBUTTONDOWN:
|
||||
if (w != NULL)
|
||||
{
|
||||
|
||||
@@ -579,6 +579,18 @@ void
|
||||
|
||||
AmmoBin *bin = (AmmoBin*)ammoBinLink.Resolve(); // FUN_00417ab4(this+0x43c)
|
||||
|
||||
// #166 forensics (ALWAYS on -- ejects are rare): every entry, with the
|
||||
// state that decides which branch runs. Oracle's field jam (bin parked
|
||||
// at Ejecting(3), rounds aboard, countdown dead) can only come from a
|
||||
// press/release sequence this line will capture -- the prime suspect is
|
||||
// a press whose bin-resolve fails falling through to the release block.
|
||||
DEBUG_STREAM << "[weap] " << GetName() << " EJECT msg data=" << message->dataContents
|
||||
<< " bin=" << (void *)bin
|
||||
<< " ejectState=" << ejectState
|
||||
<< " binState=" << (bin != 0 ? bin->GetAmmoState() : -1)
|
||||
<< " rounds=" << (bin != 0 ? bin->GetAmmoCount() : -1)
|
||||
<< "\n" << std::flush;
|
||||
|
||||
if (message->dataContents > 0 && bin != 0) // PRESS @4bb9d0/4bb9e9
|
||||
{
|
||||
bin->SetAmmoState(AmmoBin::Ejecting); // SetLevel(bin+0x194, 3)
|
||||
|
||||
Reference in New Issue
Block a user