mirror of
https://github.com/jkdansereau/goldeneye-pc-port.git
synced 2026-10-24 00:02:45 +02:00
docs(dev): D205 M-73 correction — Klobb is a specific in-game SMG (Skorpion, idx 106); the user's sound identifications stand; capture shows no 106 while user was punching (47-49/105 all voiced), so melee->Klobb identification is OPEN (H3 vs H4), not resolved by the 109 barrage
This commit is contained in:
1 parent
fb037b3c0c
commit
044d24a15f
1 file changed
+16
-6
+16
-6
@@ -405,7 +405,7 @@ covers D24–D69; the log continues in §H (D32 procedure, D70–D121).
|
||||
| D203 | **Steam Deck (SteamOS, x86_64 Linux) v0.1.0 release bundle: Facility (`-level_34`) crashes "after loading in as James Bond" (user bug report).** Idle repro attempts on WSL Ubuntu with the actual `dist/goldeneye-pc-port-0.1.0-linux-x86_64.tar.gz` are **negative**: 120 s idle → frame 3300+ clean exit (the intro auto-advances, so "sitting as Bond" is covered), and a ~4-min stick-forward-only run → frame 6900+ also survived. So the trigger needs real gameplay input (fire/action) or is Deck-environment-specific. **Leading suspect: the D191 family** — both known v0.1.0 field crashes are SIGSEGVs in `modelGetNodeRwData` (`model.c:478`) over a truncated/NULL `root->Parent` node link, and both were triggered by *gameplay state* (first guard kill on Bunker ii; post-cutscene on Statue), never by idling; Facility opens into the Ourumov + soldier-squad scripted beat (D193a instance), which fits the trigger profile. Alternatives: Deck GL driver path (RADV/zink vs llvmpipe) or 40/50/60 Hz timing (D193 family). **Next:** (1) WSL run under gdb with a walk+fire `GE_INPUTSCRIPT` — generate the script into a file first (earlier attempts were blocked by a `bash -lc` quoting quirk that emptied the loop var, so no fire buttons ever went out); on SIGSEGV compare the fault PC against `modelGetNodeRwData`; (2) if not reproducible on WSL, get `ge007.crash.log` from the Deck (the Linux build writes it — proven by a stale one in the smoke tree) + ask what Bond was doing at crash time; optionally a gdb run from the SteamOS terminal. | OPEN — negative idle repros only; not yet reproduced with input. |
|
||||
| D201 | **`src/libultra/audio/bnkf.c` bank/instrument/sound/wavetable relocation offsets were `s32`, truncating the real 64-bit base pointer.** `alSeqFileNew`/`alBnkfNew` compute `offset = (s32) base` from a heap pointer and thread it through `_bnkfPatchBank/Inst/Sound/WaveTable` as `s32 offset, table` parameters, used to rebase every embedded pointer field in a loaded bank/inst/sound/wavetable/book/loop record. On N64 (32-bit pointers) the truncation is a no-op; on PC, sign-extension of the truncated `s32` during the rebase arithmetic reconstructs the wrong 64-bit address whenever the base allocation's low 32 bits have the top bit set (~50% of allocations, allocator-dependent) — corrupting every relocated pointer in the bank file, a plausible contributor to bad model/audio pointers surfacing downstream (D191-family symptoms are a node-tree walk, not this, but the class is the same). **Fix (ABI-layer, no logic change):** widen `offset`/`table`/`woffset` and all four `_bnkfPatch*` parameters from `s32` to `uintptr_t` (`<stdint.h>`) — already this codebase's idiom for pointer-safe integers in `src/game/*.c`. No behavior change on the 32-bit N64 build. | FIXED (`src/libultra/audio/bnkf.c`) — part of the Phase-3 mixer landing, not yet build/runtime-verified in isolation |
|
||||
| D202 | **Silenced PPK plays a "slap" instead of a gunshot, PLUS user reports broader real-time audio corruption (M-52 → M-59 → REOPENED M-60 → M-61/M-62 closed the data chain, recommended close → REOPENED M-63 on a fuller symptom report).** M-56–M-62: exhaustively verified the index/bank/pointer/decode/ROM-offset/source-data chain — soundIndex 46 is correctly requested and the data is ground truth (byte-match checksum corroboration, M-62). **M-63: user's actual complaint is broader — wrong sound always plays, correct one SOMETIMES plays too (both heard together), and sounds "pile up and spirally glitch out" over a session until only a stuck looping sound (e.g. Bunker's door) remains.** Got a live build+run repro this session (`-level_09`, 60s, `GE_MIXERTRACE`+`GE_AUDIOTRACE`+`GE_AUDIODUMP`, 58 scripted PPK fires). **Ruled out voice-pool exhaustion/leak** — only 16 distinct voice slots used, properly recycled (`sndDeactivate` count tracks `sndPlaySfx` count 1:1). **Found an unexplained anomaly**: `soundIndex=109` (AK47 bolt-action SFX) fires 94 times in 60s despite no AK47 in the repro, some retriggering the same voice slot at a suspiciously uniform ~32.6ms cadence (4-in-a-row) — far faster than plausible weapon fire; looks like something re-issuing `sndPlaySfx` every audio tick instead of once per game event. Not yet confirmed as the cause of the user's symptom, but the top concrete lead. Traces preserved: `scratchpad/d202-m63/`. (Side note, not a real bug: chased a `load_bg_file` crash this session that turned out to be an incomplete test-data setup on the investigator's part — see M-63 write-up.) **M-65 PARTIALLY resolved:** the "eventual silence" cascade is root-caused and mitigated (ownerless `SOUND_FLAG_LOOPED` SFX — sound 203, `METAL_SLIDE_CLOSE_SFX`, `decayTime=-1`, played by `doorPlayCloseSound0/1` with `NULL` owner — leaks 7 of 8 voices; a 4-line guard in the preemption scan reclaims only provably-ownerless loops, measured 171→629 acquisitions), and a second independent cause is fixed (`sndCreatePostEvent` was stubbed out per D138, removing ALL distance attenuation). The audible stuck door loop is still not reproduced — every candidate mechanism ruled out by measurement (see M-65); needs a user capture at the failing door with `GE_AUDIOTRACE=1 GE_AUDIODUMP=1`. | ROOT CAUSE ESTABLISHED (M-66); DISPOSITION C IMPLEMENTED + MEASURED (M-66b) — the audible stuck loop is sound 203 (`METAL_SLIDE_CLOSE_SFX`): ROM infinite ADPCM loop (`count=-1`) + `decayTime=-1`, played fire-and-forget by `doorPlayCloseSound0/1` with NULL owner, never stored in any slot, exempt from preemption (flag 0x12) and from decay-stop scheduling, priority 0x41 makes it unstealable — **faithful N64 behaviour / original quirk, not a port bug**. 327 ms period = -550-cent pitch (keyBase 54 + detune 50 − shift 6000 → ratio 0.7278; 5248 samples @ 22050×0.7278 = 327.007 ms). M-65's guard fires only under pool pressure (twice in the user capture) and cannot silence the idle loop. **Disposition C implemented + measured (M-66b):** PC-only `AL_SNDP_PORT_EXPIRE_EVT` fades provably-ownerless infinite-loop SFX out ~2.5 s after start (2 s delay + 0.5 s fade); per-second spectral check: pre-fix drone flat at max t≈39→361 s, post-fix transient bursts with full silence between; run ends allocated=0/8. **M-67: static analysis exhausted — full-bank data scan clean (all 261), DSP audit complete vs PD, A_LOOP branch dead code in GE, reference clip B00I00S2D.wav REFUTED as an in-game capture (best waveform CC 0.19 ≈ noise; M-61's +0.999 was envelope-only correlation); new `GE_VOICEDUMP` per-voice probe + timestamped WIRE/AUDIOTRACE for the decisive runtime A/B; self-test found the offline resample direction had been inverted all along (y[k]=x[ratio·k]) and that GE "music" is an SFX-sequence system with its own ~8-sample set sharing the 8-voice pool; parked anomaly: sound 232 requested at level start produces no audible audio. **M-68 (user captures ×3): all three complaint classes verified per-voice at runtime — doors CC 0.91–0.99, PPK 46 CC 0.90–0.97, armor 81 full 833 ms vs ROM-predicted 837 ms @ ratio 0.5612; the earlier "instant death" metric was a line-count artifact (µs-timestamped `[EVT]` probe shows every STOP lands on schedule). No port bug: the heard "wrong" sounds are the original design (overlapping SFX, short decays, quick-stop truncation).** **M-69 (full-corpus exact match, 320 scripted-run requests): 286/320 CC ≥ 0.85 — every allocated voice plays the exact ROM sample at the exact ROM pitch; the initial 44 "BAD" were tooling artifacts (voicedump stamps are block-END times; coarse-slide missed sharp onsets; refs not clipped at voice death). Remaining failures = dropped allocations (no `[VOICE+]` — suspected 8-voice pool exhaustion, unverified) + shared-wavetable wire misattribution. No corruption.** **M-70 (decisive clean re-capture, 209 requests, matcher v3): every voiced request Line truncated
|
||||
| D205 | **PC plays wrong/extra SFX for gameplay events the user can A/B against N64: general gunfire has a slap/glass layer audible on PC but silent on N64; an explosion plays a soldier-scream sample; armor pickup plays a wrong sample; unarmed melee (slap) plays Klobb's shooting sound idx 106 instead of the slap effect (M-71/M-72, user by-ear + N64 A/B). M-73: user combat capture root-causes all three "wrong-sound" moments to ONE phenomenon — guards stuck in sustained ACT_ATTACK re-triggering weapon fire sound idx 109 (AK47/Spectre) 256×/30 s at fixed per-guard periods with NO corresponding bullets/impacts; the "Klobb" was never 106 (never requested); explosion 182 + armor 81 each requested exactly once and correct, but masked by the 109 barrage. Sustained-attack gate = `seen_bond_time` refreshed via `stanTestLineUnobstructed` LOS on converted geometry → leading suspect is a LOS/collision query returning clear when N64 blocks.** The playback chain is proven faithful end-to-end — M-68/M-70 exact match: every voiced request plays the exact ROM sample at the exact ROM pitch — and this session's offline harness (`scratchpad/banktest/`: real D37 converter + `diff_bank.py`) shows all 261 bank entries map identically N64→PC (base/len/type/keyMap/env, 0 mismatches). So the bug is upstream of the bank: **PC requests different or extra sound indices than N64 in the same scenario.** Ranked suspects: (a) data-driven sndID/explosion-type/item-sound fields in converted level/setup assets (pccg sidecars) differ from ROM — explosions play `sp44->sndID` from `g_ExplosionTypes[]` (`src/game/explosion.c:285`), explosion *type* comes from level data; explosion SFX are idx 169–183, a scream is outside that range; armor idx 81 verified exact in M-68, so a wrong armor sample means a different index is requested; (b) extra hit events — converted collision geometry makes bullet raycasts (D154/D135, both ABI-verified) or explosion proximity checks hit surfaces/NPCs the N64 misses → layered impact/ricochet/scream SFX; the slap+glass-over-gunshot signature is exactly the non-penetrating-OBJ-hit path (`HIT_BULLET_GLASS_SFX` idx 70 via `sub_GAME_7F064720`, `src/game/gunfire.c`). | OPEN — bank + playback exonerated (M-71); M-73 root-caused the user's three "wrong-sound" moments to guards stuck in sustained fire-sound re-triggering (idx 109 barrage, no bullets) — next: A/B whether N64 guards sustain fire in the same combat + verify `stanTestLineUnobstructed` LOS results on converted geometry vs ROM for guard→Bond segments |
|
||||
| D205 | **PC plays wrong/extra SFX for gameplay events the user can A/B against N64: general gunfire has a slap/glass layer audible on PC but silent on N64; an explosion plays a soldier-scream sample; armor pickup plays a wrong sample; unarmed melee (slap) plays Klobb's shooting sound idx 106 instead of the slap effect (M-71/M-72, user by-ear + N64 A/B). M-73: user combat capture shows guards re-triggering weapon fire sound idx 109 (AK47/Spectre) 256×/30 s at fixed per-guard periods with NO corresponding bullets/impacts (sustained ACT_ATTACK; gate = `seen_bond_time` via LOS on converted geometry). The capture contains NO idx 106 at all, while the user WAS punching in it (47/48/49 ×13 hits + 105 ×19 whiffs, all voiced) — so in THIS session the only gun sound present during melee was the 109 barrage; whether the user's "Klobb" identification (a specific SMG = Skorpion, idx 106, from N64 A/B) refers to a 109 misheard as Klobb or to a real 106 in another session/moment is OPEN — do not assert either. Explosion 182 + armor 81 each requested exactly once and correct. Sustained-attack gate = `seen_bond_time` refreshed via `stanTestLineUnobstructed` LOS on converted geometry → leading suspect is a LOS/collision query returning clear when N64 blocks.** The playback chain is proven faithful end-to-end — M-68/M-70 exact match: every voiced request plays the exact ROM sample at the exact ROM pitch — and this session's offline harness (`scratchpad/banktest/`: real D37 converter + `diff_bank.py`) shows all 261 bank entries map identically N64→PC (base/len/type/keyMap/env, 0 mismatches). So the bug is upstream of the bank: **PC requests different or extra sound indices than N64 in the same scenario.** Ranked suspects: (a) data-driven sndID/explosion-type/item-sound fields in converted level/setup assets (pccg sidecars) differ from ROM — explosions play `sp44->sndID` from `g_ExplosionTypes[]` (`src/game/explosion.c:285`), explosion *type* comes from level data; explosion SFX are idx 169–183, a scream is outside that range; armor idx 81 verified exact in M-68, so a wrong armor sample means a different index is requested; (b) extra hit events — converted collision geometry makes bullet raycasts (D154/D135, both ABI-verified) or explosion proximity checks hit surfaces/NPCs the N64 misses → layered impact/ricochet/scream SFX; the slap+glass-over-gunshot signature is exactly the non-penetrating-OBJ-hit path (`HIT_BULLET_GLASS_SFX` idx 70 via `sub_GAME_7F064720`, `src/game/gunfire.c`). | OPEN — bank + playback exonerated (M-71); M-73 root-caused the user's three "wrong-sound" moments to guards stuck in sustained fire-sound re-triggering (idx 109 barrage, no bullets) — next: A/B whether N64 guards sustain fire in the same combat + verify `stanTestLineUnobstructed` LOS results on converted geometry vs ROM for guard→Bond segments |
|
||||
| D152+ | D152 addendum (M-31): static audit of every compiled-audio `osSetIntMask(OS_IM_NONE)` — **all balanced**, no unbalanced early-return. Real fixes: `sndSetSfxSlotVolume` now holds the mask across its list walk (matches its twin `sndDeactivateAllSfxByFlag`) + `sndApplyVolumeAllSfxSlot` batches the slot loop under one recursive hold (kills the fade-out lock-acquire storm); `portThreadWrapper` calls `imThreadExitRelease()` on thread exit (kills the "transient thread acquired `OS_IM_NONE` and died" leak + the pthread-id-reuse re-wedge). Steal-lock kept as backstop. | FIXED (`src/snd.c`, `port/src/libultra.c`, `#ifdef PORT`) — fade-out repro playtest-gated, not headless-verified |
|
||||
| RC3 · D167 | **Non-power-of-two texture wrap period (`docs/dev/TEXTURE-GLITCH-ANALYSIS.md` §6 RC3 — "textures repeat oddly", residual Depot-ceiling noise after D161).** The N64 RDP masks the texel coordinate of a wrapping render tile at `1<<mask`, and GE sets `mask = texDimensionToMask(dim) = ceil(log2(dim))` (`src/game/tex.c:361`), so a non-PoT tile (Depot's 65×65 / 96×48 / 56×56 room surfaces) repeats at the **next power of two**, not at its image size the way GL `GL_REPEAT` does → the pattern is squashed/stretched and the seam lands in the wrong place. fast3d never stored `masks`/`maskt` at all (`gfx_dp_set_tile` dropped them) and wrapped purely at the uploaded image dimension. **Fix (`port/fast3d/gfx_pc.cpp`, behind the existing `Video.WrapFix` knob, default OFF):** store `masks`/`maskt` on the tile; in the hoisted per-texunit pre-wrap block in `gfx_sp_tri1` (D74 block — already lifted out of the vertex loop, indexed by texunit `t` not vertex `i`), when the tile is WRAP (no CLAMP/MIRROR bit) and `1<<mask != tex_width`, fold the UV at the N64 period `1<<mask` and clamp the `[dim, 1<<mask)` overflow band (which is a TMEM smear on console, no real texels) to the last texel so it reads as an edge streak instead of a bogus early image restart. `GE_WRAPFIX=0/1` env override added (env wins over the ini, matching `Debug.FrameDump`). **Per-level captures (`-level_09`/`-30`/`-34`/`-20`, WrapFix OFF vs ON, `GE_PCDUMP` 6-frame windows):** no crashes, 6/6 frames each; on settled/comparable frames Silo is ~pixel-identical (phash 0–11), Facility 180–260 pixel-identical, Depot shows small localized texel changes on ceiling/wall cells (dmean 5–9, no structural break); the large per-run deltas are all the D117 intro-camera-pan nondeterminism, not the fix. Default kept **OFF** — no regression, but a headless structural diff can't confirm the Depot ceiling actually looks *better*; needs a human eyeball with `Video.WrapFix=1`. Default-off is byte-identical to golden (all new behaviour is inside `if (g_wrap_fix)`). D74's dead in-vertex-loop wrap block was already reworked/hoisted at M-30; this only adds the mask-period trigger. Confidence: **medium** (mechanism correct; overflow-band handling is an approximation, not exact TMEM-smear emulation; visual win unconfirmed). porting-notes.md §D. | KNOB ADDED, default OFF (`port/fast3d/gfx_pc.cpp`). Needs user visual check on Depot. |
|
||||
| D168 | **`GE_PCDUMP` / F12 PPM captures were vertically flipped — the entire source of the bogus D114/D116 "HUD/text X-mirror" (M-33, developer-confirmed).** `gfx_opengl_dump_bound_fbo` (`port/fast3d/gfx_opengl.cpp`) wrote `glReadPixels` output straight to a P6 PPM. GL framebuffer origin is bottom-left; PPM P6 is top-row-first — so every capture (and the `tools_pc/golden/` set, and every screenshot pasted into the finding log since M-6) was upside-down. On real hardware / an actual screen the game renders correctly (developer confirmed). The successive D114→D116 "shared fast3d mirror" investigations — each of which found *every probed stage clean yet the output "mirrored"* — were reading an inverted capture and pattern-matching upside-down asymmetric content (text, guards, the Nintendo logo) as "mirrored". Fix: emit PPM rows bottom-to-top. `tools_pc/golden/*.png` flipped in place to match (see `tools_pc/golden/README.md`); regenerate from a real run when convenient. **Not runtime-verified this session** (no ROM / toolchain in the migrated tree — see the migration note) — needs a fresh capture to confirm text reads normally. Confidence: **high** (mechanism is unambiguous; developer has hardware confirmation the screen is correct). porting-notes.md §D2. | FIXED (`port/fast3d/gfx_opengl.cpp`); D114 / D116 reclassified as capture-orientation artifacts (below). |
|
||||
@@ -7540,9 +7540,15 @@ refreshed by `setSeenBondTimeToNow`, gated on
|
||||
LOS queries (chraction.c:3917, :3972, and `chrCanSeeBond` :3945). **If the
|
||||
converted collision geometry makes those guard→Bond LOS raycasts return
|
||||
clear where the N64 blocks them, guards never lose their target → 30 s of
|
||||
sustained fire sound.** Per-symptom accounting: (1) "Klobb sound on melee" —
|
||||
idx 106 is NEVER requested in the capture; the user heard the 109 barrage
|
||||
(gun-bolt SFX) during his melee combat. (2) "explosion → scream" — explosion
|
||||
sustained fire sound.** Per-symptom accounting (this capture only; the user's ear identifications
|
||||
stand): (1) "Klobb sound on melee" — idx 106 is NOT requested anywhere in
|
||||
this capture, and the user WAS punching in it (47/48/49 ×13, 105 ×19, all
|
||||
voiced at pool ≤ 4/8); the only gun sound present during those punches was
|
||||
the 109 barrage. Two open readings: the heard "Klobb" = a 109 (user knows
|
||||
Klobb from N64 A/B — do NOT assume misidentification), or the melee→106
|
||||
moment happened in another session this capture doesn't cover. Decisive
|
||||
test: extract ROM samples 106 and 109 to WAV (scratchpad rom_sfx_decode.py)
|
||||
for the user to identify, plus a targeted punch capture. (2) "explosion → scream" — explosion
|
||||
182 was requested exactly once (correct, in 169–183); GET_HIT_MALE screams
|
||||
(137/138/139) fired ±1 s around it (guards hit by the blast — possibly
|
||||
legitimate, needs N64 A/B), all under the 109 barrage. (3) "armor wrong" —
|
||||
@@ -7592,8 +7598,12 @@ same scenario.** Two mechanisms, ranked:
|
||||
guard→Bond segment from step 2: replay the exact ray against the ROM
|
||||
original collision (decode in Python) vs the pccg sidecar; identify the
|
||||
converter/parser bug class (D154/D135 family).
|
||||
4. After root-cause + fix: user re-test of melee / explosion / armor pickup
|
||||
vs N64 — expect all three "wrong sounds" to disappear with the barrage.
|
||||
4. Resolve the "Klobb" identification (open, see M-73): ROM samples 106
|
||||
vs 109 as WAVs for the user to identify by ear + a targeted PC capture
|
||||
of the exact melee moment (`GE_AUDIOTRACE=1`, punch a guard repeatedly;
|
||||
is 106 requested in that window?).
|
||||
5. After root-cause + fix: user re-test of melee / explosion / armor pickup
|
||||
vs N64.
|
||||
|
||||
**Probes added this session (live under `GE_AUDIOTRACE`, catalogued in
|
||||
GE-ENV-PROBES.md):** `[VOL] t=… state=… rawVol=… playing=…` (`src/snd.c:
|
||||
|
||||
Reference in new issue
Block a user