• Welcome to Smashboards, the world's largest Super Smash Brothers community! Over 250,000 Smash Bros. fans from around the world have come to discuss these great games in over 19 million posts!

    You are currently viewing our boards as a visitor. Click here to sign up right now and start on your path in the Smash community!

Completed Simple Stage Geometry 2.0

Punkline

Dr. Frankenstack
Joined
May 15, 2015
Messages
423
This code uses global data generated from stage files to draw out collision links in place of stage models. Instead of relying on the developer mode option like in my older code; this new concept uses sword trails to trace out the geometry with lines of a fixed pixel width.

It may be possible to use some of the info detailed in the ASM comments/symbols to make more codes that create visualizations for ECB mechanics -- or even edit the stage mid-game.




To install the DOL Mod, use the latest version of Melee Code Manager.

Simple Stage Geometry 2.0
includes PRIM LITE

Code:
-==-


Simple Stage Geometry 2.0
Draws stage collision links in place of stage
- can be toggled from status flag in <simple_stage_geometry_params>
- includes primitive drawing module
[Punkline]
<simple_stage_geometry_params> All
E5E5E5FF # 0 - normal stage floor color
635C66FF # 1 - ceiling color
635C66FF # 2 - right wall color
635C66FF # 3 - left wall color
00FFE5FF # 4 - ice floor color
F02040FF # 5 - ledge floor color
26211360 # 6 - intangible color
408040C0 # 7 - polygon region
A08040C0 # 8 - fallthrough floor color
10 # line width
03 # flags:
# +01 = toggle the whole code on/off
# +02 = toggle geometry drawing
# +04 = toggle world GObj displays
# +08 = toggle background color changes
# +10 = include stage polygon region boxes when drawing geometry
# +20 = draw lines on top of models (ignore Z)

0000 # reserved for code


1.02 ------ 800301f0 --- 387b0000 -> Branch
lis r0, <<simple_stage_geometry_params>>@h
ori r12, r0, <<simple_stage_geometry_params>>@l
3D608048 816B9D60 2C0B0001 890C0025 892C0026 7D004378 7D0A4A78 40A20008 394000FF 51402636 7C003120 4FDFD842 4C19C382 4C00DB82 4FDE0342 41BE0030 990C0026 807C0398 64632000 409F0008 40BD0008 6C632000 64630400 409F0008 40BC0008 6C630400 907C0398 387B0000 00000000
1.02 ------ 800304c8 --- 48338141 -> Branch
lis r0, <<simple_stage_geometry_params>>@h
ori r3, r0, <<simple_stage_geometry_params>>@l
bl <draw_simple_stage_geometry>
bl    0x80368608
00000000
<draw_simple_stage_geometry> 1.02
7C0802A6 90010004 9421FF00 BEC10010 7C7C1B78 A07C0025 7C60C120 409701E4 409601E0 881C0024 3AE01305 3AC01455 5017821E 40B20008 6AF71000 83EDAE24 83CDAE1C 83ADAE18 40930078 881C001F 2C000000 4182006C A07F0008 70600004 40820054 38600005 7EE4BB78 7EC5B378 38840001
bl <prim.new>
809C001C E09F0010 C0628044 E0BF0018 10242420 104424E0
bl <store_vert>
10452CE0
bl <store_vert>
10252C20
bl <store_vert>
104424E0
bl <store_vert>
10242420
bl <store_vert>
83FF0000 2C1F0000 4180FF9C 83EDAE24 3B600005 835F0004 A01A0002 5403083D 41A20110 7EE4BB78 7EC5B378
bl <prim.new>
90610084 A0BA0000 3805FFFF 54051838 7F3E2A14 A01A0002 7C0903A6 87190008 A0190006 7C001120 40BF0038 8878000F
bl 0x800569ec
809C0000 7C8A2378 E0018000 108100C0 40A40008 809C0010 8078000C 546005AD 41A20028 809C0014 48000020 40BE000C 809C0004 48000014 40BC000C 809C000C 48000008 809C0008 A0790004 70600004 41A20008 809C0018 80610084 4FFFF982 3998FFFE C0628044 7C8B2378 A4AC0002 1CC50018 38A60008 103D280C 10410CE0 8018000C 70050500 41820030 A0B90006 70A60001 4082000C 809C0018 4800001C 7C0A2000 801C0020 7C0401D6 5004C63E 40820008 809C0020
bl <store_vert>
419F000C 4FFFF842 4BFFFFA8 4200FF20 377BFFFF 3B5A0004 4181FEE0 83FF0000 2C1F0000 4180FECC
bl <prim.close>
BAC10010 38210100 80010004 7C0803A6 4E800020
<store_vert>
D0230000 D0430000 D0630000 90830000 4E800020
1.02 ----- 0x802EAA38 --- C822DE80 -> C82280A0
1.02 ----- 0x802E8D68 --- C862DE80 -> C86280A0
1.02 ----- 0x804DD860 --- 4330000080000000 -> 0010130300001455
1.02 ----- 0x800c2684 ----
38600001 38800004 38a00005 38c00005
->
57E3A7BE 57E4C77E 57E5E77E 57E6073E
1.02 ----- 0x800c26b0 ----
38600001 38800003 38A00000
->
57C3A7FE 57C4C77E 57C5AFFE
1.02 ----- 0x800c26c0 --- 38600000 -> 57C39FFE
1.02 ----- 0x800c272c --- 38600000 -> 57C317BE
<prim.setup> 1.02
7C0802A6 90010004 9421C000 BFC10010 7C7E1B78 7C9F2378 38600001
b 0x800c2678
<prim.setup2> 1.02
7C0802A6 90010004 9421C000
bl 0x8033C3C8
b 0x800c2d40
<projection_return> 1.02
38214000 80010004 7C0803A6 4E800020
1.02 ----- 0x800c2da0 --- 38b80001 -> b <projection_return>
1.02 ----- 0x800c2674 --- 38600001 -> b <prim.setup_projection>
<prim.setup_projection> 1.02
8062DE80 8082DE84
bl <prim.setup>
881C2101
b 0x800c2738
1.02 ----- 0x800c2734 --- 881c2101 -> b <prim.setup_projection_epilog>
<prim.setup_projection_epilog> 1.02
BBC10010
b <projection_return>
1.02 ----- 0x800c2d3c --- 4827968d -> b <prim.setup2_projection>
<prim.setup2_projection> 1.02
bl <prim.setup2>
38B80001
b 0x800c2da4
1.02 ----- 0x802E8B48 --- C822DE68 -> C82280A0
1.02 ----- 0x804DD848 --- 43300000 -> b <prim.close>
<prim.close> 1.02
3860FFFF
b 0x80361fc4
1.02 ----- 0x804DD84C --- 80000000 -> b <prim.new>
<prim.new> 1.02
7C0802A6 90010004 9421FFC0 BFA10010 7C7E1B78 7C9F2378 7C832378 7CA42B78
bl <prim.setup>
bl <prim.setup2>
57E3063E 2C030005 41A00024 2C030007 4181001C 57E385BE 38800005 4182000C
bl 0x8033D240
48000008
bl 0x8033d298
57E31E38 38630080 38800000 57C5043E
bl 0x8033D0DC
3C60CC01 38638000 BBA10010 38210040 80010004 7C0803A6 4E800020
#
Code:
-==-

