mirror of
https://github.com/jkdansereau/goldeneye-pc-port.git
synced 2026-10-24 00:02:45 +02:00
Root cause of the "doesn't recover after the alarm stops" half of the user's D207 report (distinct bug from D207's voice-pool question). struct field bondview.h:200 `s32 field_A48` is used as a SECOND ALSoundState* sound-handle slot for the player's double-buffered per-hand fire sound (gunfire.c:3186-3200). sndPlaySfx stores the new state through `&field_A48` as an 8-byte `pendingState->link.next = nextState`; as s32 that write tears into the adjacent field_A4C (the auto-fire cadence timer, rewritten every frame). After enough double-buffered fire cycles field_A48 holds a value that is neither 0 nor a valid pointer, so the `else if (field_A48 == 0)` re-arm gate never fires again and no further player gunshot is issued. Evidence: user Bunker audiotrace.log — silenced-PP7 idx-46 sndPlaySfx requests stop dead at log line 18930/25086 while all other SFX continue; the player-gun slot 0x70076630 is then caught holding a torn value 0x000001db00000000 (field_A48=0 + field_A4C=0x1db read as one word). Fix (D3x ABI/layout, #ifdef PORT): declare field_A48 as ALSoundState* under PORT, s32 verbatim under #else. hands[] is runtime-only state (g_CurrentPlayer), never ROM-serialized, and all downstream fields are accessed by member name — widening 4 bytes is layout-safe. The (struct ALSoundState *) casts at the use sites become no-ops and stay for a minimal diff. Build clean (gunfire.c + full link). Runtime verification owed: replay the Bunker firefight, confirm idx-46 requests continue for its full duration. Claude-Session: https://claude.ai/code/session_01U7gyYC3pcatXHhD1kPCgsR