From 8775ca6435627f6feb31fdb5cc085c85ed87d0a1 Mon Sep 17 00:00:00 2001 From: James Dansereau <106631954+jkdansereau@users.noreply.github.com> Date: Sun, 27 Sep 2026 14:55:54 -0400 Subject: [PATCH] docs: D358 (D356 level-1 overlap fix) finding + index/CSV --- docs/dev/findings-index.csv | 1 + docs/dev/findings.md | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/docs/dev/findings-index.csv b/docs/dev/findings-index.csv index a50998e9..5c6f4324 100644 --- a/docs/dev/findings-index.csv +++ b/docs/dev/findings-index.csv @@ -234,3 +234,4 @@ D353,FIXED,Turok-style settings regrouping:,"FIXED (port-only, optionsoverlay.c/ D354,FIXED,Front-end F10 Bond rows silently disabled:,"FIXED (port-only, port/src/watchsettings.c):" D355,FIXED,F10/options Music slider inaudible in-stage:,"FIXED (port-only, port/src/watchsettings.c):" D356,FIXED,"Settings regroup: Turok-style pages renamed to functional sections (INPUT/GAMEPLAY/GRAPHICS/AUDIO/VIDEO) with PD-style ""(File N)"" scoping annotations, the redu…","FIXED (port-only, port/src/optionsoverlay.{h,c} + port/src/watchsettings.{h,c} + port/src/frontoptions.c; plan docs/dev/D356-SETTINGS-REGROUP-PLAN.md):" +D358,FIXED,D356 level-1 overlap:,"FIXED (port-only, port/src/frontoptions.c):" diff --git a/docs/dev/findings.md b/docs/dev/findings.md index 4cfa7076..3f38a9de 100644 --- a/docs/dev/findings.md +++ b/docs/dev/findings.md @@ -642,6 +642,7 @@ covers D24–D69; the log continues in §H (D32 procedure, D70–D121). | D354 | **Front-end F10 Bond rows silently disabled: `watchSettingsAvailable()` mis-routed F10-on-file-select through the stage path (returned 0), so with the hidden chooser stuck at "none" the volume sliders read "Select file" and did nothing; maintainer-reported (2026-09-27).** — full `## D354` entry at file tail | FIXED (port-only, `port/src/watchsettings.c`): all non-stage contexts route through the front path with a lazily-resolved default folder (explicit pick > `selected_folder_num` > first valid), one-shot game-thread `fileBuildWriteNewSave(FOLDER1)` fallback, GE_WSPROBE/GE_WSPROBE_FRONT env probes headless-verified (stage: live+save changed; front: default file 1 + save changed). | | D355 | **F10/options Music slider inaudible in-stage: the slider drives only the X-track (track 2) via `set_mTrack2Vol`, but in-stage BGM is track 1, which the game pins to `VOLUME_MAX` at level start (lv.c:364) and never rescales from `mTrack2Vol` in solo -- so neither the N64 watch nor the F10 could change the music the player was hearing; maintainer-reported (2026-09-27).** — full `## D355` entry at file tail | FIXED (port-only, `port/src/watchsettings.c`): the Music commit now also calls `musicTrack1ApplySeqpVol(v)` (the exact resync the MP path already does, mpmenu.c:354) and a once-per-activation resync runs on stage entry; by-ear confirmed by the maintainer. N64 watch path untouched. | | D356 | **Settings regroup: Turok-style pages renamed to functional sections (INPUT/GAMEPLAY/GRAPHICS/AUDIO/VIDEO) with PD-style "(File N)" scoping annotations, the redundant N64-watch rows (`Bond.Look`, `Bond.AimControl`) off the menu surface, and a real per-section Reset-to-defaults (two-step arm->confirm, watch rows to BLANKSAVEDATA via the D352 commit path, ini rows to the port's C initializers; `__Resolution` a documented exclusion) replacing the Turok reset rows the PC build never honored (2026-09-27).** — full `## D356` entry at file tail | FIXED (port-only, `port/src/optionsoverlay.{h,c}` + `port/src/watchsettings.{h,c}` + `port/src/frontoptions.c`; plan `docs/dev/D356-SETTINGS-REGROUP-PLAN.md`): 5 sections all below MAX_PROWS, hidden rows D181/D216-style (keys + watch paths stay live), edge-triggered reset with 3 s arm window + maintain/clear disarm, GE_WSPROBE_RESET front + in-stage probes headless-verified (all sections failures=0, scope isolation OK, saved bytes 0xFF), GE_WSPROBE/GE_WSPROBE_FRONT regressions clean. | +| D358 | **D356 level-1 overlap: the front options save-file row (item 0) painted under the first content row, and `s_hl` (item-numbered) was indexed straight into `s_rowIdx` (content-numbered) -- wrong-row adjusts, a dead last row, a one-past read, wrong highlight (2026-09-27).** — full `## D358` entry at file tail | FIXED (port-only, `port/src/frontoptions.c`): content rows draw at `rowY(k+1)`; all `s_hl` -> `s_rowIdx` uses take `s_hl-1`; A-press guards `s_hl >= 1 && s_hl <= s_rowN`; hit-test/cursor untouched (already item-numbered). Companion: "(save)" tag -> "(profile)". | Phase 2 replaced the Phase-1 demo loop with the real `mainproc()` on real OS threads, compiled GE's real `src/sched.c`, and brought in PD's fast3d software @@ -13939,3 +13940,29 @@ replace the Turok reset row with a real per-section reset-to-defaults. (`Bond.Look`, `Bond.AimControl`) are still reachable by hand-editing the save file, exactly as on N64 -- only the menu surface is gone (D181/D216/D304 pattern). + +## D358 — D356 level-1 overlap: the front options save-file row painted under the first content row; s_hl -> s_rowIdx off-by-one (2026-09-27) + +**Problem.** D356's top save-file row (item 0 of the level-1 page) shared +the page's item numbering (0 = save row, k = content row k-1) but the +level-1 draw loop painted content row k at `rowY(k)` -- the save row's own +line -- so "Save file: File N" and the section's first row (e.g. +"Auto-aim") printed on top of each other (maintainer-reported overlap, +2026-09-27). The same item/content confusion ran through the input paths: +`s_hl` (item-numbered) was indexed straight into `s_rowIdx` +(content-numbered), so A-press / L-R adjusts hit the row *below* the +highlight, the last content row (`s_hl == s_rowN`) fell through both +handlers entirely, `s_rowIdx[s_hl]` could read one past the built rows, +and the highlight test (`k == s_hl`) lit the wrong row. + +**Fix (port-only, `port/src/frontoptions.c`).** Content rows now draw at +`rowY(k + 1)` (one line below the save row, as `rowY`'s level-1 shift +intended) and every `s_hl` -> `s_rowIdx` use takes `s_hl - 1` (A-press, +L/R repeat, `optionsResetMaintain`); the A-press branch now guards +`s_hl >= 1 && s_hl <= s_rowN` so the last row is live. The hit-test and +cursor paths were already item-numbered (they use `rowY(k)` for item k) +and are untouched. Verified by build + headless boot smoke; visual check +of the screen owed (D357 plan gate 4). + +**Companion change (same commit):** the per-file row tag now reads +"(profile)" (was "(save)", maintainer request), both UIs.