ASM - Simple Stage Geometry 2.0
Draws stage collision links in place of stage
- can be toggled from status flag in <simple_stage_geometry_params>
- includes primitive drawing module
[Punkline]
<simple_stage_geometry_params> All
.long 0xe5e5e5ff  # 0 - normal stage floor color
.long 0x635c66ff  # 1 - ceiling color
.long 0x635c66ff  # 2 - right wall color
.long 0x635c66ff  # 3 - left wall color
.long 0x00ffe5ff  # 4 - ice floor color
.long 0xf02040ff  # 5 - ledge floor color
.long 0x26211360  # 6 - intangible color
.long 0x408040C0  # 7 - polygon region
.long 0xA08040C0  # 8 - fallthrough floor color

# 0x24
.byte 0x10 # line width (in 1/16th pixels)

# 0x25
# flags:
.set enable,      0x01 # toggle the whole code on/off
.set showDrawing, 0x02 # toggle geometry drawing
.set showWorld,   0x04 # toggle world GObj displays
.set showBG,      0x08 # toggle background color changes

.set PolyRegions, 0x10 # toggle stage polygon region boxes when drawing
.set IgnoreZ,     0x11 # use this to draw geometry in front of everything else

.byte enable | showDrawing
# set flags by name using '|' to combine
# default = "enable | showDrawing"
# these can be modified in-game

.byte 0
# memory variable for flags byte
# this byte copies over the flags byte on each drawing to create a trigger mask
# when the memory does not match the flags byte, camera settings are modified to reflect options
# -- the code does not otherwise passively update the camera settings

.align 2


1.02 ------ 800301f0 --- 387b0000 -> Branch
# just before stage camera GX function starts
# deciding if going to draw stage models using flag

# injection attempts to introduce toggle logic while minimally intruding on vanilla mechanics
# uses memory bits to only operate when changes in flags are detected

# registers:
.set rFlags,    8
.set rMemory,   9
.set rTrigger, 10
.set rParams,  12
.set rFrame,   11
.set rCam,     28

# offsets:
.set xFlags,  0x25
.set xMemory, 0x26

# cr bools:
.set bEnable,    31
.set bNOOP,      30
.set bShowWorld, 29
.set bShowBG,    28
.set bETrig,     27  # "enable" trigger
.set bWTrig,     25  # "world" trigger
.set bBTrig,     24  # "background" trigger

