Files
goldeneye-pc-port/docs/PLAN-M6-playable.md
T
James Dansereau 7bdb19e96f D115: fix gunfire THROW* raw struct player offsets; M-6 D113/D114 findings
D115: THROWMTX/THROWPOS/THROWPREV in gunfire.c were raw byte offsets
((u8*)g_CurrentPlayer + handnum*sizeof(struct hand) + 0xAD8/0xB08/0xB48).
Both the stride (PC sizeof(struct hand) ~0x968 vs N64 0x3B8, D102) and the
base offset are N64-sized, so on x86-64 the address lands inside the
inline gait Model / bondhead-matrix region of struct player and
matrix_4x4_copy(THROWMTX,..) scribbles 64 bytes of live render state on
every casing-ejecting shot. The offsets are exactly
hands[handnum].throw_item_pos_related[_prev] and its translation row -
macros now use those field accessors under #ifdef PORT; N64 build
unchanged. Full survey in docs/AUDIT-M6-player-offsets.md (10 sites,
3 HIGH fixed here, 2 MED open incl. the likely 'weapon model doesn't
draw' cause).

D113 (investigation, no code change): the 'portal-BFS under-reach / void'
premise is stale - the BFS output is correct for BUNKER1's topology
(rooms 26/27 are behind PORTALFLAG_DISABLED closed-door portals, culled
identically on N64). The void is the closed-door models obj 153/154 not
rendering in their doorway -> D114 track.

D114 (investigation, no code change): joint-matrix chain + d43_emit.py
float emission verified clean post-D112; basemtx is a proper
right-handed +Y-up lookat, joint render_pos coherent and upright. All
plan hypotheses disproven. Residual = a horizontal mirror in the shared
port/fast3d viewport / MP-matrix path vs GE's left-handed screen
convention (also explains the open D75 mirrored-text / logo items).
Still open.

Plan + agent reports: docs/PLAN-M6-playable.md. §F: D113/D114/D115.
2026-08-29 09:53:00 -04:00

95 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Plan — Session M-6: toward a playable, low-glitch BUNKER1 PC build
Baseline: D112 committed (`67d674da`). Build green. `-level_09` renders
BUNKER1 continuously, crash-free. Three tracks below, in priority order.
Each track: **investigate → root-cause → narrow `#ifdef PORT` fix or
write-up** per AGENTS.md non-negotiables (no game-logic changes; ABI /
layout / format exceptions only, each documented in
`docs/PCPortResearch.md` §F).
## Track 1 — Portal-BFS under-reach ("the void") [highest visual impact]
**Symptom:** in BUNKER storage area (rooms 27–29) the per-frame visible
room count collapses to 1–2; large sky-fill void where an adjacent room
should show through an open doorway. Portal *visibility* is otherwise
healthy post-D106 (room 18 → 8 rooms deep on enabled doorways).
**Known-good / ruled out:** `currentPlayerGetProjectionMatrix()`,
`g_CurrentPlayer->screensize`, the intentional `g_RoomLoadBudget` 200→3
FP-cam drop, `zfar`, the plane-side metric cull (`bg.c:4135/4144`).
**Suspects:** `sub_GAME_7F0B5864` screen-space portal projection
(`bg.c:1619`) — sibling of the D106 z==0 near-plane case, but for
partially-off-screen (not straddling) portals; `bgQueuePortalTraversal`
(`bg.c:3814/3843`) depth/dedup; `bgDetermineVisibleRooms` (`bg.c:4615`)
seed set; `sub_GAME_7F0B5528` clip-point generation (`bg.c:1551`);
`transform3Dto2DWithZScaling` (`bondview.c:730`).
**Deliverable:** root-cause writeup in §F ("D113"); if a narrow PORT fix
is obviously correct (e.g. another degenerate-box / clamp mismatch),
apply it, else stop and document.
**RESULT (Track 1 agent):** NOT a portal-BFS bug. The BFS output is
correct for BUNKER1's topology — rooms 26/27 sit behind portals 25/26
which carry `PORTALFLAG_DISABLED` (closed doors), culled identically on
N64. Stable 3 visible rooms {29,28,25}, not "1–2". The void is the
**closed-door prop models (obj 153/154) rendering with a wrong world
transform** — their leaf DLs are emitted (`GE_D96`) but land outside the
doorway, leaving the wall hole unoccluded → sky. **Folds into Track 2**
(same model-matrix defect as the inverted guard / mislocated crate). No
`bg.c` change. Probes reverted, tree clean.
## Track 2 — Character pose / orientation
**Symptom:** post-D112 a BUNKER guard renders as a coherent humanoid but
appears **inverted**. Also a mispositioned static crate prop (top-left in
the control room).
**Known-good:** joint *rotations* from the anim bitstream; `render_pos[]`
positions now sane (~±60 units) after the D112 f32 fix; `basemtx` from
`camGetWorldToScreenMtxf()` (`bondview.c:824`) was a clean orthonormal
lookat.
**Suspects:** matrix handedness / lookat sign in the joint base matrix;
`modelBuildGroupMatrices` / `process_02_position` / `subcalcmatrices`
composition order on LE; a converter sign/axis issue in `d43_emit.py`
group `Origin` or matrix rodata that survived the D112 fix (byte order
right, axis convention wrong); guMtxF2L / Mtxf→Mtx path.
**Deliverable:** root-cause writeup in §F ("D114"); narrow fix if
obviously correct.
## Track 3 — `struct player` raw-offset audit [gate to playability]
**Symptom:** 1P weapon model doesn't draw. Landmine (§F D100): raw
hardcoded-offset accessors into `struct player` / `struct hand` are NOT
PORT-adjusted and are already PC-wrong.
**Known instances:** `gunfire.c` `THROWMTX_OFFSET 0xAD8` / `THROWPOS`
`0xB08` / `THROWPREV` `0xB48` (all `g_CurrentPlayer + handoffset + K`);
plus D102 (weapon Model pool) already fixed.
**Task:** enumerate *every* raw byte-offset / hardcoded-size access into
`struct player`, `struct hand`, and siblings across `src/game/` (grep for
`+ 0x`, `handoffset`, `(u8 *)`, hardcoded `0x2A80`-class sizes, pointer
arithmetic on player). For each: N64 offset vs PC offset (struct is
0x2A8-class larger per D100), whether it's on a BUNKER1-reachable path,
severity. Produce a table + recommended fix order. Do NOT fix yet —
this is a survey feeding a follow-up.
**Deliverable:** `docs/AUDIT-M6-player-offsets.md` table + §F pointer.
## Execution
- Tracks 1, 2, 3 dispatched as parallel investigation subagents
(read-mostly; each returns a writeup + optional narrow patch).
- Integrator (this session) reviews each, applies/adjusts verified narrow
fixes, rebuilds (`export PATH="/c/msys64/mingw64/bin:$PATH" &&
./build-pc.sh ntsc-final`), spot-checks `-level_09`, commits per-track
with §F docs.
- Repro: `./build-pc/ge007.x86_64.exe -level_09 -ml0 -me0 -mgfx100
-mvtx50 -mt700 -ma150`. Frame capture: `GE_PCDUMP="<range>:<stride>"` +
`tools_pc/pixcount.py` / `tools_pc/pixcount.py`.
- Sidecar regen (if a converter changes): `python tools_pc/d43_emit.py
ntsc-final`.