User Tools

Site Tools


mission_impossible:sool_engine

SOOL Engine

SOOL (Scenaric Object Oriented Language) is a proprietary scripting language and engine used by Mission Impossible.


SOOL File structure

File header

OffsetTypeNameDescription
0x00charsignature[4] “SOOL”
0x04u32 fileSize Size of the sool file.
0x08u16 numSections Number of interactor sections.
0x0Au8 padding[2] Alignment padding.
0x0Cu32 sectionOffsets[]Array of interactor section offsets. The length of this array is defined by the numSections field.
….u32 unknownData[] Unknown data. Always the same size as sectionOffsets.

Interactor sections

OffsetTypeNameDescription
0x00u16 offsVars Offset of the interactor's variables.
0x02u16 offsVarsEnd End offset of the interactor's variables.
0x04u16 offsElements Offset of the interactor's elements. 0xFFFF if numElements is zero.
0x06u16 numElements Number of elements.
0x08u16 unk08 Unknown - always 0xFFFF?
0x0Au16 specialMethodIdxAn index of methodOffsets. Unknown purpose.
0x0Cu16 offsMethodsEnd End offset of the method code.
0x0Eu16 numMethods Number of methods.
0x10u16 methodOffsets[] Array of method offsets. The length of this array is defined by the numMethods field.
….u16 variables[] Variable definitions. The position and length of this array are defined by the offsVars and offsVarsEnd fields.
….u8 methodCode[] Method bytecode. See commands below.
….u8 garbage[] If offsMethodsEnd is uneven, there will be one padding byte of an arbitrary value here for alignment.
….elemelements[] Element lookup table. Each entry contains two u16 fields for the key and value.

Commands

00: exit

00

ASM Summary: Sets flag 1 and does not increment the command pointer.


01: unk_ret0

01

Unknown purpose. ASM Summary: Returns 0 in the native opcode processing function and does not increment command pointer.


02: return

02

Return from method call: Pop offset and context ID from the stack, set the current execution context to the context specified by returnCtxId and jump to returnOffs.

This command is at the end of every method that would be invoked via a call_method or call_ctx_method command.

Stack: […] [returnCtxId] [returnOffs] → […]


03: branch_imm_cond

03 [XX XX]

XXXX=branchOffs

Pop value from the stack. If value is non-zero, branch to immediate offset.

Stack: […] [value] → […]


04: branch_imm

04 [XX XX]

XXXX=branchOffs

Branch to immediate offset.


05: load_imm

05 [XX XX]

XXXX=value

Push immediate value to the stack.

Stack: […] → […] [value]


06: load_imm__06

06 [XX XX]

XXXX=value

Push immediate value to the stack.

Stack: […] → […] [value]


07: load_imm_var

07 [XX XX]

XXXX=varOffset

Push variable from immediate offset to the stack.

Stack: […] → […] [varValue]


08: load_imm_ctx_var

08 [XX XX] [YY YY]

XXXX=ctxId, YYYY=varOffset

Push variable from immediate offset in context to the stack.

Stack: […] → […] [varValue]


09: load_imm__09

09 [XX XX]

XXXX=value

Push immediate value to the stack.

Stack: […] → […] [immValue]


0A: load_imm2

0A [XX XX] [YY YY]

XXXX=immValue1, YYYY=immValue2

Push two immediate values to the stack.

Stack: […] → […] [immValue1] [immValue2]


0B: load_ctx_elem

0B

Pop element key and context id from the stack, push context's element value to the stack.

Stack: […] [ctxId] [elemKey] → […] [elemValue]


0C: load_ctx_elem_keep_ctx

0C

Pop element key from the stack, load context id from top of stack (do not pop context id). Push context's element value to the stack.

Stack: […] [ctxId] [elemKey] → […] [ctxId] [elemValue]


0D: load_ctx_elem_var

0D

Pop element key and context id from the stack. Using the element's value as a variable offset, push context's variable to the stack.

Stack: […] [ctxId] [elemKey] → […] [varValue]


0E: unk0E

0E [XXXX] [YYYY]