lis r0, <<simple_stage_geometry_params>>@h
ori rParams, r0, <<simple_stage_geometry_params>>@l
lis r11, 0x8048
lwz rFrame, 0x9D60-0x10000(r11)
cmpwi rFrame, 1
# r12 = params
# r11 = scene timer
# cr0 eq = initialization bool, TRUE if 1st frame of scene

lbz rFlags, xFlags(rParams)
lbz rMemory, xMemory(rParams)
# rFlags = parameters
# rMemory = parameters from last check

mr  r0, rFlags
xor rTrigger, rFlags, rMemory
bne+ _finish_bools
# differences between rFlags and rMemory are generated in rTrigger

  _initial_frame_trigger:
  li rTrigger, 0xFF
  # if this is the first frame of the scene, then force the trigger mask
  # -- otherwise, only changes to the bools will cause code to trigger

_finish_bools:
rlwimi r0, rTrigger, 4, 0xF0
mtcrf 0x03, r0
# cr7 = flag params
# cr6 = trigger bools




crnor bNOOP, bEnable, bETrig
# if ((not enabled) AND (not enabletrigger))
# -- then NOOP

cror 0, bWTrig, bBTrig
cror 0, 0, bETrig
crorc bNOOP, bNOOP, 0
# or if not (any trigger)
# -- then NOOP

bt+ bNOOP, _return
# HA-HA I'M USING LOGIC

stb rFlags, xMemory(rParams)

_setup_hide_world:
lwz r3, 0x398(rCam)
oris r3, r3, 0x2000
# r3 = ORed flag will cause stage model to disappear

bf- bEnable, _setup_show_world
# if disabled, but ~bNOOP, then we need show the stage

bf+ bShowWorld, _setup_hide_bg
# if not showing world, then use ORed flag to inhibit drawing

  _setup_show_world:
  xoris r3, r3, 0x2000
  # r3 = OR -> XORed flag = absolute false

_setup_hide_bg:
oris r3, r3, 0x0400
bf- bEnable, _setup_show_bg
bf+ bShowBG, _set_cam_options

  _setup_show_bg:
  xoris r3, r3, 0x0400

_set_cam_options:
stw r3, 0x398(rCam)
# store resulting flag mask

_return:
addi    r3, r27, 0
.long 0


1.02 ------ 800304c8 --- 48338141 -> Branch
lis r0, <<simple_stage_geometry_params>>@h
ori r3, r0, <<simple_stage_geometry_params>>@l
bl <draw_simple_stage_geometry>
bl    0x80368608  # HSD_CObjEndCurrent
.long 0


<draw_simple_stage_geometry> 1.02
# r3 = colors and parameters

# registers:
.set rThis,   31  # current polygon
.set rLinks,  30  # base of link array
.set rVerts,  29  # base of vert array
.set rColors, 28  # base of custom colors array, and parameters
.set rCount,  27  # counter for facing groups loop
.set rRoot,   26  # address of current root link parameters for (facing groups)
.set rLink,   25  # current link, from links
.set rDesc,   24  # current link description, from link
.set rPrim1,  23
.set rPrim2,  22

.set rGX,    3
.set rColor, 4

# float registers:
.set fPolyMin, 4
.set fPolyMax, 5

# global r13 offsets:
.set xFirstActivePoly,  -0x51DC
.set xBaseOfLinksArray, -0x51E4
.set xBaseOfVertsArray, -0x51E8

# global rtoc offsets:
.set xZero, -0x7FBC

# color offsets:
.set xGroundColor,   0x00
.set xCeilColor,     0x04
.set xRightColor,    0x08
.set xLeftColor,     0x0C
.set xIceColor,      0x10
.set xLedgeColor,    0x14
.set xIntanColor,    0x18
.set xRegionColor,   0x1C
.set xFallthruColor, 0x20

# parameter offsets:
.set xLineWidth, 0x24
.set xFlags,     0x25
.set xMemory,    0x26

# polygon offsets
.set xPlyNext,  0x0
.set xPlyLinks, 0x4
.set xPlyFlags, 0x8
.set xPlyMin,   0x10
.set xPlyMax,   0x18

# polygon info offsets:
.set xRootLink,  0x0
.set xLinkCount, 0x2

# collision link offsets:
.set xLinkDesc,  0x0
.set xLinkClip,  0x4
.set xLinkBools, 0x6

# collision link description offsets:
.set xVert1, 0x0
.set xVert2, 0x2
.set xDescBools, 0xC
.set xDescMat,   0xF

# vertex offsets:
.set xCurrentXY, 0x8

# stack offsets:
.set xStackSize, 0x100
.set xQR7,       0x80
.set xGXsaved,   0x84
.set xAlphaPair, 0x88

# bools:
.set bEnable,      23
.set bShowDrawing, 22
.set bPolyRegions, 19
.set bIgnoreZ,     18
.set bLeft,  28
.set bRight, 29
.set bCeil,  30
.set bFloor, 31
.set bVertPass, 31

