-
Notifications
You must be signed in to change notification settings - Fork 3
Format: Mjo script
Robert Jordan edited this page May 20, 2021
·
8 revisions
Compiled Majiro scenario scripts (and other UI scripts like the console) use the .mjo extension. The extension most often seen for text source scripts is .mjs and .txt.
| Type | Value | Description |
|---|---|---|
char[16] |
"MajiroObjV1.000" "MajiroObjX1.000" |
File SignatureV = decryptedX = encrypted |
uint32 |
MainOffset | Bytecode offset to $main function |
uint32 |
LineCount1 | Number of lines in the script (equal to value of last line instruction) |
uint32 |
FunctionCount | Number of functions in following table |
| Function[Count] | Functions | Function name hashes and their bytecode offsets |
uint32 |
BytecodeSize | Size of following bytecode data. |
| byte[Size] | Bytecode | Bytecode instructions (encryption starts here) |
[1] : LineCount is only non-zero when the #use_readflg on preprocessor is added to the script before compilation. Essentially only seen in story scripts.
| Type | Value | Description |
|---|---|---|
uint32 |
Hash | Hash of original function name |
uint32 |
Offset | Bytecode offset to function start |
See here for information on bytecode encryption.
The bytecode is a continuous set of instructions, each with variable length depending on the opcode.
| Type | Value | Description |
|---|---|---|
uint16 |
Opcode | Opcode ID that determines how the instruction is read and behaves |
| ... | Operands | All remaining data depends on the opcode. An instruction can have 0 bytes of operands |
WIP
| Operand | Data | Description |
|---|---|---|
| Integer | int32 |
|
| JumpOffset | int32 |
|
| Hash | uint32 |
|
| Placeholder | uint32 |
Placeholder for call address after first being run. Must be 0
|
| Float | float32 |
|
| VarOffset | int16 |
|
| VarFlags | uint16 |
(bitmask) |
| ArgCount | uint16 |
Number of values on stack consumed by function call (first in, last out) |
| LineNumber | uint16 |
Line number from source script (1-indexed) |
| String |
uint16 (N), char[N]
|
N includes the string null terminator. Majiro often treats N==0' as null` for this reason.But there's no evidence of this being supported in scripts. |
| TypeList |
uint16 (N), byte[N]
|
|
| CaseList |
uint16 (N), int32[N]
|
List of switch case offsets, each absolute offset is calculated relative to the end of the respective offset element. i.e. case\[n\] += OperandOffset + 2 + (n+1) * 4
|
| Opcode | Operands |
|---|---|
| ldc.i | Integer |
| ldc.r | Float |
|
ldstr ctrl text |
String |
|
st. stp. stelem. stelemp. ld ldelem |
VarFlags, Hash, VarOffset |
|
call callp |
Hash, Placeholder, ArgCount |
|
syscall syscallp |
Hash, ArgCount |
| line | LineNumber |
|
argcheck alloca |
TypeList |
| switch | CaseOffsets |
|
br brfalse brtrue br.case bne.case blt.case ble.case bgt.case bge.case bsel.1 bsel.2 bsel.3 bsel.4 bsel.5 bsel.x |
JumpOffset |
|
add. sub. mul. div. rem shl shr ceq. cne. clt. cle. cgt. cge. and andl or orl xor neg. not notl nop.191 nop.1a8 nop.1a9 conv. ret pop proc bsel.clr bsel.jmp.4 |
(none) |