Skip to content

Instantly share code, notes, and snippets.

@dkorpel
Last active July 17, 2023 20:03
Show Gist options
  • Save dkorpel/dc7c435bf937fe886b67bfb51b7ec43a to your computer and use it in GitHub Desktop.
Save dkorpel/dc7c435bf937fe886b67bfb51b7ec43a to your computer and use it in GitHub Desktop.
/*
.:SM64 Hitbox view hack:.
April 2018
This one-time RAM-modification displays collision triangles and object cylinders in Super Mario 64.
With L + D-pad up you toggle cylinders, with L + D-pad down you toggle collision triangles.
Compiled with: https://github.com/notwa/lips
Save this file as 'hitboxview.asm' in the lips folder, and create a Lua script 'apply_hitboxhack.lua':
```
local lips = require "lips.init"
local err = lips.assemble("hitboxview.asm", mainmemory.write_u8)
```
Open Super Mario 64 in Bizhawk (http://tasvideos.org/BizHawk.html) and run the script 'apply_hitboxhack.lua' to enable the hack.
If you don't want to immediately write it but, say, print the RAM modifications, you can use a different function:
```
local err = lips.assemble("hitboxview.asm", function (address, byte) print(("%02X"):format(address)..":"..("%02X"):format(byte)) end)
```
--
It assumes the Japanese version of Super Mario 64, but after all JP specific lines there is a
commented out US-equivalent. You can change the lines with a Regex replace:
Find what: .+//U:
Replace with: <leave it blank>
Lines like this:
LW T8, 0xFDF0 (T8) //U: LW T8, 0x1160 (T8)
Become this:
LW T8, 0x1160 (T8)
Then you can compile it for the US version.
--
Useful for debugging: When the game crashes, find out at what instruction it crashed:
emu.disassemble(mainmemory.read_u32_be(0x33983C)).disasm --JP
emu.disassemble(mainmemory.read_u32_be(0x33ABAC)).disasm --US
--
## Changelog (July 2018):
Collision cylinders are now 24-sides instead of 12-sided making them more accurate
Lava triangles are no longer drawn avoiding z-fighting in Lethal Lava Land / Bowser in the Fire Sea
Tiny Huge Island's small version no longer has z-fighting (because of the scaling node)
New (better?) textures and shading for triangles
Triangle count is capped at 2250 now to avoid buffer overflows in ROM hacks
Todo: custom shade rules?
Todo: draw Mario wall checks?
*/
//0x3D6FF0 mystatcount
//0x3D6FF4 cylinder enable
//0x3D6FF8 level enable
//0x3D6FFC previous enabl
//0x3D7000 - variables / code (0x800), 512 words
//0x3D7800 - texture (0x800)
//0x3D8000 - cylinder verts (24)
//0x3D8400 - cylinder verts (12)
//0x3D8600 - cylinder list
//0x3D9000 - cylinder texture
//0x3E0000 - display list for vertices
//0x3E5500 - vertices
//0x400000 - end
//27897C 278F2C pushBackQueueHead(int amount)
//37A434 37A434 void matrix_float_to_fixed(short[32] dest, float[16] source)
//27B354 27B904 void appendNewDisplayList(void* list, int index)
//37A434 37A434 void storeTransformAsFixed(dest, src)
//Transform stack symbols:
//33A770 short StackIndex
//33A778 float[16][] StackFloat
//33AF78 struct fixedMat [] StackFixed
////////////////////////////////////////////////////////////////////////////////
.org 0x3D7000
////////////////////////////////////////////////////////////////////////////////
update_triangle_hook:
LUI T8, 0x803D
LW T8, 0x6FF8 (T8)
BEQ T8, R0, + //only if hitbox hack is active
NOP
LUI T8, 0x8036
LW T8, 0xFDF0 (T8) //U: LW T8, 0x1160 (T8)
LHU T9, 0x0002 (T8)
ORI T9, T9, 0x0010 //set obj invisible flag
SH T9, 0x0002 (T8)
+:
LW T8, 0x0020 (SP) //re-insert code that got overwritten
ADDIU T9, T8, 0x0002
J 0x80383AC0 //and continue as if no-one injected any code...
NOP
update_triangle_hook_start:
LUI T8, 0x8036
LW T8, 0xFDF0 (T8) //U: LW T8, 0x1160 (T8)
LHU T9, 0x0002 (T8)
ANDI T9, T9, 0xFFEF //unset obj invisible flag
SH T9, 0x0002 (T8)
+:
ADDIU SP, SP, 0xFB28 //re-insert code that got overwritten
SW RA, 0x0014 (SP)
J 0x803839D4 //and continue as if no-one injected any code...
NOP
////////////////////////////////////////////////////////////////////////////////
// A0 = enable
draw_level_triangles:
ADDIU SP, SP, 0xFF80
SW RA, 0x14 (SP)
SW S0, 0x18 (SP)
SW S1, 0x1C (SP)
SW S2, 0x20 (SP)
SW S3, 0x24 (SP)
SW S4, 0x28 (SP)
SW S5, 0x2C (SP)
BEQ A0, R0, draw_level_triangles_return // if A0 = 0, ignore
//35FE00 361170 int free_triangle_index
//35FE08 361178 int old_free_triangle_index //STATBG
//S0 = lastindex = statcount
LUI AT, 0x8036
LW S0, 0xFE08 (AT) //U: LW S0, 0x1178 (AT)
LUI AT, 0x803D
LW T0, 0x6FF0 (AT) // T1 = mystatcount
BEQ T0, S0 + // if (mystatcount != statcount) {
NOP
// Triggers GFX tree / landscape object visibility update
LUI AT, 0x803D
SW R0, 0x6FFC (AT) // hitbox enabled prev
SW S0, 0x6FF0 (AT) //mystatcount = statcount
ADDIU S0, R0, 0x0000 //S0 = lastindex = 0
+:
ADDIU AT, R0, 5
DIV S0, AT
MFHI S1 //S1 = offset = lastindex % 5
MFLO T0 //T0 = lastindex / 5
ADDU T0, S0, T0 //T0 = (lastindex + lastindex/5)
SLL T0, T0, 3 //T0 * = 8
LUI AT, 0x803E
ADDU S2, AT, T0 //S2 = listpointer = 0x3E0000 + (lastindex + (lastindex/5)) * 8
BEQ S1, R0, + //is THIS *the* fix of ages?
NOP
ADDIU S2, S2, 0x0008
+:
//S3 = totalcount = *0x35FE00 - U: 361170
LUI S3, 0x8036
LW S3, 0xFE00 (S3) //U: LW S3, 0x1170 (S3)
LUI AT, 0x8039
LW T0, 0xEE9C (AT) //T0 = *38EE9C = Triangle[2300]
SLL T1, S0, 2 //48*S0 = (4*S0-S0)*16
SUB T1, T1, S0
SLL T1, T1, 4
ADDU S5, T0, T1 //S5 = triangle pointer = *38EE9C + 48*lastindex
LUI S4, 0x803E
ADDU S4, S4, T1
ADDIU S4, S4, 0x5500 //S4 = vertexpointer = 0x3E5500 + 16*lastindex - 16?!?!?! WHAT WERE YOU THINKING, 48
-:
SLT AT, S0, S3
BEQ AT, R0, draw_level_triangles_break //if not (lastindex < totalcount), break
ADDIU T0, R0, 0x08D0 //~2250 triangles max to prevent buffer overflow
SLT AT, S0, T0 //lastindex < maxcount
BEQ AT, R0, draw_level_triangles_break
NOP
BNE S1, R0, + //if (offset == 0)
NOP
LUI AT, 0x04E0 //G_VTX for 0xE+1 vertices (=15)
ORI AT, AT, 0x00F0 //load 0x50 bytes
SW AT, 0x0000 (S2)
SW S4, 0x0004 (S2) //store segmented address to vertices
ADDIU S2, S2, 0x0008
+:
// Add triangle
LUI AT, 0xBF00
SW AT, 0x0000 (S2)
LUI AT, 0x803D
SLL T0, S1, 2
ADDU AT, AT, T0 //add offset*4
LW AT, 0x6EE0(AT) //lookup table for vertices
SW AT, 0x0004 (S2)
// Add vertex
OR A0, R0, S5
JAL add_triangle_to_vertexbuffer //(a0 = triangle pointer, a1 = vertexpointer)
OR A1, R0, S4
ADDIU S0, S0, 1 //increment lastIndex
ADDIU S1, S1, 1 //increment offset
ADDIU S2, S2, 0x0008 //increment listPointer
ADDIU S4, S4, 0x30 //increment vertex pointer
ADDIU S5, S5, 0x30 //triangle ptr too, (same size, how nice!)
ADDIU AT, R0, 0x0005
BNE S1, AT, + //if offset == 5
NOP
ADDIU S1, R0, 0x0000 //offset = 0
+:
B -
NOP
draw_level_triangles_break:
LUI AT, 0xB800
SW AT, 0x0000 (S2)
SW R0, 0x0004 (S2)
SW R0, 0x0008 (S2)
SW R0, 0x000C (S2)
SW R0, 0x0010 (S2)
SW R0, 0x0014 (S2)
SW R0, 0x0018 (S2)
SW R0, 0x001C (S2)
// appendNewDisplayList(address, list)
LUI A0, 0x003D
ORI A0, A0, 0x6F00
JAL 0x8027B354 //U: JAL 0x8027B904
ADDIU A1, R0, 0x0001 //index, 0-6?
draw_level_triangles_return:
LW S5, 0x2C (SP)
LW S4, 0x28 (SP)
LW S3, 0x24 (SP)
LW S2, 0x20 (SP)
LW S1, 0x1C (SP)
LW S0, 0x18 (SP)
LW RA, 0x14 (SP)
JR RA
ADDIU SP, SP, 0x0080
////////////////////////////////////////////////////////////////////////////////
// A0 = enable
obj_draw_hitboxes:
ADDIU SP, SP, 0xFF80
SW RA, 0x14 (SP)
SW S0, 0x18 (SP)
BEQ A0, R0, ++ //is not on screen, skip
NOP
LUI AT, 0x803D
LW AT, 0x6FF4 (AT) // cylinder enabled
BEQ AT, R0, ++ //is not enabled screen, skip
LW T0, 0x00F0 (SP) // SP 0x80 (this stack) + 0x70 (caller stack)
//LW T1, 0x0130 (T0) // interaction bits
JAL 0x8029F198 //U: JAL 0x8029F914 //object_get_group
LW A0, 0x020C (T0) // behavior script
LW T0, 0x00F0 (SP) // load object again
LUI AT, 0x803D
ADDIU AT, AT, 0x6ED0
LB AT, AT (V0) //lookup table
BEQ AT, R0, ++
//LUI AT, 0x8036 // if mario, draw cylinder
//LW T2, 0xFDE8 (AT)
//BEQ T0, T2, +
//BEQ T1, R0, ++ // if no interaction bits, no cylinder
+:
//// draw cylinder
// build transformation matrix
LW T5, 0x0A0 (T0) // x
LW T7, 0x0A8 (T0) // z
LUI AT, 0x3A80 // 1/1024 = 0x3A80
MTC1 AT, F0
LWC1 F8, 0x1FC (T0) // cylinder height
MUL.S F8, F8, F0
LWC1 F16, 0x208 (T0) // y offset
LWC1 F12, 0x0A4 (T0) // y
SUB.S F10, F12, F16 // y - yoffset
LUI AT, 0x3A80 // 1/1024 = 0x3A80
MTC1 AT, F0
LWC1 F6, 0x1F8 (T0) // radius
MUL.S F6, F6, F0
//[ 00 10 20 30 ]
//[ 04 14 24 34 ]
//[ 08 18 28 38 ]
//[ 0C 1C 2C 3C ]
LUI AT, 0x3F80 // = 1.0f,
ADDIU A1, SP, 0x0020 //A1 = float matrix
SWC1 F6, 0x0000 (A1) //xscale = F6 = radius
SW R0, 0x0004 (A1)
SW R0, 0x0008 (A1)
SW R0, 0x000C (A1)
SW R0, 0x0010 (A1)
SWC1 F8, 0x0014 (A1) //yscale = F8 = height
SW R0, 0x0018 (A1)
SW R0, 0x001C (A1)
SW R0, 0x0020 (A1)
SW R0, 0x0024 (A1)
SWC1 F6, 0x0028 (A1) //zscale = F6
SW R0, 0x002C (A1)
SW T5, 0x0030 (A1) //x
SWC1 F10, 0x0034 (A1) //y
SW T7, 0x0038 (A1) //z
SW AT, 0x003C (A1)
//matrix_mult(stack[stackIndex+1], newTransform, stack[stackIndex])
LUI AT, 0x8034
ADDIU T0, AT, 0xA778 //U: ADDIU T0, AT, 0xBAE8 // 33A778 = stack base
LH T1, 0xA770 (AT) //U: LH T1, 0xBAE0 (AT) // 33A770 = stack index
SLL T1, T1, 0x6 //
ADDU S0, T0, T1 // S0 = stack[index]
ADDIU A2, S0, 0x0000 // original = stack[i]
ADDIU A1, SP, 0x0020 // redundant, see above
JAL 0x80379F60 // matrix_mult(dest, new, original) -- 0x379F60
ADDIU A0, S0, 0x0040 // dest = stack[i + 1]
// stackIndex += 1
LUI AT, 0x8034
LH T6, 0xA770 (AT) //U: LH T6, 0xBAE0 (AT)
ADDIU T6, T6, 0x0001
SH T6, 0xA770 (AT) //U: SH T6, 0xBAE0 (AT)
// reserve space for new matrix
JAL 0x8027897C //U: JAL 0x80278F2C //reserve_buffer(64)
ADDIU A0, R0, 0x0040
SW V0, 0x20 (SP)
//stack[stackIndex] = storage
LW V0, 0x20 (SP)
LUI AT, 0x8034
LH T6, 0xA770 (AT) //U: LH T6, 0xBAE0 (AT)
SLL T8, T6, 0x2
ADDU T9, AT, T8 //0x33AF78[0x33A770] = fixedPointStack
SW V0, 0xAF78 (T9) //U: SW V0, 0xC2E8 (T9)
//storeTransformAsFixed(reservedSpace, stack[stackIndex])
LW A0, 0x20 (SP) // result from pushBackQueueHead
ADDIU A1, S0, 0x40 // note: we incremented stackIndex, S0 still contains old value, therefore +0x40
JAL 0x8037A434
NOP
// appendNewDisplayList(address = 0x3D6F80, list = 5)
LUI A0, 0x003D
ORI A0, A0, 0x6F80
ADDIU A1, R0, 0x0005 //index, 0 = non transparent, or 1?
JAL 0x8027B354 //U: JAL 0x8027B904
NOP
// stackIndex -= 1
LUI AT, 0x8034
LH T6, 0xA770 (AT) //U: LH T6, 0xBAE0 (AT)
ADDIU T6, T6, 0xFFFF
SH T6, 0xA770 (AT) //U: SH T6, 0xBAE0 (AT)
+:
LW S0, 0x18 (SP)
LW RA, 0x14 (SP)
JR RA
ADDIU SP, SP, 0x0080
////////////////////////////////////////////////////////////////////////////////
// A0 = 1 / 0 for enable / disable
set_landscape_invisible:
ADDIU SP, SP, 0xFFC0
SW RA, 0x14 (SP)
// A2 = head, A3 = current
LUI AT, 0x8036 // 0x35FD78 + 0x340 = 0x3600B8 = group 8 head
LW A2, 0xFD78 (AT) //U: LW A2, 0x10E8 (AT)
ADDIU A2, A2, 0x0340 // = 0x68*8
OR A3, R0, A2 //current = head
LUI T1, 0x800E
ORI T1, T1, 0xAD50 //U: ORI T1, T1, 0xDBC8 // T1 = landscape visual behavior (0x20C) 0x800EAD50,
-:
LW A3, 0x060 (A3) // next object
BEQ A2, A3, ++ // done if reaching head again
NOP
LW T0, 0x20C (A3) // load behavior script
BNE T0, T1, - // continue if not landscape visual
NOP
LH T2, 0x02 (A3)
BEQ A0, R0, +
ANDI T2, T2, 0xFFEF // reset invisible obj flag
ORI T2, T2, 0x0010 // set invisible obj flag
+:
SH T2, 0x02 (A3)
B -
NOP
+:
LW RA, 0x14 (SP)
JR RA
ADDIU SP, SP, 0x0040
////////////////////////////////////////////////////////////////////////////////
// Custom function
hitbox_draw_main:
ADDIU SP, SP, 0xFFE0
SW RA, 0x14 (SP)
LUI A0, 0x803D
JAL draw_level_triangles
LW A0, 0x6FFC (A0) // hitbox enabled prev
LUI AT, 0x8033
LW T0, 0xC6A4 (AT) //U: LW T0, 0xD5E4 (AT)
LHU T1, 0x0010 (T0) // button pressed
ANDI T1, T1, 0x0020 // L button
BEQ T1, R0, ++
LHU T0, 0x0012 (T0)
ANDI T1, T0, 0x0800 //Dpad up
BEQ T1, R0, +
LUI AT, 0x803D
LW T0, 0x6FF4 (AT) // toggle cylinder hitbox
XORI T0, T0, 1
SW T0, 0x6FF4 (AT)
+:
ANDI T1, T0, 0x0400 //Dpad up
BEQ T1, R0, +
LUI AT, 0x803D //toggle triangles
LW T0, 0x6FF8 (AT)
XORI T0, T0, 1
SW T0, 0x6FF8 (AT)
+:
//0x0800 = dpad_up
//0x0400 = dpad_down
//0x0200 = dpad_left
//0x0100 = dpad_right
//0x0080 = unused?
//0x0040 = unused?
//0x0020 = L
LUI AT, 0x803D
LW T0, 0x6FF8 (AT) // hitbox enabled
LW T1, 0x6FFC (AT) // hitbox enabled prev
BEQ T0, T1, ++
NOP
SW T0, 0x6FFC (AT) // hitbox enabled prev
LUI T0, 0x8033
LW T0, 0xCE6C (T0) //U: LW T0, 0xDDCC (T0) //load GFX struct
BEQ T0, R0, +
NOP
LW T1, 0x0004 (T0) //load root
BEQ T1, R0, +
NOP
LW T1, 0x10 (T1) //load masterlist0
BEQ T1, R0, +
NOP
LW T1, 0x08 (T1) //load masterlist1
BEQ T1, R0, +
NOP
LW T1, 0x10 (T1) //load projection3D
BEQ T1, R0, +
NOP
LW T1, 0x10 (T1) //load Camera
BEQ T1, R0, +
NOP
LW A0, 0x10 (T1) //load displaylist
LUI A1, 0x803D
JAL set_displaylists_visible
LW A1, 0x6FF8 (A1) // hitbox enabled
+:
LUI A0, 0x803D
JAL set_landscape_invisible
LW A0, 0x6FF8 (A0) // hitbox enabled
+:
LW RA, 0x14 (SP)
JR RA
ADDIU SP, SP, 0x0020
////////////////////////////////////////////////////////////////////////////////
// Disable / enable a display list node and siblings
//A0 = pointer to display list node, A1 = disable?
set_displaylists_visible:
ADDIU SP, SP, 0xFFE0
SW RA, 0x14 (SP)
SW S0, 0x18 (SP) //S0 = A0 = current node (gets modified during iteration)
SW S1, 0x1C (SP) //S1 = A1
SW S2, 0x20 (SP) //S2 = last
BEQ A0, R0, set_displaylists_visible_return //Check if node isn't null
NOP
ADDU S0, R0, A0
ADDU S1, R0, A1
ADDU S2, R0, S0
//LW S2, 0x0004 (S0) //S2 = last, but means last node won't get disabled
-:
LHU T1, 0x0000 (S0) // Get GFX type
ADDIU AT, R0, 0x010C // child selector type
BEQ T1, AT, +
NOP
ADDIU AT, R0, 0x001C // scaling node type (for small Tiny Huge Island)
BEQ T1, AT, +
NOP
ADDIU AT, R0, 0x000A // group node type
BNE T1, AT, ++
NOP
+:
LW A0, 0x0010 (S0) //load child, recursively disable/enable those as well
JAL set_displaylists_visible
ADDU A1, R0, S1
B set_displaylists_visible_continue
NOP
+:
ADDIU AT, R0, 0x001B //only displaylist
BNE T1, AT, set_displaylists_visible_continue
NOP
//ADDIU AT, R0, 0x056C //802D056C = water rectangle drawer, U: ?
//LHU T2, 0x0016 (S0) //lower 16 bits of GFX node function
LH T0, 0x02 (S0)
BEQ A1, R0, +
ORI T0, T0, 0x0001
ANDI T0, T0, 0xFFFE // set 'enabled' bit to 0
+:
SH T0, 0x02 (S0)
set_displaylists_visible_continue:
LW S0, 0x08 (S0) //S0 = next node
BNE S0, S2, - // loop while current node != last
NOP
set_displaylists_visible_return:
LW S2, 0x20 (SP)
LW S1, 0x1C (SP)
LW S0, 0x18 (SP)
LW RA, 0x14 (SP)
JR RA
ADDIU SP, SP, 0x0020
////////////////////////////////////////////////////////////////////////////////
//struct Triangle* A0 = triangle, struct vtx_col[3] A1 = destination
add_triangle_to_vertexbuffer:
LH T0, 0x00 (A0)
ADDIU AT, R0, 0x0001 //type 1 = lava triangles
BNE T0, AT, + //don't draw these, they cause z-fighting
NOP
SW R0, 0x00 (A1) //(0, 0, 0) triangle
SH R0, 0x06 (A1)
SW R0, 0x10 (A1)
SH R0, 0x16 (A1)
SW R0, 0x20 (A1)
B ++
SH R0, 0x26 (A1)
+:
// Triangle -> vertices xyz
// 0A 0C 0D -> 00 02 04
// 10 12 14 -> 10 12 14
// 16 18 1A -> 20 22 24
LH T1, 0x0A (A0)
SH T1, 0x00 (A1)
LH T1, 0x0C (A0)
SH T1, 0x02 (A1)
LH T1, 0x0E (A0)
SH T1, 0x04 (A1)
LH T1, 0x10 (A0)
SH T1, 0x10 (A1)
LH T1, 0x12 (A0)
SH T1, 0x12 (A1)
LH T1, 0x14 (A0)
SH T1, 0x14 (A1)
LH T1, 0x16 (A0)
SH T1, 0x20 (A1)
LH T1, 0x18 (A0)
SH T1, 0x22 (A1)
LH T1, 0x1A (A0)
SH T1, 0x24 (A1)
+:
//flag, can be used to set primary vertex (doesn't matter in this case)
SH R0, 0x06 (A1)
SH R0, 0x16 (A1)
SH R0, 0x26 (A1)
// tex coords, 1024 = image wide
// starting at 0 causes bleeding, so half a pixel offset
ADDIU T0, R0, 0x0010 // 0000 + 16
ADDIU T1, R0, 0x03F0 // 1024 + 16
SH T0, 0x08 (A1) //triangle coordinates: (0, 1), (1, 0), (1, 1)
SH T1, 0x0A (A1)
SH T1, 0x18 (A1)
SH T0, 0x1A (A1)
LH AT, 0x0000 (A0) //load triangle type
BNE AT, R0, + //if non-default type, give different half of texture
SH T1, 0x28 (A1)
B ++
SH T1, 0x2A (A1)
+:
SH T0, 0x28 (A1)
SH T0, 0x2A (A1)
+:
// T5, T6, T7 = R, G, B
LUI AT, 0x8039
LDC1 F8, 0xBBB0 (AT) // = +0.01
LWC1 F4, 0x0020 (A0)
CVT.D.S F6, F4 // F6 = (double) triangle->normal.x
C.LT.D F8, F6
NOP // compiler inserts NOP, R4300i bug?
BC1T floor_color
LDC1 F8, 0xBBB8 (AT) // = -0.01
C.LT.D F6, F8
NOP
BC1T ceiling_color
NOP
wall_color:
LB T0, 0x04 (A0)
ANDI T0, T0, 0x0008 //bit 3 = x projection flag
BNE T0, R0, +
NOP
ADDIU T5, R0, 0x80
ADDIU T6, R0, 0xE0 // light green
B end_color
ADDIU T7, R0, 0x80
+:
ADDIU T5, R0, 0x40
ADDIU T6, R0, 0x80 // dark green
B end_color
ADDIU T7, R0, 0x40
floor_color:
LUI AT, 0x3F00 //= 0.5f
MTC1 AT, F8
ADD.S F4, F4, F8
LUI AT, 0x432A //= 170.0f
MTC1 AT, F10
LUI AT, 0x42C0 //= 96.0f
MTC1 AT, F12
MUL.S F10, F4, F10 // F4 = normal.y (see up)
MUL.S F12, F4, F12
TRUNC.W.S F10, F10 // (can destination be an operand?)
TRUNC.W.S F12, F12
MFC1 T5, F12
MFC1 T6, F12
B end_color
MFC1 T7, F10
//ADDIU T7, R0, 0xF0
ceiling_color:
NEG.S F4, F4
LUI AT, 0x3F00 //= 0.5f
MTC1 AT, F8
ADD.S F4, F4, F8
LUI AT, 0x432A //= 170.0f
MTC1 AT, F10
LUI AT, 0x42C0 //= 96.0f
MTC1 AT, F12
MUL.S F10, F4, F10 // F4 = normal.y (see up)
MUL.S F12, F4, F12
TRUNC.W.S F10, F10 // (can destination be an operand?)
TRUNC.W.S F12, F12
MFC1 T5, F10
MFC1 T6, F12
B end_color
MFC1 T7, F12
end_color:
//rgba
SB T5, 0x0C (A1) //red
SB T5, 0x1C (A1)
SB T5, 0x2C (A1)
SB T6, 0x0D (A1) //green
SB T6, 0x1D (A1)
SB T6, 0x2D (A1)
SB T7, 0x0E (A1) //blue
SB T7, 0x1E (A1)
SB T7, 0x2E (A1)
ADDIU T0, R0, 0xFF //alpha (doesn't matter anyway)
SB T0, 0x0F (A1)
SB T0, 0x1F (A1)
SB T0, 0x2F (A1)
JR RA
NOP
//////////////////////////////////////////////////////////////////////////////////////////
// 24 sides cylinder
// Four cylinder quarters
.org 0x3D8000
.word 0x00000000, 0x04000000, 0x00000000, 0xEE6666AA
.word 0x00000400, 0x04000000, 0x00000400, 0xEE6666AA
.word 0x01090000, 0x03DD0000, 0x002A0000, 0xEE6666AA
.word 0x01090400, 0x03DD0000, 0x002A0400, 0xEE6666AA
.word 0x01FF0000, 0x03760000, 0x00550000, 0xEE6666AA
.word 0x01FF0400, 0x03760000, 0x00550400, 0xEE6666AA
.word 0x02D40000, 0x02D40000, 0x00800000, 0xEE6666AA
.word 0x02D40400, 0x02D40000, 0x00800400, 0xEE6666AA
.word 0x03760000, 0x02000000, 0x00AA0000, 0xEE6666AA
.word 0x03760400, 0x02000000, 0x00AA0400, 0xEE6666AA
.word 0x03DD0000, 0x01090000, 0x00D50000, 0xEE6666AA
.word 0x03DD0400, 0x01090000, 0x00D50400, 0xEE6666AA
.word 0x04000000, 0x00000000, 0x00FF0000, 0xEE6666AA
.word 0x04000400, 0x00000000, 0x00FF0400, 0xEE6666AA
.word 0x00000000, 0x00000000, 0x02000200, 0xEE6666AA
.word 0x00000400, 0x00000000, 0x02000200, 0xEE6666AA
.word 0x04000000, 0x00000000, 0x01000000, 0xEE6666AA
.word 0x04000400, 0x00000000, 0x01000400, 0xEE6666AA
.word 0x03DD0000, 0xFEF70000, 0x012A0000, 0xEE6666AA
.word 0x03DD0400, 0xFEF70000, 0x012A0400, 0xEE6666AA
.word 0x03760000, 0xFE000000, 0x01550000, 0xEE6666AA
.word 0x03760400, 0xFE000000, 0x01550400, 0xEE6666AA
.word 0x02D40000, 0xFD2C0000, 0x01800000, 0xEE6666AA
.word 0x02D40400, 0xFD2C0000, 0x01800400, 0xEE6666AA
.word 0x01FF0000, 0xFC8A0000, 0x01AA0000, 0xEE6666AA
.word 0x01FF0400, 0xFC8A0000, 0x01AA0400, 0xEE6666AA
.word 0x01090000, 0xFC230000, 0x01D50000, 0xEE6666AA
.word 0x01090400, 0xFC230000, 0x01D50400, 0xEE6666AA
.word 0x00000000, 0xFC000000, 0x02000000, 0xEE6666AA
.word 0x00000400, 0xFC000000, 0x02000400, 0xEE6666AA
.word 0x00000000, 0x00000000, 0x02000200, 0xEE6666AA
.word 0x00000400, 0x00000000, 0x02000200, 0xEE6666AA
.word 0x00000000, 0xFC000000, 0x02000000, 0xEE6666AA
.word 0x00000400, 0xFC000000, 0x02000400, 0xEE6666AA
.word 0xFEF70000, 0xFC230000, 0x022A0000, 0xEE6666AA
.word 0xFEF70400, 0xFC230000, 0x022A0400, 0xEE6666AA
.word 0xFE010000, 0xFC8A0000, 0x02550000, 0xEE6666AA
.word 0xFE010400, 0xFC8A0000, 0x02550400, 0xEE6666AA
.word 0xFD2C0000, 0xFD2C0000, 0x027F0000, 0xEE6666AA
.word 0xFD2C0400, 0xFD2C0000, 0x027F0400, 0xEE6666AA
.word 0xFC8A0000, 0xFE000000, 0x02AA0000, 0xEE6666AA
.word 0xFC8A0400, 0xFE000000, 0x02AA0400, 0xEE6666AA
.word 0xFC230000, 0xFEF70000, 0x02D50000, 0xEE6666AA
.word 0xFC230400, 0xFEF70000, 0x02D50400, 0xEE6666AA
.word 0xFC000000, 0x00000000, 0x02FF0000, 0xEE6666AA
.word 0xFC000400, 0x00000000, 0x02FF0400, 0xEE6666AA
.word 0x00000000, 0x00000000, 0x02000200, 0xEE6666AA
.word 0x00000400, 0x00000000, 0x02000200, 0xEE6666AA
.word 0xFC000000, 0x00000000, 0x03000000, 0xEE6666AA
.word 0xFC000400, 0x00000000, 0x03000400, 0xEE6666AA
.word 0xFC230000, 0x01090000, 0x032A0000, 0xEE6666AA
.word 0xFC230400, 0x01090000, 0x032A0400, 0xEE6666AA
.word 0xFC8A0000, 0x01FF0000, 0x03550000, 0xEE6666AA
.word 0xFC8A0400, 0x01FF0000, 0x03550400, 0xEE6666AA
.word 0xFD2C0000, 0x02D40000, 0x037F0000, 0xEE6666AA
.word 0xFD2C0400, 0x02D40000, 0x037F0400, 0xEE6666AA
.word 0xFE000000, 0x03760000, 0x03AA0000, 0xEE6666AA
.word 0xFE000400, 0x03760000, 0x03AA0400, 0xEE6666AA
.word 0xFEF70000, 0x03DD0000, 0x03D50000, 0xEE6666AA
.word 0xFEF70400, 0x03DD0000, 0x03D50400, 0xEE6666AA
.word 0x00000000, 0x04000000, 0x03FF0000, 0xEE6666AA
.word 0x00000400, 0x04000000, 0x03FF0400, 0xEE6666AA
.word 0x00000000, 0x00000000, 0x02000200, 0xEE6666AA
.word 0x00000400, 0x00000000, 0x02000200, 0xEE6666AA
// Two cylinder halves
.org 0x3D8400
.word 0x00000000, 0x04000000, 0x00000000, 0xDD6666AA
.word 0x00000400, 0x04000000, 0x00000400, 0xDD6666AA
.word 0x01FF0000, 0x03760000, 0x00550000, 0xDD6666AA
.word 0x01FF0400, 0x03760000, 0x00550400, 0xDD6666AA
.word 0x03760000, 0x02000000, 0x00AA0000, 0xDD6666AA
.word 0x03760400, 0x02000000, 0x00AA0400, 0xDD6666AA
.word 0x04000000, 0x00000000, 0x01000000, 0xDD6666AA
.word 0x04000400, 0x00000000, 0x01000400, 0xDD6666AA
.word 0x03760000, 0xFE010000, 0x01550000, 0xDD6666AA
.word 0x03760400, 0xFE010000, 0x01550400, 0xDD6666AA
.word 0x02000000, 0xFC8A0000, 0x01AA0000, 0xDD6666AA
.word 0x02000400, 0xFC8A0000, 0x01AA0400, 0xDD6666AA
.word 0x00000000, 0xFC000000, 0x01FF0000, 0xDD6666AA
.word 0x00000400, 0xFC000000, 0x01FF0400, 0xDD6666AA
.word 0x00000000, 0x00000000, 0x02000200, 0xDD6666AA
.word 0x00000400, 0x00000000, 0x02000200, 0xDD6666AA
.word 0x00000000, 0xFC000000, 0x02000000, 0xDD6666AA //+0x100 second half
.word 0x00000400, 0xFC000000, 0x02000400, 0xDD6666AA
.word 0xFE000000, 0xFC8A0000, 0x02550000, 0xDD6666AA
.word 0xFE000400, 0xFC8A0000, 0x02550400, 0xDD6666AA
.word 0xFC8A0000, 0xFE010000, 0x02AA0000, 0xDD6666AA
.word 0xFC8A0400, 0xFE010000, 0x02AA0400, 0xDD6666AA
.word 0xFC000000, 0x00000000, 0x03000000, 0xDD6666AA
.word 0xFC000400, 0x00000000, 0x03000400, 0xDD6666AA
.word 0xFC8A0000, 0x02000000, 0x03550000, 0xDD6666AA
.word 0xFC8A0400, 0x02000000, 0x03550400, 0xDD6666AA
.word 0xFE010000, 0x03760000, 0x03AA0000, 0xDD6666AA
.word 0xFE010400, 0x03760000, 0x03AA0400, 0xDD6666AA
.word 0x00000000, 0x04000000, 0x04000000, 0xDD6666AA
.word 0x00000400, 0x04000000, 0x04000400, 0xDD6666AA
.word 0x00000000, 0x00000000, 0x02000200, 0xDD6666AA
.word 0x00000400, 0x00000000, 0x02000200, 0xDD6666AA
////////////////////
//24-cylinder
.org 0x3D8600
.word 0x04f000f0, 0x003D8000 //set to address
.word 0xBF000000, 0x0014008C
.word 0xBF000000, 0x000A1E96
.word 0xBF000000, 0x00141E00
.word 0xBF000000, 0x001E0A00
.word 0xBF000000, 0x0028148C
.word 0xBF000000, 0x001E3296
.word 0xBF000000, 0x00283214
.word 0xBF000000, 0x00321E14
.word 0xBF000000, 0x003C288C
.word 0xBF000000, 0x00324696
.word 0xBF000000, 0x003C4628
.word 0xBF000000, 0x00463228
.word 0xBF000000, 0x00503C8C
.word 0xBF000000, 0x00465A96
.word 0xBF000000, 0x00505A3C
.word 0xBF000000, 0x005A463C
.word 0xBF000000, 0x0064508C
.word 0xBF000000, 0x005A6E96
.word 0xBF000000, 0x00646E50
.word 0xBF000000, 0x006E5A50
.word 0xBF000000, 0x0078648C
.word 0xBF000000, 0x006E8296
.word 0xBF000000, 0x00788264
.word 0xBF000000, 0x00826E64
.word 0x04f000f0, 0x003D8100 //set to address
.word 0xBF000000, 0x0014008C
.word 0xBF000000, 0x000A1E96
.word 0xBF000000, 0x00141E00
.word 0xBF000000, 0x001E0A00
.word 0xBF000000, 0x0028148C
.word 0xBF000000, 0x001E3296
.word 0xBF000000, 0x00283214
.word 0xBF000000, 0x00321E14
.word 0xBF000000, 0x003C288C
.word 0xBF000000, 0x00324696
.word 0xBF000000, 0x003C4628
.word 0xBF000000, 0x00463228
.word 0xBF000000, 0x00503C8C
.word 0xBF000000, 0x00465A96
.word 0xBF000000, 0x00505A3C
.word 0xBF000000, 0x005A463C
.word 0xBF000000, 0x0064508C
.word 0xBF000000, 0x005A6E96
.word 0xBF000000, 0x00646E50
.word 0xBF000000, 0x006E5A50
.word 0xBF000000, 0x0078648C
.word 0xBF000000, 0x006E8296
.word 0xBF000000, 0x00788264
.word 0xBF000000, 0x00826E64
.word 0x04f000f0, 0x003D8200 //set to address
.word 0xBF000000, 0x0014008C
.word 0xBF000000, 0x000A1E96
.word 0xBF000000, 0x00141E00
.word 0xBF000000, 0x001E0A00
.word 0xBF000000, 0x0028148C
.word 0xBF000000, 0x001E3296
.word 0xBF000000, 0x00283214
.word 0xBF000000, 0x00321E14
.word 0xBF000000, 0x003C288C
.word 0xBF000000, 0x00324696
.word 0xBF000000, 0x003C4628
.word 0xBF000000, 0x00463228
.word 0xBF000000, 0x00503C8C
.word 0xBF000000, 0x00465A96
.word 0xBF000000, 0x00505A3C
.word 0xBF000000, 0x005A463C
.word 0xBF000000, 0x0064508C
.word 0xBF000000, 0x005A6E96
.word 0xBF000000, 0x00646E50
.word 0xBF000000, 0x006E5A50
.word 0xBF000000, 0x0078648C
.word 0xBF000000, 0x006E8296
.word 0xBF000000, 0x00788264
.word 0xBF000000, 0x00826E64
.word 0x04f000f0, 0x003D8300 //set to address
.word 0xBF000000, 0x0014008C
.word 0xBF000000, 0x000A1E96
.word 0xBF000000, 0x00141E00
.word 0xBF000000, 0x001E0A00
.word 0xBF000000, 0x0028148C
.word 0xBF000000, 0x001E3296
.word 0xBF000000, 0x00283214
.word 0xBF000000, 0x00321E14
.word 0xBF000000, 0x003C288C
.word 0xBF000000, 0x00324696
.word 0xBF000000, 0x003C4628
.word 0xBF000000, 0x00463228
.word 0xBF000000, 0x00503C8C
.word 0xBF000000, 0x00465A96
.word 0xBF000000, 0x00505A3C
.word 0xBF000000, 0x005A463C
.word 0xBF000000, 0x0064508C
.word 0xBF000000, 0x005A6E96
.word 0xBF000000, 0x00646E50
.word 0xBF000000, 0x006E5A50
.word 0xBF000000, 0x0078648C
.word 0xBF000000, 0x006E8296
.word 0xBF000000, 0x00788264
.word 0xBF000000, 0x00826E64
.word 0xB8000000, 0x00000000 //end list
//101 * 0x08 = 0x328
// 12-Cylinder
.org 0x3D8A00
.word 0x04F000F0, 0x003D8400 //set to address
.word 0xBF000000, 0x0014008C
.word 0xBF000000, 0x000A1E96
.word 0xBF000000, 0x00141E00
.word 0xBF000000, 0x001E0A00
.word 0xBF000000, 0x0028148C
.word 0xBF000000, 0x001E3296
.word 0xBF000000, 0x00283214
.word 0xBF000000, 0x00321E14
.word 0xBF000000, 0x003C288C
.word 0xBF000000, 0x00324696
.word 0xBF000000, 0x003C4628
.word 0xBF000000, 0x00463228
.word 0xBF000000, 0x00503C8C
.word 0xBF000000, 0x00465A96
.word 0xBF000000, 0x00505A3C
.word 0xBF000000, 0x005A463C
.word 0xBF000000, 0x0064508C
.word 0xBF000000, 0x005A6E96
.word 0xBF000000, 0x00646E50
.word 0xBF000000, 0x006E5A50
.word 0xBF000000, 0x0078648C
.word 0xBF000000, 0x006E8296
.word 0xBF000000, 0x00788264
.word 0xBF000000, 0x00826E64
.word 0x04F000F0, 0x003D8500 //set to address
.word 0xBF000000, 0x0014008C
.word 0xBF000000, 0x000A1E96
.word 0xBF000000, 0x00141E00
.word 0xBF000000, 0x001E0A00
.word 0xBF000000, 0x0028148C
.word 0xBF000000, 0x001E3296
.word 0xBF000000, 0x00283214
.word 0xBF000000, 0x00321E14
.word 0xBF000000, 0x003C288C
.word 0xBF000000, 0x00324696
.word 0xBF000000, 0x003C4628
.word 0xBF000000, 0x00463228
.word 0xBF000000, 0x00503C8C
.word 0xBF000000, 0x00465A96
.word 0xBF000000, 0x00505A3C
.word 0xBF000000, 0x005A463C
.word 0xBF000000, 0x0064508C
.word 0xBF000000, 0x005A6E96
.word 0xBF000000, 0x00646E50
.word 0xBF000000, 0x006E5A50
.word 0xBF000000, 0x0078648C
.word 0xBF000000, 0x006E8296
.word 0xBF000000, 0x00788264
.word 0xBF000000, 0x00826E64
.word 0xB8000000, 0x00000000 //end list
//////////////////////////////////////////////////////////////////////////////////////////
// Rectangle with diagonal line texture
.org 0x3D7800
.halfword 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xE739, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xFFFF, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xEF7B, 0xEF7B, 0xEF7B, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xDEF7, 0xDEF7, 0xDEF7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0x9CE7, 0x9CE7, 0xBDEF, 0xDEF7, 0xFFFF, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xE739, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0x9CE7, 0x9CE7, 0xBDEF, 0xDEF7, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xBDEF
.halfword 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF
////////////////////////////////////////////////////////////////////////////////
// Cylinder texture
//
.org 0x3D9000
.halfword 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7
.halfword 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE
.halfword 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B, 0xEF7B
.halfword 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7, 0xDEF7
////////////////////////////////////////////////////////////////////////////////
// Lookup table for which object groups should be drawn with hitbox
// Groups 0, 2, 4, 5, 6, 9, 10 have collisions processed, though not all object use them
// Objects with interaction bits use their cylinder hitbox, but there's also objects with no bits
// but still a cylinder hitbox so it's not a good discriminant.
// This way some useless hitboxes are drawn, but no hitboxes are skipped
.org 0x3D6ED0
//.word 0x00000000, 0x00000000, 0x00000000, 0x00000000
hex {01 00 01 00 01 01 01 00 00 01 01 00 00 00 00 00}
// Lookup table for G_TRI commands, 5 possibilities
.org 0x3D6EE0
.word 0x00000A14
.word 0x001E2832
.word 0x003C4650
.word 0x005A646E
.word 0x0078828C
////////////////////////////////////////////////////////////////////////////////
// Level geometry display list (max 16 commands here!)
.org 0x3D6F00
.word 0xE7000000, 0x00000000 //G_RDPPIPESYNC
//.word 0xFC121824, 0xFF33FFFF //G_SETCOMBINE (aquarium)
.word 0xFC127E24, 0xFFFFF9FC //G_SETCOMBINE (influenced by environment color triangles?)
.word 0xB6000000, 0x00020000 //G_CLEARGEOMETRYMODE G_LIGHTING
.word 0xBB000001, 0xFFFFFFFF //G_TEXTURE
.word 0xE8000000, 0x00000000 //G_RDPTILESYNC
.word 0xF5101000, 0x00014050 //G_SETTILE RGBA 16-bit
.word 0xF2000000, 0x0007C07C //G_SETTILESIZE 32 * 32
.word 0xFD100000, 0x003D7800 //G_SETTIMG [segmented address]
.word 0xE6000000, 0x00000000 //G_RDPLOADSYNC
.word 0xF3000000, 0x073FF100 //G_LOADBLOCK
//.word 0xFB000000, 0xFF888888 //G_SETENVCOLOR (doesn't work with this combine / lighting mode?!)
.word 0x06000000, 0x003E0000 //G_DL level geometry list
.word 0xB7000000, 0x00020000 //G_SETGEOMETRYMODE G_LIGHTING
.word 0xB8000000, 0x00000000 //end list
////////////////////////////////////////////////////////////////////////////////
.org 0x3E0000 //initialize list of 0 triangles
.word 0xB8000000, 0x00000000 //end list
////////////////////////////////////////////////////////////////////////////////
// Cylinder display list (max 14 commands here!)
.org 0x3D6F80
.word 0xE7000000, 0x00000000 //G_RDPPIPESYNC
.word 0xFC127E24, 0xFFFFF9FC //G_SETCOMBINE (influenced by environment color triangles?)
.word 0xB6000000, 0x00020000 //G_CLEARGEOMETRYMODE G_LIGHTING
.word 0xBB000001, 0xFFFFFFFF //G_TEXTURE
.word 0xE8000000, 0x00000000 //G_RDPTILESYNC
.word 0xF5101000, 0x00014050 //G_SETTILE RGBA 16-bit
.word 0xF2000000, 0x0007C07C //G_SETTILESIZE 32 * 32
.word 0xFD100000, 0x003D9000 //G_SETTIMG [segmented address]
.word 0xE6000000, 0x00000000 //G_RDPLOADSYNC
.word 0xF3000000, 0x073FF100 //G_LOADBLOCK
.word 0x06000000, 0x003D8600 //G_DL 24 cylinder (0x003D8A00 = 12 cylinder)
.word 0xE7000000, 0x00000000 //G_RDPPIPESYNC
.word 0xB7000000, 0x00020000 //G_SETGEOMETRYMODE G_LIGHTING
.word 0xB8000000, 0x00000000 //G_ENDDL
.org 0x3D6FF0
.word 0xFFFFFFFF // statcount = -1
.word 0x00000001 // cylinder enabled
.word 0x00000001 // hitbox enabled
.word 0x00000001 // active at all
////////////////////////////////////////////////////////////////////////////////
.org 0x27D4BC //U: .org 0x27DA6C //object parent GFX node nop jump
JAL hitbox_draw_main
////////////////////////////////////////////////////////////////////////////////
// To avoid z-fighting of collision triangles with visible triangles:
// Make objects with collision triangles invisible if tangible
/*
.org 0x383A9C //reset A3
ADDIU A3, R0, 0x0000
.org 0x383AB4 //set A3 if distance_to_object(mario) < tangible_distance
ADDIU A3, R0, 0x0001
.org 0x383B18 //also branch if A3 is set
BNE A3, R0, 0x80383B3C
NOP
BC1F 0x80383B3C
*/
.org 0x383AB8 //0x3839CC
J update_triangle_hook
NOP
.org 0x3839CC
J update_triangle_hook_start
NOP
////////////////////////////////////////////////////////////////////////////////
// Hook into process_object_node function
.org 0x27D370 //U: .org 0x27D920
SW V0, 0x0010 (SP) //store result of isOnScreen
.org 0x27D444 //U: .org 0x27D9F4 //NOP jump
JAL obj_draw_hitboxes
LW A0, 0x0010 (SP) //load result of isOnScreen
// 0x800 bytes required for texture
// 3*2300*0x10 = 0x1AF40 bytes required for 2300 vertices
// 2300*8+2310/15*8 = 0x4CB0 bytes display list WRONG! 2300/15*48
// cylinder model: ~0x800 bytes
// 24 sides, 50 unique verts, 64 verts, 96 triangles
// every block contains 16 vertices, 2 for center and 2*7 angles = 6 sides. 24-cylinder: 96 triangles = 0x300 bytes
// 16*0x10 * 4 = 0x400 for vertices
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment