mirror of
https://github.com/jkdansereau/goldeneye-pc-port.git
synced 2026-10-24 00:02:45 +02:00
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.
7.2 KiB
7.2 KiB
HANDOFF — AI X-macro system (D7), the last build blocker
Status
Full ge007 build: 224 objects compile; only chraidata.c fails. All other
.c files build clean. Findings D1–D6 are resolved and recorded in
docs/PCPortResearch.md §11. D7 (this file) is the remaining blocker.
Build command:
export PATH="/c/msys64/mingw64/bin:$PATH"
cd build-pc && cmake --build . --target ge007 2>&1 | grep -A3 -i "chraidata\|aicommands\|bondaicommands"
The failing file and its includes
src/game/chraidata.c includes (lines 14–17):
#include <ultra64.h>
#include <bondgame.h>
#include <bondaicommands.h> // <- pulls in the whole AI X-macro system
#include "chrobjdata.h"
bondaicommands.h includes:
bondconstants.h(which at line 17 includes<CPPLib.h>, and at line 731 includes"aicommands.def"to build theAI_CMDenum)aicommands2.h(line 864) — a pre-generated header (fromtools/cmdbuilder.c), already preprocessed.
So the failing path is the raw aicommands.def include (bondconstants.h:731)
plus the bondaicommands.h macros (isSubroutine, SWITCH, CALL, …) that
chraidata.c uses directly.
Exact error chain (verified by rebuild)
Trigger: CALL(GAILIST_PLAY_IDLE_ANIMATION) at chraidata.c:114 (and similar at
123, 126, …). The chain:
CALL(...)expands to code that callsisSubroutine(<ID>).isSubroutine(ID)(bondaicommands.h:275–284) contains:#define isSubroutine(ID) ((ID == GAILIST_PLAY_IDLE_ANIMATION) |\ (ID == GAILIST_BASH_KEYBOARD) | \ (ID == GAILIST_ATTACK_BOND) | \ (ID == GAILIST_RUN_TO_BOND) | \ (ID == GAILIST_STARTLE_AND_RUN_TO_BOND) | \ (ID == GAILIST_WAIT_ONE_SECOND) \ IF(NOT(DEFINED(SETUPSUBROUTINES(ID))))\ (\ | SETUPSUBROUTINES(ID)\ ))DEFINED(x)(CPPLib.h:279–280):With#define DEFINED(x) _DEFINED(x) #define _DEFINED(x) IS_PROBE(CAT(_DEFINED, _##x##_))x = SETUPSUBROUTINES(ID), the##pasting_##x##_tries to paste_againstSETUPSUBROUTINES(ID)— a macro call (multiple tokens), not a single pp-token. GCC hard-errors:bondaicommands.h:281:63: error: pasting ')' and '_' does not give a valid preprocessing token- CPPLib.h:287 has a special case that was meant to handle this:
i.e. the intent is that
#define _DEFINED_SETUPSUBROUTINES(ID) PROBE(~),_##SETUPSUBROUTINES(ID)##_→_DEFINED_SETUPSUBROUTINES(ID)_→ the defined macro above. But GCC's##requires each side to be a single pp-token, so it never reaches that special case. IDO's preprocessor evidently tolerated / expanded this differently.
Secondary errors (same root family)
chraidata.c:183/202/249/640:macro 'SWITCH' requires 49 arguments, but only 20/14/26/26 given. TheSWITCHmacro (bondaicommands.h, ~line 776) has 49 fixed parameters (1 VAR + 16×3 case slots) and usesIF_VA(NOT(IS_EMPTY(..)))to detect which cases are present. Game code calls it with fewer args, relying on IDO leniency. GCC enforces the exact arg count.aicommands.def:514:270 / 550:21 / 2846:21: "expected expression before ','" / "expected '}' before 'AI_Return'" / "expected '}' before 'AI_IFICouldSeeBond'". These are downstream of theisSubroutine/DEFINEDfailure (theCALLexpansion aborts mid-macro, leaving dangling tokens). Note the reported line numbers (514/550/2846) do not match the rawaicommands.deflines (those are comment/brace lines) — they are positions in the expanded macro text, not the source file. Don't chase them as source lines.
Key facts / ground truth
aicommands.defcall counts: 255_AI_CMD(, 119_AI_CMD_POLYMORPH(, 2_AI_DEBUG(._AI_CMD_POLYMORPHdefinitions across the tree:aicommands.def:97— 4-arg(PRE, NAME, CMD_PARAMS_POST, POLY_PARAMS)but inside a#if 0block (lines 88–100) → inactive.bondconstants.h:721— 5-arg(CMD, A, P, Q, D)under#ifdef __sgi(not us).bondconstants.h:726— variadic(...)under#else(this is the one active for GCC when building theAI_CMDenum at bondconstants.h:731).chrai.c:170— 5-arg(CMD, A, P, Q, D).chrai.c:915— 5-arg(C, N, P1, P2, D).
aicommands.def:85–87:#ifndef __GNUC__ #include <CPPLib.h> #endif→ for GCC CPPLib.h is not included from aicommands.def itself; it comes in viabondconstants.h:17.aicommands.def:11888:#undef _AI_CMD_POLYMORPH(late in the file).aicommands2.his pre-generated (header says "Do not edit … generated by cmdbuilder from src/aicommands.def"). It is included by bondaicommands.h:864 and deb_loadallmodels.c:8. It is not the failing path.isSubroutineis the only macro that feeds a macro call (SETUPSUBROUTINES(ID)) intoDEFINED(). That is the unique trigger for the##pasting error.
Recommended next steps (in order)
- Fix the
DEFINED(SETUPSUBROUTINES(ID))pasting — the single root cause of theCALL/isSubroutineerrors. Preferred: aport/shim that redefinesDEFINED(or_DEFINED) after CPPLib.h is included, special-casing theSETUPSUBROUTINES(ID)argument so it does not##-paste a multi-token macro-call. Sketch:The tricky part: detecting "x is exactly/* port/shim/... after <CPPLib.h> */ #undef DEFINED #define DEFINED(x) _PORT_DEFINED(x) #define _PORT_DEFINED(x) /* if x is SETUPSUBROUTINES(ID) -> PROBE(~), else fall back */SETUPSUBROUTINES(ID)" in the preprocessor. Alternative: redefineisSubroutinein the shim to compute theSETUPSUBROUTINESpresence withoutDEFINED()(e.g. via a per-setup#define HAS_SETUPSUBROUTINES 0/1flag set before the include). Investigate which is less invasive before committing.- Constraint:
bondaicommands.handCPPLib.hare game files — do not edit them. All fixes go inport/(shim headers found first via include path) or, if truly unavoidable, a-DPORT-gatedsrc/change with aPC port:comment.
- Constraint:
- Fix the
SWITCH49-arg requirement — make a shimSWITCHvariadic (or pad the call sites). Verify theIF_VA/IS_EMPTYcase-detection still works under GCC once variadic. - Re-verify the aicommands.def:514/550/2846 errors disappear once (1) and
(2) are in — they are likely downstream of the
CALLexpansion abort, not independent bugs. - Rebuild and confirm
chraidata.ccompiles → fullge007links. - Record the resolution in
docs/PCPortResearch.md§11 D7 (replace the "OPEN" / "TBD" text) and delete this handoff file.
Do NOT
- Do not edit
tools/,Makefile,rsp/,ld/(N64 build, non-negotiable). - Do not edit
bondaicommands.h,bondconstants.h,CPPLib.h,aicommands.def,aicommands2.hunless a-DPORT-gated, layout/semantics- preserving change is truly unavoidable (and then flag itPC port:). - Do not chase the aicommands.def:514/550/2846 line numbers as source lines (they are expanded-macro positions).