# masks:
.set mIntangible, 4
.set mFloor,       0x0001
.set mFallthrough, 0x0100
.set mLedge,       0x0200
.set mOmniFall,    0x0400

# Stage Collision Link Info (in File)
# -0x51EC(r13) - 804D64B4 = point to section of file
#
# 0x00  point  to Collision Link Vertex Array (in File)
# 0x04  word   Vertex Array size
# 0x08  point  to Collision Link Array (in File)
# 0x0C  word   Link Array Size


# Instantiated Collision Link Vertex
# -0x51E8(r13) - 804D64B8 - point to base of array
# (0x18 byte alignment)
#
# 0x00  float  Initial X position
# 0x04  float  Initial Y position
# 0x08  float  Current X position # can be poked live
# 0x0C  float  Current Y position
# 0x10  float  Previous X position
# 0x14  float  Previous Y position


# Instantiated Collision Link
# -0x51E4(r13) - 804D64BC = point to base of array
# (0x8 byte alignment)
#
# 0x0  point  to Collision Link (in File)
# 0x4  flags  short:
# 0x4  (0001) = collision link floor is active, and can be landed on
# 0x4  (0004) = temporarily disabled
# 0x6  flags  short:
# 0x6  (0001) = Link is a floor
# 0x6  (0002) = Link is a ceiling
# 0x6  (0004) = Link is a right wall
# 0x6  (0008) = Link is a left wall
# 0x6  (0010) = Link is omnidirectional (?)
# 0x6  (0100) = seems to be related to updating facing type for omnidirectional links

# this index appears to be ordered by facing type: floor, ceiling, right, left, omni


# Collision Link desc (in File)
# pointed to by instantiated links (0x0)
# (0x10 byte alignment)
#
# 0x0  short  Vertex ID 1  (these can be used to navigate vert array)
# 0x2  short  Vertex ID 2
# 0x4  short  Next Link ID (these can be used to navigate link array)
# 0x6  short  Prev Link ID
# 0x8  short  unk ID (these are usually FFFF for null)
# 0xA  short  unk ID
# 0xC  flags  short:
# 0xC  (0001) = enable collisions
# 0xC  (0004) = temporarily disable collisions?
#
# 0xE  flags  byte:
# 0xE  (01)   = Platform can be fallen through by holding down
# 0xE  (02)   = Link edge(s) may be used as a grabbable ledge
# 0xE  (04)   = Omnidirectional fallthrough platforms
# 0xF  byte   Material ID for link (causes SFX and Physics changes)


# Instantiated Collision Polygon
# -0x51E0(r13) - 804D64C0 = Base of array
# -0x51DC(r13) - 804D64C4 - First Active Stage Polygon
# -0x51D8(r13) - 804D64C8 - Last Active Stage Polygon
# (0x34 byte alignment)
#
# 0x00  point  Next Active Polygon
# 0x04  point  Polygon Link Info (in File)
#
# 0x08  flags  short:
# 0x08  (0001) enable polygon collisions  # these appear to globally set contained link flags
# 0x08  (0004) temporarily disable polygon collisions?
# 0x0A  flags  short:
# 0x0A  (0100) enable polygon?  # unknown
# 0x0A  (0200) animated polygon?  # see brinstar depths
# 0x0C  short  unknown counter, sometimes doesn't increment
# 0x0E  short  unknown flags, or unused padding
#
# 0x10  float  unknown X value  # these are related to attached joint in 0x20
# 0x14  float  unknown Y value  # possibly min/max?
# 0x18  float  unknown X2 value
# 0x1C  float  unknown Y2 value
#
# 0x20  point  Polygon Joint (JObj)
# 0x24  point  ECB Callback Function (runs once for every player standing on this polygon)
# 0x28  point  Stage GObj Data table (if GObj exists)
# 0x2C  point? unknown
# 0x30  point? these were null in all of my observations

# ---
#
# Polygon Link Info (in File)
# pointed to by Instantiated Collision Polygon (0x4)
# 0x00  short  Root Link ID  # floors
# 0x02  short  number of links
#
# 0x00  short  Root Link ID  # ceilings
# 0x02  short  number of links
#
# 0x00  short  Root Link ID   # right walls
# 0x02  short  number of links
#
# 0x00  short  Root Link ID  # left walls
# 0x02  short  number of links
#
# 0x00  short  Root Link ID  # omnidirectional
# 0x02  short  number of links



mflr r0
stw  r0, 0x4(sp)
stwu sp, -xStackSize(sp)
stmw r22, 0x10(sp)
# tons of stack and register room

mr rColors, r3
lhz r3, xFlags(rColors)
mtcrf 0x0C, r3
# load bools

bf- bEnable, _return
bf- bShowDrawing, _return
# if not enabled, then skip the rest of code

