The release/v0.4.0 branch had never been compiled on Linux; two
port-layer include-resolution spots that MinGW tolerated break under
glibc. Shim-only fixes, zero src/ edits, no rule-2:
- port/shim/PR/ucode.h + port/shim/bondconstants.h: break the
bondconstants.h -> ultra64.h -> pc_protos.h -> bondtypes.h ->
bondconstants.h first-include re-entry by deferring pc_protos.h during
bondconstants.h's own ultra64.h pass (_PORT_DEFER_PC_PROTOS).
- port/shim/PR/gbi.h: define _SHIFTL/_SHIFTR when absent, so video.c's
gbi.h macros keep their mbi.h definitions on Linux.
Builds + links clean on Ubuntu 24.04 (glibc 2.39 <= SteamOS 2.41).
optionsoverlay.c called atoi and lround through implicit int declarations
(GE's stub stdlib.h/math.h shadow the CRT, D324 class); atoi joins the
other K&R decls in port/shim/stdlib.h, lround gets a local prototype.
Windows + Linux builds clean of both warnings.
GE_INPUTSCRIPT gains ZHOLD/ZREL (sustained fire) for automatic-weapon
audio repros. D207/D241: headless burst-fire at 60 vs 30 fps with the
alarm forced logged zero voice drops at both caps; owed a real-play
capture. Golden gate 3/3.
The N64 <stdlib.h> stub declares neither. MinGW's other CRT headers leak
them; a strict host GCC (Linux/macOS, -std=gnu11) does not, so getenv()'s
64-bit char* return is assumed int and truncated -> configGetFrameDump
(GE_PCDUMP path) dereferenced a low-32 pointer and segfaulted. Add K&R
decls: pc_protos.h (D38 mechanism -> game TUs via <ultra64.h>) and the
port/shim/stdlib.h non-Windows branch (-> port TUs that #include
<stdlib.h>). K&R form stays compatible with the real prototypes; malloc/
calloc/free are already covered elsewhere so not repeated.
The decomp's src/sched.h (N64 OSSc* scheduler) is on the include path and
shadows the system header. libstdc++'s <thread>/<mutex> gthr headers in the
fast3d C++ TUs #include <sched.h> and need the real one (cpu_set_t,
sched_yield) -- with -std=gnu++20 libstdc++ defines _GNU_SOURCE so
<pthread.h> also references cpu_set_t. New shim: C++ -> generated
hostsched.h (absolute path, hoststring pattern); C -> #include_next so
src/sched.h still wins as before. Windows build verified green (240/241).
SDL2's headers (SDL_stdinc.h, SDL_hidapi.h) and glibc's <bits/wchar2.h>
reference wchar_t. In C it is a library typedef owned by the compiler's
shadowed <stddef.h>, which our shim replaces with builtin-derived types
on Linux/macOS. Add wchar_t from __WCHAR_TYPE__, guarded by _WCHAR_T so a
real <stddef.h> reached another way stays a no-op. C-on-Linux/macOS
branch only; MinGW and C++ paths untouched.
Next GCC-on-Linux breaks after the stddef fix (linux-build CI):
- port/shim/stdarg.h routed to the decomp include/stdarg.h, which defines
va_list from __builtin_va_list but NOT the __gnuc_va_list alias that
glibc's <stdio.h> references — 'unknown type name __gnuc_va_list' across
every TU that pulls <stdio.h>. Add a Linux/macOS branch that provides
va_list / __gnuc_va_list / va_* straight from compiler builtins and does
not drag <ultra64.h> into system-header parsing. Windows branch unchanged.
- pc_protos.h declared snprintf's size argument as 'unsigned long long' —
correct on MinGW (LLP64) but not glibc, where size_t is 'unsigned long':
'conflicting types for snprintf'. Spell it size_t (now visible via the
stddef fix); identical to ull on MinGW.
Windows: both changes are no-ops on MinGW (stdarg Windows branch byte-identical;
size_t == unsigned long long).
The first cut routed C TUs to hoststddef.h unconditionally. That regresses
MinGW: its <stddef.h> defines `errno (*_errno())`, which collides with
PR/os.h's `u8 errno;` field. And hoststddef.h's bin/../include/stddef.h path
does not exist on Linux anyway.
Split three ways: C++ -> hoststddef.h (unchanged); C on Windows -> the empty
N64 stub (unchanged, pre-existing behaviour); C on Linux/macOS -> size_t /
ptrdiff_t / NULL / offsetof from __SIZE_TYPE__ / __PTRDIFF_TYPE__ /
__builtin_offsetof (always predefined, no header, no collision).
Verified: Windows ntsc-final builds 240/240, -level_09 boots crash-free.
Two GCC-on-Linux build breaks that MinGW masked (surfaced by the new
linux-build CI job):
- port/shim/stddef.h routed C TUs to the empty N64 include/stddef.h stub.
MinGW's CRT headers leak size_t/ptrdiff_t transitively; glibc/GCC define
them only in the compiler's own <stddef.h>, so include/PR/ultratypes.h's
non-N64 path ("typedef ptrdiff_t ssize_t") failed with "unknown type name".
Route C TUs to hoststddef.h too (C++ already was). Additive — the active
N64 stub typedefs nothing.
- CMakeLists: dram_syms.s absolute symbols at 0x70000000 need a non-PIE image
on Linux exactly as they need --disable-dynamicbase on Windows. Add an
elseif(UNIX AND NOT APPLE) branch: -fno-pie / -no-pie.
Windows unaffected (host <stddef.h> is strictly more correct than the stub;
the MINGW linker branch is unchanged).
- README, LICENSE (MIT for the port layer), NOTICE, CONTRIBUTING.
- Restructure docs: internals.md, porting-notes.md, dev-process.md +
dev/agentic-development.md (the research write-up), dev/ (raw record).
- Replace decomp status-badge CI with a PC-port validate workflow.
- Remove session/agent scaffolding and stale planning docs from the tree.
- Add .gitattributes (normalize line endings to LF); add screenshots.
The pre-2026-08 history is the GoldenEye 007 decompilation by Larry Ficken
(KholdFuzion) and contributors, preserved unchanged. The PC-port work from
2026-08-17 on is mine.
D59/D64: the 'external GL DLL' crash was an unbounded blood-RLE write
(sentinel die_blood_image_end lost its N64 section adjacency on PC)
clobbering the gun-barrel sub-DL at ptr_logo_and_walletbond_DL+0x200.
D60: osPiStartDma DMA-target validation (VirtualQuery-based) in libultra.c.
D61/D63: TEMP env-gated ROM-read / VTX-pool / menu probes (strip list in
HANDOFF Task 3). D62: OSMesgQueue/OSScMsg PC layout verification.
D65/D65b: enum HEADS/BODIES signed sentinels under PORT (PC GCC picks
unsigned underlying types; N64 semantics were signed).
D66: romCopyAligned + ramrom replay 64-bit pointer width (s32 truncation
of .bss targets > 4 GiB). D67: struct image_entry N64 layout
reconstruction (dataoffset:24 first, all-u32 bitfields, sizeof==8).
D68: Globalimagetable BE->LE fixup (port/src/gimgfixup.c): bswap the
IMAGESEG-marked Gfx w1 words in the 17 ROM-copied DLs + sImageTableEntry.
index in the 32 tables after texReset's romCopy; marker scan moved to
bytes 6..7 under PORT; compiled globalDL shadows synced post-texLoad for
explosion.c's g_ExplosionDisplayLists.
Result: game boots, plays intro music, and renders the entire ~3.5-minute
intro (logo -> gun barrel with Brosnan -> cast screen) at ~59 fps. New
blocker D69: load_bg_file faults on first stage load - BG-file headers are
N64 big-endian segment-0x0F offsets read LE on PC. Full analysis + strategy
in PCPortResearch.md §F/D69; HANDOFF rewritten for the D69 session.
- D38: implicit function declarations truncated pointer returns on x86-64;
added port/include/pc_protos.h prototype shim (398 decls, C-only, anchored
in port/shim/PR/ucode.h) + pc_netorder.c for ntohl/ntohs; build warning-clean.
- D39: Globalimagetable rebasing - per-symbol offsets + GIMG_OFF() in
image_bank.c (== N64 (u32)&sym incl. the 0x02000000 base); segment end
markers extended to the true 0x13F8 size (CSV entry truncated by 0x930).
- D40: g_ModelHitEntries pool sized for the 40-byte PC ModelHitEntry stride
(was a 12KB .bss overflow clobbering is_ramrom_flag -> demo-replay SIGSEGV).
- D41: release the GL context from the host main thread after videoInit so
the game scheduler thread can bind it (WGL single-thread currency; this
SDL2 build's MakeCurrent return value is an inverted ABI artifact).
- D42: rsp.c g_gfxTaskSettingsList XOR toggle -> explicit toggle on x86-64.
Boot now renders real frames ([NOTE] frame N rendered in ... us). Next
blocker D43 (model-file loading ABI mismatch) documented in PCPortResearch.md
section F/H; HANDOFF.md rewritten for it.
- Replace setjmp/longjmp green threads with real pthreads (8MB stacks);
PortQueue side table (mutex+condvar) for OSMesgQueue; dedicated tick
thread posts VI retrace + services timers (D24).
- Dual-mapped N64 DRAM: one 8MB store at V1 0x70000000 (s32-safe, all game
RAM symbols) and V2 0x80000000 (KSEG0 mirror for offset|0x80000000
rebuilds). Windows: CreateFileMappingW + MapViewOfFileEx; POSIX: memfd
+ MAP_FIXED. dram_syms.s pins cfb_16/_bssSegmentEnd/tlb block (D25).
- Address-width shims: PHYS_TO_K0 identity, OS_K0_TO_PHYSICAL = offset from
V1 base, OS_PHYSICAL_TO_K0 identity; fast3d seg_addr() remaps small
offsets into V2 (D26).
- ASLR off (-Wl,--disable-dynamicbase): absolute symbols referenced through
pointer-typed externs (.refptr + BASE reloc) must not rebase; startup
sanity check on image base 0x140000000 (D27).
- osPiStartDma posts its completion message on every path (fixes
romReceiveMesg deadlock) (D29).
- SEH-free crash handler: raw fault log first, validated manual EBP-chain
walk second (-fno-omit-frame-pointer), TerminateProcess; crashDumpThreads
via Toolhelp32 for heartbeat hang dumps (D30).
- PD fast3d integrated (port/fast3d/), replaces gfxstub.c; real src/sched.c
compiled; mainproc runs as a real pthread, host thread pumps SDL events.
- Docs: findings D24-D31 + Phase 2 status (section F/G).
Current state: boots through bossInitMainthreadData to langInit(), then
SIGSEGVs on the first file load — stack frame clobbered by a table of
truncated s32 pointers (D31, open). Next: attribute the write with
'set scheduler-locking on' + hardware watchpoint.
All ~235 translation units now compile and the target links under MSYS2
GCC 16 + CMake/Ninja (ninja ge007 -k 0: 236/236, zero errors). N64 build
untouched; every src/ change is -DPORT-gated.
Portability fixes (findings D7-D17 in docs/PCPortResearch.md section 11):
- AI X-macro system: SWITCH() call sites activated to the author's
hand-written byte-identical references under PORT; port/shim/
bondaicommands.h + bondconstants.h + CPPLib.h re-emit the IDO paste
tricks (isSubroutine, file-record macros, generated CALL) GCC-clean.
- 64-bit pointer-in-word initializers: monAnim jump targets now go
through an index table resolved by the interpreter (chrai.h/propobj.c);
UsetuplenZ.c credits pointer PORT-gated to 0.
- IDO printf engine compiled for PC (xprintf/xlitob/xldtob) with a
shadow xstdio.h resolving the _Printf prototype clash.
- Host-libc gaps stubbed in port/: bcopy/bzero, __libm_qnan_f,
tlbmanage*, g_ViXScales/YScales; chrObjRandom PRNG ported from .s.
Asset data strategy (D16): single-file assets compiled for real
(animation tables, fonts, textures, rareware logo); obseg per-file .c
excluded (colliding file-local globals the N64 build isolates via
per-ELF linking); 758 ROM-derived table symbols + ramrom_* + segment
markers stubbed in port/src/assetstubs.c / n64stubs.c.
fast3d is a no-op placeholder (port/src/gfxstub.c) until Phase 2 brings
in the real software RSP. Binary not yet runnable end-to-end: ROM
loading in romdata.c is still a TODO.