Branch to YYYY if (m_UnkA4 == XXXX), else push XXXX to the stack. Stack (if branch is not taken): […] → […] [XXXX]


0F: unk0F

0F

ASM Summary: if (v2 == 0) call this→func_8006261C(v1), else do nothing.

Stack: […] [v1] [v2] → […]


10: set_flag_2

10

Unknown purpose. Set flag 2.


11: clear_flag_2

11

Unknown purpose. Clear flag 2.


12: unk12

12

Stack: […] [value] → [result]

ASM Summary: Pop value from the stack. If (value == m_ExecCtx→GetA4()), push 1, else push 0.


13: unk13

13

Stack: […] [value] [ctxId] → [result]

ASM Summary: Pop value from the stack. If (value == ctx→GetA4()), push 1, else push 0.


14: leqz

14

Pop value from the stack. If (value ⇐ 0), push 1, else push 0.

Stack: […] [value] → [value ⇐ 0]


15: cmp_eq

15

Pop 2 values from the stack, compare (val1 == val2), push 1 if true, 0 if false.

Stack: […] [value2] [value1] → […] [value1 == value2]


16: cmp_neq

16

Pop 2 values from the stack, compare (val1 != val2), push 1 if true, 0 if false.

Stack: […] [value2] [value1] → […] [value1 != value2]


17: lgc_and

17

Logical and (&&). Pop 2 values from the stack, if both values are non-zero, push 1, else push 0.

Stack: […] [value2] [value1] → […] [value1 != 0 && value2 != 0]


18: lgc_or

18

Logical or (||). Pop 2 values from the stack, if either value is non-zero, push 1, else push 0.

Stack: […] [value2] [value1] → […] [value1 != 0 || value2 != 0]


19: sub

19

Pop two values from the stack, subtract second value from the first, push result to the stack.

Stack: […] [value2] [value1] → […] [value1 - value2]


1A: add

1A

Pop two values from the stack, sum them, push result to the stack.

Stack: […] [value2] [value1] → […] [value1 + value2]


1B: mod

1B

Pop two values from the stack, mod divide second value by the first, push result to the stack.

Stack: […] [value2] [value1] → […] [value2 % value1]


1C: mul

1C

Pop two values from the stack, multiply them, push result to the stack.

Stack: […] [value2] [value1] → […] [value2 * value1]


1D: div

1D

Pop two values from the stack, divide second value by the first, push result to the stack.

Stack: […] [value2] [value1] → […] [value2 / value1]


1E: cmp_lt

1E

Pop two values from the stack, compare (val1 < val2), push 1 to the stack if true, 0 if false.

Stack: […] [value2] [value1] → […] [value1 < value2]


1F: cmp_gt

1F

Pop two values from the stack, compare (val1 > val2), push 1 to the stack if true, 0 if false.

Stack: […] [value2] [value1] → […] [value1 < value2]


20: cmp_lte

20

Pop two values from the stack, compare (val1 ⇐ val2), push 1 to the stack if true, 0 if false.

Stack: […] [value2] [value1] → […] [value1 ⇐ value2]


21: cmp_gte

21

Pop two values from the stack, compare (val1 >= val2), push 1 to the stack if true, 0 if false.

Stack: […] [value2] [value1] → […] [value1 >= value2]


22: inv

22

Pop value from the stack, invert value, push result to the stack.

Stack: […] [value] → […] [-value]


23: and

23

Pop two values from the stack, bitwise AND the first value with the second, push result to the stack.

Stack: […] [value2] [value1] → […] [value1 & value2]


24: or

24

Pop two values from the stack, bitwise OR them, push result to the stack.

Stack: […] [value2] [value1] → […] [value1 | value2]


25: lsh

25

Pop two values from the stack, bitwise shift first value left by second value, push result to the stack.

Stack: […] [value2] [value1] → […] [value1 « value2]


26: rsh

26

Pop two values from the stack, bitwise shift first value right by second value, push result to the stack.

Stack: […] [value2] [value1] → […] [value1 » value2]


28: store_var

28

Pop variable offset from the stack, copy value from top of stack to variable (do not pop value).

