The level commands define the top-level control of the game. They are used to load levels, textures, collision data, objects, warps, etc. and determine how everything is connected. The first byte of the level command is the command type and the second byte is the length of the command in bytes.
[CC] [LL] …
C | Command type (full list below) |
L | Length of command in bytes (including CC and LL) |
Loads raw data to RAM segment and jumps to segment offset. Used for loading level scripts and then jumping to an offset in them
00 10 00 [XX] [YY YY YY YY] [ZZ ZZ ZZ ZZ] [AA AA AA AA]
X | RAM segment number |
Y | ROM address start |
Z | ROM address end |
A | Segment offset of jump target |
Load raw data to RAM segment and jump to segment offset. The only difference between this command and 0x00 is a call to 0x80278498
01 10 00 [XX] [YY YY YY YY] [ZZ ZZ ZZ ZZ] [AA AA AA AA]
X | RAM segment number |
Y | ROM address start |
Z | ROM address end |
A | Segment offset of jump target |
End of level layout data. Typically followed by null padding.
02 04 00 00
Set flag to 0, delay X frames, set flag to 1. Sets s16 flag (8038BE20) to 0 before delay and 1 after. Does not increment level script pointer until after delay.
03 04 [XX XX]
X | number of delay frames |
Set flag to -1, delay X frames, set flag to 1. Identical to 0x03, except for flag set at start: sets s16 flag (8038BE20) to -1 before delay and 1 after. Does not increment level pointer until after delay.
04 04 [XX XX]
X | number of delay frames |
Jump to level script at segmented address.
05 08 00 00 [XX XX XX XX]
X | segmented address of jump |
Push script stack and jump to level script at segmented address. Similar to 05, but also pushes current place on script stack so it can be popped later.
06 08 00 00 [XX XX XX XX]
X | segmented address of jump |
Pop script stack, returns to where previous 06 or 0C pushed from.
07 04 00 00
Push script stack and 16-bit value on stack. This command is never used in any of the level scripts.
08 04 [XX XX]
X | 16 bit value pushed on script stack after current address |
Pops script stack and param (possibly from previous 08 or 0A). This command is never used in any of the level scripts.
09 04 00 00
Pushes next level command on script stack and param 0x00000000. This command is only used once in main level scripts.
0A 04 00 00
If result of operation is true, pop stack. This command is only used once in main level scripts.
0B 08 [XX] 00 [YY YY YY YY]
X | operation, a0 to 8037E1A0 (unsigned 8) |
Y | argument, a1 to 8037E1A0 (signed 32) |
Operations | |
---|---|
0 | script_accum & argument |
1 | !(script_accum & argument) |
2 | script_accum == argument |
3 | script_accum != argument |
4 | script_accum < argument |
5 | script_accum ⇐ argument |
6 | script_accum > argument |
7 | script_accum >= argument |
If result of operation is true, jumps to segmented address.
0C 0C [XX] 00 [YY YY YY YY] [ZZ ZZ ZZ ZZ]
X | operation, a0 to 8037E1A0 (unsigned 8). See 0B: Conditional Pop for valid operations |
Y | argument, a1 to 8037E1A0 (signed 32) |
Z | segment address of jump |
If result of operation is true, pushes next command on stack and jumps to segmented address This command is never used in any of the level scripts.
0D 08 [XX] 00 [YY YY YY YY]
X | operation, a0 to 8037E1A0 (unsigned 8). See 0B: Conditional Pop for valid operations |
Y | argument, a1 to 8037E1A0 (signed 32) |
If result of operation is false, skips over following 0x0F, 0x10 commands. This command is never used in any of the level scripts.
0E 08 [XX] 00 [YY YY YY YY]
X | operation, a0 to 8037E1A0 (unsigned 8). See 0B: Conditional Pop for valid operations |
Y | argument, a1 to 8037E1A0 (signed 32) |
Skips over the following 0x10 commands. This command is never used in any of the level scripts.
0F 04 00 00
Doesn't do anything, nop. This command is never used in any of the level scripts.
10 04 00 00
Set level accumulator (8038BE24) from assembly routine.
11 08 [XX XX] [YY YY YY YY]
X | A0 value passed to function Y |
Y | Assembly routine of format u32 func(u32 a0, u16 A1) |
Call assembly routine Y (A0 = halfword X, A1 = word from 0x8038BE24). Store return value at 0x8038BE24.
Game startup | 8016F5B0 |
File select | 801766DC |
File select → Castle grounds | 8024BD5C |
Other levels | 8024BE14, 8024BCD8 |
12 08 [XX XX] [YY YY YY YY]
X | A0 value passed to function Y |
Y | Assembly routine of format u32 func(u32 a0, u16 A1) |
Call assembly routine Y (A0 = halfword X, A1 = word from 0x8038BE24). Store return value at 0x8038BE24. If return value is 0, set upper halfword @ 0x8039BE20 = 0 and do not continue to next command. Else, set upper halfword @ 0x8039BE20 = 1 and continue to the next command.
Demo screen | 8016F5B0 |
File select | 801768A0 |
Other levels | 8024BCD8 |
Set level accumulator (8038BE24) to constant value.
13 04 [XX XX]
X | Value to set level accumulator |
Calls PushPoolState/802783E8 and returns. This command is never used in any of the level scripts.
14 04 00 00
Calls PopPoolState/80278498 and returns. This command is never used in any of the level scripts.
15 04 00 00
Load raw data from ROM to absolute RAM address. Call 0x802786F0 (A0 = X, A1 = Y, A2 = Z)
16 10 00 00 [XX XX XX XX] [YY YY YY YY] [ZZ ZZ ZZ ZZ]
X | RAM address |
Y | ROM address start |
Z | ROM address end |
Load raw data from ROM to RAM segment.
17 0C 00 [XX] [YY YY YY YY] [ZZ ZZ ZZ ZZ]
X | RAM segment number |
Y | ROM address start |
Z | ROM address end |
Load and decompress MIO0 data from ROM to RAM segment.
18 0C 00 [XX] [YY YY YY YY] [ZZ ZZ ZZ ZZ]
X | RAM segment number |
Y | ROM address start |
Z | ROM address end |
Create Mario face for the demo screen.
19 04 00 [XX]
X | Settings: 01 No face, 02 Regular face, 03 Game over face |
Call 0x80278120 (A0 = 0x000E1000, A1 = 0); allocate 0xE1000 bytes for mario face settings If allocation was successful: Call 0x8019C450(A0 = 0x000E1000, A1 = pointer to allocated area in ram) Call 0x8019C418(A0 = 0x80000400, A1 = 0x00025800) Call 0x8019C418(A0 = 0x8039F800, A1 = 0x00070800) Call 0x8019C4EC ; data gets loaded into 80000400 and 8039F800 after this call Call 0x8019C684(A0 = X)
Load and decompress MIO0 data from ROM to RAM segment (level terrain textures)
1A 0C 00 [XX] [YY YY YY YY] [ZZ ZZ ZZ ZZ]
X | RAM segment number |
Y | ROM address start |
Z | ROM address end |
Start load sequence. Used before a chain of load commands.
1B 04 00 00
1C 04 00 00
More detailed notes can be found here: https://pastebin.com/raw/GjDsJYqq
Used after a chain of load commands.
1D 04 00 00
Allocates data from the pool and reset a couple variables
1E 04 00 00
More detailed notes can be found here: https://pastebin.com/raw/XkCfkFyT
Start of an area.
1F 08 [XX] 00 [YY YY YY YY]
X | Area number |
Y | Segment offset address of geometry layout |
End of an area.
20 04 00 00
Load polygon data without geometry layout.
21 08 [X]0 [YY] [ZZ ZZ ZZ ZZ]
X | Drawing layer |
Y | ID of the model to be used with 3D objects |
Z | Segment offset address |
Load polygon data with geometry layout.
22 08 00 [XX] [YY YY YY YY]
X | ID of the model to be used with 3D objects |
Y | Segment offset address |
Unknown. This command is never used in any of the level scripts.
23 0C [A][B BB] [CC CC CC CC] [DD DD DD DD]
A | most significant nibble of third byte |
B | 3 least significant nibbles of first word |
C | word |
D | float? |
(short)sp[0x2a] = (short)8038be28[2] & 0xFFF; // B (short)sp[0x28] = (short)8038be28[2] >> 12; // A sp[0x24] = (int)8038be28[4]; // C sp[0x2C] = (int)8038be28[8]; // D if (sp[0x2a] < 0x100) { f4 = sp[0x2C]; v0 = 8037B940(*0x8038b8a0, 0, sp[0x28], sp[0x24], f4); // t8 = sp[0x2a]; t7 = *0x8032ddc4; t9 = t8 << 2; t0 = t7 + t9; t0 = *0x8032ddc4 + sp[0x2a] * 4; *t0 = v0; } *0x8038be28 = *0x8038be28 + 8038be28[1]; // advance to next level command
Places a 3D object in the level.
24 18 [AA] [ID] [XX XX] [YY YY] [ZZ ZZ] [RX RX] [RY RY] [RZ RZ] [BB BB BB BB] [BS BS BS BS]
AA | Act mask in which this object will appear in |
ID | ID of the model to use for this object (defined by 21: Load Polygon Without Geo and 22: Load Polygon With Geo) |
XX | X position of object (s16) |
YY | Y position of object (s16) |
ZZ | Z position of object (s16) |
RX | Rotation across X axis in degrees (s16) |
RY | Rotation across Y axis in degrees (s16) |
RZ | Rotation across Z axis in degrees (s16) |
BB | Behavior parameters for the object. The entire word gets stored at Object→0x188, while only the second byte gets stored at Object→0x144. |
BS | RAM segment address for behavior script |
Loads the Mario object.
25 0C 00 [XX] [YY YY YY YY] [ZZ ZZ ZZ ZZ]
Always: 25 0C 00 [01] [00 00 00 01] [13 00 2E C0]
X | ID of the model to use for Mario (defined by 21: Load Polygon Without Geo and 22: Load Polygon With Geo) |
Y | Behavior parameters for Mario's Object. The entire word gets stored at MarioObject→0x188, while only the second byte gets stored at MarioObject→0x144. |
Z | RAM segment for behavior script |
Connect warps defined by previous 24: Place Object commands.
26 08 [AA] [BB] [CC] [DD] [EE] 00
A | Warp ID to jump from (defined by 21: Load Polygon Without Geo and 22: Load Polygon With Geo) |
B | Course ID number to warp to |
C | Course area to jump to |
D | Warp ID number in destination level area |
E | If set to 0x80, then the game will create a checkpoint when the warp is triggered. |
Define level warps for paintings inside the Castle.
27 08 [AA] [BB] [CC] [DD] [EE] 00
A | Warp ID to jump from (defined by 21: Load Polygon Without Geo and 22: Load Polygon With Geo) |
B | Course ID number to warp to |
C | Course area to jump to |
D | Warp ID number in destination level area |
E | If set to 0x80, then the game will create a checkpoint when the warp is triggered. |
Allows Mario to be instantly teleported to another area within the current level. The teleport to an area is triggered by the collision IDs 0x1B to 0x1E.
28 0C [CC] [AA] [XX XX] [YY YY] [ZZ ZZ] 00 00
C | Determines which collision to use starting with 0x1B. (00 = 0x1B, 01 = 0x1C, etc.) |
A | Course area # to go to |
X | Teleport Mario by this amount on the X axis (s16) |
Y | Teleport Mario by this amount on the Y axis (s16) |
Z | Teleport Mario by this amount on the Z axis (s16) |
Teleporting between 4 areas example:
(In area 1 level script) Warp to area 2 (Collision 0x1C): [ 28 0C 01 02 XX XX YY YY ZZ ZZ 00 00 ]
(In area 2 level script) Warp to area 1 (Collision 0x1B): [ 28 0C 00 01 XX XX YY YY ZZ ZZ 00 00 ] Warp to area 3 (Collision 0x1D): [ 28 0C 02 03 XX XX YY YY ZZ ZZ 00 00 ]
(In area 3 level script) Warp to area 2 (Collision 0x1C): [ 28 0C 01 02 XX XX YY YY ZZ ZZ 00 00 ] Warp to area 4 (Collision 0x1E): [ 28 0C 03 04 XX XX YY YY ZZ ZZ 00 00 ]
(In area 4 level script) Warp to area 3 (Collision 0x1D): [ 28 0C 02 03 XX XX YY YY ZZ ZZ 00 00 ]
29 04 [??] 00
? | Unknown |
Note: ?? is usually 01. ?? being 02 was only used once in the original game, in the Act Select level script.
2A 04 00 00
2B 0C [AA] 00 [RY RY] [XX XX] [YY YY] [ZZ ZZ]
Y = Y position of Mario (Signed 16-bits) Z = Z position of Mario (Signed 16-bits)
AA | Starting course area number |
RY RY | Rotation across Y axis (Signed 16-bits) |
X | X position of Mario (Signed 16-bits) |
Y | Y position of Mario (Signed 16-bits) |
Z | Z position of Mario (Signed 16-bits) |
2C 04 00 00
2D 04 00 00
Loads terrain collision data for level, and other special models to be placed in the level.
2E 08 00 00 [XX XX XX XX]
X | Segmented address of Collision Data |
Used in the levels Big Boo's Haunt, Hazy Maze Cave, and Inside Castle.
The segmented pointer in this command points to a byte array, with the same length as number of collision triangles in the level. Each byte in this array will be placed into offset 0x5 in the collision triangle structure.
When the ASM function 0x8029DBD4 is used with geometry layout switch command, it will use that offset 0x5 byte of the collision triangle that is below Mario as an index to determine which display list to render.
2F 08 00 00 [XX XX XX XX]
X | Segment offset to the byte array |
Shows a dialog at the beginning of a level. Ignored if the value at 0x8038B8AC equals -1 or XX > 1.
30 04 [XX] [YY]
X | Always 00? |
Y | Dialog ID |
Examples:
[ 30 04 00 00 ] # Bob-Omb's Battlefield [ 30 04 00 1E ] # Whomp's Fortress [ 30 04 00 5A ] # Bowser 1 Course [ 30 04 00 81 ] # Vanish Cap [ 30 04 00 82 ] # Metal Cap [ 30 04 00 83 ] # Wing Cap
Set default terrain.
31 04 00 [XX]
X | 00 Normal A, 01 Normal B, 02 Snow, 03 Sand, 04 Haunted house, 05 Water levels, 06 Slippery Slide |
No operation. This command is not used in any of the level scripts.
32 [XX]
Fade/overlay screen with color.
33 08 [XX] [YY] [RR] [GG] [BB] 00
X | 01 Enable, 00 Disable |
Y | Controls duration? usually 0x10 |
R,G,B = red/green/blue color value |
35 04 [XX] 00
If X is 0, call 0x803733B0 (A0 = 2) Else, call 0x803733B0 (A0 = 1)
Set music.
36 08 [??] [??] [??] [XX] 00 00
? | Other music parameters? |
X | Sequence number |
Set music. Used only in screen levels, like select file, select star and mario face and demo screen.
37 04 00 [XX]
X | Sequence number |
38 04 [XX XX]
Call 0x8024922C (A0 = X)
Place macro objects defined in segmented address.
39 08 00 00 [XX XX XX XX]
X | Segment offset pointer to object placement list |
List format: (each entry is 10 bytes)
[BB BB] [XX XX] [YY YY] [ZZ ZZ] [?? ??]
B | Object type ID (references behaviour address and model id) and Y Rotation. First 7 bit are the Y-Rotation, the last 9 bit are the Object type ID. |
X,Y,Z | Coordinates |
?? | Always 00 00 ? |
Define jet streams in JRB or DDD that repulse or suck Mario.
3B 0C 00 00 [XX XX] [YY YY] [ZZ ZZ] [II II]
X | X position |
Y | Y position |
Z | Z position |
I | Intensity. negative means repulsion, positive means suction |
Get/put remote values? Only used in main or menu level scripts.
3C 04 [XX] [YY]
X | ?? 01 in main level scripts, 00 in menu |
Y | ?? 00, 02, 03 |