12 KiB
Crusader Disasm Reference Corpus
Purpose
This note records the reusable knowledge in the separate local project at K:/ghidra/crusader-disasm and how it should be consumed inside the main Crusader_Decomp workflow.
Treat that repo as an auxiliary evidence corpus, not as direct rename authority for CRUSADER-RAW.EXE or the NE-loaded CRUSADER.EXE program.
Main Assets
Handwritten notes
misc_crusader_notes.txt is a compact scratchpad with a few still-useful anchors:
- keyboard event/code notes:
CTRL-M = 0x432,CTRL-L = 0x426,CTRL-V = 0x42f,CTRL-Q = 0x410 - shape/event examples:
STEAM2(shape 1297) is noted with event15(enterFastArea) and 24 animation frames SnapEgg(shape 0x4fe) is noted as entering the fast area and being handed to aSnapProcess- chest/monitor examples preserve concrete shape ids and field snapshots that can be cross-checked against map/object dumps
- old standalone function labels such as
FUN_1130_0896are useful only as historical waypoints; they are not direct rename authority for the current raw or NE Ghidra databases
Safe use:
- event/id hinting
- shape-id cross-checks
- lead generation for later binary confirmation
Unsafe use:
- direct function renames based only on these handwritten notes
- assuming the old segment numbering matches the current
CRUSADER-RAW.EXEorCRUSADER.EXEimports without a verified address mapping
Shape metadata tables
shapedata.txt and especially shapedata_more_complete.txt provide a broad Shape info N data 4(top),5,7,8 table.
Current best reuse:
- cross-check
shapeinfobytes and flags against item/entity behavior already seen in the binary - identify repeated per-shape flag/value families before promoting any field meaning
- support later naming of shape-related globals, cache entries, and trigger/object classes
This is one of the strongest data-side additions in the external corpus because it is broad, structured, and easy to re-test locally.
Static map/object dumps
mapdump/map-item-dump.txt is a large coordinate/event-style dump of placed world items.
Current best reuse:
- correlate static placements with
EVENT,NPCTRIG,CRUZTRIG, and related USECODE families - cross-check specific shapes noted in
misc_crusader_notes.txtagainst real map presence - build targeted map-level test cases for later
CRUSADER.EXEnaming and annotation work
This file is valuable because it gives real world-layout evidence that complements the owner-loaded USECODE work already documented in docs/usecode-roundtrip-ir.md.
USECODE opcode list
usecode_opcodes.txt contains an extracted opcode table for the JP release of Crusader: No Remorse.
Useful properties:
- broad opcode coverage from
0x00through0x7b - readable names for assignment, local/member reference, control-flow, spawn/process, and search-family operations
- a concrete local opcode vocabulary independent of ScummVM/Pentagram naming layers
Reuse rule:
- use these names as parser and report hints only
- do not assume the textual names alone are enough to rename compiled handlers in the DOS binary
Intrinsic and function dumps
The unkcoffs/ directory holds older cross-version name tables such as:
reg_functions.txtrem_functions.txtreg_intrinsic_dump.txtrem_intrinsic_dump.txtu8_intrinsic_dump.txt
These dumps are useful because they preserve prior RE vocabulary for Remorse/Regret/U8 function and intrinsic families, including many item, actor, audio, palette, and world operations.
Current safe use:
- hint-only metadata for intrinsic ordinals, signatures, and broad subsystem labels
- cross-version comparison when a Remorse/Regret difference matters
- porting candidate generation for the NE
CRUSADER.EXEproject, where segment-based labels may be easier to reconcile than in the flat raw import
Current unsafe use:
- direct rename authority for modern Ghidra functions
- assuming one game's intrinsic numbering matches another without local confirmation
Validated follow-up on misc_crusader_notes.txt
Several of the old scratchpad items are now tight enough to record as verified follow-up rather than open leads.
STEAM2(shape 1297) is no longer just a handwritten event hint. Local extracted data now confirms non-emptySTEAM2::enterFastArea(event 0x0f) andSTEAM2::gotHit(event 0x06) bodies inUSECODE/EUSECODE_extracted/class_event_index.tsv, which matches the old note'sevent 15 (enter fast area)andGot Hit: spawn processdirection.- The old standalone labels
FUN_1130_0896,FUN_1130_32af,FUN_1020_0000, andFUN_1128_026bare now closed in the live NE database asKey_HandleOptionKeys,NPC_ResetToStartOfAnim,Game_Start, andItem_ReceiveHit. The historical notes were directionally useful, but the live names now capture their real scope:NPC_ResetToStartOfAnimresets an NPC/item frame to the first frame of a chosen animation and updates the stored last-anim state, whileItem_ReceiveHitis the main damage/death handler rather than a loose "various deaths" helper. - The
Item_ReceiveHitdecomp also closes several handwritten shape hints directly from code. It uses0x576for the burning human replacement path (flaming guy running around),0x5a9and0x52bfor shield-zap sprites, and still routes controlled-NPC death throughTarget_PutTargetingReticleOnItem(0), which keeps the old0x59areticle note on the right subsystem. - The old
ItemNPC_AnotherCreatearea-search TODO is now directly closed in the live NE program:10e8:2710(now renamedNPC_CreateIfAreaSearchValid) allocates/initializes anAreaSearchstruct, checksAreaSearch_IsValidPositionPt, and only then runsNPC_CreateplusItem_PopToCoords. So the practical role iscreate NPC only if the requested point passes area-search placement validation, not a second independent spawn path. - The handwritten
Kernel_11d0_2491gloss was incomplete. The live function is not merely "prints kernel info"; it serializes the process table, timer/keyboard/mouse process-id lists, process sizes, and per-process state through file-like writer callbacks, then restores timer/interrupt state afterward. Current safest read iskernel/process snapshot writerrather than a simple printf-style diagnostics helper. FREE::ordinal3Cis still corpus-side evidence rather than live-NE proof, but the old disassembly now constrains it much better than the original note implied. It clears the alert state, checks avatar stasis, rolls random thresholds, and spawnsFREE::ordinal21with a small set of ordinals (0x0e,0x0f,0x00b6,0x00d2). That makesrandom global FREE event chooser after alert cleara safer description than the narrowerrandom voices when alarm is disabledguess.- The old
high priority unknown intrinsic: 01E - firenote is now effectively closed as a hint. The old Remorse intrinsic tables mapInt01EtoActor::I_maybeFire(...), and the current live export map tiesInt01Eto1128:11da. That is still hint-level naming until the compiled body is analyzed locally, but it is no longer an unidentified ordinal. - The
combat.datscratch note is also better grounded now. The external corpus already showed the extracted tactic files are identical between Remorse and Regret, and the liveCRUSADER.EXEexport map now has NPC fields such ascombatDatTacticPtr,combatDatTacticCurOffset,combatDatBlockNo, andtacticNo. So the named tactic strings are good portable data labels, but they should still be attached to tactic records and NPC state fields, not promoted directly into compiled function names.
Two shape hints also have light compiled-side support now:
0x59ais passed intoSpriteProcess::I_createSpritefrom the cursor/targeting lane in segment1130, which fits the oldtargetting reticlenote.0x5a3is passed intoSpriteProcess::I_createSpritefrom the13e8gameplay/UI lane and stored at0x6054, which fits the olduse item crosshairsnote.
Remaining caution:
- these follow-ups make the scratchpad much more reusable, but
misc_crusader_notes.txtis still an auxiliary corpus. The verified parts above should be cited with their live NE addresses or extracted-data files when reused elsewhere in the repo.
Combat data note
combat_dat/readme.txt records that the extracted combat.dat tactic files are identical between No Remorse and No Regret.
That is small but useful: tactic names from the combat data are portable labels and should be treated as version-stable unless contradicted by later binary evidence.
How This Fits The Existing Docs
This external corpus mainly strengthens four areas already active in Crusader_Decomp:
-
docs/usecode-roundtrip-ir.mdThe opcode list, intrinsic dumps, and static trigger/map data provide local cross-checks for the USECODE parser and event-family work. -
docs/ne-segment1.mdThe handwritten note set preserves shape ids, keyboard/event codes, and gameplay object examples that can be matched against the segment-1 gameplay/input lane. -
docs/raw-porting-progress.mdThe external notes add candidate gameplay/object labels and map-backed test targets, but they should remain supporting evidence until verified in the raw full-EXE database. -
docs/overview.mdThe separate disasm repo is now part of the local evidence stack alongside ScummVM and Pentagram, but unlike those source ports it is a prior RE corpus tied directly to Crusader assets and old disassembly work.
Safe Reuse Policy
Use the external disasm repo for:
- opcode-name hints
- intrinsic/signature hints
- shape-id and map-placement cross-checks
- event-code and key-code lead generation
- candidate subsystem vocabulary before binary confirmation
Do not use it for:
- speculative raw-function renames
- address mapping without an explicit verified translation
- replacing direct binary evidence from
CRUSADER-RAW.EXEorCRUSADER.EXE
Immediate Porting Frontier For CRUSADER.EXE
The next practical use of this corpus is not another raw-only note pass. It is a controlled porting pass into the NE-loaded CRUSADER.EXE project in Ghidra.
Best initial targets:
- Port already-verified raw names that clearly correspond to NE-segment functions where the segment:offset identity can be confirmed directly.
- Use
unkcoffs/function and intrinsic dumps as hint-only comparison tables when the NE database exposes clearer segment-local call structure than the flat raw import. - Use
map-item-dump.txtplus shape tables to annotate trigger-heavy or object-heavy NE lanes before promoting any names. - Use
usecode_opcodes.txtto keep future USECODE parser/report output aligned with an additional local opcode vocabulary, especially where ScummVM and Pentagram leave placeholders.
Recommended Order For The Next Porting Pass
- Start with one small NE segment or subsystem that already has strong raw names or old disasm vocabulary.
- Prefer functions with direct string, data-table, or caller-role evidence over unlabeled wrappers.
- Use the map/shape corpus to explain data-driven objects first; use the intrinsic/function dumps only as secondary hints.
- Record exact successful raw-to-NE name correspondences so later passes can reuse the mapping instead of re-deriving it.
Current High-Value Follow-Ups
- Build a shape-id crosswalk between
shapedata_more_complete.txt,map-item-dump.txt, and the existingEVENT/NPCTRIG/CRUZTRIGfamilies. - Compare the handwritten key/event codes against the already-named cheat/input paths to see which parts of the old notes are now directly closed.
- Use
rem_functions.txt/reg_functions.txtto identify conservative candidate names for still-positional NE functions, but only when the local caller/data evidence matches. - Keep the external disasm corpus explicitly separated from ScummVM/Pentagram-derived evidence so provenance stays clear in future porting notes.