mirror of
https://github.com/jkdansereau/goldeneye-pc-port.git
synced 2026-10-23 15:52:42 +02:00
95 lines
7.2 KiB
Markdown
95 lines
7.2 KiB
Markdown
# M-36 — graphics / QA bug triage sweep
|
||
|
||
Branch `qol/native-pc-input-menu` (local). Goal: sort the open
|
||
`GRAPHICS-BACKLOG.md` + QA-report bugs into **root-cause families** so a
|
||
fix hits several at once, and correct one mis-attribution.
|
||
|
||
Method: headless `GE_PCDUMP` captures (`-level_36` Surface, `GE_STARTMENU=10`
|
||
briefing) + static read of the implicated port code. Frames in
|
||
`scratchpad/` this session; not committed (auto window size = 1957×1468,
|
||
can't framediff — visual only).
|
||
|
||
---
|
||
|
||
## Headline findings
|
||
|
||
### 1. The "comb interlacing" is NOT the D159 family
|
||
|
||
`GRAPHICS-BACKLOG.md` attributes D176(b) and D182(2) to `texSwapAltRowBytes`
|
||
"recurring on re-import". **That function is a full `#ifdef PORT` no-op** —
|
||
`src/game/image.c:2199` `return;` before any work. It cannot be the cause of
|
||
anything. The mis-attribution is now corrected in the backlog.
|
||
|
||
The real defect: `port/fast3d/gfx_pc.cpp` `import_texture_*` assume
|
||
`full_image_line_size_bytes == line_size_bytes` (explicit `SUPPORT_CHECK`
|
||
on rgba32/ia4/ia8/ia16/…; the rgba16 one is commented out with
|
||
*"this trips in some places with a garbage size in
|
||
full_image_line_size_bytes"*, `gfx_pc.cpp:658`). When a tile's `line`
|
||
(SETTILE pitch) differs from the source image row width — non-power-of-two
|
||
textures, or a sub-rect tile load — the importer does a flat linear read and
|
||
every row walks off by a few bytes → **diagonal shear that reads as grey
|
||
static**. Matches the Surface cliff/tree walls (`-level_36` frame 300–900:
|
||
structured rock texture tiling but each tile sheared to noise) and the
|
||
file-select spiral after re-entry.
|
||
|
||
Open question: why does D182 only scramble **after** navigating away and
|
||
back? Either the first import happens to have `line == width` and the
|
||
re-import doesn't, or the tile descriptor is stale on the second visit.
|
||
|
||
### 2. Briefing objectives are BLANK, not wrong
|
||
|
||
`GE_STARTMENU=10` briefing (Dam): header renders perfectly ("OHMSS / Agent:
|
||
James Bond / Mission 1: Arkangelsk / Part i: Dam / PRIMARY OBJECTIVES:").
|
||
Under it: just the bullet letter **"a."** with **no objective text**, and no
|
||
b/c/d lines. So D178 is the **D143/D151 blank-text family** (`langGet()`
|
||
returns NULL for the objective string slot → text silently blank), *not* a
|
||
propDef walk-desync or difficulty-decode problem. Fix = find which lang bank
|
||
the front-end briefing flow fails to load/map.
|
||
|
||
Caveat: this repro used the synthetic `GE_STARTMENU` boot (skips real
|
||
save/unlock state). The user's D178 report is from a live playthrough, and
|
||
D143 independently documents blank briefing text, so it is a real defect —
|
||
but re-confirm the exact "a." + blank shape in a real briefing.
|
||
|
||
---
|
||
|
||
## Family table
|
||
|
||
| Family | Bugs | Root cause (hypothesis) | Files | ROI |
|
||
|---|---|---|---|---|
|
||
| **A — fast3d texture line/pitch shear** | D176(b) Surface walls; D182(2) file-select bg | **HYPOTHESIS DISPROVEN (D183, `4b71435d`).** 0/166 texture loads on `-level_36` are strided; the wall texture is a 32×32 IA8 whose ROM bytes are genuinely a noise field, decoded correctly. A golden-safe de-stride + `GE_TEXRAW`/`GE_DTEX` diagnostics landed anyway (latent hardening). **D176(b)/D182(2) still OPEN** — next: ROM ground-truth decode of the wall texnum (`TEXTURE-GLITCH-ANALYSIS.md` §7) → likely a tiling-density / UV-scale / `shifts`/`shiftt`-LOD issue (RC3/D167 family) or a wrong-texture bind, not a decode bug. | `port/fast3d/gfx_pc.cpp` | was HIGH, **now needs re-scoping** |
|
||
| **B — front-end string bank not loaded** | D178 briefing objectives blank; D143 briefing text blank | **FIXED (D178, `cd1ed574`).** Not a bank-load problem — the `Ubrief*Z` segment is a raw 48-byte BE ROM image loaded with no converter; all 24 `u16` (string ids + difficulty gates) read byte-swapped on LE → `langGet()` NULL → blank, and `>=` difficulty gate always-false → objectives vanish. `romdataFixupBriefing()` swaps in place. Verified: all 4 Dam objectives render at 00 Agent with correct gating. **D143 was a symptom of this** — annotate it superseded. D151 (watch objective text) still owed a re-verify. | `port/src/romdata.c`, `src/game/front.c` (`#ifdef PORT`) | **DONE** |
|
||
| **C — D75 front-end / cutscene 3D models** | D75 Nintendo logo; D148 Dam rappel cutscene; D149 MISSION COMPLETE / mode-select models; D182(1) file-select Bond image "renders once"; D173 3rd-person Bond floats; 1P weapon viewmodel absent | mixed: compiled sub-DL corruption (D144/D146), model transform/geometry, `render_pos` arena lifetime, constructor-runs-once | `port/fast3d/gfx_pc.cpp`, `title.c`, `bondview*.c`, model path | **LOW** per fix, deep. **DEFER** (agreed COA). |
|
||
| **D — blood / particle** | D172 spray magenta/cyan; D174 no blood decals | D172: CC-mode / texture-format decode in the fast3d sprite path. D174: likely D120 `PointUsage[]` — **only takes effect after a full sidecar regen** (`d43 && d69 && d88 --regen`); verify that first. | `blood_animation.c`, fast3d sprite path; `tools_pc/d43_emit.py` | **MEDIUM**. D174 may already be fixed — regen + BUNKER1 firefight to confirm before touching code. |
|
||
| **E — transient hang / anim speed / clip** | D175 door-open stutter (Runway/Surface); D170 NPC flee runs not walks; D171 Silo grey-triangle sweep | D175: matches D155/D156/D134/D147 known classes (benign texture-import spike most likely). D170: D155/D156 wall-clock `deltaFrames` anim speed-up, or just scripted. D171: near-plane clip fan (D106 family). | frametiming clamp, `chrTick`/AI, portal near-plane | **LOW–MED** — needs interactive repro + N64 reference footage. **DEFER**. |
|
||
| **F — misc cosmetic** | D74 dead wrap-block (latent, harmless); D76 disclaimer partial (D164 fix owed an eyeball); D77 audio (Phase 3); **D176(a) black sky** | D176(a): sky DL not emitting / wrong transform — **separate from D176(b)**, own investigation (could be C-family or a sky-pass issue). | various | **LOW**, opportunistic. |
|
||
|
||
---
|
||
|
||
## Results (2 subagents, integrated + verified on branch HEAD)
|
||
|
||
- **Family B → FIXED** (`cd1ed574`). Byte-swapped raw briefing segment. Also
|
||
explains D143. High confidence.
|
||
- **Family A → hypothesis disproven** (`4b71435d`, D183). D176(b) is not a
|
||
texture decode bug. Golden-safe de-stride + diagnostics shipped for the
|
||
latent case. **D176(b) / D182(2) remain open and need re-scoping** — start
|
||
from the ROM ground-truth decode of the wall texnum; suspect
|
||
tiling-density / UV / per-LOD `shifts`/`shiftt` (RC3/D167 family) or a
|
||
wrong-texture bind.
|
||
|
||
Harness note: both agent worktrees were created from `def0e0ac` (the M-35
|
||
branch point, ~5 commits stale — the M-31 stale-worktree bug again). No harm
|
||
this round: the integrator re-applied both patches onto branch HEAD and
|
||
verified there. Check `git worktree list` HEADs on the next burst.
|
||
|
||
## Next
|
||
|
||
1. **D176(b) re-scope** — offline decode the Surface wall texnum from ROM
|
||
(`TEXTURE-GLITCH-ANALYSIS.md` §7). Structured rock in ROM → wrong bind or
|
||
UV/tiling; noise in ROM → not our bug (or a shift-LOD density issue).
|
||
2. **D176(a)** black sky — untouched, separate investigation.
|
||
3. **D182** — re-test the file-select round-trip now that `GE_TEXPITCH` /
|
||
`GE_TEXRAW` exist; the "renders once" half (D182-1) is Family C.
|
||
4. Reassess C/D/E with the user. D174 (blood) is the cheapest — just needs a
|
||
sidecar regen + BUNKER1 firefight to confirm the D120 fix.
|