lbz r0, xLineWidth(rColors) # line width
li rPrim1, 0x1305         # params 1
li rPrim2, 0x1455         # params 2
rlwimi rPrim1, r0, 16, 0xFF0000  # insert line width param
bf+ bIgnoreZ, _finish_setup
  xori rPrim1, rPrim1, 0x1000
  # toggle argument bit if ignoring z buffer comparison

_finish_setup:
lwz rThis,  xFirstActivePoly(r13)
lwz rLinks, xBaseOfLinksArray(r13)
lwz rVerts, xBaseOfVertsArray(r13)
# rColors = index of user-specified RGBA colors
# rPoly = first active polygon
# rLinks = base of link array, 0x8 byte aligned
# rVerts = base of vert array, 0x18 byte aligned

bf- bPolyRegions, _setup_for_each_polygon2
lbz r0, xRegionColor+3(rColors)
cmpwi r0, 0
beq- _setup_for_each_polygon2
# if color alpha is 0 for region color, or flag is flase; then skip first pass

_for_each_polygon1:
  lhz r3, xPlyFlags(rThis)
  andi. r0, r3, mIntangible
  bne- _iter_polygons1

  li r3, 5              # vert count
  mr r4, rPrim1
  mr r5, rPrim2
  addi r4, r4, 1 # lines -> linestrip
  bl <prim.new>
  # r3 = GX pipe

  lwz rColor, xRegionColor(rColors)
  psq_l fPolyMin, xPlyMin(rThis),0,0
  lfs f3, -0x7FBC(rtoc)
  psq_l fPolyMax, xPlyMax(rThis),0,0
  ps_merge00 f1, fPolyMin, fPolyMin
  ps_merge11 f2, fPolyMin, fPolyMin
  bl <store_vert>
  ps_merge11 f2, fPolyMax, fPolyMax
  bl <store_vert>
  ps_merge00 f1, fPolyMax, fPolyMax
  bl <store_vert>
  ps_merge11 f2, fPolyMin, fPolyMin
  bl <store_vert>
  ps_merge00 f1, fPolyMin, fPolyMin
  bl <store_vert>
  # unknown box region envelopes polygon shape
  # drawn using given poly region color

  _iter_polygons1:
  lwz rThis, xPlyNext(rThis)
  cmpwi rThis, 0
  blt+ _for_each_polygon1


# first pass complete -- only poly regions have been (optionally) drawn
# now begin second pass, which is the actual geometry


_setup_for_each_polygon2:
lwz rThis, xFirstActivePoly(r13)
# we'll be going through each polygon again to draw contained links
# each polygon has up to 5 groups of links that represent possible facing orientations
# these reach into an array sorted by facing type

