6830 lines
145 KiB
TOML
6830 lines
145 KiB
TOML
# vm-map/opcodes.toml -- CANONICAL living opcode reference (hand-edited).
|
|
# Generated artifacts (age_opcodes_himegari.py, build/opcodes.json, docs/opcode-reference.md,
|
|
# build/opcode-coverage.md) come from this file via tools/opcodes_build.py --build. Do not edit those.
|
|
# Skeletons are appended by --bootstrap; enrich each [opcode.semantics] as we investigate.
|
|
[meta]
|
|
instruction_model = "code = seq of <opcode:u32> then argc*(<argtype:u32><value:u32>); len_dwords = 1 + 2*argc"
|
|
opcodes_used_by_himegari = 248
|
|
|
|
[meta.arg_types]
|
|
"0x0" = "immediate"
|
|
"0x1" = "float"
|
|
"0x2" = "string"
|
|
"0x3" = "global-int"
|
|
"0x4" = "global-float"
|
|
"0x5" = "global-string"
|
|
"0x6" = "global-ptr"
|
|
"0x8" = "global-string-ptr"
|
|
"0x9" = "local-int"
|
|
"0xa" = "local-float"
|
|
"0xb" = "local-string"
|
|
"0xc" = "local-ptr"
|
|
"0xd" = "local-float-ptr"
|
|
"0xe" = "local-string-ptr"
|
|
|
|
[meta.header_fields]
|
|
"F0" = "local_integer_1"
|
|
"F1" = "local_floats"
|
|
"F2" = "local_strings_1"
|
|
"F3" = "local_integer_2"
|
|
"F4" = "unknown_data"
|
|
"F5" = "local_strings_2"
|
|
"F6" = "sub_header_length(=0x1C)"
|
|
"F7" = "table_1_length"
|
|
"F8" = "table_1_offset(=code end)"
|
|
"F9" = "table_2_length"
|
|
"F10" = "table_2_offset"
|
|
"F11" = "table_3_length"
|
|
"F12" = "table_3_offset"
|
|
|
|
[[opcode]]
|
|
op = 0x1
|
|
label = "u004149C0"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u004149C0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x2
|
|
label = "exit"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "exit"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x3
|
|
label = "call-script"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "call-script"
|
|
category = "control"
|
|
summary = "load & call another SYS4 script by id; id = RAW index into the SYS4INI file table (asset-index). Pushes a script frame; returns to caller when the callee ends."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "native-RE (Ghidra): handler FUN_0041bc90 -> loader FUN_0040e980 -> resolver FUN_0044f390 indexes an 80-byte record table (base [ctx+0x414], count [ctx+0x40c]) at base+id*0x50 = the SYS4INI record layout {name[64],arc_id@0x40,file_number@0x44,offset@0x48,size@0x4c}. Confirmed statically: all 297 distinct corpus call-script ids resolve to a .BIN script with a semantically-exact name (0x1ab->ADDITEM, 0x2ae7->MES, 0x143->BUNKI, 0x329d->CALCREVISE), 0 out-of-range, 0 pack-branch. See docs/engine-re.md + name-resolution.md #1."
|
|
confirm_by = ""
|
|
details = """
|
|
op 0x03 (call-script, argc 1): `call-script <id>`. RESOLVED — the id is a direct RAW index into
|
|
the SYS4INI global file table (the same table parse_sys4ini.py reads, but indexed WITHOUT skipping
|
|
'@' placeholders; SYS4INI has 13208 records / 2 placeholders). No separate on-disk id->code registry
|
|
exists; SYS4INI *is* the call-script registry.
|
|
Native mechanism (dispatch table `handler(op)=ctx[0x26c93+op]`, op 0x03 -> FUN_0041bc90):
|
|
1. FUN_0041bc90 fetches operand 1 (id), bounds-checks call depth (<=0x26), pushes a frame.
|
|
2. FUN_0040e980 (loader): opens the resource by id, reads the 0x20-byte SYS4 header, checks magic,
|
|
allocates per-frame code/local buffers from the header var-counts, reads the bytecode body,
|
|
pushes a script frame (stride 0x1e = 30 dwords, indexed by ctx[0x14f45]).
|
|
3. FUN_0044f390 (resolver): record = [ctx+0x414] + id*0x50. Tries a LOOSE OVERRIDE first
|
|
(CreateFileA on record.name -> mod/patch hook point), else opens archive [record.arc_id*0x100 +
|
|
ctx+0x410], SetFilePointer to record.offset, size = record.size.
|
|
(High-byte-tagged ids `id & 0xff000000` select an alternate pack via [ctx+0x3028]; UNUSED by the
|
|
corpus -- 0/297 ids have a high byte.)
|
|
Companion op 0x8f `call` is INTRA-script (a local JSR), not cross-script -- see its entry.
|
|
This also names the whole call graph statically (build/callscript-names.json).
|
|
"""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "script id = raw SYS4INI file index"
|
|
observed_types = ["imm", "g-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x5
|
|
label = "ret"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "ret"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x6
|
|
label = "u00417E80"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00417E80"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x8
|
|
label = "u00417FC0"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00417FC0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x9
|
|
label = "exit-script"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "exit-script"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x21
|
|
label = "u00418860"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00418860"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x22
|
|
label = "u00418920"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00418920"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x25
|
|
label = "u00418B40"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00418B40"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x50
|
|
label = "add"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "add"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x51
|
|
label = "sub"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "sub"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x52
|
|
label = "mul"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "mul"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x53
|
|
label = "div"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "div"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x54
|
|
label = "mod"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "mod"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x55
|
|
label = "mov"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "mov"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x56
|
|
label = "and"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "and"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x57
|
|
label = "or"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "or"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x58
|
|
label = "sar"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "sar"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x59
|
|
label = "shl"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "shl"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x5a
|
|
label = "eq"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "eq"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x5b
|
|
label = "ne"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "ne"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x5c
|
|
label = "lt"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "lt"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x5d
|
|
label = "lte"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "lte"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x5e
|
|
label = "gr"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "gr"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x5f
|
|
label = "gre"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "gre"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x60
|
|
label = "u0041A270"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041A270"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x61
|
|
label = "lookup-array"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "lookup-array"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-ptr", "l-str-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-int", "g-str", "l-int", "l-str"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x63
|
|
label = "u00414A60"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00414A60"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x64
|
|
label = "copy-local-array"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "copy-local-array"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x6c
|
|
label = "copy-to-global"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "copy-to-global"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x6e
|
|
label = "show-text"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "show-text"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["string", "g-str"]
|
|
|
|
[[opcode]]
|
|
op = 0x6f
|
|
label = "end-text-line"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "end-text-line"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x70
|
|
label = "u0041A750"
|
|
argc = 5
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041A750"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x71
|
|
label = "u0041A7B0"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "label-def"
|
|
category = "structural"
|
|
summary = "1 imm; count == T1 table size -> the label/anchor T1 indexes. v1 no-op; revisit if menu/callback dispatch looks up by id"
|
|
noop_headless = true
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x72
|
|
label = "wait-for-input"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "wait-for-input"
|
|
category = "adv"
|
|
summary = "(layout_slot) - arm the ADV input wait after text reveal completes; activates the wait indicator configured for the selected text layout by op 0x73."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra /v2: op_0x72_handler@0x41e690 fetches operand 1 and calls FUN_00453120(text_manager, layout_slot, -1, &state), then sets the input-wait run-state flags. FUN_00453120 resolves layout slot 0 as current and consumes the indicator descriptor at layout+0x3c configured by op 0x73. SYSTEM4 layout 1 uses SO000's bat strip; the click that completes show-text is consumed before this opcode is reached."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "layout slot (0 = current)"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x73
|
|
label = "configure-adv-wait-indicator"
|
|
argc = 10
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "configure-adv-wait-indicator"
|
|
category = "adv"
|
|
summary = "(layout_slot)(dst_x)(dst_y)(surface_slot)(src_x)(src_y)(cell_w)(cell_h)(terminal_frame)(frame_period_ms) - configure the animated marker shown while the selected ADV layout waits for input."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra /v2: op_0x73_configure_wait_indicator@0x41e900 passes operands 1..9 to adv_text_configure_wait_indicator@0x44ff60 and operand 10 to adv_indicator_set_frame_period@0x44d060. The worker writes surface/source rect, layout-relative destination, enabled=1, and terminal/column values to the selected layout at +0x3c..+0x60. SYSTEM4 executes `set-texture 0x337c 0xc 0xff00` (raw id 0x337c = SO000.AGF, a 390x27 strip of thirteen 30x27 bat frames), then `0x73 1 385 140 12 0 0 30 27 12 48`; layout 1 begins at y=430, placing the 30x27 marker at screen (385,570), matching the original. Op 0x72 activates this descriptor only after reveal completion."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "layout slot (0 = current)"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = "destination x, layout-relative"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = "destination y, layout-relative"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = "source surface slot"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = "source x"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 6
|
|
role = "source y"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 7
|
|
role = "cell width"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 8
|
|
role = "cell height"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 9
|
|
role = "terminal frame index / sheet columns"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 10
|
|
role = "frame period (milliseconds)"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x75
|
|
label = "u0041AC30"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041AC30"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x76
|
|
label = "u0041AC60"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041AC60"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x77
|
|
label = "u0041ACB0"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041ACB0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x78
|
|
label = "u0041AD00"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041AD00"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x79
|
|
label = "u0041AD30"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041AD30"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x7a
|
|
label = "set-adv-text-cursor"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "set-adv-text-cursor"
|
|
category = "adv"
|
|
summary = "(layout_slot)(x)(y) - set the cursor in the selected ADV text layout's last 20-byte record. Slot 0 selects the current layout."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra /v2: op_0x7a_handler@0x41eba0 fetches operands 3,2,1 and calls adv_text_set_cursor@0x4530f0 on text manager ctx+0x14940. Slot 0 resolves manager+0x4c8; manager+0x414[slot] selects the layout; text_layout_set_cursor@0x452530 writes x/y to +4/+8 of its last 0x14-byte record. SC0000 0x9d3 computes slot 1, x=75, y=47 before voiced show-text."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "layout slot (0 = current)"
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = "cursor x"
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = "cursor y"
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x7b
|
|
label = "u0041ADB0"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "coroutine-save-yield-handlers"
|
|
category = "control"
|
|
summary = "(handler1_pc)(handler2_pc) — scene-coroutine: save the two per-frame yield/resume handler PCs. Native writes op1→ctx[0x6da88+idx*4], op2→ctx[0x6db28+idx*4] (idx=ctx[0x53d14] script-context index) + gfx cmd-type 5. SC0000 0x79: `0x7b label_3c9 label_41e` registers the ADV per-frame render→poll→yield handlers. Part of the scene-coroutine framework (see engine-re.md §Scene-coroutine framework); pairs with 0x7c (resume) + 0x140 (loop iterator)."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra: handler FUN_0041ebf0 (dispatch ctx[0x26c93+0x7b]) = {*(ctx+0x53d88+ctx[0x53d14]*0x78)=5; ctx[0x6da88+idx*4]=op1; ctx[0x6db28+idx*4]=op2}. Both operands are code PCs (handler labels)."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "yield handler-1 PC"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = "yield handler-2 PC"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x7c
|
|
label = "u00416A90"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "coroutine-resume"
|
|
category = "control"
|
|
summary = "() — scene-coroutine RESUME point. Native requires run-state bit 0x2000000 (ctx[0x6dbc8]) set — THROWS (__CxxThrowException) if unset, so it is only ever reached on a scheduler-driven re-entry, NEVER on a cold first pass (cold flow jmps over it). Restores PC=ctx[0x53d28]+ctx[0x6dbcc]*4, clears the run-bit (ctx+0xa0ce4 &= ~0x2000000), resets input/line state. SC0000 0x443 (falls into the main loop label_444). See engine-re.md §Scene-coroutine framework."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra: handler FUN_00417cb0 (dispatch ctx[0x26c93+0x7c]). Guards on (ctx[0x6dbc8] & 0x2000000)==0 → throw; else restores PC = ctx[0x53d2c-slot] = ctx[0x53d28]+ctx[0x6dbcc]*4, ctx[0xa0ce4]=ctx[0x6dbc8]&0xfdffffff, clears input state (ctx[0x13bdc]/0xc6f8=-1 etc.)."
|
|
|
|
[[opcode]]
|
|
op = 0x7f
|
|
label = "u00414C60"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00414C60"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x80
|
|
label = "u0041AF00"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041AF00"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x85
|
|
label = "u00414CF0"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00414CF0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x86
|
|
label = "u0041B210"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041B210"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x87
|
|
label = "u00414D10"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00414D10"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x88
|
|
label = "u0041B290"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041B290"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x8b
|
|
label = "u0041B3D0"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041B3D0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x8c
|
|
label = "jmp"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "jmp"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x8f
|
|
label = "call"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "call"
|
|
category = "control"
|
|
summary = "intra-script subroutine call (local JSR): PC = frame.codebase + operand*4; pushes a return address on the per-frame return stack. NOT cross-script (that is call-script 0x03)."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "native-RE (Ghidra): handler FUN_0041fba0 (= ctx[0x26c93+0x8f]) sets [frame PC @+0x53d2c] = [frame codebase @+0x53d28] + operand*4 and pushes ((pc-base)>>2)+3 onto the per-frame return stack ([ctx+0x552e8]/[ctx+0x55248]). Target is a code OFFSET within the current script (matches header table T3 tag 0x8F = local call targets), confirming it is a local JSR, not a script load."
|
|
confirm_by = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "local code target (word offset within current script)"
|
|
observed_types = ["imm", "g-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x90
|
|
label = "u0041BEB0"
|
|
argc = 7
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "hotspot-branch"
|
|
category = "input"
|
|
summary = "cursor/input hotspot hit-test: rect (x,y,w,h) -> 3-way branch on interaction, else fall through to pc+1"
|
|
noop_headless = true
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = [0x1f4, 0x1f5]
|
|
evidence = "all 301 ADV scripts contain the identical 8 sites; enc.len 15 lands pc+1 on the fall-through stmt (design-confirmed); fall-through = correct headless no-input path, proven by 279 CLEAN dialogue scenes"
|
|
confirm_by = "target->interaction-state mapping (hover-enter/leave/click) via live input capture or Frida in A2"
|
|
details = """
|
|
op 0x90 (u0041BEB0, argc 7): `0x90 x y w h tgt_a tgt_b tgt_c`. Kelebek left it "ukn" noting args
|
|
5-7 are code locations. Corpus analysis (all 301 ADV scripts) resolves it:
|
|
- Two forms, both ONLY in one shared ADV-chrome subroutine copied into every ADV script:
|
|
* Mode A (1505 = 5x301): immediate x,y,w,h with w=h=20; the five on-screen buttons at
|
|
(684|706|728|750|772, 572), each setting one of G[0x6c9..0x6cd] to 1 / 0 / 0+run-action
|
|
(reads as hover-enter / hover-leave / click). All 3 targets real.
|
|
* Mode B (903 = 3x301): local-int operands, w=h=1, only tgt_c real -- a keyed 2-way input test.
|
|
- Every one of the 301 scripts has EXACTLY 8 sites (5 A + 3 B); zero scene-specific use.
|
|
- Falls through (pc+1) when nothing matches -- design-confirmed (0xd0 + 15 dwords = 0xdf = label_df).
|
|
- Headless (no cursor/input) => fall through => vm0 stub already correct; the 12 EMPTY sweep scenes
|
|
are gated by state + this input-wait chrome, NOT by unmodelled 0x90. Model live in A2.
|
|
"""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 6
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 7
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x93
|
|
label = "u00415040"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00415040"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x94
|
|
label = "u00415090"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00415090"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x97
|
|
label = "u0041C150"
|
|
argc = 5
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "hotspot-reg?"
|
|
category = "input"
|
|
summary = "companion register-hotspot / set-widget-action (argc5: v1 v2 1 1 <action-id>; NO code targets)"
|
|
noop_headless = true
|
|
source = "inference"
|
|
confidence = "med"
|
|
depends_on = [0x90]
|
|
evidence = "interleaves with 0x90 in the shared ADV-chrome subroutine; trailing imm = action id 0x0/0x7/0x8; same widget cluster as 0x90/0x91/0x92/0x95; confirm via frida"
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0xa0
|
|
label = "jcc"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "jcc"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0xa1
|
|
label = "u00427C00"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00427C00"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0xa2
|
|
label = "u00427FD0"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00427FD0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0xa3
|
|
label = "u004244D0"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u004244D0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0xae
|
|
label = "u00415130"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00415130"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0xb4
|
|
label = "play-sound-effect"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "sfx-load"
|
|
category = "audio"
|
|
summary = "(resource_id)(channel) — synchronously resolve/open the scene-manifest asset and replace the channel's decoded sound buffer without starting playback. Native manager supports channels 0..12; SC0000 uses 0..9."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra op 0xb4 handler 0x4201d0 -> sfx_channel_load@0x482500 -> asset_open@0x44f390 + sound_decode_channel@0x483360. Native trace: SC0000 0xc29 loads resource 0x28 into channel 0; resource resolves by section_base+id to E0808.WAV; completion precedes 0xb5 in the same millisecond."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "resource_id"
|
|
observed_types = ["imm", "g-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = "channel"
|
|
observed_types = ["imm", "g-int", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0xb5
|
|
label = "u0041D050"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "sfx-start"
|
|
category = "audio"
|
|
summary = "(channel) — start the already-loaded channel once (logical loop=false). DirectSound publishes synchronously through Play(0,0,DSBPLAY_LOOPING); the low-level flag loops only the streaming ring, while decoder EOF stops logical playback."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra op 0xb5 handler 0x420210 passes mode 0 to sfx_channel_start@0x4825d0; mode 1 belongs to op 0xba. sound_buffer_start@0x484270 primes four quarter-buffer notifications then calls IDirectSoundBuffer::Play with flag 1 before returning. Native trace at SC0000 0xc2e: E0808 channel 0 start enters/leaves in the same ms, preloaded 1->0 and playing 0->1."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "channel"
|
|
observed_types = ["imm", "g-int"]
|
|
|
|
[[opcode]]
|
|
op = 0xb6
|
|
label = "u0041D080"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "sfx-release"
|
|
category = "audio"
|
|
summary = "(channel) - stop/destroy the channel decoder and DirectSound buffer, clear its retained resource id, and leave the slot empty. Idempotent for an unused channel."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra op 0xb6 handler 0x420250 -> sfx_channel_release@0x482600 -> sound_buffer_destroy@0x4831a0, which releases the per-channel object under its critical section and clears the slot. Native trace captured SC0000's channels 0..9 release sweep in consecutive calls."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "channel"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0xb7
|
|
label = "u0041D0E0"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041D0E0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0xb8
|
|
label = "u00415520"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00415520"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0xb9
|
|
label = "u0041D140"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041D140"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0xba
|
|
label = "u0041D0B0"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041D0B0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0xbf
|
|
label = "play-bgm"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "play-bgm"
|
|
category = "audio"
|
|
summary = "Play background music by id. BGM is addressed by DIRECT LITERAL NAME: id -> BGM{id:03d}.OGG (in DATA3), NOT the per-scene section manifest (that's voices/textures). E.g. play-bgm 5 -> BGM005."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "By-ear confirmed (2026-07-06): SC0000 real game plays BGM005 for play-bgm 0x5 and BGM008 for play-bgm 0x8 (we initially mis-played BGM006/BGM009 via the manifest = off-by-one). Direct-name proven by play-bgm 0x23 -> BGM035.OGG, a real standalone track (BGM set skips 030-034) that the manifest mis-resolved to a graphics entry (EV049AA.AGF). CORRECTS the earlier 'unified manifest / Frida BGM006' claim, which was wrong by one. Voices/textures still use the manifest (files[base+id], offset 0). Diagnostic: `Age.Cli audio SC0000.BIN`."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "bgm id (direct file-name number: BGM{id:03d}.OGG)"
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0xc0
|
|
label = "u00415620"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00415620"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0xc2
|
|
label = "u0041D2B0"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "fade-bgm"
|
|
category = "audio"
|
|
summary = "(target_percent)(duration_ms) — block script service while linearly fading current BGM volume to 0..100%. Durations >=1000 ms use 100 steps; shorter fades use 10. Target 0 releases the current BGM source at completion."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra op 0xc2 handler 0x4204c0 sets run-state 0x200, arms the service timer, and calls bgm_fade_arm@0x464830; bgm_fade_tick@0x464960 interpolates current/target percent and applies volume, releasing at target 0. Native SC0000 trace at 0x7c1/0x126c shows target 0, duration 3000, 1% ticks at about 30 ms."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "target_percent"
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = "duration_ms"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0xc4
|
|
label = "play-voice"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "play-voice"
|
|
category = "audio"
|
|
summary = "Play a voice clip by id; id resolves via the SYS4INI section manifest -> files[section_base(scene)+id] (voice OGG in DATA1/DATA4). Same rule as set-texture (NOT play-bgm, which is direct-name BGM{id:03d})."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "By-ear confirmed (2026-07-06): SC0000 prologue voices play on their lines via Godot AudioStreamPlayer. Off-by-one disproven structurally: manifest interleaves graphics/voice (files[35]=EV049AA, [36]=MAN999, [37]=EV052CA, [38]=SYL0001), so files[base+id] lands voices on OGGs while files[base+id-1] would land them on .AGF graphics (silent) -- and they play, so the offset is exactly 0. Lily's lines are correctly form-gated (G[0xa57/0xa58/0xa59]) and stay silent when no form flag is seeded -- not a bug."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "voice id (section-manifest index)"
|
|
observed_types = ["imm", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0xc5
|
|
label = "u0041D4A0"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041D4A0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0xc6
|
|
label = "u0041D5D0"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041D5D0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0xc7
|
|
label = "u0041D760"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041D760"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0xc8
|
|
label = "sleep"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "sleep"
|
|
category = "control"
|
|
summary = "Pause the current script for <duration> milliseconds while retained presentation continues."
|
|
details = "Native handler sleep_op_0xc8 @0x420ec0 is NON-BLOCKING: it arms a timer (sleep_timer_arm @0x44cff0 at ctx+0x5f304 = active flag + start tick + duration) that the engine main loop polls, resuming the script when elapsed. Operand UNIT = MILLISECONDS (start = ms tick source DAT_0056f3d4, timeGetTime/GetTickCount class). duration<10 fast-paths via [0x56f0b8]; all real scene sleeps (100/750/1000) are >=10. The handler also writes gfx cmd-type 3 + runs anti-tamper checks, neither needed host-side. Port equivalent: the Godot host parks the VM thread for duration ms while the presentation compositor continues. Sleep is one proven presentation-capable service boundary; ordinary AE setup runs burst-fast to 0x21c and is not paced per opcode. Headless hosts no-op it (parity)."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra: dispatch ctx[0x26c93+0xc8]=0x420ec0; sleep_op_0xc8 + sleep_timer_arm decoded/annotated 2026-07-08. docs/engine-re.md sleep section."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "duration_ms"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0xcc
|
|
label = "mouse_callback"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "mouse_callback"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0xcd
|
|
label = "get-input-type"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "get-input-type"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0xd0
|
|
label = "u00415830"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00415830"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0xd3
|
|
label = "u00425960"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00425960"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0xd4
|
|
label = "u004266F0"
|
|
argc = 4
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u004266F0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0xd5
|
|
label = "u004262C0"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u004262C0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0xd9
|
|
label = "u00415880"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "clear-run-state-0x1000"
|
|
category = "control"
|
|
summary = "Clear native run/service bit 0x1000; if the secondary context is active, clear the same bit there. SC0000 executes it once after the initial SFX-channel reset, with no VM-visible result."
|
|
noop_headless = true
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra op 0xd9 handler 0x416da0: ctx->run_state_flags &= ~0x1000; when ctx+0x6f8b8 is nonzero, also clears bit 0x1000 at ctx+0x53d20. No operands, calls, or return value."
|
|
|
|
[[opcode]]
|
|
op = 0xfb
|
|
label = "joy_callback"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "joy_callback"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0xfe
|
|
label = "u0041E360"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041E360"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0xff
|
|
label = "u00415A10"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00415A10"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x100
|
|
label = "u00415A60"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00415A60"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x101
|
|
label = "u00415BF0"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00415BF0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x107
|
|
label = "u0041E500"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041E500"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x108
|
|
label = "u00415E70"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00415E70"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x109
|
|
label = "u00415EC0"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00415EC0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x10a
|
|
label = "u0041E540"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041E540"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x10b
|
|
label = "u0041E5A0"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041E5A0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x10c
|
|
label = "u0041E5E0"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041E5E0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x10d
|
|
label = "u00415F10"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00415F10"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x12c
|
|
label = "lookup-array-2d"
|
|
argc = 5
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "lookup-array-2d"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-ptr", "l-str-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-int", "g-str", "l-int", "l-str"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x12e
|
|
label = "u0041E940"
|
|
argc = 8
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041E940"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 6
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 7
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 8
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x12f
|
|
label = "u0041ECB0"
|
|
argc = 4
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041ECB0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x130
|
|
label = "u00415F40"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00415F40"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x131
|
|
label = "u00415F70"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00415F70"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x132
|
|
label = "u0041EF00"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041EF00"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x133
|
|
label = "u0041EFF0"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041EFF0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x134
|
|
label = "u0041F050"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041F050"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x135
|
|
label = "bit-set"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "bit-set"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x136
|
|
label = "bit-reset"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "bit-reset"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x137
|
|
label = "u0041F1C0"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041F1C0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x13a
|
|
label = "u0041F3A0"
|
|
argc = 6
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041F3A0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 6
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x13f
|
|
label = "check-bit"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "check-bit"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x140
|
|
label = "u0041F9C0"
|
|
argc = 4
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "coroutine-label-yield"
|
|
category = "control"
|
|
summary = "(out)(name_str)(sub_str)(in) — scene-coroutine LOOP ITERATOR / labeled yield. Handler copies name/sub strings + the int operand and calls the NATIVE video/transition service (*DAT_005c6018)(8, ctx[0x54fe8], &{name,sub,in}); writes the returned PC-like value to operand 1. In SC0000 label_462 'ループ開始' (@0x46d): `out=G[0x6be]=LABEL('J',G[0x6be])`; loop runs the intro-setup body (incl. call label_125bd = slot-table fill G[0x3239..0x324e]=4..11) and jmps back until out==G[0x6c3] (a per-scene exit-PC immediate) → mov aba5c 0 → content. The gate G[0xaba5c]==1 that opens this loop is NATIVE scene-entry state (no script sets it to 1). DAT_005c6018 is runtime-resolved (all xrefs READ) = SAME class as the DirectDraw workers we don't model. PORT = HOST-MODEL IMPLEMENTED: synthesize the ADV scene-entry gate, run the LABEL/J setup body once, then return the structurally discovered per-scene terminal; do not emulate the video service. See engine-re.md §Scene-coroutine framework."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = "Ghidra: handler 0x4299c0 (dispatch ctx[0x9b74c]=0x4299c0; created+typed EngineCtx*+annotated; Kelebek u0041F9C0 = VA-drift). Writes gfx cmd-type 9; op2→local_204, op3→local_104, op4→local_208; (*DAT_005c6018)(8, ctx[0x54fe8], &local_210) → FUN_00425fb0(1,ret). DAT_005c6018: 6 xrefs all READ, no static writer; FUN_00405740 (screen-fade) calls it w/ cmd 3, branches on ret 1/2 = transition progress = native video service."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "out: returned label/resume PC (SC0000 G[0x6be])"
|
|
observed_types = ["g-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = "label name string (e.g. \"LABEL\")"
|
|
observed_types = ["string"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = "sub-label string (e.g. \"J\")"
|
|
observed_types = ["string"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = "in: current label/resume PC fed back (SC0000 G[0x6be])"
|
|
observed_types = ["g-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x141
|
|
label = "u0041FAA0"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041FAA0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x142
|
|
label = "u0041FB10"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041FB10"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x143
|
|
label = "u00415FB0"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00415FB0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x144
|
|
label = "u004259D0"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u004259D0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-str"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-str"]
|
|
|
|
[[opcode]]
|
|
op = 0x149
|
|
label = "u0041FCE0"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041FCE0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x191
|
|
label = "u0041A4A0"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041A4A0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x192
|
|
label = "set-string"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "set-string"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-str", "l-str", "l-str-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["string", "g-int", "g-str", "l-str", "l-str-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x193
|
|
label = "concat"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "concat"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-str", "l-str"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["string", "g-str", "l-str", "l-str-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["string", "g-str", "l-str", "l-ptr", "l-str-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x194
|
|
label = "u00425480"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00425480"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-str", "l-str", "l-str-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["string", "l-str", "l-str-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x195
|
|
label = "u00425580"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00425580"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-str", "l-str", "l-str-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["string", "g-str"]
|
|
|
|
[[opcode]]
|
|
op = 0x196
|
|
label = "display-furigana"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "display-furigana"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["string"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["string"]
|
|
|
|
[[opcode]]
|
|
op = 0x197
|
|
label = "u0041B510"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041B510"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x198
|
|
label = "u0041B540"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041B540"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x199
|
|
label = "u00414D50"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00414D50"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x19a
|
|
label = "u00414E50"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00414E50"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x19b
|
|
label = "u00414E80"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00414E80"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x19c
|
|
label = "u00414EC0"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00414EC0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x19d
|
|
label = "u0041C680"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041C680"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x19e
|
|
label = "u0041C6E0"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041C6E0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1a0
|
|
label = "u0041C9B0"
|
|
argc = 9
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041C9B0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 6
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 7
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 8
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 9
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1a1
|
|
label = "u0041CB40"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041CB40"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1a2
|
|
label = "gfx-cmd-register"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "gfx-cmd-register"
|
|
category = "draw"
|
|
summary = "0x1a2 (value) — gfx cmd-type 3. Handler gfx_op_0x1a2_descriptor_register@0x42d360 builds a key from operand 1's lvalue descriptor and inserts its value into an open-addressing descriptor hash (vm_lvalue_descriptor_hash_insert@0x42cf70). This structure is separate from op 0x215's retained gfx-object map; op 0x215 does not query this hash. NOT save/scene."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra: handler 0x42d360 fetches operand 1's value and lvalue descriptor separately, formats the descriptor key, then calls FUN_0042cf70. By contrast op 0x215 passes ctx+0x46614 to gfx_object_query_source_slot@0x47f280, which searches the retained object map and returns obj+4."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "value"
|
|
observed_types = ["g-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x1a3
|
|
label = "string-lookup-set"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "string-lookup-set"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x1a4
|
|
label = "u0041B580"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041B580"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x1a5
|
|
label = "set-font"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "set-font"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["string"]
|
|
|
|
[[opcode]]
|
|
op = 0x1a6
|
|
label = "halve-strlen"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "halve-strlen"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-str", "l-str-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x1a7
|
|
label = "comment"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "comment"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["string", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x1a8
|
|
label = "dev_ukn"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "dev_ukn"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x1a9
|
|
label = "u00428090"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00428090"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-str", "l-str-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x1aa
|
|
label = "u00425920"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00425920"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-str", "l-str-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x1ab
|
|
label = "u0041CCA0"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041CCA0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1ac
|
|
label = "u0041CD80"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041CD80"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1ad
|
|
label = "u004154F0"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u004154F0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x1ae
|
|
label = "u0041CED0"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041CED0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x1af
|
|
label = "u004245C0"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u004245C0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1b0
|
|
label = "u0041A510"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041A510"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1b2
|
|
label = "u00425790"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00425790"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["string", "g-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1b3
|
|
label = "u004257D0"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u004257D0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x1b4
|
|
label = "u004237C0"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u004237C0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x1b5
|
|
label = "u0041B5F0"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041B5F0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1b6
|
|
label = "u00414F60"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00414F60"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1b7
|
|
label = "u0041B640"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041B640"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1b8
|
|
label = "u0041B670"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041B670"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1b9
|
|
label = "u0041B710"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041B710"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1ba
|
|
label = "u0041D850"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041D850"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x1bb
|
|
label = "u0041B7B0"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041B7B0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x1bc
|
|
label = "u00415670"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "block-mark"
|
|
category = "marker"
|
|
summary = "zero-arg; follows jcc/mov, precedes mov/ret — block boundary"
|
|
noop_headless = true
|
|
source = "inference"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x1bd
|
|
label = "u0041D910"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041D910"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1bf
|
|
label = "u004156C0"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "call-end"
|
|
category = "marker"
|
|
summary = "zero-arg; call->0x1bf->stmt-end — end-of-call-statement marker"
|
|
noop_headless = true
|
|
source = "inference"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x1c1
|
|
label = "u0041B820"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041B820"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1c7
|
|
label = "get-message-skip"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "get-message-skip"
|
|
category = "input"
|
|
summary = "(out) - write 1 iff ADV message-skip run-state bit 0x08000000 is set, otherwise 0."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra handler 0x4272b0 reads ctx+0xa0ce4 bit 0x08000000 and vm_operand_write(1, 1|0). SC0000 label_1235a ORs it with op 0x1cc."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1c8
|
|
label = "toString"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "toString"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-str"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1ca
|
|
label = "u0041B9B0"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041B9B0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "g-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1cb
|
|
label = "u00414FD0"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00414FD0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1cc
|
|
label = "get-adv-read-skip-state"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "get-adv-read-skip-state"
|
|
category = "control"
|
|
summary = "(out) - copy the current ADV read/click-skip service state from ctx+0x6dbd4. label_1235a ORs it with 0x1c7's Ctrl/message-skip bit: zero takes 0x21c's normal transition/yield path; nonzero resets the animation service and presents the completed endpoint through 0x20c."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra handler 0x427330 calls vm_operand_write(1, ctx+0x6dbd4). Producer recovered 2026-07-10: adv_update_read_text_skip_state@0x406cd0 and op 0x6e/0x71/0x72 maintain the field from message_ReadTextSkip plus current-PC read-history lookup; adv_interpreter_tick consumes it in click/read-skip control. It is not the 0x223 surface-transition progress flag."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1ce
|
|
label = "u0041B9F0"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041B9F0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x1cf
|
|
label = "u0041DA10"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041DA10"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "g-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1d0
|
|
label = "u0041BA80"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041BA80"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1d1
|
|
label = "u0041BAE0"
|
|
argc = 5
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041BAE0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x1d2
|
|
label = "u0041BB40"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "stmt-desc?"
|
|
category = "marker"
|
|
summary = "2 imm; immediately after stmt-begin 0x1f4 — statement descriptor?"
|
|
noop_headless = true
|
|
source = "harness"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x1d3
|
|
label = "u0041BB90"
|
|
argc = 5
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041BB90"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x1d4
|
|
label = "u0041BC00"
|
|
argc = 4
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0041BC00"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1d5
|
|
label = "u00415700"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "cond-block"
|
|
category = "marker"
|
|
summary = "zero-arg; ALWAYS follows jcc — marks conditional body entry"
|
|
noop_headless = true
|
|
source = "inference"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x1f4
|
|
label = "u004160D0"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "stmt-begin"
|
|
category = "marker"
|
|
summary = "zero-arg; opens scripts, pairs with stmt-end 0x1f5"
|
|
noop_headless = true
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x1f5
|
|
label = "u00416120"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "stmt-end"
|
|
category = "marker"
|
|
summary = "zero-arg; precedes exit/next-stmt, pairs with 0x1f4"
|
|
noop_headless = true
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x1f6
|
|
label = "u00416170"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00416170"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x1f7
|
|
label = "gfx-elem-erase"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "gfx-elem-erase"
|
|
category = "draw"
|
|
summary = "0x1f7 (handle)(count) — erase retained gfx objects. Handler 0x422270 calls gfx_object_erase_range@0x47d8b0 for [handle,handle+count) when count>1, else gfx_object_erase@0x47d850. This removes entries from the same object map queried by op 0x215, so erased objects stop compositing. SC0000 uses it before op 0x1fa releases the returned surface slot."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra handler 0x422270; gfx_object_erase_range@0x47d8b0 loops gfx_object_erase@0x47d850. Both operate on owner+0x408, the retained-object map also used by gfx_object_get_or_create/draw and gfx_object_query_source_slot."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1f8
|
|
label = "create-texture"
|
|
argc = 4
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "create-texture"
|
|
category = "draw"
|
|
summary = "Allocate/prepare a texture slot: (slot, width, height, flag). e.g. `create-texture 0xd 0x190 0x1e 0x0` = slot 13, 400x30."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = "SC0000 CG/UI-draw path disasm; slot/w/h roles read off the operands (400x30 text bars, etc.)."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "texture slot"
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = "width"
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = "height"
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = "flag"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x1f9
|
|
label = "set-texture"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "set-texture"
|
|
category = "draw"
|
|
summary = "Load asset #resId into texture slot: (resId, slot, flag=-1). resId resolves via the SYS4INI per-scene section manifest: files[section_base(scene)+resId] (same rule for play-bgm/play-voice). See docs/asset-resolution-re.md."
|
|
noop_headless = false
|
|
source = "frida"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "SC0000 Frida-confirmed 17/17 (0x25->EV052CA, 0x2e->EV052DB, 0x36->BG030A background); resolution rule validated on 586/595 captured loads. Traced in CG-load subroutine label_12649 as `set-texture G[0x62424] <slot> -1`."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "resId (section-manifest index into SYS4INI)"
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = "texture slot"
|
|
observed_types = ["imm", "g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = "flag (typically -1 / 0xffffffff)"
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1fa
|
|
label = "gfx-elem-release"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "gfx-elem-release"
|
|
category = "draw"
|
|
summary = "0x1fa (surface_slot) — release the surface at ctx+0x52bd4[slot] (virtual free, then null) and call FUN_00474e40(slot). It releases a surface slot, not a retained object handle. SC0000 feeds it the slot returned by op 0x215 after op 0x1f7 erases the associated object group."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra handler 0x4224a0 (dispatch ctx[0x26c93+0x1fa]); frees ctx+0x52bd4[operand1*4] via vtbl, then FUN_00474e40(operand1)."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "surface slot"
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x1fb
|
|
label = "draw-texture"
|
|
argc = 8
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "draw-texture"
|
|
category = "draw"
|
|
summary = "Blit a texture slot to screen. Observed 8 args: (handle, slot, srcx, srcy, w, h, dstx, dsty). e.g. `draw-texture 0xcf08 0x3 0 0 0x320 0x258 0 0` = full-screen (800x600) slot 3 at (0,0)."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = "SC0000 CG-load subroutine label_12649: `draw-texture (ptr) (slot) 0 0 (w) (h) (dstx) (dsty)`; full-screen slot-3 draws use 0x320x0x258 (800x600)."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "handle/source ref"
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = "texture slot"
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = "src x"
|
|
observed_types = ["imm", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = "src y"
|
|
observed_types = ["imm", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = "width"
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 6
|
|
role = "height"
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 7
|
|
role = "dst x"
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 8
|
|
role = "dst y"
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x1fd
|
|
label = "u00420620"
|
|
argc = 4
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "gfx-set-scale-current"
|
|
category = "draw"
|
|
summary = "(handle)(scale_x_percent)(scale_y_percent)(scale_z_percent) — immediately replace the retained object's current scale matrix at obj+0x6c. The handler divides each integer operand by 100.0 before calling matrix4_make_scale; this is distinct from 0x21e's delayed one-shot target scale."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra /v2: handler gfx_op_0x1fd_set_vec_scaled@0x422650 fetches operands 2..4, divides each by the 100.0 constant, and calls gfx_object_set_scale_current@0x47e6b0. The worker gets/creates the object, marks obj+0x68, and calls matrix4_make_scale on obj+0x6c. SC0000 sets AE001D handles to 210/210/100 and 240/240/100; without this setter their 800x800 alpha circles remain below the viewport. Both functions annotated and /v2 saved 2026-07-11."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "retained object handle"
|
|
observed_types = ["imm", "g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = "current X scale percent"
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = "current Y scale percent"
|
|
observed_types = ["imm", "g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = "current Z scale percent"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x1fe
|
|
label = "u004206C0"
|
|
argc = 5
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u004206C0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x1ff
|
|
label = "set-gfx-geom3-c"
|
|
argc = 4
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "set-current-translation"
|
|
category = "draw"
|
|
summary = "0x1ff (handle)(x)(y)(z) — immediately replace the retained object's current translation matrix at obj+0x16c. This is the direct-current companion to 0x220's delayed target at obj+0x1ac."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra /v2: handler gfx_op_0x1ff_set_geom3@0x4227b0 converts operands 2..4 to float and calls gfx_object_set_translation_current@0x47e800. The worker gets/creates the object, marks obj+0x168, and calls matrix4_make_translation on obj+0x16c. SC0000 uses (0,0,0) before animating BG001A. Annotated and saved 2026-07-11."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x202
|
|
label = "gfx-blit-color"
|
|
argc = 5
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "gfx-blit-color"
|
|
category = "draw"
|
|
summary = "0x202 (handle)(delay_ms)(duration_ms)(alpha)(color) — arm the one-shot packed-ARGB channel. Worker gfx_op_0x202_worker_set_color_anim @0x47ea00 resets shared start obj+0x34, writes delay +0x38, duration +0x4c, and target +0x64. gfx_object_apply_transform_channels @0x472f00 linearly interpolates each byte from current +0x60 on frame clock ctx+0xb550, commits the target, clears timing, writes target -1, and clears the one-shot active bit when all sibling channels finish. Negative alpha/RGB independently preserve current bytes. Implemented in GfxState with synchronized current/target timeline evidence; draw-string 0x204/0x7a remains separate."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra handler 0x4228d0 packs operands 4/5 and calls worker 0x47ea00(handle,delay,duration,packed). Consumer 0x472f00: shared start +0x34; color delay/duration +0x38/+0x4c; current/target +0x60/+0x64; frame clock ctx+0xb550; bytewise integer LERP; natural or ctx+0xb55c forced completion. /v2 annotated and saved 2026-07-10."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "retained object handle"
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = "delay in frame-clock milliseconds"
|
|
observed_types = ["imm", "g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = "duration in frame-clock milliseconds"
|
|
observed_types = ["imm", "g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = "target tint-strength/ARGB high byte; negative preserves current"
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = "target RGB; negative preserves current"
|
|
observed_types = ["imm", "g-int", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x203
|
|
label = "gfx-draw-color"
|
|
argc = 4
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "gfx-draw-color"
|
|
category = "draw"
|
|
summary = "0x203 (handle)(mode)(alpha)(color) — gfx cmd-type 9. Worker stores the D3D blend selector at obj+0x30 and STATIC packed color at obj+0x60. Negative alpha/RGB preserve current static bytes. Mode 0 is the opaque textured path: preserved 0xffffffff is identity (the alpha byte is not tint strength); mode 1 is SRCALPHA/INVSRCALPHA with ARGB alpha opacity and multiplicative RGB modulation; mode 2 is the 0x223 transition-source identity path. Surfaceless mode-0 fill consumption remains a distinct case."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra handler 0x4229a0; negative operands read current obj+0x60, then worker 0x47e9b0 stores op2 at obj+0x30 and ARGB at +0x60. gfx_object_composite call-site 0x47f78f passes +0x30/+0x60 directly to gfx_object_blit_d3d9; mode 1 sets D3DRS SRCALPHA/INVSRCALPHA and the packed color is the device draw modulation. Mode 2 transition setup and synchronized pixels prove 0xffffffff is identity, not solid white. SC0000 page 14 adds the mode-0 endpoint proof: after the EV052CA->EV052DA 0x223 crossfade, 0x203@0x12478 restores the base CG to mode 0 with preserved 0xffffffff; native keeps EV052DA visible while the port's tint-strength interpretation turns every texel white."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x204
|
|
label = "draw-string"
|
|
argc = 4
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "draw-string"
|
|
category = "adv"
|
|
summary = "(surface_slot)(x)(y)(string) - rasterize a CP932 string immediately into a numbered graphics surface using current font/color/effect state."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra /v2: op_0x204_handler@0x422a60 resolves operand 4 as a string, fetches surface/x/y, then calls draw_string_to_surface@0x450150 on text manager ctx+0x14940. The worker validates and locks gfx-manager surface table +0xa590[slot], chooses text_raster_string_uncached@0x459d90 or cached/effect path @0x45b600, rasterizes GDI GetGlyphOutlineA bitmaps through text_blit_glyph_bitmap@0x458c80 using font/color state +0x4d0/+0x458, then unlocks. SC0000 0x9b2 draws the speaker name into 400x30 surface 0xd at (1,1); following 0x1fb binds it to retained object 0xe678 at (74,444)."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "destination surface slot"
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = "x"
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = "y"
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = "CP932 string"
|
|
observed_types = ["string", "g-str", "l-str", "l-str-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x205
|
|
label = "u00420A60"
|
|
argc = 6
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00420A60"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 6
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x207
|
|
label = "u00420B00"
|
|
argc = 8
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00420B00"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "g-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 6
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 7
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 8
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x208
|
|
label = "get-texture-size"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "get-texture-size"
|
|
category = "draw"
|
|
summary = "0x208 (slot)(out_w)(out_h) — writes the loaded texture's width/height into two output globals; keystone for bytecode-computed sprite/bg geometry (SC0000 label_12649)"
|
|
noop_headless = false
|
|
source = "inference"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = "SC0000 label_12649: set-texture(resId,slot) then 0x208(slot)->w,h feeds w/2 horizontal-center + foot-anchor subtraction into draw-texture dst; stubbing yields 0x0 sizes / off-center draws"
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "slot"
|
|
observed_types = ["imm", "g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = "out_width"
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = "out_height"
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x20a
|
|
label = "u00420CE0"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00420CE0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x20b
|
|
label = "u00420D50"
|
|
argc = 7
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00420D50"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 6
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 7
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x20c
|
|
label = "present-frame"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "present-frame"
|
|
category = "draw"
|
|
summary = "Present the composited frame; label_1235a uses this on the read/message-skip branch to expose the completed foreground endpoint immediately."
|
|
details = "Native handler gfx_op_0x20c_present_frame -> gfx_render_frame @0x4820b0. This is an explicit retained-state publication boundary, not a continuously visible object-store mutation. The read/message-skip branch resets the animation service then presents; the port publishes and snaps pending 0x223 state here. Normal playback branches to 0x21c, which owns repeated render/wait/resume. Headless hosts remain non-blocking."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = [0x223, 0x1c7, 0x1cc]
|
|
evidence = "Ghidra: dispatch table FUN_00413860 param_1[0x26e9f]=gfx_op_0x20c_present_frame; 0x26e9f-0x26c93=0x20c. 2026-07-08."
|
|
|
|
[[opcode]]
|
|
op = 0x20d
|
|
label = "u00420E10"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00420E10"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = [0x20c, 0x1c7, 0x1cc]
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x20e
|
|
label = "u00416250"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00416250"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x20f
|
|
label = "u00420E40"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00420E40"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x212
|
|
label = "set-gfx-field64"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "set-gfx-field64"
|
|
category = "draw"
|
|
summary = "0x212 (obj_idx)(val) — gfx cmd-type 5. Handler gfx_op_0x212_set_field64 @0x4230c0: obj=[ctx+0x14d54 + obj_idx*4]; if obj: *(obj+0x64)=val. Sets one per-object field. See docs/engine-re.md gfx op-contract table."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra handler 0x4230c0 (dispatch ctx[0x26c93+0x212]); writes [obj+0x64]=operand2, obj from ctx+0x14d54[operand1*4]."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "obj_idx"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = "value"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x213
|
|
label = "set-gfx-xy"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "set-gfx-xy"
|
|
category = "draw"
|
|
summary = "0x213 (obj_idx)(x)(y) — gfx cmd-type 7. Handler gfx_op_0x213_set_field68_6c @0x423110: obj=[ctx+0x14d54 + obj_idx*4]; if obj: *(obj+0x68)=x; *(obj+0x6c)=y (an (x,y) pair). See docs/engine-re.md gfx op-contract table."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra handler 0x423110; writes obj+0x68/+0x6c from operands 2/3, obj from ctx+0x14d54[operand1*4]."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "obj_idx"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = "x"
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = "y"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x215
|
|
label = "query-gfx-object?"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "query-gfx-object?"
|
|
category = "draw"
|
|
summary = "0x215 (out_slot)(handle) — query the retained gfx-object map. Handler gfx_op_0x215_query_source_slot@0x42a0b0 calls gfx_object_query_source_slot@0x47f280 with owner ctx+0x46614. The worker searches owner+0x408, the same map populated by geometry/draw workers, and returns obj+4: the live source-surface slot written by draw-texture, or -1 if absent. gfx_object_init_default zeroes obj+4, so a geometry/animation-created but draw-unbound object returns slot 0, not -1. SC0000 uses a successful result for query-guarded teardown: op 0x1f7 erases the object group and op 0x1fa releases this slot. Matching the zero default prevents stale transforms from surviving into the EV050EA CG at SC0000 page 58."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra: handler 0x42a0b0 passes ECX=ctx+0x46614 to 0x47f280, which searches ECX+0x408 and returns object+4. gfx_object_bind_draw@0x47e870 writes the bound slot there; gfx_object_init_default@0x472810 explicitly writes zero to dword index 1. SC0000 page-58 trace: the old -1 default skipped cleanup of transform-created handle 0xcb2a, then EV050EA inherited translation (-100,0), rotation -90, and alpha 0; the native zero default makes the guard succeed and the reused object is identity/opaque."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "out_slot_status"
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = "handle_id"
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x216
|
|
label = "query-gfx-field?"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "query-gfx-field?"
|
|
category = "draw"
|
|
summary = "0x216 (out)(idx) — gfx cmd-type 5. Handler gfx_op_0x216_query_table46d14 @0x42a0f0: out = *(ctx+0x46d14 + idx*0x14). A per-object field query over a stride-0x14 table. See docs/engine-re.md gfx op-contract table."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra handler 0x42a0f0; reads ctx+0x46d14[operand2 * 0x14], writes operand1 via FUN_00425fb0(1,·)."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "out"
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = "idx"
|
|
observed_types = ["imm", "g-int", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x217
|
|
label = "set-gfx-geom3"
|
|
argc = 4
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "set-gfx-geom3"
|
|
category = "draw"
|
|
summary = "0x217 (handle)(a)(b)(c) — gfx cmd-type 9. Handler gfx_op_0x217_set_geom3 @0x4231b0: SETS a 3-vector (int→float a,b,c) on object `handle` via native worker FUN_0047e960. In SC0000 label_12649 it writes the anchor vector G[0x6249b/c/d] INTO the object; op 0x218 reads it back. See docs/engine-re.md gfx op-contract table."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra handler 0x4231b0 (dispatch ctx[0x26c93+0x217]); FUN_0047e960(op1,(float)op2,(float)op3,(float)op4). label_12649 sites e.g. 0x00c67 handle=G[0x62457], vec=G[0x6249b/c/d]."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "handle"
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = "a"
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = "b"
|
|
observed_types = ["imm", "g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = "c"
|
|
observed_types = ["imm", "g-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x218
|
|
label = "get-gfx-geom3?"
|
|
argc = 4
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "get-gfx-geom3?"
|
|
category = "draw"
|
|
summary = "0x218 (handle)(out_a)(out_b)(out_c) — gfx cmd-type 9. Handler gfx_op_0x218_query_geom3 @0x42a130: GETS a stored 3-vector from object `handle` (FUN_0047f360) into out_a/b/c. In label_12649 it reads the object's anchor vector back into G[0x6249b/c/d] — a stubbed DRIVER of the render drift (stale anchor → bad centering). See docs/engine-re.md gfx op-contract table."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra handler 0x42a130; FUN_0047f360(obj op1) + 3x FUN_00550850→FUN_00425fb0(2/3/4). label_12649 site 0x00c8f handle=G[0x62457] → G[0x6249b/c/d]."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["g-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["g-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x219
|
|
label = "set-gfx-geom3-b"
|
|
argc = 4
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "set-gfx-geom3-b"
|
|
category = "draw"
|
|
summary = "0x219 (handle)(a)(b)(c) — gfx cmd-type 9. Handler gfx_op_0x219_set_geom3 @0x423240: SETS a 3-vector (int→float) on object `handle` via native worker FUN_0047e910 (sibling of 0x217, a different per-object vector). See docs/engine-re.md gfx op-contract table."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra handler 0x423240 (was unanalyzed; function created this session; dispatch ctx[0x26c93+0x219]); FUN_0047e910(op1,(float)op2,(float)op3,(float)op4)."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["g-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["g-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x21a
|
|
label = "get-gfx-geom3-b?"
|
|
argc = 4
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "get-gfx-geom3-b?"
|
|
category = "draw"
|
|
summary = "0x21a (handle)(out_a)(out_b)(out_c) — gfx cmd-type 9. Handler gfx_op_0x21a_query_geom3 @0x42a1b0: GETS a stored 3-vector from object `handle` (FUN_0047f2e0) into out_a/b/c. In label_12649 it reads the object's position vector into G[0x62498/9/a] — a stubbed DRIVER of the render drift. See docs/engine-re.md gfx op-contract table."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra handler 0x42a1b0; FUN_0047f2e0(obj op1) + 3x→FUN_00425fb0(2/3/4). label_12649 site 0x00c86 handle=G[0x62457] → G[0x62498/9/a]."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x21b
|
|
label = "u004213E0"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "line-id?"
|
|
category = "marker"
|
|
summary = "1 imm; mov->0x21b->stmt-end; near save/load-messkip — likely line/stmt id, verify not msg-control"
|
|
noop_headless = true
|
|
source = "harness"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x21c
|
|
label = "mark-frame-yield"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "mark-frame-yield"
|
|
category = "control"
|
|
summary = "Set native run-state bit 0x400; in normal ADV playback this is the retained-presentation render/wait/resume boundary."
|
|
details = "SC0000 label_1235a reaches this when 0x1c7/0x1cc are zero. Native run-state bit 0x400 parks the interpreter while gfx_render_frame repeatedly samples finite one-shot object channels and queued surface commands; op 0x224 follows after dirty state clears. Native trace proves AE001D bind, mode-1 0x203, and 0x202 targets complete in one 5 ms batch with no render, then first compose here. The port publishes and waits for visible finite one-shot channels or 0x223 commands; click forcing remains limited to the latter."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = [0x223, 0x1c7, 0x1cc]
|
|
evidence = "Ghidra handler 0x417520 sets cmd-type 1 and ORs ctx+0xa0ce4 with 0x400. capture_presentation_trace.py: after 0x125a6 render, 0xcb8e/0xcb98 bind and 0xd5a/0xd63/0xd73/0xd8a mode+targets execute without render; repeated gfx_render_frame begins only at 0x21c. 2026-07-10."
|
|
|
|
[[opcode]]
|
|
op = 0x21d
|
|
label = "clone-gfx-object"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "clone-gfx-object"
|
|
category = "draw"
|
|
summary = "(source_handle)(destination_handle) - clone the complete retained gfx object record (0xb5 dwords / 0x2d4 bytes). SC0000 uses destination=source+1 as range A's old-frame snapshot immediately before 0x223 crossfades range B's updated source into target handle source+2."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = [0x223]
|
|
evidence = "Ghidra handler 0x423310 -> gfx_object_clone@0x47e4f0. Worker requires source in ctx+0x408 map, creates destination, copies exactly 0xb5 dwords from source object record, then marks ctx+0xb558 dirty. SC0000 site 0x128fc passes current handle and handle+1 before queueing 0x223 at 0x129e7."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x21e
|
|
label = "set-anim-transform-norm"
|
|
argc = 6
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "set-anim-transform-norm"
|
|
category = "draw"
|
|
summary = "(handle)(delay_ms)(duration_ms)(sx)(sy)(sz) — set the normalized SCALE-matrix channel (100=identity). Target obj+0xac is linearly sampled from current obj+0x6c by gfx_object_apply_transform_channels@0x472f00 on frame-time ctx+0xb550, after delay and for duration, then committed. Shares only start timestamp obj+0x34 with op 0x220; neither Z is opacity."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra 0x47eaa0 calls matrix builder 0x48af1d for target obj+0xac. Consumer 0x472f00 uses delay obj+0x3c, duration obj+0x50, current obj+0x6c, target obj+0xac, shared start obj+0x34, and frame-time ctx+0xb550."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 6
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x21f
|
|
label = "set-anim-rotation-axis-angle"
|
|
argc = 7
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "set-anim-rotation-axis-angle"
|
|
category = "draw"
|
|
summary = "(handle)(delay_ms)(duration_ms)(axis_x)(axis_y)(axis_z)(angle_deg) — set the delayed one-shot axis-angle rotation channel. Handler converts axis/angle integers to floats; worker stores target axis obj+0x1f8 and angle obj+0x208 and builds target matrix obj+0x12c. gfx_object_apply_transform_channels samples current axis/angle linearly on shared start obj+0x34 and composes T(-anchor)*scale*rotation*translation*T(anchor)."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra handler 0x423410 -> gfx_object_set_rotation_channel@0x47eb70; consumer gfx_object_apply_transform_channels@0x472f00 uses delay +0x40, duration +0x54, current axis +0x1ec/angle +0x204, target axis +0x1f8/angle +0x208, current matrix +0xec and target +0x12c. Native SC0000 handle 0xcb8e sample at 11/390 of axis (0,0,1), 30deg matches matrix [0.9055,0.0134;-0.0134,0.9055] and translation (74.1449,47.3127)."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "object handle"
|
|
observed_types = ["imm", "g-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = "delay milliseconds"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = "duration milliseconds"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = "rotation axis X"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = "rotation axis Y"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 6
|
|
role = "rotation axis Z"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 7
|
|
role = "target angle degrees"
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x220
|
|
label = "set-anim-transform-abs"
|
|
argc = 6
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "set-anim-transform-abs"
|
|
category = "draw"
|
|
summary = "(handle)(delay_ms)(duration_ms)(tx)(ty)(tz) — set the absolute TRANSLATION-matrix channel. Target obj+0x1ac is linearly sampled from current obj+0x16c by gfx_object_apply_transform_channels@0x472f00 on frame-time ctx+0xb550, after delay and for duration, then committed. Independent of op 0x21e scale; neither Z is opacity."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra 0x47ecc0 calls matrix builder 0x48afb1 for target obj+0x1ac. Consumer 0x472f00 uses delay obj+0x44, duration obj+0x58, current obj+0x16c, target obj+0x1ac, shared start obj+0x34, and frame-time ctx+0xb550."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 6
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x222
|
|
label = "u004216C0"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u004216C0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x223
|
|
label = "queue-surface-alpha-transition"
|
|
argc = 8
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "queue-surface-alpha-transition"
|
|
category = "draw"
|
|
summary = "(command_key)(target_slot)(range_a_start)(range_a_count)(range_b_start)(range_b_count)(delay_ms)(duration_ms) — queue a type-0 timed alpha transition command in the separate ctx+0x414 command map. This is render-target/surface presentation state, not an object affine matrix. The render frame composites the two handle ranges into target_slot and ramps alpha 0->1 after delay over duration."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = [0x20c, 0x21c, 0x1c7, 0x1cc]
|
|
evidence = "Ghidra handler 0x423620 -> gfx_queue_surface_alpha_transition@0x47f440. Record fields: type +0=0, start +4=0, delay +8=arg7, duration +0xc=arg8, slot +0x10=arg2, range A +0x14/+0x1c=args3/4, range B +0x18/+0x20=args5/6. gfx_render_frame@0x47fbc0 initializes start from ctx+0xb550 and consumes type 0 as an alpha ramp. SC0000 executes one shared-helper site at 0x129e7."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "command record key"
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = "target surface slot"
|
|
observed_types = ["imm", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = "first object range start handle"
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = "first object range count"
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = "second object range start handle"
|
|
observed_types = ["imm", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 6
|
|
role = "second object range count"
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 7
|
|
role = "delay milliseconds"
|
|
observed_types = ["imm", "g-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 8
|
|
role = "duration milliseconds"
|
|
observed_types = ["imm", "g-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x224
|
|
label = "clear-gfx-command-queue"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "clear-gfx-command-queue"
|
|
category = "draw"
|
|
summary = "Clear the native gfx command queue rooted at ctx+0x418. Host-implicit because the port composites retained state directly."
|
|
noop_headless = true
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra handler 0x417550 -> gfx_command_queue_clear 0x47cb10, which destroys queued nodes and restores the sentinel links/count."
|
|
|
|
[[opcode]]
|
|
op = 0x228
|
|
label = "u00421940"
|
|
argc = 5
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00421940"
|
|
category = "draw"
|
|
summary = "0x228 query translation target (succ)(handle)(outX)(outY)(outZ): clone the retained object, decompose its target translation matrix at obj+0x17c, and return matrix translation obj+0x1ac/+0x1b0/+0x1b4. Returns succ=0 when found; when absent, writes succ=1 and leaves outputs untouched. The C# VM queries TranslationTarget independently of V24. See docs/engine-re.md §SC0000 anim cluster."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra /v2 handler gfx_op_0x228_query_position@0x42a3a0 calls gfx_object_query_translation_target@0x47cdd0. The worker copies the complete 0xb5-dword object record, passes copied obj+0x17c to matrix4_decompose_affine@0x48d7c8, and returns its translation outputs; the decomposition reads matrix elements +0x30/+0x34/+0x38, corresponding to obj+0x1ac/+0x1b0/+0x1b4. SC0000 AE001H queries this before each 0x220 leg. C# regression covers targets (40,-20), (50,-80), (130,-100), plus the missing-object output-preservation path."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x229
|
|
label = "u004219E0"
|
|
argc = 5
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u004219E0"
|
|
category = "draw"
|
|
summary = "0x229 set-position2 (handle)(op2)(x)(y)(z): set object position/geometry directly (FUN_00472bb0/be0). C# VM: sets V24. See docs/engine-re.md §SC0000 anim cluster."
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "g-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm", "g-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x22a
|
|
label = "u00421A90"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00421A90"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x22c
|
|
label = "u00421BD0"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00421BD0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x22d
|
|
label = "u00421C60"
|
|
argc = 5
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00421C60"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["g-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["g-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x22f
|
|
label = "u00421DD0"
|
|
argc = 5
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00421DD0"
|
|
category = "draw"
|
|
summary = "0x22f set-position (handle)(op2)(x)(y)(z): set the object base position (direct transform, not ping-pong). Worker gfx_worker_set_translation @0x472e90. C# VM: sets V24. See docs/engine-re.md §SC0000 anim cluster."
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x230
|
|
label = "u00421E70"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00421E70"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x231
|
|
label = "u00421EA0"
|
|
argc = 4
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00421EA0"
|
|
category = "draw"
|
|
summary = "(handle)(frame_period_ms)(frame_count)(column_count) — loop row-major through the spritesheet. Every frame preserves draw-texture's source-rectangle width/height; frame=floor(elapsed/frame_period)%frame_count, src offset=(frame%columns*width, frame/columns*height). Worker gfx_worker_anim_srcrect @0x47eec0; consumer gfx_object_anim_interpolate @0x473ed0."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Native /v2 decompile: worker stores period at obj+0x230, frame_count at +0x238, columns at +0x23c. Interpolator computes ((now-start)/period)%frame_count, then offsets both source-rect X bounds by rect_width*(frame%columns) and Y bounds by rect_height*(frame/columns). SC0000 uses (100,8,4) with AE001H's eight 200x200 cells in a 4x2 800x400 sheet."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x232
|
|
label = "u00421EF0"
|
|
argc = 4
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00421EF0"
|
|
category = "draw"
|
|
summary = "0x232 anim-color (handle)(period)(alpha)(color): ping-pong the temporary packed ARGB passed to the normal object blit. Handler resolves negative alpha/RGB from static color obj+0x60 and clamps alpha above 255. Blend selector obj+0x30 is unchanged: mode 0 keeps default opaque blending (animated alpha is inert; RGB is vertex modulation), while mode 1 consumes ARGB alpha as opacity. Fresh static color is 0xffffffff. The C# VM resolves sentinels and consumes sampled ARGB through the unchanged mode-specific path. See docs/engine-re.md §SC0000 anim cluster."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra /v2: gfx_op_0x232_anim_color@0x423c30 resolves sentinels then calls gfx_worker_anim_color@0x47ef50; gfx_object_anim_interpolate@0x473ed0 samples static obj+0x60 toward target obj+0x240 into a temporary packed color; gfx_object_composite@0x47f650 passes that color plus unchanged selector obj+0x30 to gfx_object_blit_d3d9@0x4774c0. Blit mode 0 enables no alpha blend and passes RGB as modulation; mode 1 enables SRCALPHA/INVSRCALPHA. gfx_object_init_default@0x472810 initializes obj+0x60=0xffffffff. SC0000 0x1a0e (handle,1200,224,-1) is therefore 0xffffffff<->0xe0ffffff with inert alpha and identity RGB: no visible pulse. C# regressions cover exact AE001H visual invariance, negative-RGB preservation, mode-0 RGB modulation, and mode-1 alpha opacity."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x233
|
|
label = "u00421FB0"
|
|
argc = 5
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00421FB0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x234
|
|
label = "anim-start"
|
|
argc = 5
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "anim-start"
|
|
category = "draw"
|
|
summary = "(handle)(period_ms)(axis_x)(axis_y)(axis_z) — configure cyclic rotation. Worker stores period obj+0x228, start obj+0x214=0, and float axis obj+0x244; each frame uses integer degrees floor(((now-start)%period)*360/period). gfx_object_composite right-multiplies this separately anchored transform after the one-shot scale/rotation/translation product, so cyclic rotation also rotates the translation vector."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra handler 0x423da0 converts axis ints to floats -> worker 0x47f060. gfx_object_anim_interpolate@0x473ed0 consumes obj+0x228/+0x214/+0x244 on ctx+0xb550 and matrix4_make_axis_angle@0x48b215. gfx_object_composite@0x47f650 calls one-shot transform first, cyclic animation second."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["g-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x236
|
|
label = "play-movie-to-surface"
|
|
argc = 4
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "play-movie-to-surface"
|
|
category = "draw"
|
|
summary = "(resource_id)(surface_slot)(movie_flags)(sync_mask) - synchronously resolve/open an archive movie and construct its DirectShow graph, then start asynchronous frame delivery into the retained destination surface. The opcode itself is non-blocking: the VM advances to the next instruction. SC0000's native site evaluates (0x33, 0, 2, 0) at 0x13c8 and resumes at bytecode 0x13d1; its later 0x21c service boundary yields until movie EOF before cleanup."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Native handler 0x423ee0 and helpers 0x463c50/0x463aa0/0x463e20/0x4625e0; SC0000 native operand capture; exact 0x13c8->0x13d1 trace; archive-only changing-frame decoder and Godot lifecycle tests."
|
|
details = "The handler requires an existing destination texture, allocates/reuses a 0x478-byte movie-to-texture object for the surface, opens operand 1 through the native indexed-asset reader, builds FilterGraph/IGraphBuilder/IMediaControl/IMediaPosition/IMediaEvent/IBasicAudio, and presents bottom-up RGB samples through the movie texture renderer. Operand 3 selects movie/sound routing policy: bits 0x10000/0x20000/0x40000/0x80000 force sound route 0/1/2/3, otherwise set:DependMovieSound is used; SC0000's low value 2 is retained as native movie mode state. Operand 4 is stored as the movie sync/device mask at object+0x42c; SC0000 passes 0. Static layer preparation after 0x236 does not terminate the retained movie; 0x21c services it through EOF and subsequent surface cleanup stops/detaches it."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "resource_id"
|
|
observed_types = ["imm", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = "surface_slot"
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = "movie_flags"
|
|
observed_types = ["imm", "g-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = "sync_mask"
|
|
observed_types = ["imm", "l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x238
|
|
label = "set-anim-clock"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "set-anim-clock"
|
|
category = "draw"
|
|
summary = "(duration) — set the GLOBAL animation clock: native ctx+0x51b78=0 (elapsed), +0x51b7c=duration. cmd-type 3. NON-BLOCKING: only configures; the render loop advances it and interpolates all animating objects. SC0000 opening @0x123bd/@0x13858. Handler 0x4240e0; Kelebek VA 0x422390 is drift."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "g-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x239
|
|
label = "u004223C0"
|
|
argc = 6
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u004223C0"
|
|
category = "draw"
|
|
summary = "(handle)(delay_ms)(duration_ms)(frame_count)(column_count)(target_frame) — one-shot row-major source-rectangle cell channel. Worker gfx_worker_set_srcrect_cell @0x47ed90 stores timing at obj+0x48/+0x5c, layout at +0x238/+0x23c, and target at +0x234. C# currently retains the endpoint cell immediately."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Native /v2 worker and gfx_object_apply_transform_channels decompile. The consumer advances target_frame cells over duration after delay, preserves the existing source-rect dimensions, and commits the endpoint."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["imm", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 6
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x23a
|
|
label = "u00422420"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00422420"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x23b
|
|
label = "u00422460"
|
|
argc = 7
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00422460"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 6
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 7
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x23c
|
|
label = "u004162B0"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u004162B0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x23d
|
|
label = "u004162F0"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u004162F0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode]]
|
|
op = 0x23f
|
|
label = "u00422930"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00422930"
|
|
category = "draw"
|
|
summary = "0x23f query-object (out)(handle): return object status (FUN_0042a520; -1 if none). C# VM: 0 if the object exists else -1. See docs/engine-re.md §SC0000 anim cluster."
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x241
|
|
label = "u00422B80"
|
|
argc = 5
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00422B80"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x242
|
|
label = "set-gfx-field2d0"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "set-gfx-field2d0"
|
|
category = "draw"
|
|
summary = "0x242 (handle)(value) — command type 5. Get-or-create the retained gfx object and write value to obj+0x2d0. SC0000's common CG loader passes zero after draw binding. This field does not reset transform or color channels; its downstream purpose remains unknown."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra /v2: op_0x242_set_object_field2d0@0x4249d0 fetches operands 2 and 1 and calls gfx_object_set_field2d0@0x47f1a0; the worker calls gfx_object_get_or_create then stores operand 2 at returned object+0x2d0."
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = "handle_id"
|
|
observed_types = ["l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = "field2d0_value"
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x243
|
|
label = "reset-anim-clock"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "reset-anim-clock"
|
|
category = "draw"
|
|
summary = "Reset the native global animation-service elapsed and duration fields to zero when service flag bit 1 is clear."
|
|
noop_headless = false
|
|
source = "investigation"
|
|
confidence = "high"
|
|
depends_on = []
|
|
evidence = "Ghidra handler 0x4182d0: if !(ctx+0x51b80 & 2), set ctx+0x51b70=1 and zero ctx+0x51b78/+0x51b7c. Normal SC0000 label_1235a calls it before present-frame."
|
|
|
|
[[opcode]]
|
|
op = 0x248
|
|
label = "u00422E80"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00422E80"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x249
|
|
label = "u00422EB0"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00422EB0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "l-int", "l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x24d
|
|
label = "u00422E90"
|
|
argc = 12
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00422E90"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 5
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 6
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 7
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 8
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 9
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 10
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 11
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 12
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x24e
|
|
label = "u00422EA0"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00422EA0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x258
|
|
label = "u00422FE0"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "decl?"
|
|
category = "marker"
|
|
summary = "2 imm; runs in a chain right after script-entry 0x259, enumerating ids — prologue declaration/registration?"
|
|
noop_headless = true
|
|
source = "harness"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x259
|
|
label = "u00416410"
|
|
argc = 0
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "script-entry"
|
|
category = "marker"
|
|
summary = "zero-arg; the first instruction of a script (offset 0), opens the decl chain that 0x258 continues — script/prologue entry marker, structural"
|
|
noop_headless = true
|
|
source = "harness"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = "SC0000 offset 0x0 = op 0x259 (argc 0); 0x258's summary names it 'script-entry 0x259'; VM treats it as no-op (default stub) across all 279 CLEAN A0 scenes"
|
|
|
|
[[opcode]]
|
|
op = 0x2bd
|
|
label = "u00423100"
|
|
argc = 1
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00423100"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode]]
|
|
op = 0x2bf
|
|
label = "u00423180"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u00423180"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["imm", "g-int", "l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["imm", "l-int"]
|
|
|
|
[[opcode]]
|
|
op = 0x2c0
|
|
label = "u004231C0"
|
|
argc = 3
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u004231C0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["imm"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["l-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x2c5
|
|
label = "strlen"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "strlen"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "med"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["g-str", "l-str", "l-str-ptr"]
|
|
|
|
[[opcode]]
|
|
op = 0x2c6
|
|
label = "u0042B5E0"
|
|
argc = 2
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0042B5E0"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-str"]
|
|
|
|
[[opcode]]
|
|
op = 0x2c8
|
|
label = "u0042B610"
|
|
argc = 4
|
|
abi_source = "kelebek+decode-validated"
|
|
|
|
[opcode.semantics]
|
|
name = "u0042B610"
|
|
category = "unknown"
|
|
summary = ""
|
|
noop_headless = false
|
|
source = "kelebek"
|
|
confidence = "low"
|
|
depends_on = []
|
|
evidence = ""
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 1
|
|
role = ""
|
|
observed_types = ["l-str-ptr"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 2
|
|
role = ""
|
|
observed_types = ["l-str"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 3
|
|
role = ""
|
|
observed_types = ["l-int"]
|
|
|
|
[[opcode.semantics.args]]
|
|
i = 4
|
|
role = ""
|
|
observed_types = ["imm"]
|