mirror of
https://github.com/jkdansereau/goldeneye-pc-port.git
synced 2026-10-23 15:52:42 +02:00
Recoil byte order, crouch-tank interactions, auto-fire cadence in ticks, hipfire turret tracking, light-fixture Gfx index parsing, hit-type byte reads. Rule-2 sign-offs recorded for D424 and D427. Documentation re-triaged onto a single tracker (docs/ROADMAP.md). Refs: D424 D425 D426 D427 D428 D430 D431 D432 D434 #114 #115 #116 #117 #118 #119
11 KiB
11 KiB
AGENTS.md — GoldenEye 007 PC Port
What this is
n64decomp/007: WIP decompilation of GoldenEye 007 (N64), byte-matches US/EU/JP ROMs.- Active work: PC port modelled on the Perfect Dark PC port (same Rare "Indy" engine family).
- Reference docs:
docs/internals.md— architecture, GE-specific RSP deltas, phased plan (§1–§10).docs/dev/findings.md— theDxxfinding log (§F + §H). Look up findings viadocs/dev/findings-index.csv(label, one-liner, status; regenerate withtools_pc/gen_findings_index.py), then read only the specific## Dxxentry (multi-pass labels like D202/D176(a) have large sections — grep within the section or read with offset/limit, don't slurp it whole). Never linear-read.docs/porting-notes.md— the recurring N64→PC bug classes (dense; skim the headers, read what's relevant). - Open work / known issues:
docs/ROADMAP.md— the single tracker; add new items there, never start a new backlog/roadmap file. - Current status: the README "Status" section (
docs/dev/LEVEL-STATUS.mdis a historical per-level sweep record). Current task + environment:docs/HANDOFF.md(a rolling local working file — may be absent in a fresh clone; fall back to the README "Status" section). - Dispatching subagents?
docs/dev-process.md— task budgets/deadlines, file partitioning, pre-flight, the standard brief template. Every investigation subagent readsdocs/porting-notes.mdfirst and appends to it.
Non-negotiables
- N64 build untouched.
Makefile,tools/,rsp/,ld/belong to the N64 build. Never modify them for the PC port. - Game logic is unmodified. The decomp's control flow and behavior are ground truth for 1:1 fidelity — never change them. All N64 hardware dependencies are satisfied by the
port/layer; if a game file seems to need a behavioral change, stop and check the exception below before assuming the fix belongs inport/. Diagnosis is never restricted — only the fix. Trace a bug as deep intosrc/gamestate as the evidence leads, and name the exact struct/field/logic responsible, before deciding which of three buckets it falls in (full framing:docs/dev-process.md). Narrow exception (ABI/layout only): the 32→64-bit pointer-width transition forces a small class of mechanical, semantics-preserving edits that cannot be isolated inport/— any struct-layout or pointer-width-driven misread caused by 32→64-bit widening, whether in a ROM-serialized record (a struct with a 32-bit-pointer field misaligns when read as 64-bit) or a live runtime struct/union (a raw-byte offset alias into a union arm whose true field shifted because an earlier member in the same union widened — the D209/D210/D255 pattern; seedocs/porting-notes.md§A1 for the full catalogue and its diagnostic tells). These follow the PD ground-truth pattern (store the embedded address asu32and cast to a real pointer at the use site; or read the correctly-named/typed field instead of a raw-offset/mistyped alias), change no logic or behavior, and are each documented indocs/dev/findings.md§F/D3x, cross-tagged to §A1 where that pattern applies. A genuine behavioral difference — the decomp's byte-identical code, given verified-correct inputs, still diverging from real N64 behavior — is not covered by this exception and requires the rule-2 sign-off procedure (docs/dev-process.md) before anysrc/gameedit. No other game-code edits are permitted. - Region macros mirror the Makefile.
CMakeLists.txtREGION_DEFSmust match the N64 Makefile's per-region macro set exactly (finding A1). Divergence = silent branch divergence + link failures. src/libultrare/Makefile.libultrareis ground truth for original-vs-Rare libultra files (finding B3). The PC build compiles:libultra/audio,libultrare/audio(drvrNew/env/reverb),libultra/gu, andlibultrare/io/vitbl.conly. All otherio/+os/files are excluded and shimmed inport/src/libultra.c.rsp/graphics/gmain.sis the RSP ground truth — the authoritative reference for which GBI commands GE emits (modified fast3d, 1545 lines). We do not run it on PC;port/fast3d/replaces it. Use it to validate the software RSP's command decoding and the custom CC/RM modes.
Critical files
| File | Role |
|---|---|
docs/internals.md |
Architecture + RSP deltas + phased plan (§1–§10). Reference, not a linear read. |
docs/dev/findings.md |
The Dxx finding log (§F/§H); lookups via docs/dev/findings-index.csv. |
CMakeLists.txt |
PC build (parallel to the N64 Makefile). Source list + REGION_DEFS live here. |
port/src/ |
Shims: libultra.c (OS API; also shims the scheduler's hardware leaf calls and runs the software RSP inline — the game's real src/sched.c is compiled), n64stubs.c (boot/TLB/FPU/rmon), random.c (PRNG ported verbatim from random.s), ucode.c (microcode segment markers), main.c, video.c, … |
port/fast3d/ |
Software RSP (adapted from the PD port). The main Phase 2 work. |
rsp/graphics/gmain.s |
GE's RSP ucode — ground truth for GBI/CC/RM. |
reference/mouse-injector/README.md |
Stub only — the vendored GEPD-Edition Mouse Injector source (GPLv2) was removed from the public repo 2026-09-19 (license hygiene: GPL code + prebuilt binary in an MIT project; it was never compiled here). The stub records provenance + how to re-vendor locally (gitignored). The ported mouse-aim model lives in port/src/input.c (D194 lineage); design record: docs/dev/GEPD-INPUT-PLAN.md. |
| A local Perfect Dark PC port checkout (fgsfdsfgs/perfect_dark) | Standing reference — consult it whenever a work item has a PD analogue (same Rare engine family): port-layer ground truth (port/fast3d/, crash/system/video), plus copy candidates port/src/preprocess/ (N64→PC asset conversion; filemodel.c is the D43 near-analogue) and mixer.c/input.c/fs.c. Port-layer files only; same family ≠ identical format — validate per field. Full audit: docs/internals.md §2.4. |
Build
./build-pc.sh ntsc-final # or pal-final / jpn-final
Needs CMake + SDL2 + zlib + OpenGL, and must run from the MSYS2 MINGW64 shell
(see build-pc.sh header and docs/building.md). ROM goes in ./data/
(not distributed); assets must be extracted from it first (docs/building.md).
Windows build environment (three recurring failure modes — diagnose in this order):
Cannot create temporary file in C:\Windows\: Permission deniedat the link step. The PE toolchain (ninja → cmd → gcc/ld) needs a writable TMP/TEMP; the msys→native env conversion drops it in non-login shells (agent harnesses; theC:/msys64tree here was built forD:/M/msys64, so its conversion is unreliable).build-pc.shnow self-heals: it probes a native child's TMP (via a file — pipedcmd.exestdout is unreliable under msys console emulation) and, if broken, re-runs cmake+build under PowerShell withTMP/TEMPset natively (the native→native boundary passes env through intact; only msys→native is broken). If you run cmake/ninja by hand from a broken shell: run them from cmd/PowerShell withC:\msys64\mingw64\binon PATH. Guard revision (2026-09-28): the re-exec writes a self-contained.ps1to a temp file and runspowershell -Filewith plain path/word args only (the msys→native argv conversion mangles$-bearing-Commandstrings; a file write is conversion-free). Inside: PATH is built explicitly (never trust the inherited value); TMP is chosen from writable candidates (%LocalAppData%\Tempfirst —[System.IO.Path]::GetTempPath()honours the inherited broken TMP, observed asC:\Windows\); every native step self-logs tobuild-pc/ge007-native-reexec-{diag,cmake,build}.log; a null$LASTEXITCODE("did not execute") is a distinct failure (exit 2/3) — in PS 5.1 a piped native command errors out non-terminating and never sets it, so an unguardedif ($LASTEXITCODE -ne 0)passes vacuously. In.ps1,-DROMID=$Varis a literal (bare tokens don't expand) — it must be"-DROMID=$Var". Launch powershell plainly —env -ibefore it breaks the nested cmake launch (verified 2026-09-28). OPEN (next session): the guard still fails insidebuild-pc.sh(cmake "did not execute": the.ps1runs, but$LASTEXITCODEstays empty) while the identical standalone invocation succeeds (cmake runs and the build completes — that is how the D401 builds were made). First test: diff the heredoc-generated.ps1against a hand-extracted copy (suspect: heredoc line-ending/whitespace corruption). Working workaround: extract the heredoc.ps1and runpowershell -NoProfile -ExecutionPolicy Bypass -File <ps1> "C:\msys64\usr\bin" "C:\msys64\mingw64\bin" C:/msys64 <repo-win-path> build-pc <romid>. Re-confirmed 2026-09-28: in-script re-exec fails again (cmake configure dies inside the ps1; re-exec logs left stale) while the identical standalone invocation reconfigured and built cleanly (extract withawk "/<<'PS1'\$/{f=1;next} /^PS1\$/{f=0} f" build-pc.sh > /tmp/ps1— mind the leading whitespace, andexport PATHto include mingw/bin first, failure mode 3).cannot open output file ge007.x86_64.exe: Permission denied. A runningge007.x86_64.exelocks the output file (Windows rule; you can't relink over a live PE). Check withGet-Process | Where-Object { $_.ProcessName -like '*ge007*' }and close the game before rebuilding. An agent must not kill the user's game process to make a link succeed.cc1.exe: ... libmpfr-6.dll: cannot open shared object file. The calling PATH lacksC:\msys64\mingw64\bin(the gcc driver finds cc1 via its own directory, but the child needs the mingw DLL dir on PATH). In an msys shell:export PATH="/c/msys64/mingw64/bin:/c/msys64/usr/bin:$PATH"before building.
Verification ritual (after any build-affecting change)
- Undefined symbols. Every symbol referenced by the compiled set (see
CMakeLists.txt:SRC_GAME,SRC_ENGINE,SRC_LIBAUDIO,SRC_LIBULTRARE_AUDIO,SRC_LIBULTRARE_DATA,SRC_GU,SRC_PORT*) must be defined exactly once in the compiled set or inport/. Symbols that live in EXCLUDED files (libultra/io/*,libultrare/io/*exceptvitbl.c,libultra/os/*,libultrare/os/*,sched.c,rmon.c,vi.c,src/*.s) must be provided byport/src/libultra.c,n64stubs.c,random.c, orucode.c. - Duplicates. No symbol defined twice across the compiled set (watch
sp_*stacks,rmon*,os*shims, segment markers). - Syntax. Every touched file must parse;
./build-pc.shis the final word.
Run /linkcheck for this sweep. Record new findings in docs/dev/findings.md §F/§H style (next Dxx label after the last used) and add the label to the §F index.
Phase status
Do not keep a status summary here — it goes stale. Open work, known issues
and decisions owed: docs/ROADMAP.md (the single tracker). Current
release state: the README "Status" section.