Stack: […] [value] [varOffset] → […] [value]


29: store_ctx_var

29

Pop variable offset and context id from the stack, copy value from top of stack to context's variable (do not pop value).

Stack: […] [value] [ctxId] [varOffset] → […] [value]


2A: inc_var

2A

Pop variable offset from the stack. Increment variable by 1.

Stack: […] [varOffset] → […]


2B: inc_ctx_var

2B

Pop variable offset and context id from the stack. Increment context's variable by 1.

Stack: […] [ctxId] [varOffset] → […]


2C: dec_var

2C

Pop variable offset from the stack. Decrement variable by 1.

Stack: […] [varOffset] → […]


2D: dec_ctx_var

2D

Pop variable offset and context id from the stack. Decrement context's variable by 1.

Stack: […] [ctxId] [varOffset] → […]


2E: copy_ctx_var

2E

Pop two variable offsets from the stack. Copy value from the first popped variable to the second.

Stack: […] [varOffsetDst] [varOffsetSrc] → […]


2F: add_ctx_var

2F

Pop variable offset, context id, and value from the stack stack. Add value to context's variable.

Stack: […] [value] [ctxId] [varOffset] → […]


30: sub_var

30

Pop variable offset and value from the stack. Subtract value from variable.

Stack: […] [value] [varOffset] → […]


31: sub_ctx_var

31

Pop variable offset, context id, and value from the stack. Subtract value from context's variable.

Stack: […] [value] [ctxId] [varOffset] → […]


32: clear_flag_3

32

Unknown purpose. Clears internal flag 3.


34: set_flag_0_clear_flag_3

34

Unknown purpose. Sets internal flag 1, clears flag 3.


35: clear_ctx_flags_0_1

35

Unknown purpose. Pop context id from the stack and clear context's 0 and 1 flags.

Stack: […] [ctxId] → […]


36: set_ctx_flag_1

36

Unknown purpose. Pop context id from the stack and set context's 1 flag.

Stack: […] [ctxId] → […]


37: clear_flag_3_unk_cond

37

Unknown purpose.

Stack: […] [value] → […]

ASM Summary: If m_ExecCtx→unkA8 is nonzero after calling m_ExecCtx→func_8006261C(value) clear 3 flag.


38: clear_ctx_flag_3_unk_cond

38

Unknown purpose.

Stack: […] [value] [ctxId] → […]

ASM Summary: If ctx→unkA8 is nonzero after calling ctx→func_8006261C(value) clear context's 3 flag.


39: call_method

39

Call local context's method: Pop method id from the stack. Push the current context ID and return offset to the stack and jump to the method's offset.

The called method will pop returnCtxId and returnOffs from the stack before returning; they are not visible to the caller.

Stack: […] [methodId] → […] [returnCtxId] [returnOffs] → […]


3A: call_ctx_method

3A

Call another context's method: Pop method ID and context ID from the stack. Push current execution context ID and return offset to the stack. Set the current execution context to the context specified by ctxId and jump to the method's offset.

The called method will pop returnCtxId and returnOffs from the stack before returning; they are not visible to the caller.

Stack: […] [methodId] [ctxId] → […] [returnCtxId] [returnOffs] → […]


3B: pop_nop

3B

Pop value from the stack and do nothing with it.


3C...4A: call_vnative

3C4A

Call a native void function with n arguments on the stack where n = (command byte - 0x3C). The function to call is specified by the function ID at the top of the stack. Function IDs 0x00 through 0x98 are valid.

Stack: […] [argument(s)] [functionId] → […]


50...5E: call_native

505E

Call a native function with n arguments on the stack where n = (command byte - 0x50), push the return value to the stack. The function to call is specified by a function ID at the top of the stack. Function IDs 0x00 through 0x47 are valid.

Stack: […] [argument(s)] [functionId] → […] [result]


Invalid opcodes

27, 33, 4B, 4C, 4D, 4E, 4F, 5F…FF.

mission_impossible/sool_engine.txt · Last modified: 2019/07/01 18:25 by shygoo