_for_each_polygon2:
  li rCount, 5
  lwz rRoot, xPlyLinks(rThis)
  # ready for facing groups loop

  _for_each_facing_group:
    lhz r0, xLinkCount(rRoot)
    slwi. r3, r0, 1
    beq+ _iter_facing_group_loop
    # ready to draw lines, unless number of lines = 0

      _if_group_contains_links:
      mr r4, rPrim1
      mr r5, rPrim2
      bl <prim.new>
      stw rGX, xGXsaved(sp)
      # stored GX Pipe hardware address in stack

      lhz r5, xRootLink(rRoot)
      addi r0, r5, -1
      slwi r5, r0, 3
      # r5 = index  for base of lwzu loop

      add rLink, rLinks, r5
      lhz r0, xLinkCount(rRoot)
      mtctr r0
      # ready for drawing loop

        _for_each_link_in_group:
          lwzu rDesc, 0x8(rLink)
          lhz  r0, xLinkBools(rLink)
          mtcrf 0b00000001, r0
          # bools loaded into volatile cr7
          # rLinks address updated

          bf+ bFloor, _check_for_ceiling
          # if this link is not a floor, check for ceiling type
          # else handle as a floor:

            _floor:
            _check_slipperyness:
            lbz r3, xDescMat(rDesc)
            # r3 = this link's material ID

            bl 0x800569ec  # $!_get_material_friction
            # returns f1 = material friction

            lwz rColor, xGroundColor(rColors)
            mr r10, rColor
            # default color for floor links
            # copy it to r10 for a later check

            psq_l f0, 0(sp),1,0  # generates 1.0
            ps_cmpo1 cr1, f1, f0
            bge+ cr1, _check_ledge
              lwz rColor, xIceColor(rColors)
              # if friction < 1.0, color with Ice color
              # save comparison for later in cr1

            _check_ledge:
            lwz r3, xDescBools(rDesc)
            rlwinm. r0, r3, 0, mLedge
            beq+ _check_if_intangible
              lwz rColor, xLedgeColor(rColors)
              b _check_if_intangible
              # if ledge, then prioritize displaying ledge color
            # all floor conditions have been checked for

          _check_for_ceiling:
          bf+ bCeil, _check_for_wall
            lwz rColor, xCeilColor(rColors)
            b _check_if_intangible
            # set ceiling color

          _check_for_wall:
          bf+ bLeft, _right_wall
            lwz rColor, xLeftColor(rColors)
            b _check_if_intangible
            # set wall left color

          _right_wall:
          lwz rColor, xRightColor(rColors)
          # else, set wall right color

          _check_if_intangible:
          lhz r3, xLinkClip(rLink)
          andi. r0, r3, mIntangible
          beq+ _draw_this_link
            lwz rColor, xIntanColor(rColors)
            # if link is intangible, then draw as intangible color

          _draw_this_link:
          lwz rGX, xGXsaved(sp)
          crclr bVertPass
          addi r12, rDesc, -2
          lfs f3, xZero(rtoc)
          mr r11, rColor
          # ready for vertex pair
          # r11 and r12 will be used for loop

          _for_each_vertex_in_link:
            lhzu r5, 0x2(r12)
            mulli r6, r5, 0x18
            addi r5, r6, xCurrentXY
            psq_lx f1, rVerts, r5,0,0
            ps_merge11 f2, f1, f1
            # f1, f2, f3 = X, Y, Z
            # r3 = GX
            # r4 = color


            _check_fallthrough_flag:
            lwz r0, xDescBools(rDesc)
            andi. r5, r0, mFallthrough | mOmniFall
            beq _commit_to_vertex
            # if not a fallthrough platform, draw at full alpha

              lhz r5, xLinkBools(rLink)
              andi. r6, r5, mFloor
              bne- _check_fallthrough_color
                lwz rColor, xIntanColor(rColors)
                b _commit_to_vertex
                # if fallthrough and not floor (because of omni)
                # then set color to intangible

              _check_fallthrough_color:
              # at this point, we know it's a fallthrough platform
              # but we want to prioritize any assigned colors besides default ground

              cmpw r10, rColor
              lwz r0, xFallthruColor(rColors)
              mullw r0, rColor, r0
              rlwimi rColor, r0, 24, 0xFF
              # crudely combine existing RGBA with the alpha of fallthrough color
              # -- this may cause the alpha to be very low if both colors are transparent

              bne- _commit_to_vertex
                lwz rColor, xFallthruColor(rColors)
                # if this is just a regular fallthrough platform, give it a unique color

            _commit_to_vertex:
            bl <store_vert>
            bt- bVertPass, _iter_link_loop
            # vertex has been written to GX pipe
            # if this is only the first vertex pass, then continue vertex loop
            # else, exit and continue link loop

              crnot bVertPass, bVertPass
              b _for_each_vertex_in_link
              # invert bVertPass bool so that this only iterates once before terminating

          _iter_link_loop:
          bdnz+ _for_each_link_in_group
          # exhaust ctr to finish writing all promised link vertices to GX

    _iter_facing_group_loop:
    subic. rCount, rCount, 1
    addi rRoot, rRoot, 4
    bgt+ _for_each_facing_group
    # iterate to next ECB facing group, if decremented count is not 0

  _iter_polygons2:
  lwz rThis, xPlyNext(rThis)
  cmpwi rThis, 0
  blt+ _for_each_polygon2
  # terminate if next polygon is inactive

_end_drawing:
bl <prim.close>

_return:
lmw r22, 0x10(sp)
addi sp, sp, xStackSize
lwz r0, 0x4(sp)
mtlr r0
blr



<store_vert>
# r3 = GX fifo
# r4 = color
# f1...f3 = XYZ
stfs f1, 0(r3)
stfs f2, 0(r3)
stfs f3, 0(r3)
stw  r4, 0(r3)
blr

