mirror of
https://github.com/jkdansereau/goldeneye-pc-port.git
synced 2026-10-23 15:52:42 +02:00
PC port: document PD-port copy-candidate audit (§2.4) — standing reference, D43 near-analogue, Phase 3/4 copy targets
This commit is contained in:
1 parent
95b6e41a0c
commit
89653cdcbb
3 files changed
+97
-16
No files matched your search
@@ -24,7 +24,7 @@
|
||||
| `port/src/` | Shims: `libultra.c` (OS API), `gesched.c` (scheduler), `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. |
|
||||
| `PD_PORT_CHECKOUT` | Perfect Dark PC port checkout — ground truth for the port layer. Its `port/fast3d/` is the starting point for ours. |
|
||||
| `PD_PORT_CHECKOUT` | Perfect Dark PC port checkout — **standing reference for this project**: consult it whenever a remaining 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 at load; `filemodel.c` is the D43 near-analogue, same vma 0x5000000) and `mixer.c`/`input.c`/`fs.c` (Phase 3/4 — our stubs were scaffolded to be replaced by these). Caveats: port-layer files only; same family ≠ identical format — validate per field. Full audit: `docs/PCPortResearch.md` §2.4. |
|
||||
|
||||
## Build
|
||||
|
||||
@@ -48,6 +48,6 @@ Run `/linkcheck` for this sweep. Record new findings in `docs/PCPortResearch.md`
|
||||
- **Compile+link milestone:** all ~235 TUs compile and `ge007.x86_64.exe` links clean (`ninja ge007 -k 0`, 236/236). Findings D7–D17 in `docs/PCPortResearch.md` §11; asset stubs in `port/src/assetstubs.c`, fast3d no-ops in `port/src/gfxstub.c` (delete when real fast3d lands).
|
||||
- **Phase 1 (boot to window):** done — ROM loads/validates/maps at cart base 0x10000000 (`romdata.c`), SDL2 window + GL clear loop (`video.c`), absolute asset symbols from `scripts/gen_romassets.py` → `port/src/romassets_<r>.s` (findings D18–D23).
|
||||
- **Phase 1.5 (boot to first frame):** DONE — boot chain complete AND real frames render (`[NOTE] frame N rendered in … us`). D34–D42 closed the blockers on top of D31–D33: ANIM_DATA lvalues, music seq-table ABI+endianness, music-heap sizing, libaudio bank-tree re-layout, implicit-declaration prototype shim (D38), Globalimagetable rebasing + true segment size (D39), ModelHitEntry pool sizing (D40), cross-thread GL context release (D41), rsp task-settings toggle (D42). ROM dump verified against the No-Intro good dump (byte-identical, header CRCs re-checked — `tools_pc/romverify.c`).
|
||||
- **Phase 2 (rendering):** IN PROGRESS — fast3d integrated + first frames render; current blocker is **D43** (model-file loading ABI mismatch: N64-layout ROM model files read as 8-byte-pointer PC structs → D37-style re-layout in `port/src/romdata.c`). Recurring sub-task: ABI/layout fixes per the D32 procedure (§H) as more asset types are first touched.
|
||||
- **Phase 3 (audio + input):** libaudio → SDL; decide the ASP strategy (C2: `aspMain*` dummies in `ucode.c`).
|
||||
- **Phase 4 (saves + polish):** file-backed EEPROM; PFS/motor already no-op stubs.
|
||||
- **Phase 2 (rendering):** IN PROGRESS — fast3d integrated + first frames render; current blocker is **D43** (model-file loading ABI mismatch: N64-layout ROM model files read as 8-byte-pointer PC structs → D37-style re-layout in `port/src/romdata.c`; a Rare-validated near-analogue exists in the PD port's `preprocess/filemodel.c` — §2.4). Recurring sub-task: ABI/layout fixes per the D32 procedure (§H) as more asset types are first touched (PD's `preprocess/` module already solves most of them).
|
||||
- **Phase 3 (audio + input):** libaudio → SDL — largely copy-and-adapt from PD (`mixer.c` 722 lines vs our 31-line stub; `input.c` SDL_GameController backend; §2.4); decide the ASP strategy (C2: `aspMain*` dummies in `ucode.c`).
|
||||
- **Phase 4 (saves + polish):** file-backed EEPROM — build on PD's `fs.c` (file-backed save dir); PFS/motor already no-op stubs.
|
||||
+35
-6
@@ -21,8 +21,9 @@ Commit message style: `PC port: <phase> — <what>`.
|
||||
## Read first (authoritative, in order)
|
||||
1. `AGENTS.md` — non-negotiables, critical files, build, verification ritual, phase status.
|
||||
2. `docs/PCPortResearch.md` §H (handoff + plan), then **§F/D44** (the quick win),
|
||||
**D43** (the open model-file task), **D37** (the libaudio bank-tree re-layout —
|
||||
the pattern to copy), D39–D42 for the first-render fixes, D31–D38 for background.
|
||||
**D43** (the open model-file task), **§2.4** (PD-port copy-candidate audit —
|
||||
read before starting D43 or Phase 3/4), **D37** (the libaudio bank-tree
|
||||
re-layout pattern), D39–D42 for the first-render fixes, D31–D38 for background.
|
||||
|
||||
## Non-negotiables (the ones that bite)
|
||||
- N64 build files (`Makefile`, `tools/`, `rsp/`, `ld/`) — never touch.
|
||||
@@ -76,7 +77,13 @@ Commit message style: `PC port: <phase> — <what>`.
|
||||
2. Understand the file format from `bondtypes.h` (`ModelFileHeader`, `ModelNode`,
|
||||
`ModelRoData` union + per-opcode records) and `bondconstants.h`
|
||||
(`MODELNODE_OPCODE_*`). N64 layout: header 24 B, node 20 B, all pointers 4 bytes.
|
||||
3. Implement a D37-style two-pass re-layout in `port/src/romdata.c`: walk the node tree
|
||||
**Do NOT design the re-layout from scratch:** PD port's
|
||||
`port/src/preprocess/filemodel.c` (1,114 lines) is a Rare-validated near-analogue —
|
||||
same `PROMOTE` idiom, **same vma 0x5000000**. Read it first; adapt its node walk /
|
||||
placement / record handling. GE's `ModelRoData` union + opcodes differ (PD has
|
||||
stargunfire/headspot/gundl types), so validate every GE record type per-field against
|
||||
bondtypes.h + ROM ground truth.
|
||||
3. Implement the two-pass re-layout in `port/src/romdata.c`: walk the node tree
|
||||
(Child/Next/Parent links), place every sub-struct once (8-aligned) in a compact image,
|
||||
rewrite each embedded pointer as a zero-extended offset from the image start, so the
|
||||
existing `PROMOTE` rebase (`diff = fileramaddr - vma`, vma = 0x5000000) works
|
||||
@@ -85,7 +92,10 @@ Commit message style: `PC port: <phase> — <what>`.
|
||||
4. Validate one small model against ROM ground truth before generalizing (opcode
|
||||
sequence, node links, a few Data records). gdb works; or write the optional
|
||||
`tools_pc/romdump.py` inspector (below) and validate statically.
|
||||
5. Expect follow-on faults in other asset types (BG/stan/propobj tables) — same procedure.
|
||||
5. Expect follow-on faults in other asset types (BG/stan/propobj tables) — same
|
||||
procedure; note PD's `preprocess/` module already solves most of them
|
||||
(`filebg.c`, `filetiles.c`, `filepads.c`, `filesetup.c`, …) — see the PD
|
||||
reference section below.
|
||||
|
||||
## Dev-loop speedups (build these when they pay off, not before)
|
||||
Priority order from the last session's measurements:
|
||||
@@ -105,6 +115,23 @@ Priority order from the last session's measurements:
|
||||
scriptable, and enables screenshot diffs against an emulator (Mupen64Plus with the
|
||||
verified No-Intro dump as ground truth).
|
||||
|
||||
## PD port as standing reference (always available)
|
||||
`PD_PORT_CHECKOUT` is the Perfect Dark PC port — same Rare engine
|
||||
family, and the **standing reference/guidance source** for this project (noted in
|
||||
AGENTS.md). Consult it whenever a remaining work item has a PD analogue:
|
||||
- **Phase 2 asset conversion:** `port/src/preprocess/` (~4,100 lines) — per-ROM-segment
|
||||
N64→PC layout converters hooked from their `romdata.c`. `filemodel.c` = D43 near-analogue
|
||||
(same vma 0x5000000); `filebg.c` (expected follow-on), `segaudio.c` (cross-check for our
|
||||
D37 bank-tree fixup), `filelang.c`, `filetiles.c`, `filepads.c`, `filesetup.c`, `gbi.c`,
|
||||
`segfonts.c`.
|
||||
- **Phase 3/4 (copy-and-adapt; our stubs were scaffolded for this):** `port/src/mixer.c`
|
||||
(722 lines vs our 31 — libaudio→SDL mixer), `input.c` (1,551 vs 48 — SDL_GameController
|
||||
backend with hotplug/rumble/keyboard; remap buttons to GE's scheme), `fs.c` (294 vs 81 —
|
||||
file-backed save dir for Phase 4 EEPROM/PFS).
|
||||
- **Caveats:** copy port-layer files only (their game code was modified for PC); same
|
||||
family ≠ identical format — validate every conversion per-field against GE headers + ROM
|
||||
ground truth. Full audit: `docs/PCPortResearch.md` §2.4.
|
||||
|
||||
## Standing procedure (you will hit more of these)
|
||||
Every ROM-serialized struct with a pointer field faults the same way once you reach more
|
||||
asset loading. The D32 fix procedure (doc §H): at the fault, `ptype /o <Struct>`; if a
|
||||
@@ -149,5 +176,7 @@ Checkpoint A: D44 committed — crash log shows a real backtrace for the D43 fau
|
||||
Then the milestone proper: stage objects load without faulting and the rendered scene
|
||||
contains actual model geometry (not just the clear color / background), stable under a
|
||||
30 s+ soak. After that, Phase 2 makes it look right (fast3d CC/RM correctness vs
|
||||
`gmain.s`) and Phase 3 adds sound (libaudio → SDL). Commit + push to `origin/master` at
|
||||
each working checkpoint using the message style `PC port: <phase> — <what>`.
|
||||
`gmain.s` — GE-specific, no PD analogue) and Phase 3 adds sound + input, largely
|
||||
copy-and-adapt from the PD port (see "PD port as standing reference" above). Commit +
|
||||
push to `origin/master` at each working checkpoint using the message style
|
||||
`PC port: <phase> — <what>`.
|
||||
+58
-6
@@ -133,6 +133,50 @@ The PC build is **CMake** (the N64 build stays Make + IDO). Dependencies:
|
||||
It deliberately **excludes** the N64 I/O drivers (`src/lib/ultra/io/*.c`),
|
||||
the boot/TLB assembly, and the RSP microcode (`.s` under `rsp/`).
|
||||
|
||||
### 2.4 PD-port copy-candidate audit (session 2026-08-22)
|
||||
|
||||
The PD port (`PD_PORT_CHECKOUT`) is a **standing reference**
|
||||
for this project (see AGENTS.md): same Rare "Indy"/Bond engine family, and its
|
||||
port layer solves the same problem classes we are currently hitting. Audited
|
||||
against our remaining work items:
|
||||
|
||||
**Direct copy candidates (Phase 3/4 — our stubs were scaffolded to be replaced
|
||||
by these):**
|
||||
|
||||
| PD file | Lines | Replaces our | Notes |
|
||||
|---|---|---|---|
|
||||
| `port/src/mixer.c` | 722 | 31-line stub | libaudio→SDL final mixer; same RareAL family. Adapt to GE's `audi.c` wiring (sample rate/buffering) |
|
||||
| `port/src/input.c` | 1551 | 48-line stub | SDL_GameController backend: hotplug, rumble, keyboard fallback. Remap the button table to GE's scheme (C-buttons/Z-trig differ from PD) |
|
||||
| `port/src/fs.c` | 294 | 81 lines | File-backed save dir (`--savedir`, `$S` path expansion) — foundation for Phase 4 EEPROM/PFS file backing (ours are no-op stubs today) |
|
||||
| `port/src/audio.c` | 75 | 70 lines | Near-identical; diff when Phase 3 starts |
|
||||
|
||||
**Reference implementations (Phase 2 — the D32/D37/D43 class).** PD's port
|
||||
layer has a `port/src/preprocess/` module (~4,125 lines): a per-ROM-segment
|
||||
`preprocessfunc` table in their `romdata.c` that converts N64-layout asset data
|
||||
to PC-native layout *at load time* — a systematic solution to the problem class
|
||||
we have been fixing ad-hoc per asset type.
|
||||
- `filemodel.c` (1,114) — the direct **D43** analogue: same `PROMOTE` idiom,
|
||||
**same vma 0x5000000**. NOT a drop-in copy (GE's `ModelRoData` union + opcode
|
||||
set differ — PD has stargunfire/headspot/gundl node types), but the node-walk
|
||||
order, placement/alignment choices, and record handling are Rare-validated
|
||||
against near-identical data: adapt rather than design from scratch.
|
||||
- `filebg.c` (524) — BG tables (an expected D43 follow-on fault).
|
||||
- `segaudio.c` (362) — audio bank-tree conversion; cross-check for our D37
|
||||
`romdataFixupAudioBank`.
|
||||
- `filelang.c`, `filetiles.c`, `filepads.c`, `filesetup.c`, `gbi.c`,
|
||||
`segfonts.c` — the remaining asset types we will hit.
|
||||
|
||||
**Not copyable:** GE-specific `ModelRoData` record map; fast3d CC/RM
|
||||
correctness (GE's custom GBI modes vs `gmain.s` do not exist in PD); PD extras
|
||||
(`config.c`, `optionsmenu.c`, `mpsetups.c`, `mod.c`) — options menu, MP setup,
|
||||
MOD player; not part of 1:1 fidelity.
|
||||
|
||||
**Caveats:** copy **port-layer files only** — their decomp was modified for PC
|
||||
(e.g. `types.h` keeps N64 offset comments while using real pointers); our
|
||||
non-negotiables are unchanged. Same family ≠ identical format: validate every
|
||||
copied conversion per-field against GE headers + ROM ground truth (the standing
|
||||
D32 procedure).
|
||||
|
||||
---
|
||||
|
||||
## 3. GoldenEye decomp: what we're porting
|
||||
@@ -1236,7 +1280,9 @@ each): `load_object_fill_header()` derives RootNode from `numtextures`
|
||||
at the wrong offset, and the `PROMOTE` rebase (`(u32)var + diff`) then
|
||||
operates on misaligned fields. Needs a D37-style re-layout of the model
|
||||
file image (header + switches array + texture table + node tree +
|
||||
ModelRoData records). Phase-2 project; see §H.
|
||||
ModelRoData records). Phase-2 project; see §H. Reference implementation:
|
||||
PD port's `port/src/preprocess/filemodel.c` — same PROMOTE idiom, same vma
|
||||
0x5000000 (§2.4); adapt + per-field validation, not a drop-in copy.
|
||||
|
||||
**D44 (OPEN)** Crash-handler Phase 2 backtrace self-faults before printing.
|
||||
`crashStackTraceSym()` in `port/src/crash.c` calls
|
||||
@@ -1335,10 +1381,14 @@ array, texture table, ModelNode tree (walked via Child/Next/Parent), and the
|
||||
per-opcode ModelRoData records — with every embedded pointer rewritten as a
|
||||
zero-extended offset from the image start so the existing
|
||||
`PROMOTE`/`diff = fileramaddr - vma` rebase works unmodified. Map the record
|
||||
types first (bondtypes.h `ModelRoData` union, opcodes in bondconstants.h);
|
||||
validate one small model against ROM ground truth under gdb before generalizing.
|
||||
Expect more D32-class ABI fixes as other per-level asset types are first
|
||||
touched — standing sub-task, not a one-off.
|
||||
types (bondtypes.h `ModelRoData` union, opcodes in bondconstants.h) — but do
|
||||
NOT design from scratch: PD port's `port/src/preprocess/filemodel.c` (§2.4) is
|
||||
a Rare-validated near-analogue (same PROMOTE idiom, same vma 0x5000000); adapt
|
||||
its node walk / placement / record handling and validate every GE record type
|
||||
per-field against bondtypes.h + ROM ground truth. Expect more D32-class ABI
|
||||
fixes as other per-level asset types are first touched — standing sub-task,
|
||||
not a one-off; PD's `preprocess/` module already solves most of them
|
||||
(`filebg.c`, `filetiles.c`, …).
|
||||
|
||||
**Dev-loop measurements + speedups (session of 2026-08-22).** Measured
|
||||
iteration costs on the dev box (16 cores): full clean rebuild ≈ 5 s wall
|
||||
@@ -1361,7 +1411,9 @@ an emulator (Mupen64Plus with the verified No-Intro dump). NOT worth it
|
||||
**Audio (Phase 3 prep).** Bank trees are correctly laid out at boot and the
|
||||
libaudio manager + audio thread run without crashing; actual sound output still
|
||||
needs an SDL backend for `alDriver`, and the ASP strategy question (C2) remains
|
||||
open. No work required until rendering is stable.
|
||||
open. No work required until rendering is stable. The SDL backend is largely
|
||||
copy-and-adapt from PD: `port/src/mixer.c` (722 lines vs our 31-line stub,
|
||||
which was scaffolded for it) plus `input.c`/`fs.c` for Phase 3/4 — see §2.4.
|
||||
|
||||
**D32 repeatable fix procedure** (apply to any ROM-serialized struct that faults
|
||||
on a pointer-field read):
|
||||
|
||||
Reference in new issue
Block a user