- Introduced new file `vm_mask_ladder.tsv` containing detailed mappings for Crusader USECODE VM masks and their associated descriptors. - Added comprehensive documentation in `scummvm-crusader-reference.md` outlining the structure, findings, and implications for reverse-engineering the Crusader engine within ScummVM. - Created `usecode-roundtrip-ir.md` to document the plan for converting Crusader USECODE bytes into a human-readable format, detailing the container layout, event names, and intrinsic tables. - Implemented a PowerShell script `temp_usecode_sample.ps1` for extracting and analyzing USECODE data from the Crusader FLX files, providing insights into class and event structures.
8 KiB
Runtime Descriptor Family Rankings
This report ranks descriptor families against the currently verified 000d VM/runtime lanes. It is intentionally conservative: it scores ecosystem-level fit, not a direct descriptor-id-to-opcode decode.
Owner Source
- Owner path:
000d:44df -> 000d:4c99 -> 000d:7000 -> (+0x10/+0x12) + 0x0d*slot + 4 - Loader evidence:
0009:67b6/6916 walk helper-owned +0x10/+0x18 tables, format per-entry paths, and then open/read/close files - Selector status:
0x19/0x1a/0x1b proven in 000d:0988; 0x18 implied; upstream [BP-0x32] seed unresolved
Ranked Families
| Rank | Runtime Lane | Descriptor Family | Labels | Fit | Confidence |
|---|---|---|---|---|---|
| 1 | active-event payload lane | event-hub | EVENT | strongest | high |
1. event-hub
- Runtime lane: active-event payload lane
- Labels: EVENT
- Fit: strongest
- Confidence: high
- Why: Explicit 69:0A00 event tag plus the richest source/dest/door/link/time/counter payload shape; best current match for the VM payload-chain plus link-matrix lane.
- Runtime ops: APPEND_UNIQUE_INLINE, APPEND_UNIQUE_INDIRECT, REMOVE_MATCHING_INDIRECT, REMOVE_MATCHING_INLINE, MATERIALIZE_OR_FORWARD_VALUE, PREPEND_INLINE_PAYLOAD, BUILD_ENTITY_LINK_MATRIX, EMIT_OR_PUSHBACK_RESULT, FINALIZE_MIXED_VALUE_TO_OUTPTR
- Mask pairs: 0x0001:0000, 0x0002:0001, 0x0004:0002, 0x0010:0004, 0x0020:0005, 0x0200:0009, 0x0400:000a, 0x0800:000b, 0x1000:000c, 0x2000:0015, 0x4000:000e, 0x8000:0007, 0x8000:000f
hub EVENT(mva3b,referent,event,item,source,dest,door,counter,counter2,link,time,post1,post2,floor,flicMan)
owner_slot = runtime_owner_table[slot]
chain = APPEND_UNIQUE_INLINE(...) or APPEND_UNIQUE_INDIRECT(...)
chain = REMOVE_MATCHING_INDIRECT(...) or REMOVE_MATCHING_INLINE(...)
payload = PREPEND_INLINE_PAYLOAD(...) when caller bytes are present
links = BUILD_ENTITY_LINK_MATRIX(shape_a, shape_b, entity_ids)
emit EVENT-style result through FINALIZE_MIXED_VALUE_TO_OUTPTR(...)
| 2 | active-event payload lane | boot-event-core | AND_BOOT, BRO_BOOT, COR_BOOT, VAR_BOOT, REE_BOOT | strong | high |
2. boot-event-core
- Runtime lane: active-event payload lane
- Labels: AND_BOOT, BRO_BOOT, COR_BOOT, VAR_BOOT, REE_BOOT
- Fit: strong
- Confidence: high
- Why: All five _BOOT descriptors share one compact referent,event,counter,item schema and sit beside referent-heavy object islands that fit the same active-event runtime lane.
- Runtime ops: APPEND_UNIQUE_INLINE, APPEND_UNIQUE_INDIRECT, REMOVE_MATCHING_INDIRECT, REMOVE_MATCHING_INLINE, MATERIALIZE_OR_FORWARD_VALUE, PREPEND_INLINE_PAYLOAD, BUILD_ENTITY_LINK_MATRIX, EMIT_OR_PUSHBACK_RESULT, FINALIZE_MIXED_VALUE_TO_OUTPTR
- Mask pairs: 0x0001:0000, 0x0002:0001, 0x0004:0002, 0x0010:0004, 0x0020:0005, 0x0200:0009, 0x0400:000a, 0x0800:000b, 0x1000:000c, 0x2000:0015, 0x4000:000e, 0x8000:0007, 0x8000:000f
attach COR_BOOT(referent,event,counter,item)
anchor referent/event/counter/item into one compact event core
materialize slot-backed value from runtime_owner_table[slot]
mutate referent payload chain via opcode_0x18_to_0x1b family
emit boot-style active event result
| 3 | active-event payload lane | npc-trigger | NPCTRIG | strong | moderate-high |
3. npc-trigger
- Runtime lane: active-event payload lane
- Labels: NPCTRIG
- Fit: strong
- Confidence: moderate-high
- Why: NPCTRIG carries an explicit event field and sits in the same compact event-bearing core as EVENT and COR_BOOT, but its narrower field set makes it look more satellite than hub.
- Runtime ops: APPEND_UNIQUE_INLINE, APPEND_UNIQUE_INDIRECT, REMOVE_MATCHING_INDIRECT, REMOVE_MATCHING_INLINE, MATERIALIZE_OR_FORWARD_VALUE, PREPEND_INLINE_PAYLOAD, BUILD_ENTITY_LINK_MATRIX, EMIT_OR_PUSHBACK_RESULT, FINALIZE_MIXED_VALUE_TO_OUTPTR
- Mask pairs: 0x0001:0000, 0x0002:0001, 0x0004:0002, 0x0010:0004, 0x0020:0005, 0x0200:0009, 0x0400:000a, 0x0800:000b, 0x1000:000c, 0x2000:0015, 0x4000:000e, 0x8000:0007, 0x8000:000f
attach NPCTRIG(referent,event,item,item2,typeNpc)
materialize slot-backed trigger payload
attach event plus item/item2/typeNpc side fields
emit NPC-trigger result through shared opcode epilogue
| 4 | active-event payload lane | minimal-event-core | SFXTRIG | moderate | moderate |
4. minimal-event-core
- Runtime lane: active-event payload lane
- Labels: SFXTRIG
- Fit: moderate
- Confidence: moderate
- Why: SFXTRIG keeps the active event tag while stripping most side fields, so it still fits the live event lane but as a smaller attachment form rather than a full hub or boot core.
- Runtime ops: APPEND_UNIQUE_INLINE, APPEND_UNIQUE_INDIRECT, REMOVE_MATCHING_INDIRECT, REMOVE_MATCHING_INLINE, MATERIALIZE_OR_FORWARD_VALUE, PREPEND_INLINE_PAYLOAD, BUILD_ENTITY_LINK_MATRIX, EMIT_OR_PUSHBACK_RESULT, FINALIZE_MIXED_VALUE_TO_OUTPTR
- Mask pairs: 0x0001:0000, 0x0002:0001, 0x0004:0002, 0x0010:0004, 0x0020:0005, 0x0200:0009, 0x0400:000a, 0x0800:000b, 0x1000:000c, 0x2000:0015, 0x4000:000e, 0x8000:0007, 0x8000:000f
attach SFXTRIG(referent,event)
bind referent to minimal event payload
reuse generic active-event mutation path without hub-style side fields
| 5 | active-event payload lane | environmental-event | FLAMEBOX, NOSTRIL, STEAMBOX | moderate | moderate |
5. environmental-event
- Runtime lane: active-event payload lane
- Labels: FLAMEBOX, NOSTRIL, STEAMBOX
- Fit: moderate
- Confidence: moderate
- Why: FLAMEBOX, NOSTRIL, and STEAMBOX share the same active event grammar, but no hazard-specific opcode or mask split is proven yet beyond the generic active-event-biased ladder.
- Runtime ops: APPEND_UNIQUE_INLINE, APPEND_UNIQUE_INDIRECT, REMOVE_MATCHING_INDIRECT, REMOVE_MATCHING_INLINE, MATERIALIZE_OR_FORWARD_VALUE, PREPEND_INLINE_PAYLOAD, BUILD_ENTITY_LINK_MATRIX, EMIT_OR_PUSHBACK_RESULT, FINALIZE_MIXED_VALUE_TO_OUTPTR
- Mask pairs: 0x0001:0000, 0x0002:0001, 0x0004:0002, 0x0010:0004, 0x0020:0005, 0x0200:0009, 0x0400:000a, 0x0800:000b, 0x1000:000c, 0x2000:0015, 0x4000:000e, 0x8000:0007, 0x8000:000f
attach FLAMEBOX(referent,event,flame,flame2,direction,count,newType)
bind referent plus event to hazard-specific side fields
reuse generic active-event lane; no hazard-specific opcode split proven
| 6 | referent-anchor / payload-owner lane | referent-anchor | JELYHACK, JELYH2 | strong | moderate-high |
6. referent-anchor
- Runtime lane: referent-anchor / payload-owner lane
- Labels: JELYHACK, JELYH2
- Fit: strong
- Confidence: moderate-high
- Why: JELYHACK and JELYH2 are still referent-only, but the VM referent registry and payload-chain machinery now make that a live anchor role rather than inert metadata.
- Runtime ops: APPEND_UNIQUE_INLINE, APPEND_UNIQUE_INDIRECT, REMOVE_MATCHING_INDIRECT, REMOVE_MATCHING_INLINE, MATERIALIZE_OR_FORWARD_VALUE
- Mask pairs: anchor role uses referent registry and payload ownership; no anchor-specific slot mask proven
anchor JELYHACK(referent)
referent_id = registry anchor
payload_chain = mutable owner-side chain attached to the referent
neighboring event-bearing descriptor supplies live event semantics
likely attachments: REE_BOOT, SURCAMEW, SFXTRIG
| 7 | callback / attachment lane | callback-eventtrigger | SURCAMNS, SURCAMEW | weak-moderate | moderate |
7. callback-eventtrigger
- Runtime lane: callback / attachment lane
- Labels: SURCAMNS, SURCAMEW
- Fit: weak-moderate
- Confidence: moderate
- Why: SURCAMNS and SURCAMEW are structurally coherent callback holders with eventTrigger tags, but the current mask ladder and opcode evidence still align more strongly with active event carriers than callback-specific dispatch.
- Runtime ops: MATERIALIZE_OR_FORWARD_VALUE, PUSH_FRAME_WORD_LITERAL, COMPARE_STREAM_DWORD_AND_PUSH_BOOL, FINALIZE_MIXED_VALUE_TO_OUTPTR
- Mask pairs: no callback-specific mask pair proven; verified ladder still favors active event carriers
callback SURCAMNS(referent,textFile,monit,valueBox,passcode,link,code,screen,cameraEgg,trueRef,therma,eventTrigger,foundGun)
callback-side attachment remains descriptor-visible
runtime bridge is still generic slot-backed context flow rather than callback-specific opcode dispatch