1.02 ----- 0x802EAA38 --- C822DE80 -> C82280A0
1.02 ----- 0x802E8D68 --- C862DE80 -> C86280A0
1.02 ----- 0x804DD860 --- 4330000080000000 -> 0010130300001455
1.02 ----- 0x800c2684 ----
38600001 38800004 38a00005 38c00005
->
57E3A7BE 57E4C77E 57E5E77E 57E6073E
1.02 ----- 0x800c26b0 ----
38600001 38800003 38A00000
->
57C3A7FE 57C4C77E 57C5AFFE
1.02 ----- 0x800c26c0 --- 38600000 -> 57C39FFE
1.02 ----- 0x800c272c --- 38600000 -> 57C317BE
<prim.setup> 1.02
7C0802A6 90010004 9421C000 BFC10010 7C7E1B78 7C9F2378 38600001
b 0x800c2678
<prim.setup2> 1.02
7C0802A6 90010004 9421C000
bl 0x8033C3C8
b 0x800c2d40
<projection_return> 1.02
38214000 80010004 7C0803A6 4E800020
1.02 ----- 0x800c2da0 --- 38b80001 -> b <projection_return>
1.02 ----- 0x800c2674 --- 38600001 -> b <prim.setup_projection>
<prim.setup_projection> 1.02
8062DE80 8082DE84
bl <prim.setup>
881C2101
b 0x800c2738
1.02 ----- 0x800c2734 --- 881c2101 -> b <prim.setup_projection_epilog>
<prim.setup_projection_epilog> 1.02
BBC10010
b <projection_return>
1.02 ----- 0x800c2d3c --- 4827968d -> b <prim.setup2_projection>
<prim.setup2_projection> 1.02
bl <prim.setup2>
38B80001
b 0x800c2da4
1.02 ----- 0x802E8B48 --- C822DE68 -> C82280A0
1.02 ----- 0x804DD848 --- 43300000 -> b <prim.close>
<prim.close> 1.02
3860FFFF
b 0x80361fc4
1.02 ----- 0x804DD84C --- 80000000 -> b <prim.new>
<prim.new> 1.02
7C0802A6 90010004 9421FFC0 BFA10010 7C7E1B78 7C9F2378 7C832378 7CA42B78
bl <prim.setup>
bl <prim.setup2>
57E3063E 2C030005 41A00024 2C030007 4181001C 57E385BE 38800005 4182000C
bl 0x8033D240
48000008
bl 0x8033d298
57E31E38 38630080 38800000 57C5043E
bl 0x8033D0DC
3C60CC01 38638000 BBA10010 38210040 80010004 7C0803A6 4E800020
#
This gecko code uses the PRIM LITE mastercode, which is included below:

Code:
$PRIM LITE 1.1 Mastercode [Punkline]
C20C2684 00000003
57E3A7BE 57E4C77E
57E5E77E 57E6073E
60000000 00000000
040c2688 4800000C
040c26b0 57C3A7FE
040c26b4 57C4C77E
040c26b8 57C5AFFE
040c26c0 57C39FFE
040c272c 57C317BE
C20C268C 00000006
7C0802A6 90010004
9421C000 BFC10010
7C7E1B78 7C9F2378
3C00800C 38600001
60002678 7C0903A6
4E800420 00000000
C20C2690 00000006
7C0802A6 90010004
9421C000 3C008033
6000C3C8 7C0803A6
4E800021 3C00800C
60002D40 7C0903A6
4E800420 00000000
C20C2DA0 00000003
38214000 80010004
7C0803A6 4E800020
60000000 00000000
042EAA38 C82280A0
042E8D68 C86280A0
044DD860 00101303
044DD864 00001455
C20C2674 00000006
8062DE80 8082DE84
3C00800C 6000268C
7C0803A6 4E800021
3C00800C 60002738
7C0903A6 881C2101
4E800420 00000000
C20C2734 00000003
BBC10010 38214000
80010004 7C0803A6
4E800020 00000000
C20C2D3C 00000005
3C00800C 60002690
7C0803A6 4E800021
38B80001 3C00800C
60002DA4 7C0903A6
4E800420 00000000
042E8B48 C82280A0
C24DD848 00000003
3C008036 60031FC4
7C6903A6 3860FFFF
4E800420 00000000
C24DD84C 00000019
7C0802A6 90010004
9421FFC0 BFA10010
7C7E1B78 7C9F2378
7C832378 7CA42B78
3C00800C 6000268C
7C0803A6 4E800021
3C00800C 60002690
7C0803A6 4E800021
57E3063E 2C030005
41A0003C 2C030007
41810034 57E385BE
38800005 41820018
3C008033 6000D240
7C0803A6 4E800021
48000014 3C008033
6000D298 7C0803A6
4E800021 57E31E38
38630080 38800000
57C5043E 3C008033
6000D0DC 7C0803A6
4E800021 3C60CC01
38638000 BBA10010
38210040 80010004
7C0803A6 4E800020
60000000 00000000

