7.8 KiB
7.8 KiB
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, notUSECODE.FLX, and the map renderer config has been updated to match the files now present inSTATIC/andSTATIC_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
0x0e16c6rather 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-jpnode 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 at0x00429056
- JP mission table is now supplied from a verified Ghidra live-table read at
- Current renderer/export fix: if
STATIC_JP/GAMEPAL.PALis missing, the exporter now falls back toSTATIC/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 asPALETTE.DAT, one of the other.PALassets, or an executable/resource path. - Asset/executable mismatch note: the Japanese static folder uses
JUSECODE.FLX, but a Ghidra string pass over/ja/CRUSADER.EXEfoundeusecode.flxat0x0047be90and found nojusecodestring at all. The string is consumed bystartup_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, anddtable.flx, but no explicit.palfilename strings.GAMEPALonly surfaced as the source path string".\\gamepal.c", so palette filename handling still needs more direct loader tracing. - Ghidra documentation added:
- comment at
0x00466ebcfor the JP startup usecode override path - comment at
0x0047b72cfor the verified warp base-map table - comment at
0x00429056for the table consumer path that adds-mapoff
- comment at
- Archive comparison note:
FIXDEMO.DATis inSTATIC_JP, notSTATIC_DEMO. It is byte-for-byte identical to the prefix of JPFIXED.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 1node src/export-static.js --game=remorse-demo --output=_tmp_export_remorse_demo
- Implemented renderer support:
- demo mission table now reads from
STATIC_DEMO/CRUSADER.EXEat file offset0x0e3a88 - extraction is fixed-length (
17entries) instead of sentinel-bounded - exported demo mission metadata now resolves map
1as the base map for mission1
- demo mission table now reads from
- Important naming difference: demo usecode is stored as
EUSECODE.FLXrather than plainUSECODE.FLX. - Investigation note:
STATIC_DEMOalso containsUSECODE.ZIPplus an extractedUSECODEZIP/folder withEUSECODE.FLX,OVERLOAD.DAT,UNKCOFF.DAT, andUNKDS.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 at0x0e3a88, and it does not expose the immediate retail-style double-zero terminator after those entries. - Ghidra string/xref pass on
/demo/CRUSADER.EXE:eusecode.flxis present at1478:07aaand is consumed byFUN_1420_0cdf, a 16-bit startup routine with the same broad shape as the JP/retail-uoverride path. It force-writes the first character to'e', resolves the full path, checks file existence, and only then swaps the usecode source.gamepal.palis present explicitly at1478:07d9, unlike the JP executable. It is referenced fromFUN_1028_0000, which looks like an early palette/static resource initialization path.fixed.datis present at1478:075fand is referenced fromFUN_10b8_0616, which resolves a path under thestaticdirectory before passing it into a loader helper.nonfixed.datis present at1478: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, and10b8:0616to 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_demonode scripts/compare-family-export-data.js
- Verified asset layout:
STATIC_REGRET_DEMO/FIXED.DATexposes two non-empty maps:1and2STATIC_REGRET_DEMO/REGRET.EXEis a tinyMZstub-like launcher (11,942bytes)STATIC_REGRET_DEMO/REGRET.DATis the real payload-bearing image (988,372bytes) and contains the expectedfixed.dat,nonfixed.dat,eusecode.flx,gamepal.pal, and-demostrings
- Mission-table support:
- the renderer now reads the demo base-map table from
REGRET.DAT, notREGRET.EXE - verified table location: absolute file offset
0x0e295c - extraction remains fixed-length at
17entries, matching the other supported variants
- the renderer now reads the demo base-map table from
- Export blocker and fix:
- the first Regret demo export failed because
STATIC_REGRET_DEMO/SHAPES.FLXcontains empty entries that retail Regret still has art for; shape404was the first hard failure - the renderer now supports per-entry
SHAPES.FLXfallback throughfallbackStaticDirs, 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
- the first Regret demo export failed because
- Family comparison note:
- retail Regret and Regret demo share only maps
1and2 - 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
- retail Regret and Regret demo share only maps
- Follow-up report: cross-version export diffs now live in
docs/versions/family-export-differences.md, generated frommap_renderer/generated/version-differences/family-export-differences.{json,md}.