6.6 KiB
Using map patch file. in retail CRUSADER.EXE
This note records the current evidence-backed read of the startup line:
Using map patch file.
Short version:
- the line is printed during
Init_Everythingstartup - it is gated by a file-existence check for
static\fixed.dat - it does not mean the
-uusecode override is active - it means the game found an alternate fixed-map archive and will prefer that archive for later fixed-map loading
- current recovered behavior looks like
replacement-preferred fixed-map source, notmerge a few patched records into the base archive
Exact Startup Print Site
The live exported Ghidra C for Init_Everything at 1048:039b shows this sequence:
LoadConfigFile()Init_CheckFreeDiskSpace()File_Exists(s_static_fixed_dat)- if present,
ConsolePrintf(..., 0x9cc, 0x78) - print the generic loading/progress strings
The relevant string symbols in the live export are:
1478:09bb=s_static\fixed.dat1478:09cc=s_Using_map_patch_file.1478:09e4=s_Loading:_[1478:09ef=s__]1478:09fd=s_dot
So the startup line is not speculative or inferred from neighboring strings. The init code really does:
- check whether
static\fixed.datexists - and print
Using map patch file.only when that file is present
What The File Is
The nearby fixed-data loader path now closes this pretty tightly.
ItemCacheFixedDat_Init() is called later in startup from the same Init_Everything body. That wrapper immediately calls ItemCache_InitAndLoadFixedDat() at 10a8:163a.
ItemCache_InitAndLoadFixedDat() does all of the following:
- initializes item data
- loads the normal base fixed-map archive through
FixedDat_LoadData()at10b8:0616 - checks again for
static\fixed.dat - if present, loads that second archive into
DAT_1478_1064 - resets
g_currentMapArray = 0xffff
FixedDat_LoadData() itself resolves the standard asset path from g_fixedDatFilenamePtr and opens the regular fixed.dat resource.
That means the printed line is specifically about an alternate fixed-map archive, not a config file, not a save file, and not a usecode package.
What It Does At Runtime
The strongest currently recovered consumer is the fixed-map load path in the same item-cache family.
In the exported Ghidra C, the map-load logic does this:
- if
DAT_1478_1064 == 0, useDAT_1478_1060(the normalfixed.dathandle) - otherwise use
DAT_1478_1064(thestatic\fixed.dathandle)
That is stronger than a vague patch support claim. The current recovered shape is:
- base
fixed.datis always loaded static\fixed.datis conditionally loaded when present- later fixed-map reads prefer the
static\fixed.dathandle when it exists
Current safest interpretation:
- the message means the game found an alternate fixed-map archive under
STATIC\FIXED.DAT - subsequent fixed-object/map loading will use that archive as the active source
Merge Or Fallback Status
Current evidence does not show a merge path.
What is directly recovered:
- the game keeps two archive handles: base
DAT_1478_1060and optional patchDAT_1478_1064 - the main fixed-map load path chooses exactly one handle before reading the map entry
- if
DAT_1478_1064is non-null, that chooser uses it instead ofDAT_1478_1060 - no currently recovered outer code does
try patch, then fall back to base if missing - no currently recovered outer code reads both archives and concatenates item lists
So the strongest current read is:
static\fixed.datis a replacement-preferred archive source- not a recovered additive overlay system
That means the current evidence does not support claims like:
missing map entries in static\fixed.dat are automatically read from base fixed.datitems missing from the patch archive are filled from the base archivethe patch archive appends extra records onto the base archive at load time
Could there still be fallback hidden inside the archive object's internal methods? Possibly, but there is no evidence of that in the currently recovered call shape. The visible loader logic selects one archive handle up front and passes only that handle into the read methods.
Current safest practical conclusion:
- if
static\fixed.datis present, the game behaves like it is loading maps from that archive instead of the base archive - using it to
add a few extra things to the base oneis not a recovered supported mode - using it as a full replacement archive is the behavior the current code most clearly supports
What It Probably Does Not Mean
Current evidence argues against a few common misreads.
It is not currently the -u startup override:
- the retail
-ulane targets the EUSECODE runtime root, documented separately indocs/usecode-startup-override.md - this startup print is in the fixed-map/archive lane instead
It is also not currently evidenced as a merge-style overlay:
- the recovered map-load chooser selects one handle or the other
- this consumer does not show
check patch archive first, then fall back per-record to base
So the safest current wording is replacement-preferred alternate FIXED.DAT source, not per-entry patch merge.
Practical Meaning
When retail No Remorse prints Using map patch file. at startup, it means:
STATIC\FIXED.DATwas found- the game has enabled its alternate fixed-map archive lane
- later fixed map/object loads will prefer that archive over the normal
FIXED.DAT
In plain terms: the executable is telling you it found a replacement/patch copy of the world-map data archive and is going to load map content from that patched archive path.
Evidence Summary
1048:039b Init_EverythingchecksFile_Exists("static\\fixed.dat")and prints1478:09cconly on success10a8:163a ItemCache_InitAndLoadFixedDatloads basefixed.datplus optionalstatic\\fixed.dat10b8:0616 FixedDat_LoadDataresolves the standardfixed.datpath fromg_fixedDatFilenamePtr- recovered fixed-map load logic prefers
DAT_1478_1064(static\\fixed.dat) overDAT_1478_1060(basefixed.dat) when the optional archive is present
Ghidra Annotation Status
The live-session note to add in Ghidra is straightforward:
Init_Everything startup status print: if static\\fixed.dat exists, print "Using map patch file.". Later ItemCache_InitAndLoadFixedDat loads that archive into DAT_1478_1064, and the fixed-map load path prefers DAT_1478_1064 over the base fixed.dat handle DAT_1478_1060.
In this session the live comment could not be pushed automatically because the reachable MCP bridge endpoints for the open GUI session were unavailable and the local PyGhidra writer path is blocked by the project lock while Ghidra owns the project.