$Simple Stage Geometry 2.0 [Punkline]
C2401800 00000006
4E800021 E5E5E5FF
635C66FF 635C66FF
635C66FF 00FFE5FF
F02040FF 26211360
408040C0 A08040C0
10030000 00000000
C20301F0 00000011
3C008040 60001800
7C0803A6 4E800021
7D8802A6 3D608048
816B9D60 2C0B0001
890C0025 892C0026
7D004378 7D0A4A78
40A20008 394000FF
51402636 7C003120
4FDFD842 4C19C382
4C00DB82 4FDE0342
41BE0030 990C0026
807C0398 64632000
409F0008 40BD0008
6C632000 64630400
409F0008 40BC0008
6C630400 907C0398
387B0000 00000000
C20304C8 00000007
3C008040 60001800
7C0803A6 4E800021
7C6802A6 3C008040
60001804 7C0803A6
4E800021 3C008036
60008608 7C0803A6
4E800021 00000000
C2401804 0000004C
7C0802A6 90010004
9421FF00 BEC10010
7C7C1B78 A07C0025
7C60C120 40970214
40960210 881C0024
3AE01305 3AC01455
5017821E 40B20008
6AF71000 83EDAE24
83CDAE1C 83ADAE18
40930084 881C001F
2C000000 41820078
A07F0008 70600004
40820060 38600005
7EE4BB78 7EC5B378
38840001 3C00804D
6000D84C 7C0803A6
4E800021 809C001C
E09F0010 C0628044
E0BF0018 10242420
104424E0 480001A9
10452CE0 480001A1
10252C20 48000199
104424E0 48000191
10242420 48000189
83FF0000 2C1F0000
4180FF90 83EDAE24
3B600005 835F0004
A01A0002 5403083D
41A20128 7EE4BB78
7EC5B378 3C00804D
6000D84C 7C0803A6
4E800021 90610084
A0BA0000 3805FFFF
54051838 7F3E2A14
A01A0002 7C0903A6
87190008 A0190006
7C001120 40BF0044
8878000F 3C008005
600069EC 7C0803A6
4E800021 809C0000
7C8A2378 E0018000
108100C0 40A40008
809C0010 8078000C
546005AD 41A20028
809C0014 48000020
40BE000C 809C0004
48000014 40BC000C
809C000C 48000008
809C0008 A0790004
70600004 41A20008
809C0018 80610084
4FFFF982 3998FFFE
C0628044 7C8B2378
A4AC0002 1CC50018
38A60008 103D280C
10410CE0 8018000C
70050500 41820030
A0B90006 70A60001
4082000C 809C0018
4800001C 7C0A2000
801C0020 7C0401D6
5004C63E 40820008
809C0020 48000051
419F000C 4FFFF842
4BFFFFA8 4200FF14
377BFFFF 3B5A0004
4181FEC8 83FF0000
2C1F0000 4180FEB4
3C00804D 6000D848
7C0803A6 4E800021
BAC10010 38210100
80010004 7C0803A6
4E800020 D0230000
D0430000 D0630000
90830000 4E800020
60000000 00000000





You can customize the default colors and a few other settings from the <simple_stage_geometry_params> function through the edit button in MCM.
Other codes can also access this function with the absolute <<RAM>> placeholder syntax to create toggles.

  • Each color can be given a custom alpha value through the AA byte in each corresponding RRGGBBAA value.
    • Any color with 0% alpha will become totally transparent, and effectively hidden.
  • Left walls, right walls, and ceilings may be given unique colors.
    • They are all the same color by default.
  • Intangible collision links that have been temporarily hidden (like breakable blocks) are given a unique color.
    • Omni-directional fallthrough platforms that are not at "floor" angles will be also be considered intangible.
    • Disabled polygons are not displayed, such as those in hidden pokemon stage transformations.
  • Grab-able ledges are given a unique color.
    • These are defined as a pair of vertices, so they must be illustrated as lines instead of points.
  • Floors with a friction less than 100% are deemed “slippery” or "ice", and are drawn with a unique color.
  • Line thickness is not affected by camera perspective.
    • The absolute thickness can be modified.

6 boolean flags can be set to TRUE or FALSE.
Only the highlighted ones are true by default:

+01 = toggle the whole code on/off
+02 = draw line geometry
+04 = show world GObj displays
+08 = show background color changes
+10 = include stage polygon region boxes when drawing geometry
+20 = draw lines on top of models (ignore Z)



The World GObj and Background Color toggles should be set together. I kept them as separate flags because they interact with some of the developer mode camera flags, and it might be necessary to enable or disable one or the other for compatibility with other codes. Toggling these should have minimal impact on vanilla devmode flag functionality.

Currently, these options have no effect on a few of the particle effects used in certain stages. This may change in a future update.


The Ignore Z option lets you see the stage lines regardless of what model geometry might be occluding them. If toggled on, it goes well with the toggle world/background flags:




Stage polygon regions can be toggled on, but are kept off by default to avoid distracting players:

 
Last edited:

schmooblidon

Smash Journeyman
Joined
Feb 18, 2014
Messages
496
This looks awesome. Unfortunately I can't turn on the ECB without turning on the old vanilla collision planes. Is there some way I can fix this?

Edit: Ah I found your isolated ECB code, which looks sick btw. Cant get it to work together with this code though :/
 
Last edited:

Punkline

Dr. Frankenstack
Joined
May 15, 2015
Messages
423
This looks awesome. Unfortunately I can't turn on the ECB without turning on the old vanilla collision planes. Is there some way I can fix this?

Edit: Ah I found your isolated ECB code, which looks sick btw. Cant get it to work together with this code though :/
IIRC, both this code and the ECB code use the same hook. This is unfortunately a problem with drawing codes like this, since useful injection points are slim pickings -- however I'm experimenting with a GObj-based solution for giving codes like this their own callback events to handle the GX routine, making it so they won't conflict.

I'll tag you when I have some updates available.
 
Top Bottom