77 lines
7.8 KiB
Markdown
77 lines
7.8 KiB
Markdown
# Version Export Differences
|
|
|
|
## 2026-03-31 exporter check
|
|
|
|
- Renderer config correction: the retail No Remorse and No Regret static folders now both use `EUSECODE.FLX`, not `USECODE.FLX`, and the map renderer config has been updated to match the files now present in `STATIC/` and `STATIC_REGRET/`.
|
|
- Mission-table correction: Remorse 1.01 also needed a version-specific mission-table override. Its executable does contain the same 17-entry base-map sequence as retail, but at file offset `0x0e16c6` rather than the retail location.
|
|
|
|
### No Remorse JP
|
|
|
|
- Status: supported in the map renderer. JP scene export works, and JP mission metadata now generates correctly from a verified live Ghidra table read.
|
|
- Verified commands:
|
|
- `node src/build-cache.js remorse-jp`
|
|
- `node src/export-static.js --game=remorse-jp --output=_tmp_export_remorse_jp`
|
|
- Implemented renderer support:
|
|
- JP mission table is now supplied from a verified Ghidra live-table read at `0x0047b72c`
|
|
- extracted base-map sequence: `0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 40`
|
|
- consumer path verified in `FUN_00428e00`, with the key table-read site at `0x00429056`
|
|
- Current renderer/export fix: if `STATIC_JP/GAMEPAL.PAL` is missing, the exporter now falls back to `STATIC/GAMEPAL.PAL`.
|
|
- Important limitation: this is only a temporary compatibility fallback. The Japanese asset set does not currently include a visible `GAMEPAL.PAL`, and it still needs investigation whether the correct palette lives in another file such as `PALETTE.DAT`, one of the other `.PAL` assets, or an executable/resource path.
|
|
- Asset/executable mismatch note: the Japanese static folder uses `JUSECODE.FLX`, but a Ghidra string pass over `/ja/CRUSADER.EXE` found `eusecode.flx` at `0x0047be90` and found no `jusecode` string at all. The string is consumed by `startup_apply_u_override_if_present`, which looks like a startup override hook for the usecode path rather than a JP-specific rename path.
|
|
- Additional Ghidra note: the JP executable string pass found `static\fixed.dat`, `fixed.dat`, `shapes.flx`, `glob.flx`, `fonts.flx`, `eusecode.flx`, and `dtable.flx`, but no explicit `.pal` filename strings. `GAMEPAL` only surfaced as the source path string `".\\gamepal.c"`, so palette filename handling still needs more direct loader tracing.
|
|
- Ghidra documentation added:
|
|
- comment at `0x00466ebc` for the JP startup usecode override path
|
|
- comment at `0x0047b72c` for the verified warp base-map table
|
|
- comment at `0x00429056` for the table consumer path that adds `-mapoff`
|
|
- Archive comparison note: `FIXDEMO.DAT` is in `STATIC_JP`, not `STATIC_DEMO`. It is byte-for-byte identical to the prefix of JP `FIXED.DAT`, but it is truncated: only the first two non-empty map payloads are readable, and the remaining 61 non-empty table entries run past EOF. That makes it look more like a cut-down/demo fragment than a complete alternate archive. It may still be worth exposing separately later for comparison, but it is not a full parallel map set.
|
|
|
|
### No Remorse Demo
|
|
|
|
- Status: supported in the map renderer. The detected demo map exports cleanly, and demo mission metadata now generates correctly.
|
|
- Verified commands:
|
|
- `node src/build-cache.js remorse-demo 1`
|
|
- `node src/export-static.js --game=remorse-demo --output=_tmp_export_remorse_demo`
|
|
- Implemented renderer support:
|
|
- demo mission table now reads from `STATIC_DEMO/CRUSADER.EXE` at file offset `0x0e3a88`
|
|
- extraction is fixed-length (`17` entries) instead of sentinel-bounded
|
|
- exported demo mission metadata now resolves map `1` as the base map for mission `1`
|
|
- Important naming difference: demo usecode is stored as `EUSECODE.FLX` rather than plain `USECODE.FLX`.
|
|
- Investigation note: `STATIC_DEMO` also contains `USECODE.ZIP` plus an extracted `USECODEZIP/` folder with `EUSECODE.FLX`, `OVERLOAD.DAT`, `UNKCOFF.DAT`, and `UNKDS.DAT`. This needs a later provenance/content check to determine whether the zip is archival noise, patch material, or the authoritative demo usecode bundle.
|
|
- Root cause and fix: the earlier garbage mission extraction came from using the retail Remorse file offset (`0x0e4088`) against the demo executable. The demo binary does still carry the same 17-entry base-map sequence, but at `0x0e3a88`, and it does not expose the immediate retail-style double-zero terminator after those entries.
|
|
- Ghidra string/xref pass on `/demo/CRUSADER.EXE`:
|
|
- `eusecode.flx` is present at `1478:07aa` and is consumed by `FUN_1420_0cdf`, a 16-bit startup routine with the same broad shape as the JP/retail `-u` override path. It force-writes the first character to `'e'`, resolves the full path, checks file existence, and only then swaps the usecode source.
|
|
- `gamepal.pal` is present explicitly at `1478:07d9`, unlike the JP executable. It is referenced from `FUN_1028_0000`, which looks like an early palette/static resource initialization path.
|
|
- `fixed.dat` is present at `1478:075f` and is referenced from `FUN_10b8_0616`, which resolves a path under the `static` directory before passing it into a loader helper.
|
|
- `nonfixed.dat` is present at `1478:0769`, but this pass did not recover any direct xrefs to the string yet, so it may be unused, late-bound, or referenced through a table path not exposed by the current MCP queries.
|
|
- The demo executable also carries `-demo`, `"Loading demo: ["`, and `"Demo mode.\n\r"` strings, which supports the idea that this build has a materially different startup/game-flow path from retail.
|
|
- Added Ghidra comments at `1420:0cdf`, `1028:0000`, and `10b8:0616` to preserve those verified findings in the demo database.
|
|
|
|
### Other follow-up
|
|
|
|
- Demo renderer/export support is now working end-to-end.
|
|
- JP renderer/export support is now working end-to-end.
|
|
- No Regret demo renderer/export support is now working end-to-end.
|
|
- The viewer now preserves map selection more intelligently across versions: equal-count variants within a family try to keep the same map ID, one-map builds auto-select their only map, and switching between the Remorse and Regret families falls back to the last remembered map for the target family.
|
|
|
|
### No Regret Demo
|
|
|
|
- Status: supported in the map renderer. Both detected demo maps export cleanly.
|
|
- Verified commands:
|
|
- `node src/export-static.js --game=regret-demo --output=_tmp_export_regret_demo`
|
|
- `node scripts/compare-family-export-data.js`
|
|
- Verified asset layout:
|
|
- `STATIC_REGRET_DEMO/FIXED.DAT` exposes two non-empty maps: `1` and `2`
|
|
- `STATIC_REGRET_DEMO/REGRET.EXE` is a tiny `MZ` stub-like launcher (`11,942` bytes)
|
|
- `STATIC_REGRET_DEMO/REGRET.DAT` is the real payload-bearing image (`988,372` bytes) and contains the expected `fixed.dat`, `nonfixed.dat`, `eusecode.flx`, `gamepal.pal`, and `-demo` strings
|
|
- Mission-table support:
|
|
- the renderer now reads the demo base-map table from `REGRET.DAT`, not `REGRET.EXE`
|
|
- verified table location: absolute file offset `0x0e295c`
|
|
- extraction remains fixed-length at `17` entries, matching the other supported variants
|
|
- Export blocker and fix:
|
|
- the first Regret demo export failed because `STATIC_REGRET_DEMO/SHAPES.FLX` contains empty entries that retail Regret still has art for; shape `404` was the first hard failure
|
|
- the renderer now supports per-entry `SHAPES.FLX` fallback through `fallbackStaticDirs`, so sparse demo shape archives can borrow only the missing retail shapes instead of replacing the whole archive
|
|
- build fingerprinting was updated so these layered archive inputs participate in cache invalidation
|
|
- Family comparison note:
|
|
- retail Regret and Regret demo share only maps `1` and `2`
|
|
- both shared maps differ in the normalized exported scene payload; the demo versions have more fixed-source rows, more editor items, and more sprites than retail for those two maps
|
|
- Follow-up report: cross-version export diffs now live in `docs/versions/family-export-differences.md`, generated from `map_renderer/generated/version-differences/family-export-differences.{json,md}`.
|