41 KiB
Crusader: No Remorse — Decompilation Notes
This file is an index. Detailed notes have been split into the docs/ folder by topic.
Active live analysis target is now CRUSADER.EXE. Existing CRUSADER-RAW.EXE notes remain in scope as cross-reference evidence and should be cited alongside live NE addresses when they support a rename, variable role, or behavior claim.
Recent verified combat-data batch: docs/combat-dat.md now documents the shipped COMBAT.DAT archive end to end. Current best read is that all local Remorse/Regret variants ship the same 14-record combat-tactic archive, each record contains a 16-byte name plus four block offsets and bytecode, and the tactic VM is now grounded both in the live CRUSADER.EXE helpers (Attack_SetupForTacticNo, Attack_SetupForBlockNo, NPC_Get/SetNPCTacticNo) and in ScummVM's readable Crusader attack-process implementation. The new note also promotes the per-tactic human-readable catalog, including the midpoint-pressure, marker-shuttle, step-out-shoot, and stationary-chaos families.
Recent verified NE movement/collision batch: docs/raw-0008-000c.md now extends the live AreaSearch_CollideMove lane one helper layer deeper. Current best read is that the collision-storage queue is no longer only anchored at StorageDataProcess_Create / Run and the legal-move wrappers: the live database now also carries the step-aware seg029 sweep helpers AreaSearch_SweepShapeBetweenPoints, AreaSearch_SweepItemToPointWithStepUp, and AreaSearch_SweepShapeBetweenPointsWithStepUp, the seg031 release-side queue cleanup pair StorageDataProcess_Release and storage_process_ref_list_terminate_item_matches, and adjacent seg090 helper ItemCache_PushAndPopToDirectionalOffset. The practical remaining gap in this lane is now earlier caller policy rather than local helper identity.
Recent map-renderer egg-link follow-up: docs/map_renderer/egg-identification.md now closes the old No Regret map-3 destination-egg 102 gap. Current best read is that Regret uses a second elevator family at shape:400 (0x0190) in addition to the earlier Remorse-focused shape:542 rule: recovered Regret ELEVATOR::gotHit accepts QLo >= 100, treats QLo < 0x00c8 as the generic same-map lane, and map 3 contains a concrete source object item:664:fixed:400:0:44030:9662:0 with quality 614 (QLo 102) that resolves the previously unexplained destination egg 102.
Recent map-renderer editor-object follow-up: docs/map_renderer/trigger-usecode-links.md and docs/map_renderer/editor-object-survey.md now promote a Regret-only controller cluster that had still been sitting in the unresolved editor bucket. Current best read is that 0x04c6 / 0x04de are WATCHNS / WATCHEW secret-door watcher controllers, 0x0510 is their nearby SECRET_DOOR_POST target keyed by shared QLo, 0x05e1 is CRYOBOX, and 0x05df / 0x05e0 are the paired pressure-barrier faces it drives by shared QLo. The same batch also closes 0x0451 / 0x05ae as CRAZYEW / CRAZYNS hit-driven NPC wake-up relays and 0x056d as VIDEOBOX, then promotes cautious local viewer arrows for WATCH* -> 0x0510 and CRYOBOX -> 0x05DF/0x05E0 in the map renderer.
Recent map-renderer control-pad follow-up: docs/map_renderer/egg-identification.md, docs/map_renderer/trigger-usecode-links.md, and docs/map_renderer/editor-object-survey.md now tighten the 0x0318 / 0x0366 read using the decompressed .cache scenes rather than the packed site export. Current best read is that 0x0318 is CRUMORPH, not a generic placeholder cube: both extracted usecode corpora expose class 0x0318 as CRUMORPH, and the recovered equip body is a control-transfer pad that scans nearby NPCs for a local-QLo actor-key match before bracketing TRIGGER.slot_20. The strongest current viewer promotion is still grounded in Regret scene evidence, where authored same-QLo local CRUMORPH -> 0x04B1 matches are strong enough to expose, while 0x0366 remains NPC_ONLY, a hit-driven NPC-only trigger pad keyed by an internal actor field.
Recent map-renderer controller follow-up: docs/map_renderer/trigger-usecode-links.md and docs/map_renderer/editor-object-survey.md now tighten three more shared controller shapes. Current best read is that 0x00A2 is PANELEW, the east-west panel-switch counterpart to PANELNS; 0x03C1 is GENERATR, a destroyable generator/controller whose gotHit body immediately forwards into TRIGGER.slot_20 lane 0; and 0x04E7 is the same DEATHBOX class in both Remorse and Regret rather than a Remorse-only crosswalk. The map viewer now has enough evidence to label those shapes directly, open PANELEW::use / GENERATR::gotHit, and expose cautious same-QLo cmd-link arrows for PANELEW and GENERATR.
Recent actor-key follow-up: the same map-renderer notes now make the current blocker explicit instead of leaving it as an implied missing export. Current best read is that the hidden actor-side value behind CRUMORPH / NPC_ONLY is mutable actor field 0x63, not a stable DTABLE row: sampled Regret DTABLE rows still read as zero at record byte 0x63, while recovered TRIGGER.slot_29 / slot_2B lanes can rewrite actor field 0x63 on nearby matched NPCs after load. The same pass also widens the sibling-family set that uses this mechanism: WATCHNS / WATCHEW, THRMBCKN / THRMBCKE, and SURCAMNS / SURCAMEW all compare controller-local bytes against actor field 0x63 in recovered lanes, so the viewer now documents a broader actor-key controller family while still withholding speculative actor-target arrows.
Recent verified PSX pre-alpha batch: docs/psx/prealpha.md now records a focused Ghidra pass on /psx/prealpha/SLUS_002.68 plus a disc-tree comparison against the released PlayStation Crusader: No Remorse build. Current best read is that this pre-pre alpha still looks much more like a trimmed early No Remorse PSX branch than a clearly rebranded Crusader 2 executable: it still carries direct Crusader: No Remorse save/quit text, the renamed wdl_resource_bundle_load_by_index still embeds the full retail \LSET1\L through \LSET7\L prefix table and the same 10/20/30/40/50/60 threshold ladder, and the mission/passcode UI scaffolding is still present with the same visible 15 mission briefing strings and consonant/digit passcode alphabet. The main concrete differences in this batch are the heavily reduced shipped content (3 level bundles, 1 XA, no .STR movies) and the surviving architectural leftovers that no longer match the current disc literally, especially the missing-file \AUDIO\TALK1.XA;1 path and the LoadExec helper for MENU.EXE / ENGINE.EXE / PSX.EXE.
Recent verified PSX executable batch: docs/psx/psx.md now records a focused Ghidra pass on SLUS_002.68 for mission/map inventory, passcode handling, and catalog text. Current best read is that the PSX loader hardcodes seven \LSETn\L folder prefixes and the extracted disc ships 62 level bundles (L0..L58, L62..L64) with a real gap at L59..L61, while the executable still exposes only 15 plain-text Mission Briefing ^Mission N strings. The same pass closes the visible passcode-generation side too: mission-complete flow synthesizes 4-character passcodes from the alphabet BCDFGHJKLMNPQRSTVWXZ0123456789, and the executable preserves direct ammo/item/weapon name tables. The hidden password-screen cheat codes remain less direct: public PSX references point to XXXX and L0SR/L0SER, but those values are not stored as plain ASCII in SLUS_002.68, so the compare path still looks numeric or transformed rather than table-driven.
Recent verified Japanese-build batch: docs/jp-remorse-windows9x-investigation.md now records a focused live-Ghidra investigation of /ja/CRUSADER.EXE around the claim that the Japanese release runs natively on Windows 95 / Windows 9x instead of requiring a DOS boot path. Current best static-analysis read is strongly in favor: the JP executable is a flat Win32 image with PE-style sections, a Windows import table, native window creation, DirectDraw/DirectSound initialization, registry-backed config under Software\Electronic Arts\Crusader: No Remorse\J1.21, and a meaningful GetVersion-based Win9x compatibility branch that changes TLS allocation behavior when the classic Win9x high bit is set. The only remaining uncertainty is practical deployment rather than architecture: this pass did not runtime-test on real Win95 or prove which DirectX/runtime prerequisites are required.
Recent verified Japanese-build follow-up: docs/jp-remorse-cheats-and-launch-params.md now records a focused pass on the surviving cheat/debug and startup-argument lanes in /ja/CRUSADER.EXE. Current best read is that the JP Win32 build kept real executable cheat/debug machinery, not just leftover strings: -laurie is still a special parser case, the hidden JASSICA16 sequence matcher still toggles the cheat-active state with live Cheats are now active/inactive. messages, the option-key handler still contains the immortality toggle path, and the command-line parser still executes live handlers for -debug, -u <arg>, -warp <mission>, -skill <n>, -mapoff <delta>, -egg <id>, and -demo. The same pass also narrows one important difference from older DOS-side notes: the JP Win32 parser has not yet been proven to support positional -warp <mission> <x> <y> <z> consumption, so that form should not currently be assumed for this build.
Recent verified localized-build batch: docs/spanish-cheat-differences.md now records a tighter live-Ghidra comparison against /es/CRUSADER.EXE for the known cheat/debug control areas. Current best read is now narrower than the earlier "moved matcher" theory: the Spanish executable still preserves the same broad cheat/debug framework as the English build with relocated addresses rather than different behavior, but it does not preserve the English jassica16 table as the same static data object and this pass also failed to recover any replacement compiled matcher or any translated ~ cheat-latch toggle. The -laurie parser still sets the broad cheat/debug gate (1478:0910), the gameplay-input gate still exists at 1478:0927, and Hack Mover still toggles through 13e8:24a5; but the old English-side slot at 1478:2833 now contains pointer-like words, the old English immortality-string slots at 1478:2850/2866 are also repurposed as non-string data in Spanish, 1478:0910 has only the -laurie write at 1050:0985, 1478:5fb3 only has the Laurie-hint helper writes at 13e8:0071/0077, World_HandleKeyboardInput does not expose a recovered 0x7e / tilde branch, and 1478:8ad6 still has no recovered writer even though Hack Mover checks it. The new keyboard-side conclusion is stronger too: 1478:5fb3 does not act like a live positive enable latch in Spanish, because every recovered consumer requires it to be zero and the Laurie-hint helper pulses it back to zero immediately, while the nearby 8ad7/8ad8/8ad9 runtime-state writes still do not explain 8ad6. The Hack Mover runtime chain is also tighter now: 1478:5fb2 is the actual on/off toggle, 13e8:0ef9 / 13e8:0f77 clear it, 13e8:282f is the adjacent runtime helper using 1478:8ad9, and 13e8:2f0e / 13e8:3009 bracket the active drag state via 1478:8ac0, 1478:8acc, and 1478:8ace. Current safest localized-build read is therefore -laurie is the only recovered positive enabler for the surviving broad Spanish cheat/debug family; no replacement hidden matcher, no runtime keyboard-latch bootstrap, and no direct Spanish F10 cheat branch have been recovered, with the remaining open question narrowed to whether 1478:8ad6 is written through an analysis-dark path or is just a dead leftover gate.
Recent verified batch: docs/retail-debug-arg.md now records the live NE proof that retail CRUSADER.EXE still recognizes and executes a real -debug command-line branch. That branch prints Debugging mode ON., sets g_debugMsgLevel at 1478:87e0, and toggles two debug globals at 1478:0845/0859. The later sink pass also closes the text-output target more tightly: ProbablyPrintDebugMessage formats through the static stdio-style table at 1478:6c32..6c81 and writes to the handle-1 entry at 1478:6c46, so the non-video side is ordinary DOS stdout gated by the debug threshold, plus the already-confirmed AVI timing overlay. Current best read remains surviving debug-output / instrumentation switch, not the missing bootstrap for the hidden seg109/seg1408 usecode debugger. The same batch also leaves the earlier -laurie and 0x659c/659e debugger-state conclusions intact: -debug is a separate switch and is not currently evidenced as constructing the hidden usecode-debugger break-state object.
Recent tooling batch: docs/map-rendering.md now starts a dedicated offline map-rendering lane. tools/render_crusader_map.py can load FIXED.DAT, expand GLOB.FLX, decode the required SHAPES.FLX entries with Crusader frame headers, apply GAMEPAL.PAL, and write a first-pass PNG, with a --fixed-dat override so the same pipeline can be pointed at either game's map file. The current renderer is intentionally limited to fixed-map content and a simple deterministic painter rather than the full Pentagram/ScummVM dependency sorter, and the current workspace caveat is that STATIC_REGRET still lacks a copied FIXED.DAT, so No Regret rendering needs that file supplied explicitly.
Recent map/editor visibility batch: docs/editor-object-visibility.md now records a focused live-Ghidra pass on whether retail CRUSADER.EXE explicitly hides editor-only map objects and whether any built-in switch re-enables them. The current best read is now tighter than the first pass: Item_PaintSprite at 1198:02e4 does contain a real downstream flags2 & 1 (SI_EDITOR) early-out, but the active world-item renderer also has an upstream controlling skip at 1180:0951..095c that filters editor-tagged shapes before draw-node allocation. That corrected render-path model explains why the first executable patch attempt, which only flipped the downstream draw-time branch, produced no visible change in-game. The same note still closes the negative side of the question more tightly: no recovered retail -debug, cheat/debug hotkey, Laurie/usecode-debugger path, or 0x410 event behavior currently reaches either gate or exposes a show editor items state. The closest confirmed toggle remains ScummVM's own _showEditorItems debugger command, which is an engine-added reimplementation feature rather than evidence of a retail built-in toggle.
Recent map-viewer trigger batch: docs/map_renderer/trigger-usecode-links.md now records the evidence-backed editor/controller-object -> USECODE mapping used by the viewer when opening readable pseudocode from pinned tooltips. Current best read is that the stable viewer targets are BOX_EW, PANELNS, CARD_NS, and SPANEL -> use; FASTSKIL -> enterFastArea; SKILLBOX, EVENT, ALARMHAT, and ALRMTRIG -> equip; TRIGPAD and NPC_ONLY -> gotHit; and the 0x04B1 cmd helper itself -> TRIGGER.slot_20, the shared high-slot fan-out lane that nearby controller families keep spawning.
Recent startup/map-selection batch: docs/first-mission-map-selection.md now records the live proof that fresh-game map choice is code-selected rather than read from CRUSADER.CFG or another external mission-mapping file. For CRUSADER.EXE, the normal fresh-game path still hardcodes map 1, egg 0x1e inside Game_Start. For REGRET.EXE, the same values are hardcoded twice: once in an early Game_Start selector and again in the later FUN_1030_032d mission-start path that actually controls a real new game. The same note also captures the separate debug -warp mission path: it indexes a small executable-embedded mission-to-map word table at 1478:0488 (0,1,3,5,...,0x1d,0x28) and then applies -mapoff, while the actual map contents remain external in FIXED.DAT.
New REGRET startup-flow batch: docs/regret-game-start.md now documents the live REGRET.EXE Game_Start neighborhood more thoroughly. That note promotes HandleCommandlineArgs, Game_RunNewGameFlow, Game_DrawCenteredStartupSplash, Game_EnterFrontendMenuViewport, and Game_RestoreGameplayViewport in the live database, records the startup-state globals used by the new-game and -warp lanes, and explains the current best reason map 1 is set twice in No Regret: two separate live startup entry paths still own their own teleporter literals instead of sharing one final startup-map source.
New command-line argument batch: docs/command-line-parameters.md now consolidates the currently recovered startup/debug argument set across the retail Crusader executables. The key new closure is the actual direct-warp syntax in REGRET.EXE: -warp <mission> [x y z] rather than separate -x/-y/-z switches. The same note also records the now-proven precedence rule that nonnegative -egg overrides beat the X/Y/Z teleport path, the practical parameter-only route into eggless maps (-warp <mission> <x> <y> <z> plus -mapoff, with -egg omitted), and the current best read of -setver as a displayed version/build-string override rather than a gameplay compatibility switch.
Follow-up No Remorse cross-check: the same command-line note and docs/first-mission-map-selection.md now record the matching live CRUSADER.EXE proof. HandleCommandlineArgs at 1048:0adc uses the same positional -warp <mission> [x y z] syntax as Regret, and Game_Start at 1020:029e / 1020:02d0 applies the same precedence rule where nonnegative -egg overrides beat the direct-coordinate NPC_Teleport path.
Latest warp-table follow-up: the same docs/first-mission-map-selection.md and docs/regret-game-start.md notes now close the missing No Regret table details directly. Live REGRET.EXE Game_RunNewGameFlow indexes the -warp mission base-map table at 1480:075c, and retail byte checks now show the same 17-word payload as No Remorse: 0,1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,40, followed by a 0,0 terminator. The public renderer project now also has a dedicated extractor that writes both retail tables into Crusader_Decomp_Public/map_renderer/.cache/mission-map-data.generated.json for scene-metadata use.
Latest command-line follow-up: that same docs/command-line-parameters.md note now closes the retail non-Japanese -u lane as well. In live CRUSADER.EXE, the parser case at 1048:0a46 copies the following token into 1478:065a, and the newly named startup_apply_u_override_if_present at 1420:0cdf consumes that buffer to load an alternate usecode/EUSECODE source into 1478:6611/6613 before rebuilding the cumulative slot-base words. Current best read is therefore real startup usecode override, not JP-only feature and not dead parser-table residue. The same follow-up also means the older consolidated -setver note is now weaker on the CRUSADER side and should be treated as needing a direct retail re-close.
Latest -u deep dive: new note docs/usecode-startup-override.md now follows that retail override into the live usecode runtime itself. Current best read is that -u replaces the single live usecode root at 1478:6611/6613 rather than adding a parallel overlay. The same root is later consumed by Usecode_ItemCallEvent, UsecodeProcess_CreateProcess, Interpreter_NextUsecodeOp, and Item_GetDamaged, so the override reaches ordinary scripted gameplay behavior, not just a startup-only side lane. Current safest tooling implication is runtime replacement for the existing Crusader usecode VM, not arbitrary native plug-in system.
Latest -u token-shape follow-up: the same docs/usecode-startup-override.md note now tightens the argument semantics materially. In live retail CRUSADER.EXE, startup_apply_u_override_if_present does not pass the copied argv token through as an arbitrary final filename. It loads the mutable filename template eusecode.flx from 1478:07a0 via the far pointer at 1478:06d6/06d8, forces the first byte to 'e', and calls Filespec_GetFullPath(0, s_usecode, "eusecode.flx", 0). Current safest read is therefore path/root override for the standard EUSECODE archive family, not free-form arbitrary filename switch. The same note now also separates the stock-path status more cleanly: the raw-side VM bootstrap is strongly cross-referenced, but the exact live-NE writer that seeds 1478:6611/6613 without -u is still not directly closed.
Latest -u practical follow-up: that same docs/usecode-startup-override.md and docs/command-line-parameters.md notes now make the immediate user-facing consequence explicit. Failed attempts like -u USECODE/FLICTEST.FLX and -u FLICTEST.FLX fit the live helper badly because retail No Remorse still appends the fixed filename template EUSECODE.FLX; the copied argv token is only the path/root component. Current safest experiment shape is therefore directory passed to -u, complete replacement archive named EUSECODE.FLX inside that directory, not free-form archive basename override.
Latest -u loader-layout follow-up: the same docs/usecode-startup-override.md note now records the direct constructor/loader pair behind the override in the live NE session. 1420:1499 is now renamed entity_vm_runtime_create and currently reads as a 0x1319-byte runtime-object constructor with a 0x1300-byte front region that behaves like 0x80 stride-0x26 slot/runtime records plus tail metadata at 0x1300..0x1318. 1430:0000 is now renamed entity_vm_runtime_owner_resource_create and currently reads as the compact 0x14-byte file-backed helper allocated from the resolved eusecode.flx path and attached to the runtime object at +0x1315/+0x1317.
Latest doc-reconciliation batch: docs/ne-segment1.md now has a combined hidden-debugger component table that explicitly separates the seg109/raw-reference UI wrappers (000b:9a86, 000b:9c0d, 000b:b3b1, 000b:b62c, 000b:2882) from the live seg1408 breakpoint-state helpers (1408:0000, 1408:0053, 1408:00dd, 1408:029e, 1408:03b0, 1408:03f7, 1408:0419, 1408:0432, 1408:0444) and the interpreter hook at 1418:04aa..04b5. Current best read remains two connected layers of one hidden usecode debugger, not conflicting address claims for the same function family.
Latest hidden-debugger floor pass: docs/retail-debugger-patch-attempts.md now records a fresh live-Ghidra constraint check on the smallest viable retail unlock patch. Current best read is tighter than the earlier "there must be one tiny jump" idea: retail still has no recovered writer for 1478:659c/659e, the constructor still seeds only the inert shared callbacks 1478:65ab -> 1408:046f / 1478:65af -> 1408:0474, and the interpreter-side gate at 1418:049e..04b5 only checks for a non-null debugger object before handing off to 1408:0053. That makes the current O/P interpreter-callsite-retarget family the smallest structurally defensible executable patch shape so far, because smaller one-site ideas lose either object bootstrap, one-shot deferred gating, or wrapper-argument sanitation.
Follow-up cheat-key correction pass: docs/ne-segment1.md now also records a live NE cleanup of several folklore keyboard-cheat claims. ~ is a real runtime cheat-latch toggle at 13e8:203d, Ctrl+C is wrong for this build and should be Ctrl+L for the coordinate popup at 13e8:255e, and the third F7-family overlay really does exist as a separate Ctrl+F7 path at 13e8:1a20 alongside the other two cheat-gated F7 overlay toggles.
That same note now also separates ~ from jassica16 more cleanly: jassica16 is the raw scan-code unlock path that toggles both 1478:0844 and 1478:6045 and sets the extra post-sequence latch 1478:8c52, while ~ is only the later translated logical-0x7e hotkey that flips 1478:6045 after 1478:0844 is already on. The F7-family clarification is tighter too: Ctrl+F7 is best read as an egg-hatcher trigger-range overlay rather than a third generic background grid.
The same docs/ne-segment1.md note now also has the first consolidated cheat/debug key matrix for the live NE target, including which paths need the broader Laurie/debug master gate (1478:0844), which ones need the full keyboard-cheat latch (1478:6045), and which ones depend on the extra post-jassica16 latch (1478:8c52). That pass also expands the egg-hatcher explanation: Ctrl+F7 is now documented as a live EggHatcherProcess range visualizer, with practical guidance on where to look for egg-trigger regions in gameplay.
Latest F7 overlay follow-up: new note docs/f7-overlays.md now separates the three F7-family debug overlays more rigorously at the geometry level. The main correction is on Alt+F7: instead of treating it as broad egg coverage, the current best read now follows the live SnapProcess path directly, where Snap_AddSnapEgg is only reached for shape 0x04fe and Snap_GetSnapEggRange derives the overlay rectangle from that item's QHi, mapNum, and npcNum bytes. The same note also clarifies the viewer-facing rule for plain F7: use an origin-aligned infinite 0x200-unit world lattice across the visible viewport, not a screen-centered patch.
Documentation Structure
| File | Contents |
|---|---|
| docs/overview.md | Binary overview, installed copy findings, address space layout, NE fixup placeholder, segment map, NE import details, next steps |
| docs/combat-dat.md | COMBAT.DAT archive layout, live CRUSADER.EXE tactic-field integration, shipped opcode subset, and a human-readable catalog of all 14 tactic records |
| docs/phar-lap-extender.md | DOS extender architecture, named functions (entry, loading, memory, I/O, interrupts), key string references |
| docs/ne-segment1.md | NE Segment 1 full analysis: cursor, input, entity system, shot lifecycle, combat, weapons, AI, player/HUD, destruction, entity constants, vtable index, cheat system |
| docs/f7-overlays.md | Focused note on the three cheat-gated F7 debug overlays: toggle sites, live consumers, recovered geometry math, what each overlay represents, and the current viewer-safe reproduction rules |
| docs/jp-remorse-windows9x-investigation.md | Focused note on the Japanese /ja/CRUSADER.EXE Windows-native claim: PE/Win32 image evidence, Win32 windowing, DirectDraw/DirectSound, registry config under J1.21, IME/DBCS clues, and the GetVersion-driven Win9x compatibility branch |
| docs/jp-remorse-cheats-and-launch-params.md | Focused note on surviving JP /ja/CRUSADER.EXE cheat/debug and startup-argument lanes: -laurie, JASSICA16, immortality, the recovered Win32 parser table, the live -u usecode override, and the current caution that JP -warp is only directly proven in mission-only form |
| docs/spanish-cheat-differences.md | Focused comparison note for /es/CRUSADER.EXE versus the English build's known cheat/debug lanes: -laurie, broad cheat gate, gameplay-input gate, low-level keyboard latch, Ctrl+Q, Hack Mover, and the current status of the unresolved secret sequence |
| docs/raw-porting-progress.md | seg091 RNG, 0x4588 callback lifecycle batches 1-6, 0007 gameplay helper batches, snap_entity_to_ground, AI sweep, animation/range/command globals, seg043 boundary recovery |
| docs/raw-000e.md | 000e parser helper cluster (record table init/parse/dispatch), 000e RIFF/animation cluster (animation object field map, RIFF format, constructor variants) |
| docs/raw-0007-rendering.md | Draw list node format and functions, world-to-screen isometric, tile visibility system, scroll/camera functions, scroll region table, save slot system, string/memory utilities, coordinate transform deep analysis |
| docs/raw-0008-000c.md | 0008 dispatch helpers (init, pair-sync, flag helpers, word-list, gate-callbacks) and 000c state machine (tick dispatch, flag guards, palette fade, mini-VM, cursor nav) |
| docs/raw-000a-000d.md | 000d proximity/visibility buckets, 000a tracked handles, cache manager, init/shutdown, seg082 allocator, seg137/138 palette helpers, seg004/005 startup, 0x4588 object-role evidence, 000d VM owner/resource loader follow-up |
| docs/far-call-targets.md | Top-104 most-called far-call targets (Tiers 1-5, ranks 1-104), supporting functions discovered, analysis gaps and seg043 reconciliation |
| docs/crusader-disasm-reference.md | Local auxiliary disassembly corpus at K:/ghidra/crusader-disasm: handwritten notes, shape tables, map dumps, opcode lists, intrinsic/function dumps, and the safe reuse rules for porting into CRUSADER.EXE |
| docs/ne-hole-filling-priorities.md | Ranked CRUSADER.EXE hole-filling tracker: NE-side unclear lanes, the verified raw-side knowledge that can close them, and the recommended order for old-to-new porting passes |
| docs/retail-debugger-patch-attempts.md | Chronological log of retail CRUSADER.EXE debugger-unlock patch attempts, byte-level designs, runtime failures, root-cause findings, and the current live candidate |
| docs/retail-debug-arg.md | Focused note on the retail -debug command-line switch: live parser evidence, exact startup message, surviving globals, segment 1468 instrumentation path, and why it is currently separate from the hidden usecode debugger bootstrap |
| docs/remorse-class-candidate-inventory.md | Evidence-backed inventory of the strongest current Remorse class families, with confidence, ctor/dtor/vtable/layout anchors, and recommended modeling order for later Ghidra class work |
| docs/remorse-class-lift-index.md | Central navigation note for the Remorse class-lift and C++-reconstruction prep lane, grouping the plan, candidate inventory, ABI notes, endpoint spec, and family-specific layout notes into one work order |
| docs/remorse-first-class-authoring-checklist.md | Operational checklist for the first real Ghidra/MCP class-authoring batch, including pilot-family order, authoring rules, and source-emission readiness gates |
| docs/remorse-cpp-decompilation-plan.md | Plan for shifting the current Remorse decompilation from flat C-like recovery toward evidence-backed C++ classes, typed object models, and an eventual recompilable source tree |
| docs/remorse-cpp-compatibility-header-draft.md | Draft contract for the future compatibility/support header that early Remorse C++ skeletons should target: exact-width aliases, packing markers, calling-convention placeholders, segmented-pointer helpers, and slot-order guardrails |
| docs/remorse-toolchain-fingerprint-evidence.md | Focused evidence note for the current toolchain story behind Remorse reconstruction: bound MZ -> NE structure, Phar Lap runtime, loader-patched far calls, and the current High-C-related runtime fingerprints |
| docs/ghidra-mcp-class-lifting-endpoint-spec.md | Draft endpoint surface for future GhidraMCP class-lifting work: namespace/class creation, symbol moves, struct and vtable authoring, this typing, and transactional class-layout application |
| docs/scummvm-crusader-reference.md | ScummVM Ultima8/Pentagram Crusader integration survey: USECODE/event tables, FLEX/resource formats, world/map loaders, HUD/media, and RE follow-up priorities |
| docs/pentagram-crusader-reference.md | Pentagram-source Crusader/U8 reference: direct Crusader USECODE parser and VM evidence, U8 usecode docs, runtime-confidence limits, and cross-checks against the ScummVM note |
| docs/map-rendering.md | Offline map-rendering lane: FIXED.DAT/GLOB.FLX/SHAPES.FLX/GAMEPAL.PAL format notes, current Python renderer, supported inputs, and fidelity gaps |
| docs/editor-object-visibility.md | Focused note on retail editor-only map object hiding: the live 1198:02e4 SI_EDITOR early-out in the normal item paint path, the lack of a recovered retail visibility toggle, and the ScummVM/Pentagram cross-check that treats show editor items as an engine-side debug feature |
| docs/entity-class-family-split.md | Focused working note on the large seg001 Entity lane: shared base-layout evidence, conservative split into projectile, debris, corpse/remnant, and adjacent non-entity families, and the recommended promotion order for later class lifting |
| docs/entity-dispatch-entry-class-layout.md | Focused working note for the EntityDispatchEntry family: base versus derived split, stable field groups, constructor and release surfaces, candidate method map, and conservative future Ghidra modeling order |
| docs/entity-vm-runtime-owner-resource-layout.md | Focused working note for the VM runtime lane: EntityVmRuntime, EntityVmOwnerResource, and EntityVmContext ownership, stable layout claims, masked-create helpers, and the safest current class-lift order |
| docs/presentation-callback-broker-layout.md | Focused working note for the 0x4588 callback-object lane: install/teardown lifecycle, global state cluster, provisional vtable slots, payload-pair evidence, and conservative class-lift guidance |
| docs/map_renderer/trigger-usecode-links.md | Evidence-backed map-viewer note for editor/controller shapes that now expose direct USECODE navigation, including the stable class/event targets and the special TRIGGER.slot_20 handling for 0x04B1 cmd helpers |
| docs/map_1_spawners_targeted_investigation.md | Focused map-1 note on suspicious 0x04D0 frame-paired spawners: decompressed-cache examples, the recovered MONSTER -> ITEM.slot_2D -> create NPC chain, QLo-based pairing, and the corrected mapNum bit 0x08 enter-area interpretation |
| docs/first-mission-map-selection.md | Focused note on fresh-game startup map selection: No Remorse Game_Start, No Regret's early and later mission-start selectors, the separate embedded -warp mission table, and the split between code-selected startup and external FIXED.DAT map content |
| docs/regret-game-start.md | Detailed REGRET.EXE startup-flow note: Game_Start, Game_RunNewGameFlow, newly named helpers, startup override globals, and the current best explanation for the duplicated map-1 selector |
| docs/remorse-rebuild-abi-notes.md | Working note for rebuild constraints: segmented-memory model, far-call provenance, runtime/toolchain evidence, ABI guardrails, and the split between original-style executable reconstruction and a behaviorally equivalent port |
| docs/command-line-parameters.md | Consolidated startup/debug argument reference for the retail Crusader executables: live retail -u usecode override, the current -setver caution, -debug, -asylum, -warp, -skill, -mapoff, -egg, -demo, the -laurie cross-reference, and the evidence-backed direct-coordinate warp syntax/limits |
| docs/psx/psx.md | PlayStation SLUS_002.68 and disc-resource note: boot/load layout, LSET/menu WDL structure, executable-backed map inventory, passcode alphabet/display path, recovered PSX ammo/item/weapon tables, and current unresolved enemy/password-compare gaps |
| docs/psx/prealpha.md | PlayStation pre-pre alpha /psx/prealpha/SLUS_002.68 comparison note: reduced disc inventory, retained retail-style LSET loader, surviving No Remorse branding, stale TALK1.XA and LoadExec leftovers, and the current read that this build is closer to an unfinished No Remorse PSX branch than to a visibly rebranded sequel executable |
| docs/sprite-node-class-layout.md | Focused working note for the SpriteNode family: current core layout, destructor and event-dispatch evidence, candidate virtual slots, and a conservative Ghidra modeling plan |
| docs/usecode-startup-override.md | Focused retail -u deep dive: startup call order, why the override looks like full live-root replacement rather than addition, which event/process/interpreter consumers use that root, and what that implies for future custom usecode experiments |
| docs/usecode-roundtrip-ir.md | ScummVM-to-binary USECODE cross-walk, owner-loaded class-layout and header/event-count reconciliation, conservative IR v0 plan, and the generated class-event/body-window outputs that now ground reversible _BOOT, SURCAM*, and environmental family decompile artifacts plus repeated-family regression checks |
| docs/usecode-pentagram-ghidra-path.md | Pentagram-derived Crusader USECODE parser plan, proof-of-concept workflow, canonical IR v1 goals, and the Ghidra-side annotation import path |
| docs/usecode-tooling-comparison.md | Comparison of Pentagram's converter/disassembler, the local crusader-disasm corpus/scripts, and the current workspace parser/pseudocode exporter, with emphasis on assumptions, strengths, and repo-specific differences |
| docs/usecode-tool-improvement-plan.md | Concrete next-step plan for the local USECODE parser/decompiler, distilled from the Pentagram and crusader-disasm comparison into prioritized parser, loop-decoding, intrinsic, trailer, corpus, and runtime-bridge upgrades |
| docs/usecode-jelyhack-analysis.md | Focused analysis of exported JELYHACK / JELYH2 pseudocode, the tiny shared use stub, and why the current best model remains referent anchor + neighboring event-bearing attachment |
| docs/usecode-equipment-system.md | Evidence-backed note on Crusader's surviving equip / unequip event system, including live compiled-side dispatcher proof, corpus-wide slot counts, actor/turret/environment examples, and the current best model of equip as a generalized inherited Ultima-style item event |
| docs/usecode-alarmhat-analysis.md | Focused analysis of exported ALARMHAT::equip, the nearby shape 0x04D0 equip loops, alarm-family comparisons, and the current gameplay-facing read of ALARMHAT as a local alarm-state driver |
| docs/usecode/flictest-investigation.md | Focused investigation of FLICTEST: class/body structure, Remorse versus Regret differences, confirmed caller scripts, and the stronger Regret finding that a hidden KEYPADNS VIDEO PLAYER route appears to have matching shipped placement evidence |
| docs/usecode/windsurf-regret-vs-remorse.md | Side-by-side comparison of WINDSURF in Regret and No Remorse, including shared slot behavior, helper-family drift, body-size differences, and the current best read of WINDSURF as a directional wind-force helper used by vent scripts |
| docs/removed_items.md | Evidence summary for suspicious removed item shapes in old No Remorse maps: grenade-family leftovers 0343/034E/034F/0350, the inventory-labeled 0548 Invalid item, and unresolved non-pickup shapes 0110/0112 |