Hack64 Wiki
Other Titles
Hack64 Wiki
Other Titles
This is an old revision of the document!
The geometry layout commands define how geometric shapes are drawn. Some geo layouts are contained after the Level data blocks and some are loaded with Level Command 0x17 The first byte of the geo layout command is the command type. Unlike the level commands, there is no length byte specified in the command. Most geo layout commands are constant length, however, some depend on the values set.
Layer | Description |
---|---|
00 | Unused |
01 | Opaque (Blending disabled). |
02 | Decals or triangles that draw on top of geometry near the same depth (Lessened depth-range). Blending disabled. Only renders when very close or on other polygons on real hardware. |
03 | Unused |
04 | Transparent pixels, no blending (OpenGL's equivalent is Alphatest). Allows perfect layering with other transparencies around it. |
05 | Blending (translucency) enabled. Layering must be handled with the order of drawn faces. |
06 | Blending (translucency) enabled. Layering must be handled with the order of drawn faces. Decal mode like layer 2. Lessened depth-range. |
Branches to segmented address and stores 2 return addresses.
00 00 00 00 [SS SS SS SS]
S | Segmented address to branch to |
/* Geo Layout 0x00 Rough translation. */ // 0x8038BD80 = Pointer to current Geo layout command // 0x8038BCB8 = Pointer to array/table to where branch return pointers are stored. // 0x8038BD7A = Branch depth value. *(0x8038BCB8 + (0x8038BD7A * 4)) = *0x8038BD80 + 8; // Stores the pointer to the next geo command *0x8038BD7A += 1; // Increment branch value *(0x8038BCB8 + (0x8038BD7A * 4)) = (*0x8038BD78 << 16) + *0x8038BD7E; // Store another address *0x8038BD7A += 1; // Increment branch value *0x8038BD7E = *0x8038BD7A; 0x8038BD80 = SegmentedToVirtual(0x8038BD80 + 4); // Go to the segmented address.
Length: 8
The ending command to close.
01 00 00 00
Length: 4
Branches the current geo layout to another area within a RAM bank.
02 [AA] 00 00 [SS SS SS SS]
A | 0 = Jump, 1 = Jump and store return address |
S | Segmented address to branch to |
Length: 8
Ends the current geometry layout branch and returns to the area following the 0x02 command.
03 00 00 00
Length: 4
If you don't understand nodes, this is basically like a sub-folder.
04 00 00 00
Length: 4
Used at the end of the data within the opened node.
05 00 00 00
Length: 4
06 00 [XX XX]
Stores the pointer of the last node into the table at address (*0x8038BCAC). This table is usually empty except for the first entry (index 0), which holds the pointer to the node created by the geo layout 0x0F command. The size of the table is defined by the geo layout 0x08 command.
X | Index in table to store pointer |
Example in a geometry layout: 0A 01 002D 0064 4E20 8029AA3C // Set camera frustum (FOV = 45, Near = 100, Far = 20000) 06 00 00 01 // Store pointer of the 0x0A command node to address ((*0x8038BCAC) + 4)
06 [OP] [VV VV]
Does an operation on the flags of the current node. (Flags are at offset 0x02 of the GraphNode structure)
OP | Operation (0 = Set flags to value, 1 = OR flags with value, 2 = AND flags with value) |
V | Value |
Example in a geometry layout: 0A 01 002D 0064 4E20 8029AA3C // Set camera frustum (FOV = 45, Near = 100, Far = 20000) 07 00 00 01 // Set Node flags of 0x0A command to be 0x0001 07 01 01 00 // OR Node flags with 0x0100 07 02 00 01 // AND Node flags with 0x0001
Only used in geo layout of levels.
08 00 00 [AA] [XX XX] [YY YY] [WW WW] [HH HH]
A | Number of entries (minus 2) to allocate in pointer table at address (*0x8038BCAC). Usually set to 0x0A for levels, and 0 for mario face. Used with the geometry layout 0x06 command. |
X | X position |
Y | Y position |
W | Width of screen |
H | Height of screen |
Length: C
Sets the frustum matrix for level backgrounds.
It is unknown if this command is actually necessary or not. You can remove this command from a level's geometry layout and it won't affect the background, and changing the scale value has no visible effect either.
09 00 [AA AA]
A | Scale of near plane, usually set to 0x64. Gets converted to a float and then divided by 100.0f |
Length: 4
/* Note: This is a simplified version of the code to explain what the 0x09 command does. It is not a 1 to 1 translation of the actual source code. All addresses are from the US ROM. */ void proc_8027BA98(struct GraphNode_Geo09* geo09_node) { if(geo09_node->children != 0) { struct GraphNode_Geo08* screenRenderArea = 0x8032DEF0; // These variables come from the geo layout 0x08 command. short x_pos = (short)screenRenderArea->_0x16; short y_pos = (short)screenRenderArea->_0x18; short width = (short)screenRenderArea->_0x1A; short height = (short)screenRenderArea->_0x1C; // Near scale is the parameter you set with the 0x09 command. float nearScale = (float)geo09_node->_0x14; // Reserve 0x40 bytes to store result matrix. Mtx* m = proc_80278F2C(0x40); // Calculate frustum matrix guFrustum( m, // Pointer to 4x4 matrix resulting from calculation ((x_pos - width) / 2.0f) * nearScale, // Near plane's lower-left x coordinate ((x_pos + width) / 2.0f) * nearScale, // Near plane's upper-right x coordinate ((y_pos + height) / 2.0f) * nearScale, // Near plane's lower-left y coordinate ((y_pos - height) / 2.0f) * nearScale, // Near plane's upper-right y coordinate -2.0f, // Distance from viewpoint to near clipping plane 2.0f, // Distance from viewpoint to far clipping plane 1.0f // Scale for matrix elements ); int** ptrToMasterDL = 0x8033B06C; // Add Fast3D cmd 0xB4 (G_RDPHALF_1) to master display list *((*ptrToMasterDL) + 0) = 0xB4000000; *((*ptrToMasterDL) + 4) = 0x0000FFFF; *ptrToMasterDL += 8; // Move by 8 bytes. // Add matrix command to master display list to process the matrix 'm'. // Parameters used: G_MTX_PUSH and G_MTX_LOAD *((*ptrToMasterDL) + 0) = 0x01030040; *((*ptrToMasterDL) + 4) = m & 0x1FFFFFFF; *ptrToMasterDL += 8; // Move by 8 bytes. proc_8027DEA8(geo09_node->children); // Process children of this GeoNode } }
Set camera frustum properties. Only used in geo layout of levels.
0A [AA] [BB BB] [NN NN] [FF FF] {EE EE EE EE}
A | Use ASM code defined by E |
B | Camera FOV (0x2D = 45) |
N | Camera Near |
F | Camera Far |
E | optional ASM function if A is non-zero (always 8029AA3C) |
Length: 8-C (variable)
Starts geometry layout with no parameters whatsoever. Seems to use a pre-set render area.
0B 00 00 00
Length: 4
This command is used in level geometry layouts. Z-Buffering is disabled when rendering the skybox, and re-enabled when rendering level geometry.
0C [AA] 00 00
A | 0x00 = Disable Z-buffer, 0x01 = Enable Z-buffer |
[ 0C 01 00 00 ]
will add the following Fast3D data to the following node:
E7 00 00 00 00 00 00 00 B7 00 00 00 00 00 00 01 // Node's Fast3D commands E7 00 00 00 00 00 00 00 B6 00 00 00 00 00 00 01
Length: 4
Used in WF, CCM, TTM, SSL levels and some geo layouts. This command will make the following node only render in a certain distance range away from the camera.
0D 00 00 00 [AA AA] [BB BB]
A | (s16) Minimum distance value |
B | (s16) Maximum distance value |
Example from “Grassy Level Part” in Whomp's fortress:
0049E3A8 / 0E000958 [ 20 00 07 D0 ] 0049E3AC / 0E00095C [ 04 00 00 00 ] 0049E3B0 / 0E000960 [ 0D 00 00 00 F8 30 1F 40 ] 0049E3B8 / 0E000968 [ 04 00 00 00 ] 0049E3BC / 0E00096C [ 15 01 00 00 07 00 AB A0 ] // Real geometry (Camera is nearby) 0049E3C4 / 0E000974 [ 15 06 00 00 07 00 AF B8 ] 0049E3CC / 0E00097C [ 05 00 00 00 ] 0049E3D0 / 0E000980 [ 0D 00 00 00 1F 40 4E 20 ] 0049E3D8 / 0E000988 [ 04 00 00 00 ] 0049E3DC / 0E00098C [ 15 01 00 00 07 00 AE C8 ] // Fake geometry (Camera is far away) 0049E3E4 / 0E000994 [ 05 00 00 00 ] 0049E3E8 / 0E000998 [ 05 00 00 00 ] 0049E3EC / 0E00099C [ 01 00 00 00 ]
Length: 8
Loads ASM in RAM that switches between the receding display lists within the node.
0E 00 00 [NN] [AA AA AA AA]
N | Number of cases/display lists, starting at 01 |
A | ASM Function |
Length: 8
0F 00 [TT TT] [XX XX] [YY YY] [ZZ ZZ] [UU UU] [VV VV] [WW WW] [AA AA AA AA]
T | ?? |
X | ?? (s16) |
Y | ?? (s16) |
Z | ?? (s16) |
U | ?? (s16) |
V | ?? (s16) |
W | ?? (s16) |
A | ASM function. Always 80287D30 (levels) or 00 (menus) |
Length: 0x14
Applies translation & rotation to the following node.
10 [AA] [BB BB] [XX XX] [YY YY] [ZZ ZZ] [RX RX] [RY RY] [RZ RZ]
A | Branching flag |
B | Used if A != 0 |
X | X translation offset (s16) |
Y | Y translation offset (s16) |
Z | Z translation offset (s16) |
RX | X rotation (s16) |
RY | Y rotation (s16) |
RZ | Z rotation (s16) |
Length: 0x10
Applies translation to the child nodes, and a display list if one is specified. You can start a geometry layout with this command to set the offset for the entire model. You cannot start a geometry layout and load a display list at the same time, as it will cause the game to freeze (white-screen).
11 [B][L] [XX XX] [YY YY] [ZZ ZZ] {AA AA AA AA}
B | Include last 4 bytes if set to 8 (command will be C bytes long instead of 8) |
L | Drawing layer if B is set, otherwise will always be zero |
X | X translation offset (s16) |
Y | Y translation offset (s16) |
Z | Z translation offset (s16) |
A | Segmented address with display list if B is set. Also creates a joint of some kind? (Does not work with animations?) |
Length: 8-C (variable)
Note: You can't just use the 8-byte version of 0x11 command just anywhere. It seems like the command needs a joint in it's parent node(s) for it to work properly (created from geo layout commands 0x11, 0x12, and 0x13).
0B000000 04000000 11 00 0000 0100 0000 // This will cause a crash 04000000 15 01 00 00 0700A290 05000000 05000000 01000000 0B000000 04000000 11 80 0000 0100 0000 00000000 // This will work, since it creates a joint. 04000000 15 01 00 00 0700A290 05000000 05000000 01000000 11 00 0000 0100 0000 // This will also work, since it is starting the geo layout. 04000000 15 01 00 00 0700A290 05000000 01000000 0B000000 04000000 13 01 0000 0000 0000 00000000 04000000 11 00 0000 0100 0000 // This will also work, since there is a joint above it. 04000000 15 01 00 00 0700A290 05000000 05000000 05000000 01000000
Applies rotation to the child nodes, and a display list if one is specified. You can start a geometry layout with this command to set the rotation for the entire model. You cannot start a geometry layout and load a display list at the same time, as it will cause the game to freeze (white-screen).
12 [B][L] [RX RX] [RY RY] [RZ RZ] {AA AA AA AA}
B | Include last 4 bytes if set to 8 (command will be C bytes long instead of 8) |
L | Drawing layer if B is set, otherwise will always be zero |
RX | X rotation (s16) |
RY | Y rotation (s16) |
RZ | Z rotation (s16) |
A | Segmented address with display list if B is set. Also creates a joint of some kind? (Does not work with animations?) |
Length: 8-C (variable)
Note: You can't just use the 8-byte version of 0x12 command just anywhere. It seems like the command needs a joint in it's parent node(s) for it to work properly (created from geo layout commands 0x11, 0x12, and 0x13).
(see geo layout command 0x11 for examples)
Loads display list with drawing layer and offsets the model and the node's children on X/Y/Z axis.
13 [LL] [XX XX] [YY YY] [ZZ ZZ] [AA AA AA AA]
L | Drawing layer |
X | Offset on X axis (s16) |
Y | Offset on Y axis (s16) |
Z | Offset on Z axis (s16) |
A | Segmented address with display list If 0x00000000, an invisible rotation joint is created |
Length: C
Billboards the model without needing the use of 0x21 in the behavior script.
14 00 00 00 00 00 00 00
Length: 8
Loads display list with drawing layer and no other properties.
15 [LL] 00 00 [AA AA AA AA]
L | Drawing layer |
A | Segmented address with display list |
Length: 8
Used at start of the geo layout, with shadow type, solidity, and size.
16 00 00 [AA] 00 [BB] [CC CC]
A | Shadow type |
B | Shadow solidity (00=invisible, FF=black) |
C | Shadow scale |
Length: 8
Sets up rendering for 3D Objects? Without it, 0x24 objects placed in level do not render.
17 00 00 00
Length: 4
Used in some original objects to point to ASM in RAM, for misc. effects such as vertex rippling.
The 3rd and 4th bytes are parameters passed into the asm function. Argument register a1 is a pointer to the node data, and the parameters are stored as a word at offset 0x18.
18 00 [XX XX] [AA AA AA AA]
X | Parameter(s) passed into asm function. a1→0x18 |
A | ASM RAM Address |
Length: 8
Set background image or color.
19 00 [TT TT] [AA AA AA AA]
T | If A == 0, RGBA color, else background ID |
A | ASM function to set the background image, always 0x802763D4 |
Length: 8
Examples:
[ 19 00 00 00 80 27 63 D4 ] # Bob-Omb's Battlefield [ 19 00 00 01 80 27 63 D4 ] # Lethal Lava Land [ 19 00 00 02 80 27 63 D4 ] # Wet Dry World [ 19 00 00 03 80 27 63 D4 ] # Rainbow Ride [ 19 00 00 04 80 27 63 D4 ] # Cool Cool Mountain [ 19 00 00 05 80 27 63 D4 ] # Shifting Sand Land [ 19 00 00 06 80 27 63 D4 ] # Big Boo's Haunt [ 19 00 00 07 80 27 63 D4 ] # Bowser 1 Course [ 19 00 00 08 80 27 63 D4 ] # Jolly Roger Bay [ 19 00 00 09 80 27 63 D4 ] # Bowser 3 Course [ 19 00 00 01 00 00 00 00 ] # Secret Slide, pure black background
Doesn't do anything, nop. This command is never used in any of the scripts.
Length: 8
Scales the receding data uniformly.
1D [A][B] 00 00 [SS SS SS SS] {?? ?? ?? ??}
A | If MSbit is set, load B and ?? |
B | If MSbit of A is set, use for A2 to 8037B940 |
S | Scale percentage (0x10000 = 100%) |
?? | optional word used if the MSbit of A is set |
Length: 8-C (variable)
Doesn't do anything, nop. This command is never used in any of the scripts.
Length: 8
Doesn't do anything, nop. This command is never used in any of the scripts.
Length: 0x10
Starts the geometry layout with no shadow and a render area.
20 00 [AA AA]
A | Render distance? |
Length: 4