diff --git a/docs/dev/findings.md b/docs/dev/findings.md index c1de7532..9002a650 100644 --- a/docs/dev/findings.md +++ b/docs/dev/findings.md @@ -380,7 +380,7 @@ covers D24–D69; the log continues in §H (D32 procedure, D70–D121). | D59–D68 | intro render: blood-RLE clobber, DMA validate, OSMesgQueue, HEADS/BODIES sentinels, romCopy width, image_entry, Globalimagetable BE→LE | resolved | | D69 · D78–D84 | stage load (`load_bg_file`): bg/stan offline sidecar (`d69_emit.py`) + StandTile/bg_room_data ABI | resolved | | D70–D74 | intro-logo pixels: C-array bswap, UV path, sinf/cosf `DVAL()`, texture-import truncation | resolved | -| D75 · D77 | front-end 3D model transforms · audio | OPEN (parked). **M-32 triage (see §F "D75 ADDENDUM"): (a) D73-scope-gap RULED OUT (gu tree fully endian-clean). Splits in two: Bug 1 = logo/photo transform = the parked D114/D116 fast3d viewport mirror (not game code). Bug 2 = absent animated models = category (b). M-32b runtime probe (`GE_D75=1`): `render_pos`/`dynAllocate`-arena hypothesis RULED OUT (render_pos valid + fresh each frame), model instances valid (nMtx 21/1), zero fast3d DL warnings — failure is downstream in `drawjointlist`/`dotube` vtx/node-DL resolution or an off-screen `basemtx`. Needs a drawjointlist-level probe. M-33 (upright captures, D168 fixed): "Bug 1 = D114/D116 mirror" retracted; **gun-barrel Bond RENDERS fine** (walk + fire, upright) — the "absent" reports were the flipped capture; **Nintendo logo genuinely broken** (renders as 2 white blobs, shifted left — a real `logoinst` transform/geometry bug, not a flip); cast roll not re-captured. See §F "D75 Bug 2 — M-33 UPDATE".** | +| D75 | front-end 3D model transforms (D77 audio split out below — resolved, unrelated cause) | OPEN (parked). **M-32 triage (see §F "D75 ADDENDUM"): (a) D73-scope-gap RULED OUT (gu tree fully endian-clean). Splits in two: Bug 1 = logo/photo transform = the parked D114/D116 fast3d viewport mirror (not game code). Bug 2 = absent animated models = category (b). M-32b runtime probe (`GE_D75=1`): `render_pos`/`dynAllocate`-arena hypothesis RULED OUT (render_pos valid + fresh each frame), model instances valid (nMtx 21/1), zero fast3d DL warnings — failure is downstream in `drawjointlist`/`dotube` vtx/node-DL resolution or an off-screen `basemtx`. Needs a drawjointlist-level probe. M-33 (upright captures, D168 fixed): "Bug 1 = D114/D116 mirror" retracted; **gun-barrel Bond RENDERS fine** (walk + fire, upright) — the "absent" reports were the flipped capture; **Nintendo logo genuinely broken** (renders as 2 white blobs, shifted left — a real `logoinst` transform/geometry bug, not a flip); cast roll not re-captured. See §F "D75 Bug 2 — M-33 UPDATE".** | | D76 · D164 | disclaimer/legal screen only draws line 1 — **root-caused (M-31)**: `constructor_menu00_legalscreen` text loop bounds `legal_text_end` on `&legalscreen_MRD`, a linker-adjacency assumption that mingw breaks (`legalscreen_MRD` links 0x60 *before* `legalpage_text_array`) → `do{}while(ptr= 1000000ull) { + const s16 *s = buf; + u32 n = len / 2u; + s32 peak = 0; + s64 sumsq = 0; + for (u32 i = 0; i < n; i++) { + s32 v = s[i]; + if (v < 0) v = -v; + if (v > peak) peak = v; + sumsq += (s64)s[i] * (s64)s[i]; + } + double rms = n ? __builtin_sqrt((double)sumsq / (double)n) : 0.0; + geTracePrintf("audiotrace.log", "[AUDIOLVL] peak=%d rms=%.1f n=%u\n", + (int)peak, rms, (unsigned)n); + lastReportUs = now; + } + } if (dev && buf && len) { if (audioGetSamplesBuffered() < queueLimit) { SDL_QueueAudio(dev, buf, len); diff --git a/src/game/mp_music.c b/src/game/mp_music.c index 9c482f2e..b43ad6a9 100644 --- a/src/game/mp_music.c +++ b/src/game/mp_music.c @@ -37,9 +37,23 @@ s32 mission_state = MISSION_STATE_0; +/** + * D6-class bug (docs/porting-notes.md): missing "return" on a non-void + * function whose body is a single tail call. The N64/IDO build happened to + * leave get_mTrack2Vol()'s result in $v0, so the ASM ground truth "works" by + * accident; GCC at -O2 (the PC release build) does not guarantee that, and + * every caller of this function (set_missionstate()'s MISSION_STATE_1/4 + * transitions -- i.e. every in-level music-track-start trigger) fed + * musicTrack1ApplySeqpVol()/musicTrack3ApplySeqpVol() a garbage/zero volume, + * silencing level music while leaving note-on processing intact (D77). + */ u16 sub_GAME_7F0C0BF0(void) { +#ifdef AVOID_UB + return get_mTrack2Vol(); +#else get_mTrack2Vol(); +#endif } u16 sub_GAME_7F0C0C10(void)