Format: Mjo script - AtomCrafty/MajiroTools GitHub Wiki
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) |