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).
4.5 KiB
BRIEF C2-GDL — model/prop GDL runtime relocation misaligns dst (Facility, Runway)
Repo: REPO_ROOT (git master, Windows).
READ FIRST
docs/HANDOFF.mdtop,docs/PORT-LEARNINGS.md§B (16-byte PC Gfx vs 8-byte N64 — this is the class) + §D.docs/PCPortResearch.md§F D124 (the C2 split — this brief is the unfinished Facility half), D80, D82, D83, D85, D95, D58, D50.6 (Gfx-stride / GDL history — jump via §F index).AGENTS.mdnon-negotiables.rsp/graphics/gmain.s= GBI ground truth.- PD analogue:
PD_PORT_CHECKOUT— its model-GDL / texture relocation path. Check before writing anything.
SYMPTOM (WS4 re-sweep — docs/LEVEL-STATUS.md)
Facility -level_34 (fault 0x72181ee8) and Runway -level_35 (fault
0x721b8ee8) both crash in import_texture_i8 (port/fast3d/gfx_pc.cpp:821)
— fast3d fed a garbage G_SETTIMG w1.
Per the D124 investigation: the bad G_SETTIMG (fmt=4 siz=2 w=0,
preceded by an unconsumed 0xba GE tex-macro opcode) sits in a
model/prop GDL relocated at runtime by texLoadFromGdl() via
sub_GAME_7F0762E0 (objecthandler_2.c:82) — NOT a room GDL, NOT the
global bank. A GE_C2 probe showed texLoadFromGdl writing to
non-16-byte-aligned dst (0x701eac01, 0x701eb7d5, …): the
replacementgdl / name(=srcsize) offset arithmetic still mixes N64
8-byte and PC 16-byte Gfx strides, so converted commands land mid-slot
and a subsequent G_SETTIMG w1 reads as garbage.
12 levels PASS — they either don't hit this model-GDL path or hit it with a GDL whose misalignment happens to be benign.
TASK
Pin the exact stride/offset error in the model-GDL runtime relocation and
fix it narrowly (#ifdef PORT, N64 line under #else, §F-documented).
Likely spots:
src/game/tex.ctexLoadFromGdl()— src/dst pointer advance per Gfx.src/game/objecthandler_2.csub_GAME_7F0762E0—replacementgdl/srcsizemath, GDL buffer sizing.src/game/model.cmodelNodeReplaceGdl/ rwdata GDL slot stride.- The
0xba(G_GEGBIMACRO_*/ GE tex-load macro) decode — fast3d may need to consume its extra word (cf. gmain.s).
Use the existing GE_D86 / model-node probes and add a capped GE_C2GDL
probe if needed.
FILES YOU MAY TOUCH
src/game/tex.c, src/game/objecthandler_2.c, src/game/model.c
(narrow #ifdef PORT); port/fast3d/gfx_pc.cpp (only a guard / the 0xba
consume, if that's the cause); new tools_pc/c2gdl_* probes;
docs/PORT-LEARNINGS.md, docs/PCPortResearch.md §F (extend D124 or new
Dxx), docs/LEVEL-STATUS.md.
NOT src/game/propobj.c / prop.c / tools_pc/d88* (C3 agent owns
those), NOT port/src/gimgfixup.c (D124-Jungle, done).
KNOWN-GOOD / RULED OUT
- D123 (C1), D124-Jungle (
gimgfixup.c) — landed, work. - 12 levels PASS — the common GDL path is fine.
- Global-bank / explosion-DL sync (D124) — separate, fixed.
- HUD/text X-mirror (D114/D116) — parked, do NOT re-trace.
PRE-FLIGHT
export PATH="/c/msys64/mingw64/bin:$PATH" && ./build-pc.sh ntsc-final— green.- Repro
./build-pc/ge007.x86_64.exe -level_34.ge007.crash.log;addr2line -e build-pc/ge007.x86_64.exe -f -C 0x<PC>. GE_PCDUMP="80-260:40"→./ppm/;python tools_pc/pixcount.py.timeoutdoes NOT kill on Windows:... &,sleep 24,taskkill //F //IM ge007.x86_64.exe.- gdb attach fast (
gdb -batch -x cmds.txt -p <winpid>). HW watchpoint on thedstcursor intexLoadFromGdlcatches the mis-advance. - Regen sidecars after any converter change (none expected here):
python tools_pc/d43_emit.py ntsc-final && python tools_pc/d69_emit.py ntsc-final && python tools_pc/d88_emit.py ntsc-final --regen.
BUDGET
Structural / shared-infra → ~14 build→run→inspect cycles or ~2 h. On expiry: revert temp probes, write up the stride spec + best hypothesis in §F with a confidence rating + files touched. A good half-solved write-up is a deliverable.
CONSTRAINTS
No game-logic / control-flow changes. ABI/layout/format only, #ifdef PORT with N64 line under #else, §F-documented. Revert your own probes.
Don't touch the C3 agent's files.
REPORT
- Root cause —
file:line, the exact stride/offset bug, why 12 levels are unaffected. - Fix diff or why-not.
- Verification —
-level_34+-level_35boot to ≥1 non-degenerate frame (pixcount.py> a few %);-level_09+-level_20unregressed (framediff.py); re-check Jungle-level_37+ Streets-level_29(may improve). - Probes left in tree.
- Confidence rating.
- Generalisable quirk appended to
docs/PORT-LEARNINGS.md.