========================================================================= | Rendering Commands And Explination | | | | Any Link Below is truncated to the root of SDK Manual, | | This Link is not visible and I request it not be Spread. | | htp://fgfc.ddns.net/NINTENDO%2064%20SDK%205%20_CDROM/man/allman50/ | | Can Also be downloaded at romhacking | | | | Compiled By Trevor | | Credits to Zoinkity for Original Find | ========================================================================= B9 G_SETOTHERMODE_L =================== typedef struct { int cmd:8; int pad0:8; int sft:8; int len:8; unsigned int data:32; } GsetothermodeL; The first obvious detail withought having to specify each time is that Upper Word B900031D is always the same. It means Literaly: G_SETOTHERMODE_L, G_MDSFT_RENDERMODE, SetRenderMode(). (where B9 = G_SETOTHERMODE_L, 00 = Nothing, 03 = G_MDSFT_RENDERMODE, 1D = SetRenderMode() ) Nothing is actually Padding for memory Alignment It is derived from the command gsDPSetRenderMode(c0, c1) This in turn is converted to the ucode: gsSPSetOtherMode(G_SETOTHERMODE_L, G_MDSFT_RENDERMODE, SetRenderMode(c0) | (c1)) There are 3 other options besides RenderMode: 0x000000xx = AlphaCompare 0x000002xx = ZSRCSEL [DepthSourceSelect] 0x000003xx = G_MDSFT_RENDERMODE 0x000016xx = Blender [not used in F3DEX - PD] Then there are the following functions after (Replace xx with these). These other options are simplistic and can be summerised per line: ----------------------------------------------------------------------------------------- | xx Lower Word Description | | 0x02 = SetAlphaCompare(0x00000000) none (Do not compare, Normal Non-Transparent | | Textures (or Multi-Bit Alpha)) | | 0x00000001 threshold (Compare with the blend Colour alpha | | value, Used for 1 bit alpha | | transparent Textures if Fog Enabled) | | 0x00000003 dither (Compare with a random dither | | value, Makes for odd Partical | | effect (eg flies)) | | /n64man/gdp/gDPSetAlphaCompare.htm | | | | 0x01 = SetDepthSource(0x00000000) pixel (Use the Z value and deltaZ value | | repeated for each pixel) | | 0x00000004 primitive (Use the primitive depth | | register's Z value and deltaZ | | value) | | This is faster but less accuriate | | /n64man/gdp/gDPSetDepthSource.htm | | | | 0x1D = SetRenderMode(*Options Below*) | | | | 0x16 = Blender - it will look like 0x00000176 as in 160 + 016 | | ! Discontinued and reserved in F3DEX ! | | | | Setting the DepthSource to a Primitive Can be used for 'Horizon' Images. | | In this case you model a horizon close to the player (a dome or cylinder centered | | around the players head, but orientated to the world), Then you set its z-value to | | 0x7fff (Far Clip Plane). This will cause the Horizon Image to Neither FOG (since | | FOG is calculated on distance) or Block View since it will always be at the back | ----------------------------------------------------------------------------------------- =Zoinkitys Original================================================================================= upper word 0000FF00 shift (PD only: 32-shift-length) here are shift values for each of the various segments (hex): 0 alpha compare 2 depth source select [ZSRCSEL] 3 render mode [G_MDSFT_RENDERMODE] 16 blender Discontinued and reserved in F3DEX 000000FF length (PD only: length-1) here are lengths for each of the various segments (hex): 1 depth source 2 alpha compare 1D render mode (encompases render mode, converge ST, depth mode, and blender from below) 16 blender Discontinued and reserved in F3DEX ===================================================================================================== SetRenderMode() =============== In 2-cycle mode, fog or pass usually is set for c0 and rendering is set for c1. G_SETOTHERMODE_L, G_MDSFT_RENDERMODE, SetRenderMode(c0) | (c1) c0 Rendering mode set for first cycle: G_RM_ [ AA_ | RA_ ] [ ZB_ ]* (Rendering type - 1 cycle) G_RM_FOG_SHADE_A (Fog type) G_RM_FOG_PRIM_A (Fog type) G_RM_PASS (Pass type) G_RM_NOOP (No operation type) c1 Rendering mode set for second cycle: G_RM_ [ AA_ | RA_ ] [ ZB_ ]*2 (Rendering type) G_RM_NOOP2 (No operation type) Each Rendering Mode also contains a blender MUX which is described later. The common Type for c1 (Mux2) is: GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) For Fog(Which can only occur on c0(MUX1)) its: GBL_c0(G_BL_CLR_FOG, G_BL_A_SHADE, G_BL_CLR_IN, G_BL_1MA) SDK States: "Fog can be used in one cycle mode for non-antialiased opaque surfaces only" I have found this to be false, AA DOES work. The correct RenderMode Settings are AA_En, ZB, ZUpdate, Img_Read, ForceBlender. 1 Cycle Mode is great for Large Untextured Shaded Tris With or without Lighting, however I advise against its use on Textured Tris, Unless you can Guarentee the tri will never be smaller on the screen than the texture resolution, since there is No Mip-Mapping or Tri-Linear Filtering. On A related note about FOG, the docs have given a reason why GE Levels cant have vertex Alpha. "You cannot, however, use vertex alpha with fog. The per alpha supplied in the vertices will be ignored and if the color combiner selects a SHADE alpha, it will get the fog alpha value instead (not what was intended)." Refer to /n64man/gdp/gDPSetRenderMode.htm for more types. Refer to /pro-man/pro12/12-07.htm for Blender Info ---------------------------------------------------------------------------------------- |Cycle Counts are the number of cycles it takes to send 1 px to the FrameBuffer. | |One-cycle mode fills a fairly high-quality pixel. You can generate pixels that | |are perspectively corrected, bilinear filtered, modulate/decal textured, transparent, | |and Z-buffered, at one-cycle-per-pixel peak bandwidth. | | | |Note: Reaching peak bandwidth is difficult. The framebuffer memory is organized in row | |order. In small triangles, it is rare to have long horizontal runs of pixels on a | |single scanline. In these cases, the pipeline is often stalled, pending memory access | |for read or write cycles. | ---------------------------------------------------------------------------------------- =Zoinkitys Original================================================================================= lower word alpha compare 0x00000000 none (New TexEdge - Transparent Textures) 0x00000001 threshold 0x00000003 dither depth source 0x00000000 pixel 0x00000004 primitive render mode 0x00000008 antialias enable 0x00000010 depth compare 0x00000020 depth update 0x00000040 image read 0x00000080 colour on converge -converge ST 0x00000000 converge delta-ST clamp 0x00000100 converge delta-ST wrap 0x00000200 converge delta-ST full 0x00000300 converge delta-ST save -depthmode 0x00000000 depth Zmode_OPA (Opaque) / Z Buff 0x00000400 depth Zmode_INTER (interpenetrating _____/___ 0x00000800 depth Zmode_XLU (Transparent) / 0x00000C00 depth Zmode_DEC (Decal) ---====---- 0x00001000 converge x alpha 0x00002000 alpha converge selection 0x00004000 force blender 0x00008000 texture edge (0 in Perfect Dark due to F3DEX) /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ This Section is to the best of my testing wrong I have a correction below -blender----- 0x00010000 blend 1 machine Multiplier_1 0x00020000 blend alpha memory 0x00040000 blend 1 0x00080000 blend 0 Colour_1 0x00100000 blend colour in 0x00200000 blend colour memory 0x00400000 blend colour blender 0x00800000 blend colour fog Alpha_1 0x01000000 blend alpha in 0x02000000 blend alpha fog 0x04000000 blend alpha shade 0x08000000 blend 0 ------- ---------------------------------------------------- Multipier_0 0x10000000 blend 1 machine 0x20000000 blend alpha memory 0x40000000 blend 1 0x80000000 blend 0 \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ ===================================================================================================== For easy identification I have drawn a Bit Map of the Lower Word -Bit Map----------------------------------------------------------------- | [------------------MUX 1 and 2 see Below!----------------] | | 0 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 | | see MUX BitMap Below | | | 1 0 0 0 0 0 0 1 1 1 1000 | 0 0 1 0 0 0 0 0 0 1 1 1 1 0 0 0 |Runway 66AFD4 | te fb acs cxa ze zi cf cw cc ir du dc AA Pr Di Th | | [-------------------flags-------------------------][-flags-] | | Flags Confirmed | ------------------------------------------------------------------------- Description of Blender Mux (c0/1): Mux1 or c0 is the first pass in the blender. As stated above it normally takes Fog. Mux2 or c1 sets the second pass. From experiments with CCBL it seems as though the best settings are, Colour_In * Alpha_In + Colour_Mem * Alpha_Mem. You will notice its an equation. CCBL shows this as follows (showing both MUX's) ----------------------------------------- |[MUX1] | |( C_FOG * A_Shade + C_IN * 1-A ) | |_______________________________ | | (A_Shade + 1-A) | | | |[MUX2] | |( C_IN * A_IN + C_MEM * A_MEM ) | |_______________________________ | | (A_IN + A_MEM) | ----------------------------------------- While there are more entries here than we can edit, the Divisions are automatic. So, Setting c0 Multiplier to 0 ALSO SETS Division to 0 (Instead of 1-A (1Machine)) OK, So MUX is now figured out. To Start with this didnt make sence, but after compiling my own code, it works. #define GBL_c0(m1a, m1b, m2a, m2b) (m1a) << 30 | (m1b) << 26 | (m2a) << 22 | (m2b) << 18 #define GBL_c1(m1a, m1b, m2a, m2b) (m1a) << 28 | (m1b) << 24 | (m2a) << 20 | (m2b) << 16 The numbers are BitShifts. This works out like the following: -Bit Map----------------------------------------------------------------- | 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 | | 0 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 |Runway 66AFD4 | [0 0] [0 0] [1 1] [0 0] [0 0] [0 1] [1 0] [0 0] | | 0m1a 1m1a 0m1b 1m1b 0m2a 1m2a 0m2b 1m2b | ------------------------------------------------------------------------ Each M Accepts the binary value of the following: #define G_BL_CLR_IN 00 #define G_BL_CLR_MEM 01 #define G_BL_CLR_BL 10 #define G_BL_CLR_FOG 11 #define G_BL_1MA 00 #define G_BL_A_MEM 01 #define G_BL_A_IN 00 #define G_BL_A_FOG 01 #define G_BL_A_SHADE 10 #define G_BL_1 10 #define G_BL_0 11 Remember the equation above, The M values are inserted as such: [MUX1] ( 0m1b * 0m1a + 0m2a * 0m2b ) <-- I have swapped 1b and 1a to match output (Fog) ________________________________ When I compile Programs, they are in abab (0m1a + 0m2b) order as against GEs seemingly baab Order [MUX2] ( 1m1b * 1m1a + 1m2a * 1m2b ) _______________________________ (1m1a + 1m2b) Rare Code Translations ====================== Here I will list the Human Readable Psudo-Commands under each Binary. B9,000,3,1D (0C18;2078) FC(26A004 1FFC93FC) C00800 02 00 000 5BC Archives:509478.bin SETOTHERMODE_L, RenderMode, SetRenderMode ( //(CLR_IN, 0, CLR_IN, 1)|(CLR_IN, A_IN, CLR_MEM, 1-A); // This produces a non fogging solid... // cant be right... (CLR_FOG, A_IN, CLR_IN, 1)|(CLR_IN, A_IN, CLR_MEM, 1-A); // This correctly Produces a fogging, // Textured Solid, Never Fully Foggs // Though. To Full FOG, c0 should end // in 1-A rather than 1. // I had to swap a and b in the equation // above. alpha_converge_selection; Converge_Dst_Clamp; depth_Zmode_opa; image_read; depth update; depth compare; AA ) SETCOMBINE( ((Texle1 - Tele0) * LOD_FRACTION + Texle0, (Texle1 - Tele0) * LOD_FRACTION + Texle0) | ((Combined - 0) * Shade, (0 - 0) * 0 + Shade)) ) ________________________________________________________________ |CYCLE1 (TRILERP) | CYCLE2 (MODULATERGB) | |CC0: t1 - t0 * LF + t0 | CC1: Com - 0 * shade + 0 | |AC0: t1 - t0 * lf + t0 | AC1: 0 - 0 * 0 + shade | |_______________________________|_______________________________| *********************** * This translates to: * *********************** Set the blender to first multiply fog colour with Z-Value placed on Vertex-Alpha, Add the result of the ColourCombiner and then divide the whole thing by Z-Value + 1. On the second Pass, Multiply the result of the ColourCombiner (CLR_IN) with ColourCombiner_Alpha (A_IN) and add fist pass Multiplied by 1-A [MUX1] ( CLR_FOG * A_IN + CLR_IN * 1 ) ________________________________ (A_IN + 1) [MUX2] ( CLR_IN * A_IN + CLR_MEM * 1-A ) _______________________________ (A_IN + 1-A) So if we add arbitary numbers we can see whats happening. Lets call the FOG 255, Z 0.5, CC 128, CC_A 1. [-----------MUX1--------] [--------MUX2--------] We end up with ((255*0.5) + (128*1))/1.5 = 170.333 ((128*1)+170.333)/1.5 = 198.89 This of cource is done for Red Green and Blue on every pixle displayed on screen. The Colour Combiner Applies Tri-Linear Filtering and then applies the shading of the object. In logical Terms the Colour Combiner should come first ********************** B900031D 0C18 2078 FC26A0041F1093FF C0080002 00 000 278 Archives:509478.bin <- Any Of these = depot SETOTHERMODE_L, RenderMode, SetRenderMode ( (CLR_FOG, A_IN, CLR_IN, 1)|(CLR_IN, A_IN, CLR_MEM, 1-A); alpha_converge_selection; Converge_Dst_Clamp; depth_Zmode_opa; image_read; depth update; depth compare; AA ) // The majority of Rares Codes are the same for Blender B900031D 0C182078 [MUX1] ( CLR_FOG * A_IN + CLR_IN * 1 ) ________________________________ (A_IN + 1) [MUX2] ( CLR_IN * A_IN + CLR_MEM * 1-A ) _______________________________ (A_IN + 1-A) SetCombine(Tex1-Tex0*L_F+Tex0, Tex1-Tex0*L_F+Tex0)|(Com-0*Shade+0, COM-0*Shade+COM) ________________________________________________________________________ | CYCLE1 TRILERP | CYCLE2 MODULATEIA2 | | CC0: (Tex1-Tex0)*LOD_FRACTION + Tex0 | CC1: (Com-0)*Shade + 0 | | AC0: (Tex1-Tex0)*LOD_FRACTION + Tex0 | AC1: (COM-0)*Shade + COM| |_______________________________________|_______________________________| This is a generic render mode. It will produce a Fogging Tri-linear Filtered Mip-Maped textured shaded triangle. It will also be z-buffered and Anti-Ailised. If the texture contains Alpha or is a greyscale type (4/0 3/1 4/4 8/8) then it will be transparent HOWEVER, B900031D 0C19;2D58 FC26A004 1F1093FF C0580002 00 000 41B Archives:509478.bin SETOTHERMODE_L, RenderMode, SetRenderMode( 0 + Alpha_Shade * colour_IN 0 1ma; alpha_converge_selection; depth_Zmode_XLU (Exclusive); converge delta-ST wrap; image_read; depth compare; AA ) B900031D 0C184DD8 FC26A004 1F1093FF C0080002 00 000 329 Archives:5095C4.bin B900031D 0C1849D8 FC26A004 1F1093FF C0580002 00 000 4FD Archives:5095C4.bin B900031D 00502078 FCFFFFFF FFFE793C Archives:50A164.bin SETOTHERMODE_L, RenderMode, SetRenderMode ( (CLR_IN, A_IN, CLR_MEM, A_IN)|(CLR_IN, A_IN, CLR_MEM, A_IN); alpha_converge_selection; Converge_Dst_Clamp; depth_Zmode_opa; image_read; depth update; depth compare; AA ) [MUX1] ( CLR_IN * A_IN + CLR_MEM * 1-A ) ________________________________ (A_IN + 1-A) [MUX2] ( CLR_IN * A_IN + CLR_MEM * 1-A ) _______________________________ (A_IN + 1-A) SetCombine(0-0*0+0,0-0*0+0, 0-Shade*Shade+shade,shade-0*shade+shade) Cycle1 Cycle2 //Possibly swap 0 - 0 * 0 + 0 0 shade shade shade 0 - 0 * 0 + 0 shade 0 shade shade This is a 1 Cycle un-textured tri. It will NOT FOG. It will ALWAYS appear Grey. Its Preset Name for Blender is AA_ZB_SUB_SURF which means Subsurfaces. "Sub surface mode, SUB_SURF, is intended to be used as a way to get an opaque object upon which an antialiased transparent surface can be overlaid. The coverage values from the transparent surface will fill in the zapped coverage values from the initial opaque surface. " B900031D 0C192D58 FC26A004 1FFC93FC C0080002 00 000 41F Archives:50D24C.bin B900031D 00504DD8 FCFFFFFF FFFE793C Aztec:598150.bin B900031D 0C1849D8 FC26E404 1F10FFFF C01B8001 FA 9A1 4B1 Bunker1:449360.bin <-Surface Trees B900031D 0C184DD8 FC26A004 1FFC93FC C0080002 00 000 309 Bunker2:573760.bin B900031D 00502078 FC127E24 FFFFF9FC C0080004 00 000 5E4 Caverns:6C05BC.bin B900031D 00502078 FC121824 FF33FFFF C0080004 00 000 8BF Control:4E22B4.bin B900031D 00504DD8 FC121824 FF33FFFF C0080004 00 000 3E5 Control:4E25C0.bin B900031D 00552D58 FCFFFFFF FFFE793C C0080002 00 000 591 Control:4E4564.bin SETOTHERMODE_L, RenderMode, SetRenderMode( ColourBlender * Colour_IN 1 1ma; alpha_converge_selection; depth_Zmode_XLU (Exclusive); converge delta-ST wrap; image_read; depth compare; AA ) B900031D 0C182048 FC26A004 1FFC93FC C0080002 00 000 3B4 Dam:6256D0.bin B900031D 0C182048 FC1219FF FFFFFE38 C0080003 00 000 5E7 Dam:62665C.bin B900031D 0C1849D8 FC26A004 1FFC93FC C0080002 00 000 1AD Dam:6267B8.bin B900031D 0C184E50 FC26A004 1F1093FF C0180002 00 000 1B5 Dam:628230.bin SETOTHERMODE_L, RenderMode, SetRenderMode( 0 + Alpha_Shade * Colour_IN 0; Force_Blender; decrement; full; image_read; depth compare ) B900031D 0C182078 FC26E404 1FFCFFFC C00BFC00 FA 000 3B5 Dam:62C888.bin B900031D 0C182078 FC1219FF FFFFFE38 C0080003 00 000 46C Dam:62E1BC.bin B900031D 0C182078 FCFFFFFF FFFE7838 Dam:62F2FC.bin B900031D 005049D8 FC121824 FF33FFFF C0080004 00 000 2A2 Facility:659C8C.bin B900031D 005049D8 FCFFFFFF FFFE793C C0080002 00 000 0EF Surface1:686C2C.bin ================================ Ok, lets deal with a whole DList as something is missing. Runway 66AFD4.bin E7 00 00 00 00 00 00 00 Pipesync BA 00 14 02 00 10 00 00 setothermode_h B9 00 03 1D 0C 18 20 78 setothermode_l, G_MDSFT_RENDERMODE, SetRenderMode( |) FC 26 A0 04 1F FC 93 FC SetCombine BA 00 10 01 00 01 00 00 setothermode_h BB 00 30 01 FF FF FF FF Texture C0 08 00 02 00 00 01 22 GETexture( 951976Other4040.bmp BA 00 11 02 00 00 00 00 setothermode_h BA 00 0C 02 00 00 20 00 setothermode_h B7 00 00 00 00 00 20 00 setgeometrymode FB 00 00 00 00 00 00 FF setenvcolour 04 E0 00 F0 0E 00 00 00 vertex B1 00 76 32 64 54 20 10 tri4 E7 00 00 00 00 00 00 00 PipeSync FC 26 A0 04 1F 10 93 FF SetCombine BB 00 28 01 FF FF FF FF texture C0 08 00 02 00 00 04 7A GETexture B1 00 0E BA 00 DC A8 98 tri4 E7 00 00 00 00 00 00 00 PipeSync FC 26 A0 04 1F FC 93 FC SetCombine BB 00 30 01 FF FF FF FF Texture C0 08 00 02 00 00 01 1E GETexture 95071BOther4040.bmp 04 F0 01 00 0E 00 00 F0 vertex B1 00 76 32 64 54 20 10 tri4 B1 00 FE BA EC DC A8 98 tri4 B8 00 00 00 00 00 00 00 enddl One Cyle Mode from Demo =============================================================== /* * init RDP */ BA 00 14 02 00 00 00 00 gsDPSetCycleType(G_CYC_1CYCLE), BA 00 17 01 00 80 00 00 gsDPPipelineMode(G_PM_1PRIMITIVE), ED 00 00 00 00 50 03 C0 gsDPSetScissor(G_SC_NON_INTERLACE, 0, 0, SCREEN_WD, SCREEN_HT), BA 00 10 01 00 00 00 00 gsDPSetTextureLOD(G_TL_TILE), BA 00 0E 02 00 00 00 00 gsDPSetTextureLUT(G_TT_NONE), BA 00 11 02 00 00 00 00 gsDPSetTextureDetail(G_TD_CLAMP), BA 00 13 01 00 08 00 00 gsDPSetTexturePersp(G_TP_PERSP), BA 00 0C 02 00 00 20 00 gsDPSetTextureFilter(G_TF_BILERP), BA 00 09 03 00 00 0C 00 gsDPSetTextureConvert(G_TC_FILT), FC FF FF FF FF FE 79 3C gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE), BA 00 08 01 00 00 00 00 gsDPSetCombineKey(G_CK_NONE), B9 00 00 02 00 00 00 00 gsDPSetAlphaCompare(G_AC_NONE), B9 00 03 1D 00 55 20 78 gsDPSetRenderMode(G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2), BA 00 06 02 00 00 00 40 gsDPSetColorDither(G_CD_BAYER), BA 00 04 02 00 00 00 00 gsDPSetAlphaDither(G_AD_PATTERN), E7 00 00 00 00 00 00 00 gsDPPipeSync(), B8 00 00 00 00 00 00 00 gsSPEndDisplayList(),