Decomp updates

This commit is contained in:
MaddoScientisto 2026-03-30 00:19:01 +02:00
commit c4fa8a6b05
62 changed files with 9413 additions and 20 deletions

View file

@ -17,6 +17,8 @@ The working split is:
- Remorse usecode export: `Crusader_Decomp_Public/USECODE_REMORSE/**`
- Regret usecode export: `Crusader_Decomp_Public/USECODE_REGRET/**` for comparison only
- Retail disassembly export: `Crusader_Decomp/exports/CRUSADER.EXE.xml`
- Generated retail dtable dump: `Crusader_Decomp/tools/dump_dtable_names.py` -> `Crusader_Decomp/out/dtable_get_name_dump.json` plus companion CSVs
- Generated Regret dtable dump: `Crusader_Decomp/tools/dump_dtable_names.py regret` -> `Crusader_Decomp/out/regret_dtable_get_name_dump.json` plus companion CSVs
## High-Level Conclusions
@ -51,7 +53,7 @@ Current best read: `0343` is a surviving but heavily stripped grenade-family obj
- `LAND MINE`
- `BLAST PAC`
- `FUSION PAC`
- The repeated `INVALID` placeholders inside that same array are also informative: `1478:22BC` is a `char *[41]` table, and slots `0`, `15`, `27`, and `33` all point to the same `INVALID` string. The removed grenade names live immediately after one of those placeholder boundaries.
- The repeated `INVALID` placeholders inside that same array are also informative: the verified retail dump from `tools/dump_dtable_names.py` shows `1478:22BC` is a `char *[41]` table whose global slots `0`, `14`, `26`, and `32` all point to the same `INVALID` string. The removed grenade names then occupy bomb-family slots `33..40` as `GRENADE`, `CONCUSSION GRENADE`, `NERVE GAS GRENADE`, `EMP GRENADE`, `SPIDER BOMB`, `LAND MINE`, `BLAST PAC`, and `FUSION PAC`.
- This means the removed grenade family is not just a renderer/catalog naming artifact. The retail executable still knows those display strings even though the distinct Remorse scripted classes appear to be gone.
Current best read: these are old grenade-family placements left in maps and editor-era data whose exact inventory/display names still survive in the retail executable, but whose distinct Remorse behavior has likely been removed or collapsed away before retail. The user-observed behavior where some can be forced into inventory but do nothing is consistent with a leftover shape/name path surviving after the actual item logic was cut.
@ -65,7 +67,7 @@ Current best read: these are old grenade-family placements left in maps and edit
- its fallback branch at `1118:05D5` returns `DS:238C`, which is the string `INVALID`
- `Weasel_OnPaint` at `13E0:0932` calls `DTable_GetNameForShapeNo`, so this is a real inventory/display UI path rather than an isolated dead string helper
- The backing data segment confirms the same model. In segment `1478`, the item-name table at `1478:22BC` is a `char *[41]` array whose placeholder slots point at the `INVALID` string at `1478:238C`.
- I still have not closed the exact shape-to-table-index mapping for `0548`, but the retail executable evidence now cleanly supports the user report that at least some bad/unmapped inventory entries resolve to visible label text `Invalid` in-game.
- The verified dump also closes one open point: `0x0548` does **not** appear in the resolved dtable category tables at all. Its visible in-game `Invalid` label is therefore best explained as a plain `DTable_GetNameForShapeNo` fallback for an unmapped shape, not as a dedicated `0548` name-table entry.
Current best read: `0548` is a real leftover item-like record that still resolves through at least one executable-side text/name path, but no meaningful use behavior has been recovered yet.
@ -101,6 +103,26 @@ The retail name table behind `DTable_GetNameForShapeNo` was useful beyond the or
Current best read: these are active explosive inventory objects, not additional removed-item discoveries. The current catalog simply does not label all of them clearly.
### Reusable dump status
- The retail `DTable_GetNameForShapeNo` mapping is now exported in reusable form for downstream tooling:
- `out/dtable_get_name_dump.json`
- `out/dtable_global_name_slots.csv`
- `out/dtable_category_entries.csv`
- `out/dtable_resolved_shapes.csv`
- That dump is generated by `tools/dump_dtable_names.py` directly from retail `CRUSADER.EXE` bytes plus `exports/CRUSADER.EXE.xml` relocations, so it is suitable for feeding the map renderer and shape catalogs without keeping the mapping only in prose notes.
### Regret-side DTable comparison
- The same dumper now also supports live `REGRET.EXE`, with the recovered helper at `1130:056a` and the Regret dtable island in segment `1480`.
- The Regret dump closes the shifted layout directly from raw bytes even without a local `REGRET.EXE.xml` export: pointer table `1480:2856`, string pool `1480:2926`, and category tables at `1480:2590` (ammo), `1480:2614` (weapons), `1480:2792` (misc items), and `1480:27DE` (bombs).
- Regret also repeats a single `INVALID` string through four global slots, but at a different expanded layout: indices `0`, `17`, `36`, and `44` all point back to `1480:2926`.
- That expanded Regret table preserves several names that do not appear in the earlier Remorse dump, including weapons `BK-16`, `LNR-81`, `XP-5`; items `IONIC SHIELD`, `PLASMA SHIELD`, `DISRUPTER`, `SPIDER MINE`, `DATA PICK`, `MINE DET`, `PORTABLE BETTY`, `RADIATION SHIELD`, and `VIR IMAGER`; and ammo `BK-16 CLIP`, `LNR-81 CLIP`.
- The resolved Regret bomb rows are also narrower than a naive string scan suggests: `0x0343` = `GRENADE`, `0x0350` = `EMP GRENADE`, `0x0560` = `SPIDER BOMB`, `0x039A` = `LAND MINE`, and `0x039C` = `FUSION PAC`.
- `BLAST PAC` is notably absent from the recovered Regret dtable output. In other words, the Regret executable still carries `LAND MINE` and `FUSION PAC`, but not a `BLAST PAC` bomb-table slot analogous to the Remorse block.
Current best read: the Regret comparison strengthens the claim that these explosive names come from a real retail inventory/display lookup family rather than renderer-only catalog text, but it also shows that the two games do not preserve the exact same bomb/item naming inventory.
### Spider bomb: stronger Regret-side evidence than Remorse-side evidence
- The same retail name table includes `SPIDER BOMB`.
@ -144,7 +166,7 @@ Current best read: these are real leftover placeholder objects worth a future de
## Open Questions
1. What exact shape or category values land on the four `INVALID` placeholder slots in the retail `1478:22BC` dtable array, and is `0548` one of them directly?
1. What code path allows `0548` and similar bad/unmapped shapes to reach the inventory/display UI if they are not direct entries in the retail `1478:22BC` dtable mapping?
2. Do `034E`, `034F`, and `0350` still have dead executable-side item-definition records even though no separate Remorse usecode classes were recovered?
3. Is the observed forced-pickup behavior using a generic item acquisition path that bypasses normal `invitem` rules and therefore reaches the `DTable_GetNameForShapeNo` fallback path?
4. What are `0110` and `0112` visually or functionally in the old maps, beyond being non-pickup leftovers?