mirror of
https://github.com/jkdansereau/goldeneye-pc-port.git
synced 2026-10-23 15:52:42 +02:00
WS4 level sweep driven to completion: 12/21 solo levels PASS (load + render + no-crash). Full matrix in docs/LEVEL-STATUS.md, reusable runner tools_pc/level_sweep.sh, WS6 checklist docs/LEVEL-PLAYTEST.md. Fixes: - D123 (tools_pc/d88_propdefs.py): crash class C1 on 6 levels (Dam/Runway/Frigate/Statue/Streets/Cradle). D122 fallout - the widened Vehichle/AircraftRecord.ailist slot was zeroed instead of carrying its read-before-write integer AI-list id, so prop.c -> ailistFindById(0) -> GAILIST_AIM_AT_BOND -> ai() ran a CHR aim list with a NULL chr -> chrIsNotDeadOrShot(NULL). New OBJ_ID_WORDS arm. 4 levels -> PASS, Runway falls through to C2. BUNKER1/Silo unregressed. - D124 (port/src/gimgfixup.c): crash class C2 on Jungle. Compiled explosion-DL pointer-sync keyed on an IMAGESEG marker that texLoad() had already erased -> compiled globalDL_0xNNN arrays kept link-time IMAGESEG words -> 0xABCDxxxx into fast3d on first explosion draw. Latent on every level. Detect the slot from the compiled array instead. Diagnosed, NOT fixed (write-ups in PCPortResearch.md SF): - C2-GDL (D124-Facility addendum): Facility/Runway - model texture-pool path yields a garbage tex->data; every model file loads at an odd bank base (mempAllocBytesInBank does no alignment). Suspect d43_emit.py/pcmodels sidecar texture-blob offsets (N64 8B vs PC 16B Gfx). - C3/C6 (D125): Aztec/Bunker2/Surface2 - converted propDefs blob in RAM doesn't match d88_propdefs.py offline output (garbage after record 0); runtime sizepropdef() walk drifts ~100 records -> wrong door/modelid. d88_propdefs.py convert_stream + sizepropdef() PORT strides verified correct; suspect a dest-offset/pd_end bug in d88_emit.py propdefs emit. Remaining: 9 crashes / 6 classes (C2-GDL, C3/C6, C2m Jungle G_MTX, C5 Control BG portal, C4 Depot BG tile/room, C7 Surface1 sndSetupSound). Priority order in docs/LEVEL-STATUS.md. Also folds in the in-progress docs restructure (HANDOFF/AGENTS/CLAUDE, PCPortResearch D121/D122 SF/SH entries, PLAN-linear-level-sweep, HANDOFF-ARCHIVE, BACKLOG).
7.4 KiB
7.4 KiB
RESOLVED — historical. D7 closed at the compile+link milestone. Kept for the AI X-macro analysis. Not active work.
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).