Punkline
Dr. Frankenstack
- Joined
- May 15, 2015
- Messages
- 423
Update 04/28/2019:
PRIM LITE is a new, tiny version of the Primitive Drawing Module that packs all of its punch into just two user-level functions. In less than 0x100 bytes, this module provides a means for drawing geometry to the screen by exploiting routines that already exist in the game for drawing sword trails. The simplified module interface now utilizes mytoc to create static addresses for its functions, and may be accessed from gecko codes.
PRIM LITE can also optionally be installed as a gecko “master code” in place of a DOL mod. Note that the gecko code is more than twice as large as the DOL mod (0x260 bytes) and will not provide named functions for MCM -- but it should otherwise be functionally identical, and useful for interfacing with fragile builds.
PRIM LITE 1.1
uses mytoc block 327, and 328
---
EXAMPLES:
- Simple Stage Geometry 2.0
- Sword Trail Blend Modes
---
HOW TO USE:
There are two user-level static functions in PRIM LITE.
They may be accessed from either a standalone function handle, or a static address.
One is for starting a new primitive:
rtoc - 0x2194 = 804DD84C = <prim.new>
The other safely ends drawing routines:
rtoc - 0x2198 = 804DD848 = <prim.close>
From MCM, you may call these using the special branch syntax:
From a gecko code (or any other format), you may call these using rtoc, or a literal address:
---
HOW TO DRAW PRIMITIVES:
Primitives will use the currently active HSD_CObj (camera object) to orient their location on the screen. Note that the "current" camera is changed multiple times per frame, and is not necessarily a reference to the main scene camera.
You can inject code into gx_link callbacks to hitch a ride on a desired drawing function that uses a camera of your choice; or you may set the camera yourself using HSD_CObjSetCurrent (80368458) before drawing. You can also check the currently active camera with HSD_CObjGetCurrent (8036a288), if you need to back it up. Each "camera" is referenced by the 32-bit address of its CObj.
You can call <prim.new> to open the gx up to reading vertex information. The function returns hardware address 0xCC008000 in r3 -- which is the gx_fifo pipe used for reading in a stream of geometry data from the game program.
You must store vertices at offset 0x0 of this hardware address, and use the same offset for each piece of information. This causes each piece of data to enter the pipe.
Store the following values to 0x0(r3) in a sequence to describe a vertex in the gx stream:
1 - floating point single = vertex X
2 - floating point single = vertex Y
3 - floating point single = vertex Z
4 - 32-bit UINT = RGBA color
When you have finished drawing your primitives, you must call <prim.close> before returning.
You may draw multiple primitives in a sequence with several <prim.new> calls before finally calling <prim.close>; however if you neglect to call it at least once at the end then the next time that the game tries to draw something, it may cause graphical errors and/or crashes.
---
This function takes its given argument values and uses them to set up a primitive/drawing type. It then opens a gx stream that will expect to be fed a specified number of vertices through the GX pipe. The address of the GX pipe is then returned in r3.
The long-form argument format of <prim.new> uses r3 to pass a vert count, and r4, r5 like a string containing several small int fields for specifying draw options:
r3 = vert count
r4 = params (cull mode, line/point size, z-buffer options, primitive type)
r5 = params (blending options)
Sword trails and 1-pixel (native) lines use the following argument values:
r3 = n
r4 = 0x00101303
r5 = 0x00001455
The above values will create standard primitive geometry that should obey the z-buffer logic in a way similar to sword trails.
Each value can be tweaked using any of the following options:
-- r4 -- -- r5 --
C0000000 00000000 = Cull Mode
03FF0000 00000000 = Line Width/Point Size
00002000 00000000 = Z Compare Timing
00001000 00000000 = Z Buffer Compare
00000800 00000000 = Z Buffer Update
00000700 00000000 = Z Buffer Comparison Logic
000000FF 00000000 = Primitive Type
00000000 00003000 = Blend Type
00000000 00000700 = Blend Source
00000000 00000070 = Blend Dest
00000000 0000000F = Blend Logic
examples of blend equation -- https://i.imgur.com/Qx6cuXX.png
examples of blend logic -- https://i.imgur.com/KnXNYYz.png
---
This function takes no arguments, and must be called before exiting your drawing routine.
It does not need to be called after every single <prim.new> stream finishes, but it does need to be called at least once before returning to the game program.
---
2018 LEGACY MODULE:
(depricated concept, supports legacy examples)
PRIM LITE is a new, tiny version of the Primitive Drawing Module that packs all of its punch into just two user-level functions. In less than 0x100 bytes, this module provides a means for drawing geometry to the screen by exploiting routines that already exist in the game for drawing sword trails. The simplified module interface now utilizes mytoc to create static addresses for its functions, and may be accessed from gecko codes.
PRIM LITE can also optionally be installed as a gecko “master code” in place of a DOL mod. Note that the gecko code is more than twice as large as the DOL mod (0x260 bytes) and will not provide named functions for MCM -- but it should otherwise be functionally identical, and useful for interfacing with fragile builds.
PRIM LITE 1.1
uses mytoc block 327, and 328
Code:
-==-
PRIM LITE 1.1
Primitive Drawing Module: LITE
rtoc - 0x2194 = 804DD84C = <prim.new>
rtoc - 0x2198 = 804DD848 = <prim.close>
rtoc - 0x2180 = 804DD860 = sword trail GX options
See ( https://smashboards.com/threads/primitive-drawing-module.454232/ ) for more info.
[Punkline]
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 - PRIM LITE 1.1
Primitive Drawing Module: LITE
rtoc - 0x2194 = 804DD84C = <prim.new>
rtoc - 0x2198 = 804DD848 = <prim.close>
rtoc - 0x2180 = 804DD860 = sword trail GX options
See ( https://smashboards.com/threads/primitive-drawing-module.454232/ ) for more info.
[Punkline]
1.02 ----- 0x802EAA38 --- C822DE80 -> C82280A0
1.02 ----- 0x802E8D68 --- C862DE80 -> C86280A0
1.02 ----- 0x804DD860 --- 4330000080000000 -> 0010130300001455
# mytoc block 328, 804DD860, -0x2180(rtoc), -0x217C(rtoc)
# = default sword trail GX params
# 00101303 00001455 = default values:
# C0000000 00000000 = Cull Mode
# +8 = cull backface
# +4 = cull frontface
# 03FF0000 00000000 = Line Width/Point Size
# 1/16 pixel increments; 0x2A8 maximum width
# -- does not apply to sword trails
# 00002000 00000000 = Compare Location
# +1 = z buffer compares before texturing
# 00001000 00000000 = Z Buffer Compare
# +1 = z buffer enables compare
# 00000800 00000000 = Z Buffer Update
# +1 = z buffer enables update
# 00000700 00000000 = Z Buffer Comparison Logic
# +4 = greater than
# +2 = equal to
# +1 = less than
# 000000FF 00000000 = Primitive Type
# 0 = quads
# 1 = --
# 2 = triangles
# 3 = trianglestrip
# 4 = trianglefan
# 5 = lines
# 6 = linestrip
# 7 = points
# 00000000 00003000 = Blend Type
# 0 = None
# 1 = Blend -- blend using blending equation
# 2 = Logic -- blend using bitwise operation
# 3 = Subtract -- input subtracts from existing pixel
# 00000000 00000700 = Blend Source
# 0 = zero -- 0.0
# 1 = one -- 1.0
# 2 = source color
# 3 = inverted source color
# 4 = source alpha
# 5 = inverted source alpha
# 6 = destination alpha
# 7 = inverted destination alpha
# 00000000 00000070 = Blend Dest
# (see above)
# 00000000 0000000F = Blend Logic
# 0 -- CLEAR; dst = 0
# 1 -- AND; dst = src & dst
# 2 -- REVAND; dst = src & ~dst
# 3 -- COPY; dst = src
# 4 -- INVAND; dst = ~src & dst
# 5 -- NOOP; dst = dst
# 6 -- XOR; dst = src ^ dst
# 7 -- OR; dst = src | dst
# 8 -- NOR; dst = ~(src | dst)
# 9 -- EQUIV; dst = ~(src ^ dst)
# A -- INV; dst = ~dst
# B -- REVOR; dst = src | ~dst
# C -- INVCOPY; dst = ~src
# D -- INVOR; dst = ~src | dst
# E -- NAND; dst = ~(src & dst)
# F -- SET; dst = 1
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
# these overwrites convert loaded immediates into rlwinms
# -- this allows the primitives to be drawn somewhat parametrically with prim.new
# -- injections allow for 2 static functions to be written, for gecko code support
<prim.setup> 1.02
# r3 = params 1 = C WWW ZZ PP (W is unused here)
# r4 = params 2 = ---- BBBB
# r30 and r31 are safe to use for projection duration
mflr r0
stw r0, 0x4(sp)
stwu sp, -0x4000(sp)
stmw r30, 0x10(sp)
mr r30, r3 # Static overwrite strings will create rlwinms that extract from r30 and r31.
mr r31, r4 # These will replace some hardcoded arguments made for GX function calls
li r3, 1 # original instruction; arg for GXSetColorUpdate
b 0x800c2678
<prim.setup2> 1.02
mflr r0
stw r0, 0x4(sp)
stwu sp, -0x4000(sp)
bl 0x8033C3C8 # GXClearVtxDesc -- original instruction
b 0x800c2d40
<projection_return> 1.02
addi sp, sp, 0x4000
lwz r0, 0x4(sp)
mtlr r0
blr
1.02 ----- 0x800c2da0 --- 38b80001 -> b <projection_return>
# projection end <prim.setup2>
1.02 ----- 0x800c2674 --- 38600001 -> b <prim.setup_projection>
<prim.setup_projection> 1.02
# -- projection start for <prim.setup>
# External prolog fabricates an interface for the
# purpose of creating parameters in the setup process:
# r3 r4
# C0000000 00000000 = r3 for GXSetCullMode
# 03FF0000 00000000 = (line width, or point size)
# 00002000 00000000 = r3 for GXSetCompLoc
# 00001000 00000000 = r3 for GXSetZMode
# 00000800 00000000 = r5 for GXSetZMode
# 00000700 00000000 = r4 for GXSetZMode
# 000000FF 00000000 = (primitive type)
# 00000000 00003000 = r3 for GXSetBlendMode
# 00000000 00000700 = r4 for GXSetBlendMode
# 00000000 00000070 = r5 for GXSetBlendMode
# 00000000 0000000F = r6 for GXSetBlendMode
# 00101303 00001455 = defaults
# each param is parsed by an rlwinm (see static overwrites)
# (line width and primite type are not parsed here)
lwz r3, -0x2180(rtoc)
lwz r4, -0x217C(rtoc)
# load sword trail parameters for natural trail drawing
# modifying these params will change the way sword trails are drawn
bl <prim.setup>
lbz r0, 0x2101 (r28) # repair INJ2 hook instruction externally
b 0x800c2738
1.02 ----- 0x800c2734 --- 881c2101 -> b <prim.setup_projection_epilog>
<prim.setup_projection_epilog> 1.02
# lbz r0, 0x2101 (r28)
lmw r30, 0x10(sp)
b <projection_return>
1.02 ----- 0x800c2d3c --- 4827968d -> b <prim.setup2_projection>
<prim.setup2_projection> 1.02
bl <prim.setup2>
addi r5, r24, 1
b 0x800c2da4
1.02 ----- 0x802E8B48 --- C822DE68 -> C82280A0
# Mytoc Block_327 -0x2198(rtoc)
1.02 ----- 0x804DD848 --- 43300000 -> b <prim.close>
<prim.close> 1.02
# rtoc - 0x2198 (804DD848)
li r3, -1
b 0x80361fc4
1.02 ----- 0x804DD84C --- 80000000 -> b <prim.new>
<prim.new> 1.02
# rtoc - 0x2194 (804DD84C)
# r3 = vert count
# r4 r5
# C0000000 00000000 = Cull Mode
# +8 = cull backface
# +4 = cull frontface
# 03FF0000 00000000 = Line Width/Point Size
# 1/16 pixel increments; 0x2A8 maximum width
# 00002000 00000000 = Compare Location
# +1 = z buffer compares before texturing
# 00001000 00000000 = Z Buffer Compare
# +1 = z buffer enables compare
# 00000800 00000000 = Z Buffer Update
# +1 = z buffer enables update
# 00000700 00000000 = Z Buffer Comparison Logic
# +4 = greater than
# +2 = equal to
# +1 = less than
# 000000FF 00000000 = Primitive Type
# 0 = quads
# 1 = --
# 2 = triangles
# 3 = trianglestrip
# 4 = trianglefan
# 5 = lines
# 6 = linestrip
# 7 = points
# 00000000 00003000 = Blend Type
# 0 = None
# 1 = Blend -- blend using blending equation
# 2 = Logic -- blend using bitwise operation
# 3 = Subtract -- input subtracts from existing pixel
# 00000000 00000700 = Blend Source
# 0 = zero -- 0.0
# 1 = one -- 1.0
# 2 = source color
# 3 = inverted source color
# 4 = source alpha
# 5 = inverted source alpha
# 6 = destination alpha
# 7 = inverted destination alpha
# 00000000 00000070 = Blend Dest
# (see above)
# 00000000 0000000F = Blend Logic
# 0 -- CLEAR; dst = 0
# 1 -- AND; dst = src & dst
# 2 -- REVAND; dst = src & ~dst
# 3 -- COPY; dst = src
# 4 -- INVAND; dst = ~src & dst
# 5 -- NOOP; dst = dst
# 6 -- XOR; dst = src ^ dst
# 7 -- OR; dst = src | dst
# 8 -- NOR; dst = ~(src | dst)
# 9 -- EQUIV; dst = ~(src ^ dst)
# A -- INV; dst = ~dst
# B -- REVOR; dst = src | ~dst
# C -- INVCOPY; dst = ~src
# D -- INVOR; dst = ~src | dst
# E -- NAND; dst = ~(src & dst)
# F -- SET; dst = 1
mflr r0
stw r0, 0x4(sp)
stwu sp, -0x40(sp)
stmw r29, 0x10(sp)
mr r30, r3 # save r3 and r4 for after projection calls
mr r31, r4 #
mr r3, r4 # r3 = params 1
mr r4, r5 # r4 = params 2
bl <prim.setup> # set up params
bl <prim.setup2> # set up mtx
rlwinm r3, r31, 0, 0xFF # r3 = primitive ID
cmpwi r3, 5 # if it's larger than
blt+ _end_width_handle
cmpwi r3, 7
bgt- _end_width_handle
rlwinm r3, r31, 16, 0x03FF
li r4, 5
beq- _point_handle
_width_handle: # exclusively for lines and linestrips
bl 0x8033D240
b _end_width_handle
_point_handle: # exclusively for points
bl 0x8033d298
_end_width_handle:
rlwinm r3, r31, 3, 0x000000F8
addi r3, r3, 0x80 # r3 is now a primitive ID that can be fed to GXBegin
li r4, 0 # use vtx format 0
rlwinm r5, r30, 0, 0xFFFF # use N number of vertices
bl 0x8033D0DC
lis r3, 0xCC01
addi r3, r3, -0x8000 # r3 = address of hardware FIFO stack
# write vertex(X, Y, Z, C) to address in r3
# each write must be to the exact same address
lmw r29, 0x10(sp)
addi sp, sp, 0x40
lwz r0, 0x4(sp)
mtlr r0
blr
$PRIM LITE 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
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
---
EXAMPLES:
- Simple Stage Geometry 2.0
- Sword Trail Blend Modes
---
HOW TO USE:
There are two user-level static functions in PRIM LITE.
They may be accessed from either a standalone function handle, or a static address.
One is for starting a new primitive:
rtoc - 0x2194 = 804DD84C = <prim.new>
The other safely ends drawing routines:
rtoc - 0x2198 = 804DD848 = <prim.close>
From MCM, you may call these using the special branch syntax:
Code:
bl <prim.new>
From a gecko code (or any other format), you may call these using rtoc, or a literal address:
Code:
addi r0, rtoc, -0x2194
mtlr r0
blrl
---
HOW TO DRAW PRIMITIVES:
Primitives will use the currently active HSD_CObj (camera object) to orient their location on the screen. Note that the "current" camera is changed multiple times per frame, and is not necessarily a reference to the main scene camera.
You can inject code into gx_link callbacks to hitch a ride on a desired drawing function that uses a camera of your choice; or you may set the camera yourself using HSD_CObjSetCurrent (80368458) before drawing. You can also check the currently active camera with HSD_CObjGetCurrent (8036a288), if you need to back it up. Each "camera" is referenced by the 32-bit address of its CObj.
You can call <prim.new> to open the gx up to reading vertex information. The function returns hardware address 0xCC008000 in r3 -- which is the gx_fifo pipe used for reading in a stream of geometry data from the game program.
You must store vertices at offset 0x0 of this hardware address, and use the same offset for each piece of information. This causes each piece of data to enter the pipe.
Store the following values to 0x0(r3) in a sequence to describe a vertex in the gx stream:
1 - floating point single = vertex X
2 - floating point single = vertex Y
3 - floating point single = vertex Z
4 - 32-bit UINT = RGBA color
When you have finished drawing your primitives, you must call <prim.close> before returning.
You may draw multiple primitives in a sequence with several <prim.new> calls before finally calling <prim.close>; however if you neglect to call it at least once at the end then the next time that the game tries to draw something, it may cause graphical errors and/or crashes.
---
<prim.new>
rtoc -0x2194
804DD84C
rtoc -0x2194
804DD84C
This function takes its given argument values and uses them to set up a primitive/drawing type. It then opens a gx stream that will expect to be fed a specified number of vertices through the GX pipe. The address of the GX pipe is then returned in r3.
The long-form argument format of <prim.new> uses r3 to pass a vert count, and r4, r5 like a string containing several small int fields for specifying draw options:
r3 = vert count
r4 = params (cull mode, line/point size, z-buffer options, primitive type)
r5 = params (blending options)
Sword trails and 1-pixel (native) lines use the following argument values:
r3 = n
r4 = 0x00101303
r5 = 0x00001455
The above values will create standard primitive geometry that should obey the z-buffer logic in a way similar to sword trails.
Each value can be tweaked using any of the following options:
-- r4 -- -- r5 --
C0000000 00000000 = Cull Mode
+8 = cull backface
+4 = cull frontface
03FF0000 00000000 = Line Width/Point Size
unit = 1/16 pixels; 0x2A8 maximum width
00002000 00000000 = Z Compare Timing
+2 = z buffer compares before texturing
00001000 00000000 = Z Buffer Compare
+1 = z buffer enables compare
00000800 00000000 = Z Buffer Update
+8 = z buffer enables update
00000700 00000000 = Z Buffer Comparison Logic
+4 = greater than
+2 = equal to
+1 = less than
000000FF 00000000 = Primitive Type
0 = quads
1 = --
2 = triangles
3 = trianglestrip
4 = trianglefan
5 = lines
6 = linestrip
7 = points
00000000 00003000 = Blend Type
0 = None
1 = Blend -- blend using blending equation
2 = Logic -- blend using bitwise operation
3 = Subtract -- input subtracts from existing pixel
00000000 00000700 = Blend Source
0 = zero -- 0.0
1 = one -- 1.0
2 = source color
3 = inverted source color
4 = source alpha
5 = inverted source alpha
6 = destination alpha
7 = inverted destination alpha
00000000 00000070 = Blend Dest
(see above key)
00000000 0000000F = Blend Logic
0 = CLEAR; --- dst = 0
1 = AND; ----- dst = src & dst
2 = REVAND; -- dst = src & ~dst
3 = COPY; ---- dst = src
4 = INVAND; -- dst = ~src & dst
5 = NOOP; ---- dst = dst
6 = XOR; ----- dst = src ^ dst
7 = OR; ------ dst = src | dst
8 = NOR; ----- dst = ~(src | dst)
9 = EQUIV; --- dst = ~(src ^ dst)
A = INV; ----- dst = ~dst
B = REVOR; --- dst = src | ~dst
C = INVCOPY; - dst = ~src
D = INVOR; --- dst = ~src | dst
E = NAND; ---- dst = ~(src & dst)
F = SET; ----- dst = 1
examples of blend equation -- https://i.imgur.com/Qx6cuXX.png
examples of blend logic -- https://i.imgur.com/KnXNYYz.png
---
<prim.close>
rtoc -0x2198
804DD848
rtoc -0x2198
804DD848
This function takes no arguments, and must be called before exiting your drawing routine.
It does not need to be called after every single <prim.new> stream finishes, but it does need to be called at least once before returning to the game program.
---
2018 LEGACY MODULE:
(depricated concept, supports legacy examples)
From 04/15/2018:
This MCM module recycles parts of the sword trail drawing function using a couple of projection mods. The resulting functions have been used to create a light-weight library that allows developers to draw various primitive types.
To make use of the functions in this library, install the DOL mod with the latest version of Melee Code Manager.
---
Example codes:
- Nibble Printer POC 0.1
- ECB Anchor Test 2
- ECB Anchor Test 1
- Player JObj tracer
- Colored Player Skeletons
---
With this module installed, developers can make use of the following functions for the purpose of drawing to the current camera coordiantes:
bl <prim_quads>
# draw a series of individual quadrilateral 4-point polygons
bl <prim_triangles>
# draw a series of individual triangle 3-point polygons
bl <prim_trianglestrip>
# draw a contiguous strip of connecting 3-point triangles that share an edge for each connection in the sequence.
bl <prim_trianglefan>
# draw a triangle strip where one side of the strip circles around a central vertex
bl <prim_lines>
# draw a series of individual lines using 2 points per line. Line width is the same for each line in the series.
bl <prim_linestrip>
# draw a contiguous strip of connecting 2-point lines
bl <prim_points>
# draw a series of individual points, using single vertices. Point size is the same for each point in the series.
Each of the above functions only require the argument:
r3 = number of vertices
When the function returns, you may use the address returned in r3 to store vertices.
note - when storing vertex information, all data goes to the exact same address; 0(r3)
To describe a vertex, store the following values to 0(r3) in a sequence:
1 - floating point single = vertex X
2 - floating point single = vertex Y
3 - floating point single = vertex Z
4 - 32-bit UINT = RGBA color
---
The following two functions can be called without arguments:
bl <prim_close>
# use this at the end of your drawing to prevent params from corrupting the next GFX drawing in the game
bl <prim_toggle_z>
# use this before starting a primitive to toggle the zbuffer comparison on or off. If off, primitives will be drawn on top of other geometry. On by default.
---
The above primitive functions all use the following functions with a set of default parameters. These functions require you to specify more parameters, but give you much more power over how each polygon is drawn.
Advanced Functions:
This MCM module recycles parts of the sword trail drawing function using a couple of projection mods. The resulting functions have been used to create a light-weight library that allows developers to draw various primitive types.
To make use of the functions in this library, install the DOL mod with the latest version of Melee Code Manager.
Code:
-==-
Primitive Drawing Module
Use included functions to send GX FIFO stack vertex information for drawing primitives.
See ( https://smashboards.com/threads/primitive-drawing-module.454232/ ) for more info.
[Punkline]
1.02 ----- 0x800c2684 --- 386000013880000438a0000538c00005 -> 57E3A7BE 57E4C77E 57E5E77E 57E6073E
1.02 ----- 0x800c26b0 --- 386000013880000338a00000 ->57C3A7FE 57C4C77E 57C5AFFE
1.02 ----- 0x800c26c0 --- 38600000 -> 57C39FFE
1.02 ----- 0x800c272c --- 38600000 -> 57C317BE
1.02 ----- 0x800c2da0 --- 38b80001 -> branch
b <projection_return>
00000000
1.02 ----- 0x800c2674 --- 38600001 -> branch
bl <prim_default_swordtrails>
7C8802A6 7C6444AA
bl <prim_setup>
881C2101
b 0x800c2738
60000000
1.02 ----- 0x800c2734 --- 881c2101 -> branch
BBC10010
b <projection_return>
60000000
1.02 ----- 0x800c2d3c --- 4827968d -> branch
bl <prim_mtx_setup>
38B80001
b 0x800c2da4
60000000
<prim_setup> 1.02
7C0802A6 90010004 9421C000 BFC10010 7C7E1B78 7C9F2378 38600001
b 0x800c2678
<prim_mtx_setup> 1.02
7C0802A6 90010004 9421C000
bl 0x8033C3C8
b 0x800c2d40
<projection_return> All
38214000 80010004 7C0803A6 4E800020
<GXBegin> 1.02
b 0x8033D0DC
<GXSetLineWidth> 1.02
b 0x8033D240
<GXSetPointSize> 1.02
b 0x8033d298
<prim_close> 1.02
3860FFFF
b 0x80361fc4
<prim_main> All
7C0802A6 90010004 9421FFF8
bl <prim_defaults>
7D0802A6 80A80000 7C842B78 80A80004 3CC00010 60C61300 38E01455 7CC845AA
bl <prim_main_parametric>
38210008 80010004 7C0803A6 4E800020
<prim_main_parametric> All
7C0802A6 90010004 9421FFC0 BFA10010 7C7E1B78 7C9F2378 7C832378 7CA42B78
bl <prim_setup>
bl <prim_mtx_setup>
57E3063E 2C030005 41A00024 2C030007 4181001C 57E385BE 38800005 4182000C
bl <GXSetLineWidth>
48000008
bl <GXSetPointSize>
57E31E38 38630080 38800000 57C5043E
bl <GXBegin>
3C60CC01 38638000 BBA10010 38210040 80010004 7C0803A6 4E800020
<prim_quads> All
38800000
b <prim_main>
<prim_triangles> All
38800002
b <prim_main>
<prim_trianglestrip> All
38800003
b <prim_main>
<prim_trianglefan> All
38800004
b <prim_main>
<prim_lines> All
38800005
b <prim_main>
<prim_linestrip> All
38800006
b <prim_main>
<prim_points> All
38800007
b <prim_main>
<prim_defaults>
4E800021 00101300 00001455
<prim_default_swordtrails>
4E800021 00101300 00001455
<prim_toggle_z>
7C0802A6 90010004 9421FFF8
bl <prim_defaults>
7C6802A6 80830000 68841000 90830000 38210008 80010004 7C0803A6 4E800020
Code:
-==-
!
ASM - Primitive Drawing Module
Use included functions to send GX FIFO stack vertex information for drawing primitives.
See ( https://smashboards.com/threads/primitive-drawing-module.454232/ ) for more info.
[Punkline]
1.02 ----- 0x800c2684 --- 386000013880000438a0000538c00005 -> 57E3A7BE 57E4C77E 57E5E77E 57E6073E
1.02 ----- 0x800c26b0 --- 386000013880000338a00000 ->57C3A7FE 57C4C77E 57C5AFFE
1.02 ----- 0x800c26c0 --- 38600000 -> 57C39FFE
1.02 ----- 0x800c272c --- 38600000 -> 57C317BE
# these overwrites convert loaded immediates into rlwinms
# -- this allows the primitives to be drawn somewhat parametrically
1.02 ----- 0x800c2da0 --- 38b80001 -> branch
# projection end <prim_mtx_setup>
b <projection_return>
.long 0
1.02 ----- 0x800c2674 --- 38600001 -> branch
# -- projection start for <prim_setup>
# External prolog fabricates an interface for the
# purpose of creating parameters in the setup process:
# r3 r4
# C0000000 00000000 = r3 for GXSetCullMode
# 03FF0000 00000000 = (line width, or point size)
# 00002000 00000000 = r3 for GXSetCompLoc
# 00001000 00000000 = r3 for GXSetZMode
# 00000800 00000000 = r5 for GXSetZMode
# 00000700 00000000 = r4 for GXSetZMode
# 000000FF 00000000 = (primitive type)
# 00000000 00003000 = r3 for GXSetBlendMode
# 00000000 00000700 = r4 for GXSetBlendMode
# 00000000 00000070 = r5 for GXSetBlendMode
# 00000000 0000000F = r6 for GXSetBlendMode
# 00101303 00001455 = defaults
# each paraam is parsed by an rlwinm (see static overwrites)
# (line width and primite type are not parsed here)
bl <prim_default_swordtrails>
mflr r4
lswi r3, r4, 0x8
# load sword trail parameters for natural trail drawing
# modifying these params will change the way sword trails are drawn
bl <prim_setup>
lbz r0, 0x2101 (r28) # repair INJ2 hook instruction externally
b 0x800c2738
nop
1.02 ----- 0x800c2734 --- 881c2101 -> branch
# projection end <prim_setup>
# lbz r0, 0x2101 (r28)
lmw r30, 0x10(sp)
b <projection_return>
nop
1.02 ----- 0x800c2d3c --- 4827968d -> branch
# projection start <prim_mtx_setup>
bl <prim_mtx_setup>
addi r5, r24, 1
b 0x800c2da4
nop
<prim_setup> 1.02
# projection handle
# r3 = params 1 = C WWW ZZ PP (W is unused here)
# r4 = params 2 = ---- BBBB
# r30 and r31 are safe to use for projection duration
mflr r0
stw r0, 0x4(sp)
stwu sp, -0x4000(sp)
stmw r30, 0x10(sp)
mr r30, r3 # Static overwrite strings will create rlwinms that extract from r30 and r31.
mr r31, r4 # These will replace some hardcoded arguments made for GX function calls
li r3, 1 # original instruction; arg for GXSetColorUpdate
b 0x800c2678
<prim_mtx_setup> 1.02
# projection handle
mflr r0
stw r0, 0x4(sp)
stwu sp, -0x4000(sp)
bl 0x8033C3C8 # GXClearVtxDesc -- original instruction
b 0x800c2d40
<projection_return> All
# reusable return function
addi sp, sp, 0x4000
lwz r0, 0x4(sp)
mtlr r0
blr
<GXBegin> 1.02
b 0x8033D0DC # portable function call
<GXSetLineWidth> 1.02
b 0x8033D240
<GXSetPointSize> 1.02
b 0x8033d298
<prim_close> 1.02
li r3, -1
b 0x80361fc4
<prim_main> All
# r3 = vert count
# r4 = primitive type
mflr r0
stw r0, 0x4(sp)
stwu sp, -0x8(sp)
bl <prim_defaults>
mflr r8
lwz r5, 0(r8)
or r4, r4, r5
lwz r5, 4(r8)
# load params
lis r6, 0x0010
ori r6, r6, 0x1300
li r7, 0x1455
stswi r6, r8, 0x8
# reset params to default for next draw
bl <prim_main_parametric>
_return:
addi sp, sp, 8
lwz r0, 0x4(sp)
mtlr r0
blr
<prim_main_parametric> All
# r3 = vert count
# r4 r5
# C0000000 00000000 = Cull Mode
# +8 = cull backface
# +4 = cull frontface
# 03FF0000 00000000 = Line Width/Point Size
# 1/16 pixel increments; 0x2A8 maximum width
# 00002000 00000000 = Compare Location
# +1 = z buffer compares before texturing
# 00001000 00000000 = Z Buffer Compare
# +1 = z buffer enables compare
# 00000800 00000000 = Z Buffer Update
# +1 = z buffer enables update
# 00000700 00000000 = Z Buffer Comparison Logic
# +4 = greater than
# +2 = equal to
# +1 = less than
# 000000FF 00000000 = Primitive Type
# 0 = quads
# 1 = --
# 2 = triangles
# 3 = trianglestrip
# 4 = trianglefan
# 5 = lines
# 6 = linestrip
# 7 = points
# 00000000 00003000 = Blend Type
# 0 = None
# 1 = Blend -- blend using blending equation
# 2 = Logic -- blend using bitwise operation
# 3 = Subtract -- input subtracts from existing pixel
# 00000000 00000700 = Blend Source
# 0 = zero -- 0.0
# 1 = one -- 1.0
# 2 = source color
# 3 = inverted source color
# 4 = source alpha
# 5 = inverted source alpha
# 6 = destination alpha
# 7 = inverted destination alpha
# 00000000 00000070 = Blend Dest
# (see above)
# 00000000 0000000F = Blend Logic
# 0 -- CLEAR; dst = 0
# 1 -- AND; dst = src & dst
# 2 -- REVAND; dst = src & ~dst
# 3 -- COPY; dst = src
# 4 -- INVAND; dst = ~src & dst
# 5 -- NOOP; dst = dst
# 6 -- XOR; dst = src ^ dst
# 7 -- OR; dst = src | dst
# 8 -- NOR; dst = ~(src | dst)
# 9 -- EQUIV; dst = ~(src ^ dst)
# A -- INV; dst = ~dst
# B -- REVOR; dst = src | ~dst
# C -- INVCOPY; dst = ~src
# D -- INVOR; dst = ~src | dst
# E -- NAND; dst = ~(src & dst)
# F -- SET; dst = 1
_macros:
.macro countShift m, c
# countShift = recursive macro updates symbol "maskShift"
# maskShift = number of 0 bits padding first mask bit (from right to left)
# <- termination condition allows us to escape loop
.if \m&1 # if (mask & 0x00000001) is not == 0
.set maskShift, \c # maskshift = count -- termination
# <- recursive macro call allows us to iterate loop
.else # else
.set maskShift, \c+1 # maskshift = count++ -- incr counter
countShift \m>>1, \c+1 # call self
.endif # close if block
.endm # close macro block
# macro "countShift" can be used to count the zero bits
# resulting symbol "maskShift" can be used to imply shift amount in rlwinm and rlwimi syntax
.macro mext rD, rS, m
# mext : masked extract
countShift \m, 0 # m = 32-bit mask
rlwinm \rD, \rS, (32-maskShift)%32, \m>>maskShift
.endm
mflr r0
stw r0, 0x4(sp)
stwu sp, -0x40(sp)
stmw r29, 0x10(sp)
mr r30, r3 # save r3 and r4 for after projection calls
mr r31, r4 #
mr r3, r4 # r3 = params 1
mr r4, r5 # r4 = params 2
bl <prim_setup> # set up params
bl <prim_mtx_setup> # set up mtx
mext r3, r31, 0x000000FF # r3 = primitive ID
cmpwi r3, 5 # if it's larger than
blt+ _end_width_handle
cmpwi r3, 7
bgt- _end_width_handle
mext r3, r31, 0x03FF0000
li r4, 5
beq- _point_handle
_width_handle: # exclusively for lines and linestrips
bl <GXSetLineWidth>
b _end_width_handle
_point_handle: # exclusively for points
bl <GXSetPointSize>
_end_width_handle:
rlwinm r3, r31, 3, 0x000000F8
addi r3, r3, 0x80 # r3 is now a primitive ID that can be fed to GXBegin
li r4, 0 # use vtx format 0
mext r5, r30, 0x0000FFFF # use N number of vertices
bl <GXBegin>
lis r3, 0xCC01
addi r3, r3, -0x8000 # r3 = address of hardware FIFO stack
# write vertex(X, Y, Z, C) to address in r3
# each write must be to the exact same address
lmw r29, 0x10(sp)
addi sp, sp, 0x40
lwz r0, 0x4(sp)
mtlr r0
blr
# convenience functions:
<prim_quads> All
li r4, 0
b <prim_main>
<prim_triangles> All
li r4, 2
b <prim_main>
<prim_trianglestrip> All
li r4, 3
b <prim_main>
<prim_trianglefan> All
li r4, 4
b <prim_main>
<prim_lines> All
li r4, 5
b <prim_main>
<prim_linestrip> All
li r4, 6
b <prim_main>
<prim_points> All
li r4, 7
b <prim_main>
<prim_defaults>
blrl
.long 0x00101300
.long 0x00001455
<prim_default_swordtrails>
blrl
.long 0x00101300
.long 0x00001455
<prim_toggle_z>
# this function simply toggle the z buffer comparison in the Z buffer options
# it's meant to make it easy for people who just want to draw on top of things
mflr r0
stw r0, 0x4(sp)
stwu sp, -0x8(sp)
bl <prim_defaults>
mflr r3
lwz r4, 0(r3)
xori r4, r4, 0x1000 # toggle z comparison bit
stw r4, 0(r3)
addi sp, sp, 8
lwz r0, 4(sp)
mtlr r0
blr
---
Example codes:
- Nibble Printer POC 0.1
- ECB Anchor Test 2
- ECB Anchor Test 1
- Player JObj tracer
- Colored Player Skeletons
---
With this module installed, developers can make use of the following functions for the purpose of drawing to the current camera coordiantes:
bl <prim_quads>
# draw a series of individual quadrilateral 4-point polygons
bl <prim_triangles>
# draw a series of individual triangle 3-point polygons
bl <prim_trianglestrip>
# draw a contiguous strip of connecting 3-point triangles that share an edge for each connection in the sequence.
bl <prim_trianglefan>
# draw a triangle strip where one side of the strip circles around a central vertex
bl <prim_lines>
# draw a series of individual lines using 2 points per line. Line width is the same for each line in the series.
bl <prim_linestrip>
# draw a contiguous strip of connecting 2-point lines
bl <prim_points>
# draw a series of individual points, using single vertices. Point size is the same for each point in the series.
Each of the above functions only require the argument:
r3 = number of vertices
When the function returns, you may use the address returned in r3 to store vertices.
note - when storing vertex information, all data goes to the exact same address; 0(r3)
To describe a vertex, store the following values to 0(r3) in a sequence:
1 - floating point single = vertex X
2 - floating point single = vertex Y
3 - floating point single = vertex Z
4 - 32-bit UINT = RGBA color
---
The following two functions can be called without arguments:
bl <prim_close>
# use this at the end of your drawing to prevent params from corrupting the next GFX drawing in the game
bl <prim_toggle_z>
# use this before starting a primitive to toggle the zbuffer comparison on or off. If off, primitives will be drawn on top of other geometry. On by default.
---
The above primitive functions all use the following functions with a set of default parameters. These functions require you to specify more parameters, but give you much more power over how each polygon is drawn.
Advanced Functions:
bl <prim_main>
# r3 = vert count
# r4 = primitive type -- used to provide all of the above basic functions
# this call creates parameters similar to the basic sword trail drawings by default
# <prim_defaults> can be modified to change the params for the next drawn primitive
# primitive types for r4 argument
# 0 - quads
# 1 - (quads2)
# 2 - triangles
# 3 - trianglestrip
# 4 - trianglefan
# 5 - lines
# 6 - linestrip
# 7 - points
# r3 = vert count
# r4 = primitive type -- used to provide all of the above basic functions
# this call creates parameters similar to the basic sword trail drawings by default
# <prim_defaults> can be modified to change the params for the next drawn primitive
# primitive types for r4 argument
# 0 - quads
# 1 - (quads2)
# 2 - triangles
# 3 - trianglestrip
# 4 - trianglefan
# 5 - lines
# 6 - linestrip
# 7 - points
bl <prim_defaults>
# this blrl table can be accessed with an mflr instruction upon return.
# it may be modified in order to change the parameters of the next <prim_main> call
# parameters will be reverted after call to <prim_main>
# see the following function for details about params structure
# this blrl table can be accessed with an mflr instruction upon return.
# it may be modified in order to change the parameters of the next <prim_main> call
# parameters will be reverted after call to <prim_main>
# see the following function for details about params structure
bl <prim_main_parametric>
# this version of the function lets you specify the parameters directly using immediates built in r4 and r5
# r3 = vert count
# r4 = params 1
# r5 = params 2
# the parameters are encoded like so:
# r4 r5
# C0000000 00000000 = Cull Mode
# +8 = cull backface
# +4 = cull frontface
# 03FF0000 00000000 = Line Width/Point Size
# 1/16 pixel increments; 0x2A8 maximum width
# only used for points and lines; otherwise ignored
# 00002000 00000000 = Compare Location
# +2 = z buffer compares before texturing
# 00001000 00000000 = Z Buffer Compare
# +1 = z buffer enables compare
# 00000800 00000000 = Z Buffer Update
# +8 = z buffer enables update
# 00000700 00000000 = Z Buffer Comparison Logic
# +4 = greater than
# +2 = equal to
# +1 = less than
# 000000FF 00000000 = Primitive Type
# 0 = quads
# 1 = --
# 2 = triangles
# 3 = trianglestrip
# 4 = trianglefan
# 5 = lines
# 6 = linestrip
# 7 = points
# 00000000 00003000 = Blend Type
# 0 = None -- write input directly to EFB
# 1 = Blend -- blend using blending equation
# 2 = Logic -- blend using bitwise operation
# 3 = Subtract -- input subtracts from existing pixel
# 00000000 00000700 = Blend Source
# 0 = zero -- 0.0
# 1 = one -- 1.0
# 2 = source color
# 3 = inverted source color
# 4 = source alpha
# 5 = inverted source alpha
# 6 = destination alpha
# 7 = inverted destination alpha
# 00000000 00000070 = Blend Dest
# (see above)
# 00000000 0000000F = Blend Logic
# 0 -- CLEAR; dst = 0
# 1 -- AND; dst = src & dst
# 2 -- REVAND; dst = src & ~dst
# 3 -- COPY; dst = src
# 4 -- INVAND; dst = ~src & dst
# 5 -- NOOP; dst = dst
# 6 -- XOR; dst = src ^ dst
# 7 -- OR; dst = src | dst
# 8 -- NOR; dst = ~(src | dst)
# 9 -- EQUIV; dst = ~(src ^ dst)
# A -- INV; dst = ~dst
# B -- REVOR; dst = src | ~dst
# C -- INVCOPY; dst = ~src
# D -- INVOR; dst = ~src | dst
# E -- NAND; dst = ~(src & dst)
# F -- SET; dst = 1
# this version of the function lets you specify the parameters directly using immediates built in r4 and r5
# r3 = vert count
# r4 = params 1
# r5 = params 2
# the parameters are encoded like so:
# r4 r5
# C0000000 00000000 = Cull Mode
# +8 = cull backface
# +4 = cull frontface
# 03FF0000 00000000 = Line Width/Point Size
# 1/16 pixel increments; 0x2A8 maximum width
# only used for points and lines; otherwise ignored
# 00002000 00000000 = Compare Location
# +2 = z buffer compares before texturing
# 00001000 00000000 = Z Buffer Compare
# +1 = z buffer enables compare
# 00000800 00000000 = Z Buffer Update
# +8 = z buffer enables update
# 00000700 00000000 = Z Buffer Comparison Logic
# +4 = greater than
# +2 = equal to
# +1 = less than
# 000000FF 00000000 = Primitive Type
# 0 = quads
# 1 = --
# 2 = triangles
# 3 = trianglestrip
# 4 = trianglefan
# 5 = lines
# 6 = linestrip
# 7 = points
# 00000000 00003000 = Blend Type
# 0 = None -- write input directly to EFB
# 1 = Blend -- blend using blending equation
# 2 = Logic -- blend using bitwise operation
# 3 = Subtract -- input subtracts from existing pixel
# 00000000 00000700 = Blend Source
# 0 = zero -- 0.0
# 1 = one -- 1.0
# 2 = source color
# 3 = inverted source color
# 4 = source alpha
# 5 = inverted source alpha
# 6 = destination alpha
# 7 = inverted destination alpha
# 00000000 00000070 = Blend Dest
# (see above)
# 00000000 0000000F = Blend Logic
# 0 -- CLEAR; dst = 0
# 1 -- AND; dst = src & dst
# 2 -- REVAND; dst = src & ~dst
# 3 -- COPY; dst = src
# 4 -- INVAND; dst = ~src & dst
# 5 -- NOOP; dst = dst
# 6 -- XOR; dst = src ^ dst
# 7 -- OR; dst = src | dst
# 8 -- NOR; dst = ~(src | dst)
# 9 -- EQUIV; dst = ~(src ^ dst)
# A -- INV; dst = ~dst
# B -- REVOR; dst = src | ~dst
# C -- INVCOPY; dst = ~src
# D -- INVOR; dst = ~src | dst
# E -- NAND; dst = ~(src & dst)
# F -- SET; dst = 1
Last edited: