Pseudocode and stuff
This commit is contained in:
parent
7310c4fe96
commit
ee33f94b4b
466 changed files with 27770 additions and 276 deletions
23
plan-mid.md
23
plan-mid.md
|
|
@ -15,8 +15,8 @@ Detailed completed analysis belongs in the files under `docs/`, not in this plan
|
|||
|
||||
## Progress Snapshot
|
||||
|
||||
- Overall useful decompilation progress: about 49%
|
||||
- Reasonable uncertainty band: about 44% to 52%
|
||||
- Overall useful decompilation progress: about 50%
|
||||
- Reasonable uncertainty band: about 45% to 52%
|
||||
- Top 100 far-call target coverage: about 80%
|
||||
- Segment spread with meaningful analysis: about 26% to 32%
|
||||
- Tooling maturity for continued work: about 77%
|
||||
|
|
@ -26,6 +26,7 @@ Detailed completed analysis belongs in the files under `docs/`, not in this plan
|
|||
- Recent work materially improved semantic confidence inside the startup/display, cache/allocator, callback-object, and USECODE/VM lanes.
|
||||
- The startup/display lane is now materially complete as an active major section: the shared `g_active_dispatch_entry_farptr[+0x40]` hold token is separated from the seg108-local `0x4f38` bit-`0x40` lane, the seg126 control stream is confirmed as file-backed, the paired `0x8c5c/0x8c60` renderer objects are narrowed to two script-selected preset text lanes, and the neighboring seg127 fade controller now has an exact local contract at `0x630a..0x6316`.
|
||||
- The current VM/loader batch also justified a small bump: `000d:ebe3` is now a named ordered opcode sequencer with a tighter entry/exit contract, the masked-create hub at `000d:463a` is now a verified owner-table gate rather than an inferred wrapper sink, and the seg070 twin loops under `entity_vm_runtime_owner_resource_create` now read as paired file-family loaders writing into separate temporary buffers rather than one ambiguous callback shard.
|
||||
- The latest live-NE caller-family batch justified another small confidence bump: the remaining direct `0005:295f -> 10a0:275f` callers now close to `Item_ReceiveHit` and `SuperSprite_HitAndFinish` non-NPC damage lanes, which removes the last direct-caller ambiguity in that selector-consumer island even though the upstream class-family selector is still unresolved.
|
||||
- The latest USECODE pass justified another small VM-lane bump: the gameplay-side wrapper ladder now extends through slots `0x10..0x14` with verified mixed payload shapes (`none` vs extra signed word), the new slot-only Ghidra names keep that taxonomy visible without overpromoting event labels, and the `000d:22bc` stage is now comment-backed as a sequencer-internal link-matrix/pushback consumer over decoded workspace bytes rather than a direct descriptor-row reader.
|
||||
- The immortality follow-up justified another small tooling-and-confidence bump: the extractor now emits a dedicated target-body scan, the strongest current USECODE candidates show no inline `0x410` / `0x00000410` literal, and the remaining frontier is narrowed to data-driven decoding of `EVENT` slot `0x0a` plus `NPCTRIG` slots `0x0a` / `0x20` rather than the older wider trigger family set.
|
||||
- The latest owner-loaded range pass justified another small confidence bump too: the owner-resource child selector now matches extracted `class_id + 2` exactly, the class header/subentry math at `000d:5066/51fd/53b4` is closed against the extractor's raw headers and event rows, and the surviving immortality uncertainty has moved from `can the loader fit NPCTRIG arithmetic at all?` to the narrower `which class family is actually selected upstream?` question.
|
||||
|
|
@ -50,6 +51,9 @@ Detailed completed analysis belongs in the files under `docs/`, not in this plan
|
|||
- The auxiliary local disassembly corpus at `K:/ghidra/crusader-disasm` is now inventoried and integrated as a separate evidence source for shape metadata, static map/object dumps, opcode names, and older Remorse/Regret intrinsic-function vocabularies; its safe-reuse rules and porting implications are captured in `docs/crusader-disasm-reference.md`.
|
||||
- The USECODE/VM owner/resource/runtime lane now has a workable partial model, a named sequencer entry, paired external file-family loader evidence, and supporting extraction/reporting tooling.
|
||||
- The USECODE/VM tooling lane now also has a concrete near-term implementation path: a Pentagram-derived proof-of-concept parser can reuse opcode decoding while swapping in the locally verified owner-loaded class and slot arithmetic, with a hybrid Ghidra comment/bookmark import path instead of a premature custom processor module.
|
||||
- The USECODE tooling lane now also has a first full readable corpus export: `tools/export_usecode_pseudocode.py` writes `977` current pseudocode bodies into `USECODE/EUSECODE_extracted/pseudocode`, and the first focused read of that corpus now shows `JELYHACK::use` / `JELYH2::use` as tiny shared `set_info(0x0207) -> process_exclude -> return` stubs rather than hidden active event cores.
|
||||
- The USECODE tooling lane now also has two new follow-up notes grounded in the exported corpus: `docs/usecode-tool-improvement-plan.md` turns the Pentagram/`crusader-disasm` comparison into a concrete parser roadmap, and `docs/usecode-alarmhat-analysis.md` records the current best evidence-backed read of `ALARMHAT::equip` as a frame-driven local alarm-state controller that equips nearby `shape 0x04D0` helper objects in different modes.
|
||||
- The USECODE tooling lane now also has a broader equipment-event note: `docs/usecode-equipment-system.md` records live binary proof that `Item_Equip` / `Item_Unequip` are real generic usecode event dispatchers gated by owner-row capability masks (`0x400` / `0x800`), and that the exported corpus currently contains `77` `equip` bodies plus `50` `unequip` bodies spread across actor, turret, alarm, conveyor, camera, and hazard classes. Current best read is `surviving Ultima-style event vocabulary generalized into activation/setup/state-change semantics`, not yet `fully proven paper-doll RPG gear subsystem`.
|
||||
- The USECODE/VM lane now also has a verified generic masked-context creation hub (`000d:463a`) plus two concrete sequencer-internal consumer blocks (`000d:208b`, `000d:21ed`) built directly on `entity_vm_context_create_from_slot_index`.
|
||||
- The USECODE/VM lane now also has first caller-role evidence outside the older seg021 wrapper island: the new seg004 callers keep masks `0x8000:0x0007` and `0x2000:0x0015` in gameplay-side materialization lanes, while the newly named seg006 helpers now separate one extra-word masked lane with a real local class-state transition fallback (`0x0008:0x0030`) from a guarded `0x0010:0x0008` materializer that simply returns `0` on miss after readiness checks.
|
||||
- The USECODE/VM lane now also has a wider verified higher-slot wrapper ladder: the `0005` island reaches slot ordinals `0x10..0x14`, slot `0x12` is a zero-extra-word lane, slots `0x11/0x13/0x14` carry extra-word payloads, and the current safest read is `slot-stable payload-shape taxonomy` rather than direct event-name promotion.
|
||||
|
|
@ -74,7 +78,11 @@ Detailed completed analysis belongs in the files under `docs/`, not in this plan
|
|||
- The first focused NE `CRUSADER.EXE` hole-filling pass tightens that same wall one step further without breaking it. In the live NE session, `0005:295f` is now confirmed as the only recovered non-hub consumer of `entity_vm_slot_index_from_entity`, and its only currently recovered callers are `0006:43c3`, `0006:c5f0`, and `0007:3584`. That gives the selector lane three concrete gameplay-side caller families to classify next, while `0005:2c35` remains outward-xref-dark and therefore still does not prove a class-family choice by itself.
|
||||
- The next focused NE pass closes the first of those caller families structurally. Repaired wrapper `0006:4379` is now a verified seg031 dispatch-entry subtype gate over objects created by `0006:42d9` with event type `0x236`, source type `8`, subtype/tag at `+0x3c`, payload/source far pointer at `+0x32`, and aux words at `+0x36/+0x38`. Within that family, subtype `0x20c` at `0006:43c3` routes into `0005:295f`, while sibling subtype `0x20b` at `0006:43e5` routes into `0005:2918` using the same aux pair. That localizes the owner-row bit-`0x0040` consumer to one subtype-tagged dispatch-entry family, but still does not identify the upstream owner-loaded class family.
|
||||
- The first doc-to-live-NE integration batch is now applied in the open `CRUSADER.EXE` database too. Comment-backed anchors landed on the live selector/core pair `1420:0dc5` / `1420:0e3a`, the consumer pair `10a0:2718` / `10a0:275f`, and the first closed caller-family runner `10f0:02d9` / `10f0:0379`, with branch comments at `10f0:03c3` and `10f0:03e5` preserving the verified `0x20c -> 10a0:275f` and `0x20b -> 10a0:2718` split. This improves the live NE handoff without justifying a headline progress-estimate change yet.
|
||||
- The compiled cheat/control lane is now split more cleanly. `cheat_code_check` (`0007:0d0a`) is still the sole hidden cheat-sequence matcher (5-byte table via `DS:0x2833`, index `DS:0x283d`), and it toggles `DS:0x844` (`cheats_enabled`) plus mirror `DS:0x6045`, then emits event `0x103`. The matcher bytes themselves are now rechecked in the live NE image as scan codes `24 1e 1f 1f 17 2e 1e 02 07` = `j a s s i c a 1 6`, with the trailing digits specifically using top-row scan codes `0x02` / `0x07`. Live data-use recovery also tightens the latch story: `0x6045` is written only by `Key_CheckCheatToggle` (`1130:2b72`) and the event-`0x7e` runtime toggle at `13e8:203d`. The live NE F10 proof is stronger than the earlier folklore-level read: inside `Key_HandleOptionKeys` (`1130:0896`), the F10 cheat branch first checks `DAT_1478_085f`, then `0x6045`, then reaches `1130:0afd` and calls helper `11c8:01a8`; the `11c8:018a` helper call in the same function appears later at `1130:0cad`, in a different branch. The helper identity is now closed from the code too: `KeyboardGetExtendedShiftStates` (`11d0:39e6`) uses BIOS `INT 16h, AH=12h`, whose AH bits are `0=left Ctrl`, `1=left Alt`, `2=right Ctrl`, `3=right Alt`, so `11c8:01a8` testing `0x0100|0x0400` is really `KeyEvent_IsCtrlDown`, and `11c8:018a` testing `0x0200|0x0800` is really `KeyEvent_IsAltDown`. Upstream keyboard-path recovery also closes the practical behavior too: the held-key repeat builder at `11b8:0129..022b` samples BIOS extended-shift state through `11d0:39e6`, stores the current `31a4` modifier snapshot into each repeated `KeyEvent`, and queues that event through `11d0:3533`, so holding `F10` first and then pressing physical `Ctrl` lets later repeated F10 events reach the immortality branch with refreshed modifier bits. The same repeated F10 event synthesis plus missing debounce explains the multi-modal on/off spam. The F10 immortality sub-branch also only runs for a live current NPC (`NPC_IsDead` gate at `10e8:1fed`). `DAT_1478_085f` is now tighter too: it is set during `Game_Start` (`1020:0127`), cleared at the end of `ComputerGump_CreateGump` (`1398:01f5`), and restored by `ComputerGump_CloseAndResumeGameplay` (`1398:0212`) during the paired computer-gump teardown path before falling into generic gump cleanup. Current safest read is a broader gameplay-input / option-key-active state rather than any cheat-state bit. Separately, event `0x410` at `000c:9703` does **not** toggle immortality; it boolean-toggles `DS:0x604f` / `g_cdTransferDisplayActive` and posts the `CD TRANSFER DISPLAY ACTIVE/INACTIVE` notifications under the broader `0x844` gate, which matches both the user's runtime observation and the old `crusader-disasm` note `CTRL-Q = 0x410`. The older `DS:0x6050` lane at `immortality_activate` (`000c:8231`) remains a separate secondary entity/process path. The old seg109 "cheat menu" label is now narrowed further: in the live NE database, `000b:9a86`, `000b:9c0d`, `000b:b3b1`, `000b:b62c`, `000b:15ac`, `000b:0b52`, `000b:0b06`, and `000b:2882` now read more defensibly as `usecode_debugger_*` helpers, with menu labels like `Open Unit`, `View File`, `Watch`, `Inspect`, `Find`, and `Break to TDP`. Current best read is a hidden usecode debugger / unit inspector, not a retail scrollable cheat list. This also tightens the `-laurie` split: `-laurie` enables `0x844`-gated event cheats and debugger-side paths, but not the low-level `0x6045` keyboard latch, which matches the observed `F`-overlay-on / `F10`-refill-off behavior. Renamed in this area: `FUN_000c_8231` -> `immortality_activate`, `FUN_000c_834a` -> `immortality_conditional_activate`, `FUN_000c_8486` -> `immortality_activate_and_reset`, `FUN_000c_743f` -> `immortality_entity_process_create`, `FUN_000b_9a86` -> `usecode_debugger_open_for_current_unit`, `FUN_000b_9c0d` -> `usecode_debugger_open_modal`, `FUN_000b_b3b1` -> `usecode_debugger_gump_create`, `FUN_000b_b62c` -> `usecode_debugger_handle_event`, `FUN_000b_15ac` -> `usecode_debugger_load_unit_file`, `FUN_000b_0b52` -> `usecode_debugger_center_on_line`, `FUN_000b_0b06` -> `usecode_debugger_set_line_selection`, `FUN_000b_2882` -> `usecode_debugger_build_menubar`, `FUN_1398_0212` -> `ComputerGump_CloseAndResumeGameplay`.
|
||||
- The next live-NE caller-family pass closes the remaining direct `0005:295f` callers too. Old `0006:c5f0` now lands at `1128:0ff0` inside `Item_ReceiveHit`, where the non-NPC damage path probes `Item_GetDamaged` with hitter sentinel `0x4000`, packed `(damagetype << 8) | damage_lo`, and a local flag-out byte; old `0007:3584` now lands at `1138:1384` inside `SuperSprite_HitAndFinish`, where the non-NPC collision lane probes the same helper with packed `(firetype << 8) | damage` before optionally falling through to local `Item_ReceiveHit` knockback logic. Live comments now anchor both sites, so the selector frontier has moved upstream again to an earlier subtype/class-family producer rather than another direct caller search.
|
||||
- The compiled cheat/control lane is now split more cleanly. `cheat_code_check` (`0007:0d0a`) is still the sole hidden cheat-sequence matcher (5-byte table via `DS:0x2833`, index `DS:0x283d`), and it toggles `DS:0x844` (`cheats_enabled`) plus mirror `DS:0x6045`, then emits event `0x103`. The matcher bytes themselves are now rechecked in the live NE image as scan codes `24 1e 1f 1f 17 2e 1e 02 07` = `j a s s i c a 1 6`, with the trailing digits specifically using top-row scan codes `0x02` / `0x07`. Live data-use recovery also tightens the latch story: `0x6045` is written only by `Key_CheckCheatToggle` (`1130:2b72`) and the event-`0x7e` runtime toggle at `13e8:203d`. The live NE F10 proof is stronger than the earlier folklore-level read: inside `Key_HandleOptionKeys` (`1130:0896`), the F10 cheat branch first checks `DAT_1478_085f`, then `0x6045`, then reaches `1130:0afd` and calls helper `11c8:01a8`; the `11c8:018a` helper call in the same function appears later at `1130:0cad`, in a different branch. The helper identity is now closed from the code too: `KeyboardGetExtendedShiftStates` (`11d0:39e6`) uses BIOS `INT 16h, AH=12h`, whose AH bits are `0=left Ctrl`, `1=left Alt`, `2=right Ctrl`, `3=right Alt`, so `11c8:01a8` testing `0x0100|0x0400` is really `KeyEvent_IsCtrlDown`, and `11c8:018a` testing `0x0200|0x0800` is really `KeyEvent_IsAltDown`. Upstream keyboard-path recovery also closes the practical behavior too: the held-key repeat builder at `11b8:0129..022b` samples BIOS extended-shift state through `11d0:39e6`, stores the current `31a4` modifier snapshot into each repeated `KeyEvent`, and queues that event through `11d0:3533`, so holding `F10` first and then pressing physical `Ctrl` lets later repeated F10 events reach the immortality branch with refreshed modifier bits. The same repeated F10 event synthesis plus missing debounce explains the multi-modal on/off spam. The F10 immortality sub-branch also only runs for a live current NPC (`NPC_IsDead` gate at `10e8:1fed`). `DAT_1478_085f` is now tighter too: it is set during `Game_Start` (`1020:0127`), cleared at the end of `ComputerGump_CreateGump` (`1398:01f5`), and restored by `ComputerGump_CloseAndResumeGameplay` (`1398:0212`) during the paired computer-gump teardown path before falling into generic gump cleanup. Current safest read is a broader gameplay-input / option-key-active state rather than any cheat-state bit. Separately, event `0x410` at `000c:9703` does **not** toggle immortality; it boolean-toggles `DS:0x604f` / `g_cdTransferDisplayActive` and posts the `CD TRANSFER DISPLAY ACTIVE/INACTIVE` notifications under the broader `0x844` gate, which matches both the user's runtime observation and the old `crusader-disasm` note `CTRL-Q = 0x410`. The older `DS:0x6050` lane at `immortality_activate` (`000c:8231`) remains a separate secondary entity/process path. The older seg109 hidden-menu label is now narrowed further: in the live NE database, `000b:9a86`, `000b:9c0d`, `000b:b3b1`, `000b:b62c`, `000b:15ac`, `000b:0b52`, `000b:0b06`, and `000b:2882` now read more defensibly as `usecode_debugger_*` helpers, with menu labels like `Open Unit`, `View File`, `Watch`, `Inspect`, `Find`, and `Break to TDP`. Current best read is a hidden usecode debugger / unit inspector, not a retail scrollable cheat list. This also tightens the `-laurie` split: `-laurie` enables `0x844`-gated event cheats and debugger-side paths, but not the low-level `0x6045` keyboard latch, which matches the observed `F`-overlay-on / `F10`-refill-off behavior. Renamed in this area: `FUN_000c_8231` -> `immortality_activate`, `FUN_000c_834a` -> `immortality_conditional_activate`, `FUN_000c_8486` -> `immortality_activate_and_reset`, `FUN_000c_743f` -> `immortality_entity_process_create`, `FUN_000b_9a86` -> `usecode_debugger_open_for_current_unit`, `FUN_000b_9c0d` -> `usecode_debugger_open_modal`, `FUN_000b_b3b1` -> `usecode_debugger_gump_create`, `FUN_000b_b62c` -> `usecode_debugger_handle_event`, `FUN_000b_15ac` -> `usecode_debugger_load_unit_file`, `FUN_000b_0b52` -> `usecode_debugger_center_on_line`, `FUN_000b_0b06` -> `usecode_debugger_set_line_selection`, `FUN_000b_2882` -> `usecode_debugger_build_menubar`, `FUN_1398_0212` -> `ComputerGump_CloseAndResumeGameplay`.
|
||||
- The same cheat/control lane is now a little cleaner at the user-facing hotkey level too. A focused live NE pass closed three folklore items: `~` is a real runtime cheat-latch toggle at `13e8:203d` under the broader `0x844` gate; the online `Ctrl+C = show current location` claim is wrong for this build and is really `Ctrl+L`, whose popup branch formats `1478:610c` at `13e8:255e`; and the missing third overlay is not bogus after all, because a separate `Ctrl+F7` branch at `13e8:1a20` toggles `1478:0ee0` while the other two F7-family toggles write `1478:2bc9` and `1478:2bca`.
|
||||
- The follow-up pass closes the `~` versus `jassica16` confusion more tightly too. `jassica16` is the earlier raw scan-code matcher that toggles both `1478:0844` and `1478:6045`, sets `1478:8c52`, and can therefore bootstrap the whole cheat state from cold; `~` is only the later translated logical-`0x7e` branch, so Shift is the expected normal gesture on a US layout and that hotkey can only flip `1478:6045` after `1478:0844` is already enabled. The same pass also improves the third-overlay classification: `Ctrl+F7` is not a third generic camera grid but an `EggHatcherProcess` trigger-range overlay, which can legitimately appear blank on maps without eligible live egg/hatcher processes.
|
||||
- The next cheat/overlay refinement pass is now folded back into the docs too. `docs/ne-segment1.md` now has a consolidated live-NE cheat/debug key matrix, the practical `-laurie` plus `Shift+~` bootstrap recipe for full keyboard cheats, and a fuller egg-hatcher note grounded in `EggHatcher_CreateProcess` / `EggHatcherProcess_Run`: non-monster egg families are enter/leave trigger items with X/Y/Z range checks, while `Ctrl+F7` visualizes the live egg-hatcher ranges and `Alt+F7` visualizes the related snap-process egg list.
|
||||
- The `0x85f` reader side is now clearer too. The live NE database now names the paired `13e8` transition wrappers as `Game_DisableGameplayInputAndRefreshCamera` (`13e8:0e7d`) and `Game_RestoreGameplayInputAndClearModalState` (`13e8:0ef9`), which matches their concrete behavior: `13e8:0e7d` clears the controller/key-input latch `1478:27cb`, raises the modal overlay-suppression state at `1478:2c64` / `1478:8c53`, preserves `1478:8c54` from `1478:2d24`, and refreshes camera state; `13e8:0ef9` performs the inverse restore path and clears the secondary `1478:6050` latch. The Laurie-only wrapper side is clearer as well: `Game_ShowLaurieHintComputerGump` (`13e8:0e31`) is the hidden `-laurie` computer-gump hint path, while `Game_ShowLaurieHintIfGameplayInputActive` (`13e8:0f4a`) only calls it when `0x85f` is high. The main camera pass consuming the same gate is now `Camera_RedrawViewportAndGameplayOverlays` (`1180:19c1`), with comment-backed `1188:010f` / `1188:0394` overlay helpers bracketing the viewport redraw.
|
||||
- The next blocker layer is narrower too. Those modal wrappers are not abstract helpers; inside `World_HandleKeyboardInput_13e8_14b4` they already wrap concrete user-facing lanes including exit-to-DOS confirmation (`0x22d`), quick save (`0x13f`), quick load (`0x13e`), restart/main-menu handling (`Game_RestartMaybe`), and the neighboring load/menu gump lanes. Separately, event `0x7e` remains the only other recovered writer of `0x6045` besides `Key_CheckCheatToggle`, so a successful `jassica16` match can still be undone later by that independent runtime path. `Key_CheckCheatToggle` itself is now comment-backed as keydown-only and still requires top-row `1` / `6` scan codes at the tail, leaving keypad digits and other non-matching input routes as a still-live explanation for failed tests.
|
||||
- Cross-game verification against the currently opened `REGRET.EXE` now has a runtime correction too. The F10 branch at `1148:0d0e` still reaches the same modifier helper at `11e0:01a8`, and live testing shows the practical gesture is hold `F10` first and then press `Ctrl`, not `Alt`. The same BIOS-backed helper swap should be verified directly in that target before promoting renames there. The same runtime test also explains the repeated immortality popups: the F10 branch is not debounced, so holding the keys lets repeated F10 keydown events flip immortality on and off multiple times. The real gameplay difference remains the latch code: `1148:34d2` (`Key_CheckSecretCodeSequences`) still contains a `jassica16` table at `1480:2ff0`, but the latch-enabling sequence in No Regret is the second table at `1480:2ffc`, decoded as `loosecannon`, which toggles `1480:0ac0` and mirrors the result into the F10 latch byte `1480:009b`.
|
||||
|
|
@ -112,10 +120,17 @@ Detailed completed analysis belongs in the files under `docs/`, not in this plan
|
|||
Both apply/restore cleanly on a disposable retail copy and are the next runtime tests.
|
||||
- Full chronology for this patch line now lives in `docs/retail-debugger-patch-attempts.md`, including the failed global callback rewrite, direct wrapper call, single-step `65af` build, break-next `65af` build, guarded `0474` trampoline, shared `046f` method patch, and the current private-vtable candidate.
|
||||
- The hidden-menu orphan model is now materially stronger too. New live renames in seg1408 (`usecode_debugger_break_state_create`, `usecode_debugger_maybe_break_on_current_line`, `usecode_debugger_breakpoint_insert_sorted`, `usecode_debugger_has_breakpoint`, `usecode_debugger_callstack_push_entry`, `usecode_debugger_callstack_pop_entry`, `usecode_debugger_enable_single_step`, `usecode_debugger_clear_step_state`, `usecode_debugger_current_entry_get_unit_name`) line up with the seg109 UI in a way the cheat-only hook never did. The concrete interpreter-side handoff at `1418:04aa..04b5` now calls `usecode_debugger_maybe_break_on_current_line` whenever the far pointer at `0x659c/0x659e` is non-null, and that helper checks `(file,line)` breakpoints before callbacking through the debugger-state object's vtable. Current best read is therefore that the retail orphan happened one layer earlier than the cheat/event experiments: the seg109 current-unit debugger UI likely used to be entered from this seg1408 breakpoint object, but retail no longer appears to instantiate/store that object at `0x659c/0x659e`. That makes the breakpoint callback lane a stronger original-entry candidate than direct event `0x103` retargeting.
|
||||
- The follow-up doc reconciliation is now closed too. `docs/ne-segment1.md` no longer presents the seg109/raw-reference UI addresses (`000b:*`) and the live seg1408 breakpoint-state addresses (`1408:*`) as if they were competing versions of one table; it now uses one combined component map that makes the layering explicit and preserves the interpreter callback at `1418:04aa..04b5` as the bridge between them.
|
||||
- The live NE `CRUSADER.EXE` mapping for that hidden-menu lane is now explicit and comment-backed in Ghidra too: direct hook `1130:2b75/2b78`, current-slot wrapper `13a0:0086` with constructor arg site `13a0:008d`, modal wrapper `13a0:020d` with inherited-arg patch subsite `13a0:024a`, listener create/dispatch `13a0:19b1` / `13a0:1df3`, compiled `0x410` CD-transfer-display body `13e8:2303`, deferred controller-side hook `13e8:25dd/25e0`, and the supporting cheat-state data cells at `1020:2833`, `1020:283d`, `1020:0844`, `1020:6045`, `1020:604f`, and `1020:6050`. The `0x410` body is still documented in place rather than renamed because it remains embedded inside the oversized `World_HandleKeyboardInput_13e8_14b4` function object. This improved live handoff and patch reproducibility still does not justify a headline estimate change by itself.
|
||||
- The retail `-debug` switch is now separated cleanly from that hidden debugger lane too. Live `HandleCommandlineArgs` recovery in `CRUSADER.EXE` confirms a real `"-debug"` branch at `1048:0a93` that sets `g_debugMsgLevel = 10` (`1478:87e0`), prints `Debugging mode ON.`, and writes `1478:0845/0859` (`g_someDebugFlag` / `g_someDebugFlag2`). The `0x87e0` threshold is read by `ConsolePrintf` / `DebugPrintAndWaitForInput`, and `0x0859` is read by the segment `1468` `VideoPlayer_*` neighborhood (`1468:2869`, `1468:2af4`, helper `1468:2de9`). Current best read is `surviving debug-output / media-instrumentation switch`, not `dead parser stub`, and still not `the missing seg109/seg1408 usecode debugger bootstrap`, because the same pass found no evidence that `-debug` constructs or stores the real debugger-state pointer at `1478:659c/659e`. Focused write-up now lives in `docs/retail-debug-arg.md`.
|
||||
- That `-debug` lane is tighter again after the follow-up deep dive and live Ghidra refinements. The seg1468 readers are now renamed/comment-backed as `VideoPlayer_AdvanceFrameAndHandleSkip`, `VideoPlayer_StreamChunks`, and `VideoPlayer_DrawDebugTimingOverlay`, and the helper body is no longer only `instrumentation-looking`: it writes two `500`-byte marker traces into adjacent scanlines near the bottom of a `0x280`-wide AVI playback buffer, using timing deltas scaled by `6000`. Current best read is therefore `built-in movie-playback timing overlay` plus the separate `g_debugMsgLevel` console/positioned-print threshold, still explicitly distinct from the hidden seg109/seg1408 usecode debugger path at `1478:659c/659e`.
|
||||
- The same `-debug` lane is now bounded more comprehensively too. The user-confirmed moving bottom-of-video dots match the static two-scanline overlay model, so that AVI timing overlay is now the first closed visible effect. Outside the video lane, `-debug` also changes the global seg12d0 print threshold (`1478:87e0 = 10`) used by `ConsolePrintf`, `DebugPrintAndWaitForInput`, and the positioned print helpers, but the sink side is now tighter as well: `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 threshold, not a separate hidden debugger console. Current xrefs still show that lane mostly as existing startup/config/cache/joystick/process diagnostics and a small set of dispatch/gump allocation failure-stop paths, not as a second confirmed hidden feature. The unresolved leftover is still `1478:0845`, which remains a parser-set latch with no recovered downstream consumer.
|
||||
- The print inventory behind that same `-debug` lane is now materially tighter too. A focused pass recovered concrete `ConsolePrintf` / `DebugPrintAndWaitForInput` strings instead of only caller families: startup/arg strings such as `Debugging mode ON.`, `You DO need help!`, `Enabling ENHANCED mode. (NOT!)`, `Warping to mission %d ...`, `Defaulting to skill level %d`, and `Demo mode.`; init/config strings such as `Using map patch file.`, `Running with partial installation.`, `Running with full installation.`, and `Redirecting mission %d tune to '%s'`; cache/swap progress scaffolding such as `Creating Swap file [` and repeated `.` / bracket fragments; plus stronger failure/debug-stop fingerprints like `COULD NOT CREATE GLOB ITEM!`, `No room for Dispatcher Record/Playback.`, `End of script! (press any key)`, and `Out of Memory! [%u]`. Recovered call levels so far are `0x32` and `0xff`, both above the `-debug` threshold of `10`, which reinforces that the practical scarcity of visible text is about path frequency and graphics-mode presentation, not about the threshold still filtering these known messages out.
|
||||
- The older folklore claim about flat offset `E69FB` and a possible secondary monochrome monitor is now materially weaker too. Local NE-segment mapping puts `0xE69FB` at live address `1478:2dfb`, which falls inside the `SYSTIMER.C` string in a data/name table (`KeyboardProcess`, `KEYIO.C`, `PRIORITY.C`, `SystemTimer`, `SYSTIMER.C`, `AccWait`), not inside executable instructions. The current retail print lane still points to ordinary `stdout` at `1478:6c46`, and targeted searches found no direct `mono`/`monochrome`/`hercules`/`MDA` strings or obvious monochrome-adapter port/memory references (`0x3b4/0x3b5/0x3b8/0x3ba`, `B000`). Current best read is therefore `folklore or address-mapping mistake`, not evidence for a hidden retail secondary-monitor debug display.
|
||||
|
||||
### Recently Closed Or No Longer Live
|
||||
|
||||
- The most reusable `misc_crusader_notes.txt` scratch items are no longer loose leads. `STEAM2` event hints are now checked against extracted USECODE rows, the old labels `FUN_1130_0896` / `FUN_1130_32af` / `FUN_1020_0000` / `FUN_1128_026b` are closed against live NE names, `ItemNPC_AnotherCreate` is now explicitly documented as the area-search-gated helper `NPC_CreateIfAreaSearchValid`, `Kernel_11d0_2491` is narrowed to a kernel/process snapshot writer, `FREE::ordinal3C` is constrained to an alert-clearing random `FREE::ordinal21` spawner, and `Int01E` is at least tightened from `unknown fire intrinsic` to `Actor::I_maybeFire` plus live export `1128:11da`.
|
||||
- `ASYLUM.24` is resolved as `_ASS_StopAllSFX`; it is no longer an open plan item.
|
||||
- The cheat/input side lane is complete enough to leave the live queue.
|
||||
- The segment coverage ledger is no longer a missing artifact; only refinement remains.
|
||||
|
|
@ -159,7 +174,7 @@ Detailed completed analysis belongs in the files under `docs/`, not in this plan
|
|||
12. Tighten the paired-file-family reading of the seg070 twin loops at `0009:67b6` and `0009:6916` by recovering which temporary buffer and record schema each family populates behind `entity_vm_runtime_owner_resource_create`.
|
||||
13. Promote additional ledger rows where the current docs already justify `Foothold`, `Partial`, or `Deep`.
|
||||
14. If the VM lane stalls again, revisit `000e:ffb0` from the now-verified `00db/00dc` caller windows and try to recover an adjacent non-overlapped helper before attempting any boundary repair.
|
||||
15. If the immortality lane is revisited, stay focused on `NPCTRIG` slot `0x0a` first, with slot `0x20` still treated as the typed/setup companion and `EVENT` only as the generic hub baseline; the first anchored `0005:295f` caller family is now closed structurally at `0006:4379` (`0x20c -> 0005:295f`, sibling `0x20b -> 0005:2918` inside one seg031 dispatch-entry family) and comment-backed in the live NE program at `10f0:02d9`, `10f0:0379`, `10f0:03c3`, and `10f0:03e5`, so the next defensible step is the remaining caller families at `0006:c5f0` and `0007:3584`, or an earlier producer that assigns subtype `0x20b/0x20c` into field `+0x3c` before the owner-loaded class choice reaches the VM lane.
|
||||
15. If the immortality lane is revisited, stay focused on `NPCTRIG` slot `0x0a` first, with slot `0x20` still treated as the typed/setup companion and `EVENT` only as the generic hub baseline; the three currently recovered direct `0005:295f` caller families are now all closed and comment-backed in the live NE program at `10f0:02d9`, `10f0:0379`, `10f0:03c3`, `10f0:03e5`, `1128:0ff0`, and `1138:1384`, so the next defensible step is an earlier producer that assigns subtype `0x20b/0x20c` into field `+0x3c` or otherwise chooses the owner-loaded class family before these generic damage consumers run.
|
||||
16. Use the new Pentagram-derived parser proof of concept as the first tooling bridge for raw class/slot bodies: extend opcode coverage conservatively, emit IR v1 artifacts, and only then prototype a Ghidra-side annotation importer against compiled anchors like `000d:51fd`, `000d:5572`, `000d:46ec`, `000d:22bc`, and `000d:ebe3`.
|
||||
|
||||
## Remaining Work To Reach A Reasonably Complete Decompilation State
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue