D290 M-152: static investigation, decomp side ruled out

Traced the watch controller-graphic render path end to end: page gating,
model/item wiring, ROM resource-table entry, and the generic equip/load
pipeline all check out byte-matched or generic-and-proven-elsewhere.
Rules out src/game/ with high confidence. Best-narrowed hypothesis (not
confirmed): a fast3d translucent-blend edge case for the one-off
PROP_TYPE_PLAYER draw used during the watch's fade-in, matching this
project's recurring one-off-combiner-mode bug class. Falsifier for the
next live session recorded in the finding. No code change.
This commit is contained in:
James Dansereau committed 2026-09-16 16:15:30 -04:00
1 parent fbc2a533ae
commit 895118c205
2 files changed
+16 -1

No files matched your search

+3 -1
View File
@@ -10889,7 +10889,9 @@ crash class C2 (Facility `-level_34`, Runway `-level_35`): `import_texture_i8` A
**Watch's in-game "controller" section shows no control-pad graphic (M-141, Steam Deck user playtest).** Likely a missing/failed texture or model bind on one of the watch's equipment-display pages — candidate area `src/game/bondview2.c` (watch display) alongside the front-end options/controller-config screens, not yet located precisely.
**Status (from §F table):** OPEN — observed, not investigated. Needs a live repro (open the watch, navigate to the controller-config page) plus a screenshot for comparison against N64 reference.
**M-152 (2026-09-16, static-only pass, no game execution this session — user was mid-playtest):** traced the real render path: `draw_watch_control_options_page()` (`src/game/options.c:3511`) gates `draw_watch_controller()` (`options.c:3336`) on `check_watch_page_transistion_running()` — this gate covers the model draw AND both text labels, so a mis-gate would drop the whole page, not just the graphic; ruled out. `draw_watch_controller()` picks `watchRenderController`/`watchRenderControllerOpaque` (`src/game/gunfire.c:1983`/`:2343`) by `g_WatchBackgroundGreen` fade state — both build a 13-node joystick+buttons model from `g_CurrentPlayer->copy_of_body_obj_header[GUNRIGHT]`, animated from live `joyGetStickX/Y`/`joyGetButtons`, then `subdraw()`. Verified the equip path is correct: `sub_GAME_7F05DA8C(GUNRIGHT, 0x55)` equips `ITEM_JOYPAD` (0x55 confirmed against `bondconstants.h`'s `ITEM_IDS` enum, not an off-by-one), the `GjoypadZ` ROM resource is present in `file_resource_table.inc.c:165`/`obseg.h:162`, and `port/shim/bondconstants.h`'s `GUNFILERECORD`/`GUNSTATS` macros are only token-paste syntax variants of the same decomp macros — no port-shim divergence. **The entire `src/game/` decomp side (item ID, model header wiring, generic equip/on-demand-load pipeline shared by every weapon, page-transition gating) is byte-matched/generic-and-proven-elsewhere — ruled out with HIGH confidence.** Root cause not found. Best-narrowed hypothesis (LOW confidence, pattern-match only, no direct evidence yet): downstream in `port/fast3d/gfx_pc.cpp`'s rasterization, not game logic — `watchRenderController`'s fading branch draws `PROP_TYPE_PLAYER` with a low `envcolour` alpha (green-6) and `fogcolour` alpha=0, a translucent one-off combiner/blend path that doesn't share code with the common in-level render path; this project has a recurring bug class of fast3d mishandling exactly this kind of one-off blend/CC-mode/texture-format combo while the common path works fine (D172 particle color, D217/D228 CI/IA16 palette, D229 water blend, D233 invisible-through-doors) — matches the "graphic vanishes, surrounding text stays" symptom shape. **Falsifier for next session:** get a live repro (open the watch → controller-config page) with `GE_PCDUMP`/F12 at both `g_WatchBackgroundGreen < 0xe0` (fading, `PROP_TYPE_PLAYER`) and `>= 0xe0` (settled, `PROP_TYPE_OBJ`) — missing in BOTH states kills the blend-mode hypothesis and points back to something structural (e.g. `objheader->Switches[]` never populated for this object); missing ONLY in the fading state confirms it and narrows the fix to `gfx_pc.cpp`'s `PROP_TYPE_PLAYER` + low-alpha handling.
**Status (from §F table):** OPEN — M-152 ruled out the entire `src/game/` decomp side (item ID, resource table, equip pipeline, gating) with high confidence via static trace; root cause not found, best-narrowed hypothesis points at a fast3d translucent-blend edge case, needs a live repro with `GE_PCDUMP` at both watch fade states to confirm/refute (see falsifier above).
## D291 — Dam: texture glitches when the truck drives past (M-141, Steam Deck user playtest).
+13
View File
@@ -689,6 +689,19 @@ through a converter or a runtime bswap fixup reads scrambled.
stray triangle), not yet confirmed against a live repro (M-152). Unlike
D233's fix, this one hasn't been shown to actually fire yet; it's a
code-review lead, not a confirmed mechanism.
- **When chasing a missing UI element, split "game logic decides to draw
it" from "fast3d actually rasterizes it."** This codebase's decomp side
for menu/watch item rendering is consistently byte-matched and rarely
at fault; the recurring bug class is a combiner/blend-mode or
texture-format edge case in `port/fast3d/gfx_pc.cpp` for a one-off
translucent/`PROP_TYPE_PLAYER` draw that doesn't share a code path with
the common in-level rendering (D172 particle color, D217/D228 CI/IA16
palette, D229 water blend, D233 invisible-through-doors, and D290's
leading hypothesis — the watch controller graphic's fade-in uses a
low-alpha `PROP_TYPE_PLAYER` combiner state nothing else exercises).
Confirm the `src/game/` side is clean first (item ID, resource-table
entry, model header, generic equip/gate pipeline) before spending time
in fast3d — but once it is, look there, not back at the decomp logic.
- **D74 wrap-block is DEAD CODE** (`gfx_pc.cpp:1546/1551`): guard is
`cms & G_TX_WRAP` but `G_TX_WRAP == 0`, so always false (line 1887 does
it right with `cms == G_TX_WRAP`). And if it did run it indexes