more work done

This commit is contained in:
MaddoScientisto 2026-04-09 00:32:12 +02:00
commit d323bb28fc
68 changed files with 714 additions and 19 deletions

View file

@ -109,14 +109,19 @@ So the safe future modeling strategy is:
## Candidate Virtual Slot Map
The currently verified slots are already good enough for a first typed vtable.
`DispatchEvent` now gives a materially tighter slot map than the earlier placeholder `A/B/C/D` read.
| Slot offset | Current best role | Evidence |
|---|---|---|
| `+0x14` | event handler A | `sprite_node_dispatch_event` dispatches here for one event class |
| `+0x18` | event handler B | same dispatcher |
| `+0x20` | event handler C | same dispatcher |
| `+0x24` | event handler D | same dispatcher |
| `+0x04` | event `1` handler | `DispatchEvent` routes event code `1` here directly |
| `+0x08` | event `2` handler | same dispatcher |
| `+0x0c` | event `4` handler | same dispatcher |
| `+0x10` | event `8` handler | same dispatcher |
| `+0x14` | event `0x10` handler | same dispatcher |
| `+0x18` | event `0x20` handler | same dispatcher |
| `+0x1c` | event `0x40` self handler | called after the dispatcher walks child nodes for the same event |
| `+0x24` | event `0x100` handler | same dispatcher |
| `+0x34` | child-broadcast event `0x40` slot | used on child nodes during the `0x40` walk, not on the root dispatch object itself |
The seg091 default-slot helpers are also useful evidence:
@ -153,11 +158,45 @@ When class authoring begins, the safest sequence for this family is:
4. create provisional vtable with slots `+0x14`, `+0x18`, `+0x20`, `+0x24`
5. keep recursive tree helpers outside the class until decompiler output shows they benefit from becoming methods
## Live Ghidra Authoring Status
Verified first live `SpriteNode` batch landed on 2026-04-08.
- Created class owner `Remorse::SpriteNode` in the active `CRUSADER.EXE` database.
- Re-anchored the strongest old `000b:` method batch into the live `1360:` segment by preserved offset delta from `000b:326e -> 1360:046e`.
- Created minimal live datatypes `/Remorse/SpriteNodeBase` and `/Remorse/SpriteNodeVtable` from the current safest note anchors.
- `/Remorse/SpriteNodeBase` currently names only the bounded field block that is directly supported by the live method batch:
- `+0x19 = child_or_next_farptr`
- `+0x21 = local_x_offset`
- `+0x23 = local_y_offset`
- `+0x29 = dirty_flags`
- `/Remorse/SpriteNodeVtable` is still the earlier minimal shell in-session, but the live `DispatchEvent` read now supports a deeper slot map than the first authoring batch encoded:
- direct self dispatch uses `+0x04`, `+0x08`, `+0x0c`, `+0x10`, `+0x14`, `+0x18`, `+0x1c`, and `+0x24`
- child broadcast during event `0x40` uses child slot `+0x34`
- Moved the first bounded method set under the class owner with short provenance comments:
- `1360:036a` -> `Create` (best current constructor-style anchor; still keep the higher-wrapper caveat visible)
- `1360:046e` -> `Destroy` (older note anchor `000b:326e`)
- `1360:0580` -> `IsDirty` (older note anchor `000b:3380`)
- `1360:05a6` -> `MarkDirty` (older note anchor `000b:33a6`)
- `1360:0955` -> `GetOrTraverse` (best current live anchor for older note anchor `000a:b988`)
- `1360:0cb2` -> `DispatchEvent` (older note anchor `000b:3ab2`)
- `1360:12ee` -> `UpdateAndDispatch` (older note anchor `000b:40ee`)
- The live decompiler now makes the core family surface much easier to navigate directly in-session:
- `Create` now exists live as the current safest constructor-style anchor: it allocates `0x34` bytes when `this` is null, stamps the `0x501a` SpriteNode vtable, initializes the child-link/core offset fields, and links the incoming parent/child lane.
- Direct callers now narrow the subtype story materially: the current call set is dominated by `GumpCreate_*` and adjacent UI wrapper constructors, which supports treating `Create` as the compact shared base-node constructor used by higher-level gump/display objects rather than as a one-off derived leaf.
- `Destroy` restores the `0x501a` base vtable, clears the global focus pointer when `this` owns it, releases child linkage, and optionally frees self.
- `IsDirty` and `MarkDirty` read and mutate the `+0x29` dirty-state lane exactly as the note predicted.
- `GetOrTraverse` now exists live as the best current `000a:b988` re-anchor: it recursively walks the child-linked subtree, adjusts the incoming query coordinates by the local offsets, and returns either the matched child node or the default sentinel through the out pointer.
- `DispatchEvent` updates the global focus pointer at `0x4fd0:0x4fd2` and now ties concrete event codes to concrete slot offsets: `1/2/4/8 -> +0x04/+0x08/+0x0c/+0x10`, `0x10/0x20 -> +0x14/+0x18`, `0x40 -> child +0x34 then optional self +0x1c`, and `0x100 -> +0x24`.
- `UpdateAndDispatch` now clearly shows the `IsDirty` / `MarkDirty` / recompute / child-walk sequence instead of staying as an anonymous seg1360 helper.
- The `SpriteNode` family is therefore no longer note-only. What remains open is narrower now: chiefly whether `Create` should remain the family's public constructor-style entry or later be split into a higher derived/UI wrapper and a smaller base-node constructor once more callers and subtype evidence land, plus the deeper vtable-slot and subtype-layout questions.
## Open Questions
- whether the current `Create` signature itself can be cleaned up further now that its caller set points to a shared compact base-node constructor used by higher-level gump wrappers
- exact root vtable address or addresses for the main SpriteNode family
- whether the `+0x17e` redraw flag belongs to a derived display node rather than the compact base node
- which event-code cases map to which slot semantically beyond the current `A/B/C/D` placeholder naming
- whether the recovered event-code map can now be promoted from raw event-code labels to prettier semantic slot names without overfitting UI behavior too early
- whether `sprite_tree_accumulate_pos` should become a class method, a static helper, or a separate geometry utility
## Immediate Follow-Up Value