Installed JDK 21 + Ghidra 12.1.2 (no admin, %LOCALAPPDATA%\bt411-tools beside DXSDK/cmake; runner uses 8.3 SHORT paths because Ghidra's .bat expands %JAVA_HOME% unquoted and the profile has a space). New tooling: reference/ghidra_scripts/ExportGaps.java -- ExportAll's exact output contract PLUS a gap-fill pass (force disassembly + createFunction at E8 call targets outside functions, data->code pointers at a plausible prologue, and the census's discovered starts; iterated to a fixpoint, logged to gapfill_report.tsv). tools/ghidra_reexport.sh (headless runner, 'reprocess' mode) and tools/gapdiff.py (score two censused exports); gapcensus.py now censuses any export dir. Results: 6267 -> 6472 functions (+205 created in 2 rounds: 195 census starts, 6 call targets, 4 data pointers; 56.1KB newly covered), ZERO decompile failures. Dark real code 90.4 -> 40.8 KB (54.8% recovered); game-side dark 53.1 -> 21.1 KB; regions 428 -> 321. EVERY historically dark function now has pseudocode -- including @0x4c05c4 VehicleDead, the absence that opened this issue. VALIDATION: the new pseudocode confirms this week's hand reconstruction of the crouch field-for-field (mapPosture/duckState/squatCapable/myomerEff/ novice gate/SetLegAnimation/ForceUpdate/stability alarm) -- and exposed one branch the raw pass missed: AIRBORNE AUTO-RISE (mode 3|4 && legState 1 -> forced squ), now implemented in mech4.cpp and re-benched un-regressed. PROMOTION: the re-export is canonical reference/decomp/; the previous export is preserved at reference/decomp/archive_2025export/ so old `part_0NN.c:LINE` citations still resolve (addresses are stable across both; line/shard membership is NOT -- cite @ADDR). New lead recorded: @0x4c0904 is the MASTER BTPlayer Performance (team resolution, EndMission console post, score heartbeat) -- our @0x4c083c PlayerSimulation attribution needs a re-check. KB: source-completeness, gotcha #20 (the rule is cheap now -- look it up), CLAUDE.md router/layout. Log: phases/phase-04-gap-census.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
5.1 KiB
5.1 KiB
GAP CENSUS -- the export dark-region inventory (#60)
Generated by tools/gapcensus.py (deterministic; re-run after any re-export).
Machine-readable twin: gap_census.tsv.
Headline
| Metric | Value |
|---|---|
| Code section (.text) | 0x401000-0x4e0000 (892 KB) |
| Indexed functions (functions_index.tsv) | 6472, covering 833 KB (93.5%) |
| RAW DARK (no indexed function at all) | 321 regions >= 16B, 49 KB (5.5%) -- 40 KB REAL CODE after padding |
| Exported pseudocode functions (part_*.c) | 6472 |
| Indexed but NOT exported (Ghidra knew it; no pseudocode) | 0 functions, 0 KB |
| Function starts discovered inside dark regions | 135 (call-graph + data-pointer evidence) |
Reading the tables: visited = the address is already cited somewhere in
game/ context/ docs/ (a prior dig reached it); everything else is UNCHARTED.
tu = nearest file-tagged export neighbors (before|after when they disagree).
Dark code by suspected TU family
| Family | Regions | Real code bytes |
|---|---|---|
| munga/ (engine core -- source in repo) | 117 | 14544 |
| BOUNDARY/mixed | 53 | 10346 |
| bt/ (GAME -- reconstruction target) | 60 | 5848 |
| munga_l4/ (engine L4 -- source in repo) | 34 | 5563 |
| bt_l4/ (GAME video/glue -- reconstruction target) | 57 | 5492 |
Top 40 dark regions by REAL CODE bytes (padding excluded)
| # | Range | Code bytes | Fn starts | Call-ins | Visited | Suspected TU |
|---|---|---|---|---|---|---|
| 1 | 0x4596ab-0x459eb8 |
1795 | 0 | 0 | 1: 4599ae |
munga_l4/l4vidrnd.cpp |
| 2 | 0x480a2a-0x48116d |
1521 | 0 | 0 | - | munga_l4/l4splr.cpp |
| 3 | 0x40c82a-0x40cdb4 |
1322 | 0 | 0 | - | munga/scalar.cpp |
| 4 | 0x40b68c-0x40bbe8 |
1293 | 0 | 0 | - | munga/scalar.cpp |
| 5 | 0x481f77-0x48255c |
1267 | 0 | 0 | - | munga_l4/l4splr.cpp |
| 6 | 0x486467-0x486a0e |
1252 | 0 | 0 | - | munga_l4/l4splr.cpp |
| 7 | 0x47ae1b-0x47b2ec |
1060 | 0 | 0 | - | munga_l4/l4ctrl.cpp |
| 8 | 0x405b1e-0x405f44 |
972 | 0 | 0 | - | munga/filestrm.hpp |
| 9 | 0x427fd0-0x4283b8 |
931 | 0 | 0 | - | munga/network.cpp |
| 10 | 0x4d41ae-0x4d45b0 |
765 | 0 | 0 | - | bt_l4/btl4app.cpp |
| 11 | 0x4af691-0x4af9cf |
707 | 0 | 0 | - | bt/heat.cpp |
| 12 | 0x4829ab-0x482c9f |
687 | 0 | 0 | - | munga_l4/l4splr.cpp |
| 13 | 0x487a38-0x487ca0 |
615 | 0 | 0 | - | munga_l4/l4splr.cpp |
| 14 | 0x483b9b-0x483df0 |
520 | 0 | 0 | - | munga_l4/l4splr.cpp |
| 15 | 0x4d95b6-0x4d9800 |
487 | 0 | 0 | - | bt_l4/btl4app.cpp |
| 16 | 0x423202-0x423414 |
460 | 0 | 0 | - | munga/network.cpp |
| 17 | 0x45472a-0x454924 |
451 | 0 | 0 | - | munga_l4/l4vidrnd.cpp |
| 18 | 0x4b8837-0x4b8a48 |
448 | 2 | 0 | 1: 4b8837 |
bt/powersub.cpp |
| 19 | 0x474671-0x474855 |
421 | 0 | 0 | - | munga_l4/l4gauge.cpp |
| 20 | 0x4d2813-0x4d29fc |
414 | 1 | 0 | - | bt_l4/btl4vid.cpp |
| 21 | 0x4816b2-0x48186d |
404 | 0 | 0 | - | munga_l4/l4splr.cpp |
| 22 | 0x42f80b-0x42f9bc |
394 | 0 | 0 | - | munga/player.cpp |
| 23 | 0x443cf5-0x443e94 |
380 | 0 | 0 | - | munga/watcher.hpp |
| 24 | 0x4b2c11-0x4b2d8c |
324 | 0 | 0 | 11: 4b2c2d 4b2c75 4b2d00 4b2d23... |
bt/powersub.cpp |
| 25 | 0x4d993f-0x4d9c38 |
321 | 12 | 0 | - | bt_l4/btl4app.cpp |
| 26 | 0x4deec5-0x4df048 |
321 | 0 | 0 | - | bt_l4/btl4app.cpp |
| 27 | 0x4c651c-0x4c668d |
318 | 0 | 0 | - | bt_l4/btl4gaug.cpp |
| 28 | 0x409c41-0x409d9c |
312 | 0 | 0 | - | munga/scalar.cpp |
| 29 | 0x484ed6-0x485020 |
307 | 0 | 0 | - | munga_l4/l4splr.cpp |
| 30 | 0x43223f-0x4323a8 |
306 | 0 | 0 | - | munga/explode.cpp |
| 31 | 0x40f6a7-0x40f7d8 |
283 | 0 | 0 | - | munga/boxsolid.cpp |
| 32 | 0x4b1a84-0x4b1bb1 |
251 | 0 | 0 | - | bt/powersub.cpp |
| 33 | 0x481565-0x481675 |
247 | 0 | 0 | - | munga_l4/l4splr.cpp |
| 34 | 0x45888e-0x4589a0 |
241 | 0 | 0 | - | munga_l4/l4vidrnd.cpp |
| 35 | 0x4d2016-0x4d2150 |
241 | 0 | 0 | - | bt_l4/btl4vid.cpp |
| 36 | 0x466ac2-0x466bc4 |
235 | 0 | 0 | - | munga_l4/l4audwtr.cpp |
| 37 | 0x4310c3-0x4311dc |
234 | 2 | 0 | - | munga/explode.cpp |
| 38 | 0x466702-0x466804 |
234 | 0 | 0 | - | munga_l4/l4audwtr.cpp |
| 39 | 0x484076-0x48416d |
229 | 0 | 0 | - | munga_l4/l4splr.cpp |
| 40 | 0x480899-0x4809ba |
222 | 0 | 0 | - | munga_l4/l4splr.cpp |
Indexed-but-unexported functions (first 60 by address)
These have index rows (address + size) but no pseudocode in all/part_*.c --
decompile them individually (raw disasm or a targeted re-export) when a dig arrives.
| Addr | Size | Index name | Cited in repo |
|---|