Mario Kart 64
gbi.h
Go to the documentation of this file.
1 /**************************************************************************
2  * *
3  * Copyright (C) 1994, Silicon Graphics, Inc. *
4  * *
5  * These coded instructions, statements, and computer programs contain *
6  * unpublished proprietary information of Silicon Graphics, Inc., and *
7  * are protected by Federal copyright law. They may not be disclosed *
8  * to third parties or copied or duplicated in any form, in whole or *
9  * in part, without the prior written consent of Silicon Graphics, Inc. *
10  * *
11  **************************************************************************/
12 /**************************************************************************
13  *
14  * $Revision: 1.141 $
15  * $Date: 1999/09/03 03:43:08 $
16  * $Source: /exdisk2/cvs/N64OS/Master/cvsmdev2/PR/include/gbi.h,v $
17  *
18  **************************************************************************/
19 
20 #ifndef _GBI_H_
21 #define _GBI_H_
22 
23 #include <PR/ultratypes.h>
24 
25 /*
26  * To use the F3DEX ucodes, define F3DEX_GBI before include this file.
27  *
28  * #define F3DEX_GBI
29  * #include <ultra64.h>
30  *
31  * or
32  *
33  * cc -c -DF3DEX_GBI -I.... foo.c
34  *
35  */
36 
37 /**************************************************************************
38  *
39  * Graphics Binary Interface
40  *
41  **************************************************************************/
42 
43 /*
44  * Graphics Commands, 'xxx' parts may be generated from ucode
45  *
46  * The command format is
47  *
48  * |00xxxxxx| = DMA 0,..,127
49  * |10xxxxxx| = Immediate Mode -65,..,-128
50  * |11xxxxxx| = RDP cmds -1,..,-64
51  *
52  * Note: in order for the RSP microcode to process RDP commands opaquely,
53  * we need to further identify those RDP commands that need DRAM address
54  * "fixup". To do this, we have the dummy command G_RDP_ADDR_FIXUP, and
55  * all |RDP commands| less than this are commands with embedded DRAM
56  * addresses. Further, the format of these commands should be similar so
57  * only one fixup routine is needed.
58  *
59  * Further explanation:
60  * The names of the commands are somewhat misleading. Here is clarification:
61  *
62  * - a 'DMA' type command has a pointer to additional data and
63  * causes a DMA transfer to bring that into DMEM.
64  *
65  * - an 'Immediate' type command isn't really 'immediate', in the
66  * traditional sense. This just means that the entire command fits
67  * in the 64-bit word, and the ucode can execute it 'immediately'
68  * without additional memory transfers.
69  *
70  * - an 'RDP' command is identified as such because the RDP
71  * commands can be passed-thru the RSP and sent to the RDP
72  * directly. One further confusing thing, is that some 'DP'
73  * macros below actually generate immediate commands, not
74  * not direct DP commands.
75  *
76  * IMPLEMENTATION NOTE:
77  * There is another group of RDP commands that includes the triangle commands
78  * generated by the RSP code. These are the raw commands the rasterizer
79  * hardware chews on, with slope info, etc. They will follow the RDP
80  * ordering...
81  *
82  * IMPLEMENTATION NOTE:
83  * The RDP hardware has some of these bit patterns wired up. If the hardware
84  * changes, we must adjust this table, likewise we can't change/add things
85  * once the hardware is frozen. (actually, the RDP hardware only looks at
86  * the lower 6 bits of the command byte)
87  *
88  */
89 
90 #ifdef F3DEX_GBI_2
91 # ifndef F3DEX_GBI
92 # define F3DEX_GBI
93 # endif
94 #define G_NOOP 0x00
95 #define G_RDPHALF_2 0xf1
96 #define G_SETOTHERMODE_H 0xe3
97 #define G_SETOTHERMODE_L 0xe2
98 #define G_RDPHALF_1 0xe1
99 #define G_SPNOOP 0xe0
100 #define G_ENDDL 0xdf
101 #define G_DL 0xde
102 #define G_LOAD_UCODE 0xdd
103 #define G_MOVEMEM 0xdc
104 #define G_MOVEWORD 0xdb
105 #define G_MTX 0xda
106 #define G_GEOMETRYMODE 0xd9
107 #define G_POPMTX 0xd8
108 #define G_TEXTURE 0xd7
109 #define G_DMA_IO 0xd6
110 #define G_SPECIAL_1 0xd5
111 #define G_SPECIAL_2 0xd4
112 #define G_SPECIAL_3 0xd3
113 
114 #define G_VTX 0x01
115 #define G_MODIFYVTX 0x02
116 #define G_CULLDL 0x03
117 #define G_BRANCH_Z 0x04
118 #define G_TRI1 0x05
119 #define G_TRI2 0x06
120 #define G_QUAD 0x07
121 #define G_LINE3D 0x08
122 #else /* F3DEX_GBI_2 */
123 
124 /* DMA commands: */
125 #define G_SPNOOP 0 /* handle 0 gracefully */
126 #define G_MTX 1
127 #define G_RESERVED0 2 /* not implemeted */
128 #define G_MOVEMEM 3 /* move a block of memory (up to 4 words) to dmem */
129 #define G_VTX 4
130 #define G_RESERVED1 5 /* not implemeted */
131 #define G_DL 6
132 #define G_RESERVED2 7 /* not implemeted */
133 #define G_RESERVED3 8 /* not implemeted */
134 #define G_SPRITE2D_BASE 9 /* sprite command */
135 
136 /* IMMEDIATE commands: */
137 #define G_IMMFIRST -65
138 #define G_TRI1 (G_IMMFIRST-0)
139 #define G_CULLDL (G_IMMFIRST-1)
140 #define G_POPMTX (G_IMMFIRST-2)
141 #define G_MOVEWORD (G_IMMFIRST-3)
142 #define G_TEXTURE (G_IMMFIRST-4)
143 #define G_SETOTHERMODE_H (G_IMMFIRST-5)
144 #define G_SETOTHERMODE_L (G_IMMFIRST-6)
145 #define G_ENDDL (G_IMMFIRST-7)
146 #define G_SETGEOMETRYMODE (G_IMMFIRST-8)
147 #define G_CLEARGEOMETRYMODE (G_IMMFIRST-9)
148 #define G_LINE3D (G_IMMFIRST-10)
149 #define G_RDPHALF_1 (G_IMMFIRST-11)
150 #define G_RDPHALF_2 (G_IMMFIRST-12)
151 #define G_RDPHALF_CONT (G_IMMFIRST-13) // From F3D_OLD used to render lap & timer UI.
152 #if (defined(F3DEX_GBI)||defined(F3DLP_GBI))
153 #ifndef F3D_OLD
154 # define G_MODIFYVTX (G_IMMFIRST-13) // older versions of f3dex still used G_RDPHALF_CONT
155 #endif
156 # define G_TRI2 (G_IMMFIRST-14)
157 # define G_BRANCH_Z (G_IMMFIRST-15)
158 # define G_LOAD_UCODE (G_IMMFIRST-16)
159 # define G_QUAD (G_IMMFIRST-10)
160 #endif
161 
162 /* We are overloading 2 of the immediate commands
163  to keep the byte alignment of dmem the same */
164 
165 #define G_SPRITE2D_SCALEFLIP (G_IMMFIRST-1)
166 #define G_SPRITE2D_DRAW (G_IMMFIRST-2)
167 
168 /* RDP commands: */
169 #define G_NOOP 0xc0 /* 0 */
170 
171 #endif /* F3DEX_GBI_2 */
172 
173 /* RDP commands: */
174 #define G_SETCIMG 0xff /* -1 */
175 #define G_SETZIMG 0xfe /* -2 */
176 #define G_SETTIMG 0xfd /* -3 */
177 #define G_SETCOMBINE 0xfc /* -4 */
178 #define G_SETENVCOLOR 0xfb /* -5 */
179 #define G_SETPRIMCOLOR 0xfa /* -6 */
180 #define G_SETBLENDCOLOR 0xf9 /* -7 */
181 #define G_SETFOGCOLOR 0xf8 /* -8 */
182 #define G_SETFILLCOLOR 0xf7 /* -9 */
183 #define G_FILLRECT 0xf6 /* -10 */
184 #define G_SETTILE 0xf5 /* -11 */
185 #define G_LOADTILE 0xf4 /* -12 */
186 #define G_LOADBLOCK 0xf3 /* -13 */
187 #define G_SETTILESIZE 0xf2 /* -14 */
188 #define G_LOADTLUT 0xf0 /* -16 */
189 #define G_RDPSETOTHERMODE 0xef /* -17 */
190 #define G_SETPRIMDEPTH 0xee /* -18 */
191 #define G_SETSCISSOR 0xed /* -19 */
192 #define G_SETCONVERT 0xec /* -20 */
193 #define G_SETKEYR 0xeb /* -21 */
194 #define G_SETKEYGB 0xea /* -22 */
195 #define G_RDPFULLSYNC 0xe9 /* -23 */
196 #define G_RDPTILESYNC 0xe8 /* -24 */
197 #define G_RDPPIPESYNC 0xe7 /* -25 */
198 #define G_RDPLOADSYNC 0xe6 /* -26 */
199 #define G_TEXRECTFLIP 0xe5 /* -27 */
200 #define G_TEXRECT 0xe4 /* -28 */
201 
202 
203 /*
204  * The following commands are the "generated" RDP commands; the user
205  * never sees them, the RSP microcode generates them.
206  *
207  * The layout of the bits is magical, to save work in the ucode.
208  * These id's are -56, -52, -54, -50, -55, -51, -53, -49, ...
209  * edge, shade, texture, zbuff bits: estz
210  */
211 #define G_TRI_FILL 0xc8 /* fill triangle: 11001000 */
212 #define G_TRI_SHADE 0xcc /* shade triangle: 11001100 */
213 #define G_TRI_TXTR 0xca /* texture triangle: 11001010 */
214 #define G_TRI_SHADE_TXTR 0xce /* shade, texture triangle: 11001110 */
215 #define G_TRI_FILL_ZBUFF 0xc9 /* fill, zbuff triangle: 11001001 */
216 #define G_TRI_SHADE_ZBUFF 0xcd /* shade, zbuff triangle: 11001101 */
217 #define G_TRI_TXTR_ZBUFF 0xcb /* texture, zbuff triangle: 11001011 */
218 #define G_TRI_SHADE_TXTR_ZBUFF 0xcf /* shade, txtr, zbuff trngl: 11001111 */
219 
220 /*
221  * A TRI_FILL triangle is just the edges. You need to set the DP
222  * to use primcolor, in order to see anything. (it is NOT a triangle
223  * that gets rendered in 'fill mode'. Triangles can't be rendered
224  * in 'fill mode')
225  *
226  * A TRI_SHADE is a gouraud triangle that has colors interpolated.
227  * Flat-shaded triangles (from the software) are still gouraud shaded,
228  * it's just the colors are all the same and the deltas are 0.
229  *
230  * Other triangle types, and combinations are more obvious.
231  */
232 
233 /* masks to build RDP triangle commands: */
234 #define G_RDP_TRI_FILL_MASK 0x08
235 #define G_RDP_TRI_SHADE_MASK 0x04
236 #define G_RDP_TRI_TXTR_MASK 0x02
237 #define G_RDP_TRI_ZBUFF_MASK 0x01
238 
239 /*
240  * HACK:
241  * This is a dreadful hack. For version 1.0 hardware, there are still
242  * some 'bowtie' hangs. This parameter can be increased to avoid
243  * the hangs. Every increase of 4 chops one scanline off of every
244  * triangle. Values of 4,8,12 should be sufficient to avoid any
245  * bowtie hang.
246  *
247  * Change this value, then recompile ALL of your program (including static
248  * display lists!)
249  *
250  * THIS WILL BE REMOVED FOR HARDWARE VERSION 2.0!
251  */
252 #define BOWTIE_VAL 0
253 
254 
255 /* gets added to RDP command, in order to test for addres fixup: */
256 #define G_RDP_ADDR_FIXUP 3 /* |RDP cmds| <= this, do addr fixup */
257 #ifdef _LANGUAGE_ASSEMBLY
258 #define G_RDP_TEXRECT_CHECK ((-1*G_TEXRECTFLIP)& 0xff)
259 #endif
260 
261 /* macros for command parsing: */
262 #define GDMACMD(x) (x)
263 #define GIMMCMD(x) (G_IMMFIRST-(x))
264 #define GRDPCMD(x) (0xff-(x))
265 
266 #define G_DMACMDSIZ 128
267 #define G_IMMCMDSIZ 64
268 #define G_RDPCMDSIZ 64
269 
270 /*
271  * Coordinate shift values, number of bits of fraction
272  */
273 #define G_TEXTURE_IMAGE_FRAC 2
274 #define G_TEXTURE_SCALE_FRAC 16
275 #define G_SCALE_FRAC 8
276 #define G_ROTATE_FRAC 16
277 
278 /*
279  * Parameters to graphics commands
280  */
281 
282 /*
283  * Data packing macros
284  */
285 
286 /*
287  * Maximum z-buffer value, used to initialize the z-buffer.
288  * Note : this number is NOT the viewport z-scale constant.
289  * See the comment next to G_MAXZ for more info.
290  */
291 #define G_MAXFBZ 0x3fff /* 3b exp, 11b mantissa */
292 
293 #define GPACK_RGBA5551(r, g, b, a) ((((r)<<8) & 0xf800) | \
294  (((g)<<3) & 0x7c0) | \
295  (((b)>>2) & 0x3e) | ((a) & 0x1))
296 #define GPACK_ZDZ(z, dz) ((z) << 2 | (dz))
297 
298 /*
299  * G_MTX: parameter flags
300  */
301 #ifdef F3DEX_GBI_2
302 # define G_MTX_MODELVIEW 0x00 /* matrix types */
303 # define G_MTX_PROJECTION 0x04
304 # define G_MTX_MUL 0x00 /* concat or load */
305 # define G_MTX_LOAD 0x02
306 # define G_MTX_NOPUSH 0x00 /* push or not */
307 # define G_MTX_PUSH 0x01
308 #else /* F3DEX_GBI_2 */
309 # define G_MTX_MODELVIEW 0x00 /* matrix types */
310 # define G_MTX_PROJECTION 0x01
311 # define G_MTX_MUL 0x00 /* concat or load */
312 # define G_MTX_LOAD 0x02
313 # define G_MTX_NOPUSH 0x00 /* push or not */
314 # define G_MTX_PUSH 0x04
315 #endif /* F3DEX_GBI_2 */
316 
317 /*
318  * flags for G_SETGEOMETRYMODE
319  * (this rendering state is maintained in RSP)
320  *
321  * DO NOT USE THE LOW 8 BITS OF GEOMETRYMODE:
322  * The weird bit-ordering is for the micro-code: the lower byte
323  * can be OR'd in with G_TRI_SHADE (11001100) to construct
324  * the triangle command directly. Don't break it...
325  *
326  * DO NOT USE THE HIGH 8 BITS OF GEOMETRYMODE:
327  * The high byte is OR'd with 0x703 to form the clip code mask.
328  * If it is set to 0x04, this will cause near clipping to occur.
329  * If it is zero, near clipping will not occur.
330  *
331  * Further explanation:
332  * G_SHADE is necessary in order to see the color that you passed
333  * down with the vertex. If G_SHADE isn't set, you need to set the DP
334  * appropriately and use primcolor to see anything.
335  *
336  * G_SHADING_SMOOTH enabled means use all 3 colors of the triangle.
337  * If it is not set, then do 'flat shading', where only one vertex color
338  * is used (and all 3 vertices are set to that same color by the ucode)
339  * See the man page for gSP1Triangle().
340  *
341  */
342 #define G_ZBUFFER 0x00000001
343 #define G_SHADE 0x00000004 /* enable Gouraud interp */
344 /* rest of low byte reserved for setup ucode */
345 #ifdef F3DEX_GBI_2
346 # define G_TEXTURE_ENABLE 0x00000000 /* Ignored */
347 # define G_SHADING_SMOOTH 0x00200000 /* flat or smooth shaded */
348 # define G_CULL_FRONT 0x00000200
349 # define G_CULL_BACK 0x00000400
350 # define G_CULL_BOTH 0x00000600 /* To make code cleaner */
351 #else
352 # define G_TEXTURE_ENABLE 0x00000002 /* Microcode use only */
353 # define G_SHADING_SMOOTH 0x00000200 /* flat or smooth shaded */
354 # define G_CULL_FRONT 0x00001000
355 # define G_CULL_BACK 0x00002000
356 # define G_CULL_BOTH 0x00003000 /* To make code cleaner */
357 #endif
358 #define G_FOG 0x00010000
359 #define G_LIGHTING 0x00020000
360 #define G_TEXTURE_GEN 0x00040000
361 #define G_TEXTURE_GEN_LINEAR 0x00080000
362 #define G_LOD 0x00100000 /* NOT IMPLEMENTED */
363 #if (defined(F3DEX_GBI)||defined(F3DLP_GBI))
364 # define G_CLIPPING 0x00800000
365 #else
366 # define G_CLIPPING 0x00000000
367 #endif
368 
369 #ifdef _LANGUAGE_ASSEMBLY
370 #define G_FOG_H (G_FOG/0x10000)
371 #define G_LIGHTING_H (G_LIGHTING/0x10000)
372 #define G_TEXTURE_GEN_H (G_TEXTURE_GEN/0x10000)
373 #define G_TEXTURE_GEN_LINEAR_H (G_TEXTURE_GEN_LINEAR/0x10000)
374 #define G_LOD_H (G_LOD/0x10000) /* NOT IMPLEMENTED */
375 #if (defined(F3DEX_GBI)||defined(F3DLP_GBI))
376 # define G_CLIPPING_H (G_CLIPPING/0x10000)
377 #endif
378 #endif
379 
380 /* Need these defined for Sprite Microcode */
381 #ifdef _LANGUAGE_ASSEMBLY
382 #define G_TX_LOADTILE 7
383 #define G_TX_RENDERTILE 0
384 
385 #define G_TX_NOMIRROR 0
386 #define G_TX_WRAP 0
387 #define G_TX_MIRROR 0x1
388 #define G_TX_CLAMP 0x2
389 #define G_TX_NOMASK 0
390 #define G_TX_NOLOD 0
391 #endif
392 
393 /*
394  * G_SETIMG fmt: set image formats
395  */
396 #define G_IM_FMT_RGBA 0
397 #define G_IM_FMT_YUV 1
398 #define G_IM_FMT_CI 2
399 #define G_IM_FMT_IA 3
400 #define G_IM_FMT_I 4
401 
402 /*
403  * G_SETIMG siz: set image pixel size
404  */
405 #define G_IM_SIZ_4b 0
406 #define G_IM_SIZ_8b 1
407 #define G_IM_SIZ_16b 2
408 #define G_IM_SIZ_32b 3
409 #define G_IM_SIZ_DD 5
410 
411 #define G_IM_SIZ_4b_BYTES 0
412 #define G_IM_SIZ_4b_TILE_BYTES G_IM_SIZ_4b_BYTES
413 #define G_IM_SIZ_4b_LINE_BYTES G_IM_SIZ_4b_BYTES
414 
415 #define G_IM_SIZ_8b_BYTES 1
416 #define G_IM_SIZ_8b_TILE_BYTES G_IM_SIZ_8b_BYTES
417 #define G_IM_SIZ_8b_LINE_BYTES G_IM_SIZ_8b_BYTES
418 
419 #define G_IM_SIZ_16b_BYTES 2
420 #define G_IM_SIZ_16b_TILE_BYTES G_IM_SIZ_16b_BYTES
421 #define G_IM_SIZ_16b_LINE_BYTES G_IM_SIZ_16b_BYTES
422 
423 #define G_IM_SIZ_32b_BYTES 4
424 #define G_IM_SIZ_32b_TILE_BYTES 2
425 #define G_IM_SIZ_32b_LINE_BYTES 2
426 
427 #define G_IM_SIZ_4b_LOAD_BLOCK G_IM_SIZ_16b
428 #define G_IM_SIZ_8b_LOAD_BLOCK G_IM_SIZ_16b
429 #define G_IM_SIZ_16b_LOAD_BLOCK G_IM_SIZ_16b
430 #define G_IM_SIZ_32b_LOAD_BLOCK G_IM_SIZ_32b
431 
432 #define G_IM_SIZ_4b_SHIFT 2
433 #define G_IM_SIZ_8b_SHIFT 1
434 #define G_IM_SIZ_16b_SHIFT 0
435 #define G_IM_SIZ_32b_SHIFT 0
436 
437 #define G_IM_SIZ_4b_INCR 3
438 #define G_IM_SIZ_8b_INCR 1
439 #define G_IM_SIZ_16b_INCR 0
440 #define G_IM_SIZ_32b_INCR 0
441 
442 /*
443  * G_SETCOMBINE: color combine modes
444  */
445 /* Color combiner constants: */
446 #define G_CCMUX_COMBINED 0
447 #define G_CCMUX_TEXEL0 1
448 #define G_CCMUX_TEXEL1 2
449 #define G_CCMUX_PRIMITIVE 3
450 #define G_CCMUX_SHADE 4
451 #define G_CCMUX_ENVIRONMENT 5
452 #define G_CCMUX_CENTER 6
453 #define G_CCMUX_SCALE 6
454 #define G_CCMUX_COMBINED_ALPHA 7
455 #define G_CCMUX_TEXEL0_ALPHA 8
456 #define G_CCMUX_TEXEL1_ALPHA 9
457 #define G_CCMUX_PRIMITIVE_ALPHA 10
458 #define G_CCMUX_SHADE_ALPHA 11
459 #define G_CCMUX_ENV_ALPHA 12
460 #define G_CCMUX_LOD_FRACTION 13
461 #define G_CCMUX_PRIM_LOD_FRAC 14
462 #define G_CCMUX_NOISE 7
463 #define G_CCMUX_K4 7
464 #define G_CCMUX_K5 15
465 #define G_CCMUX_1 6
466 #define G_CCMUX_0 31
467 
468 /* Alpha combiner constants: */
469 #define G_ACMUX_COMBINED 0
470 #define G_ACMUX_TEXEL0 1
471 #define G_ACMUX_TEXEL1 2
472 #define G_ACMUX_PRIMITIVE 3
473 #define G_ACMUX_SHADE 4
474 #define G_ACMUX_ENVIRONMENT 5
475 #define G_ACMUX_LOD_FRACTION 0
476 #define G_ACMUX_PRIM_LOD_FRAC 6
477 #define G_ACMUX_1 6
478 #define G_ACMUX_0 7
479 
480 /* typical CC cycle 1 modes */
481 #define G_CC_PRIMITIVE 0, 0, 0, PRIMITIVE, 0, 0, 0, PRIMITIVE
482 #define G_CC_SHADE 0, 0, 0, SHADE, 0, 0, 0, SHADE
483 
484 #define G_CC_MODULATEI TEXEL0, 0, SHADE, 0, 0, 0, 0, SHADE
485 #define G_CC_MODULATEIDECALA TEXEL0, 0, SHADE, 0, 0, 0, 0, TEXEL0
486 #define G_CC_MODULATEIFADE TEXEL0, 0, SHADE, 0, 0, 0, 0, ENVIRONMENT
487 
488 #define G_CC_MODULATERGB G_CC_MODULATEI
489 #define G_CC_MODULATERGBDECALA G_CC_MODULATEIDECALA
490 #define G_CC_MODULATERGBFADE G_CC_MODULATEIFADE
491 
492 #define G_CC_MODULATEIA TEXEL0, 0, SHADE, 0, TEXEL0, 0, SHADE, 0
493 #define G_CC_MODULATEIFADEA TEXEL0, 0, SHADE, 0, TEXEL0, 0, ENVIRONMENT, 0
494 
495 #define G_CC_MODULATEFADE TEXEL0, 0, SHADE, 0, ENVIRONMENT, 0, TEXEL0, 0
496 
497 #define G_CC_MODULATERGBA G_CC_MODULATEIA
498 #define G_CC_MODULATERGBFADEA G_CC_MODULATEIFADEA
499 
500 #define G_CC_MODULATEI_PRIM TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE
501 #define G_CC_MODULATEIA_PRIM TEXEL0, 0, PRIMITIVE, 0, TEXEL0, 0, PRIMITIVE, 0
502 #define G_CC_MODULATEIDECALA_PRIM TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, TEXEL0
503 
504 #define G_CC_MODULATERGB_PRIM G_CC_MODULATEI_PRIM
505 #define G_CC_MODULATERGBA_PRIM G_CC_MODULATEIA_PRIM
506 #define G_CC_MODULATERGBDECALA_PRIM G_CC_MODULATEIDECALA_PRIM
507 
508 #define G_CC_FADE SHADE, 0, ENVIRONMENT, 0, SHADE, 0, ENVIRONMENT, 0
509 #define G_CC_FADEA TEXEL0, 0, ENVIRONMENT, 0, TEXEL0, 0, ENVIRONMENT, 0
510 
511 #define G_CC_DECALRGB 0, 0, 0, TEXEL0, 0, 0, 0, SHADE
512 #define G_CC_DECALRGBA 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0
513 #define G_CC_DECALFADE 0, 0, 0, TEXEL0, 0, 0, 0, ENVIRONMENT
514 
515 #define G_CC_DECALFADEA 0, 0, 0, TEXEL0, TEXEL0, 0, ENVIRONMENT, 0
516 
517 #define G_CC_BLENDI ENVIRONMENT, SHADE, TEXEL0, SHADE, 0, 0, 0, SHADE
518 #define G_CC_BLENDIA ENVIRONMENT, SHADE, TEXEL0, SHADE, TEXEL0, 0, SHADE, 0
519 #define G_CC_BLENDIDECALA ENVIRONMENT, SHADE, TEXEL0, SHADE, 0, 0, 0, TEXEL0
520 
521 #define G_CC_BLENDRGBA TEXEL0, SHADE, TEXEL0_ALPHA, SHADE, 0, 0, 0, SHADE
522 #define G_CC_BLENDRGBDECALA TEXEL0, SHADE, TEXEL0_ALPHA, SHADE, 0, 0, 0, TEXEL0
523 #define G_CC_BLENDRGBFADEA TEXEL0, SHADE, TEXEL0_ALPHA, SHADE, 0, 0, 0, ENVIRONMENT
524 
525 #define G_CC_ADDRGB TEXEL0, 0, TEXEL0, SHADE, 0, 0, 0, SHADE
526 #define G_CC_ADDRGBDECALA TEXEL0, 0, TEXEL0, SHADE, 0, 0, 0, TEXEL0
527 #define G_CC_ADDRGBFADE TEXEL0, 0, TEXEL0, SHADE, 0, 0, 0, ENVIRONMENT
528 
529 #define G_CC_REFLECTRGB ENVIRONMENT, 0, TEXEL0, SHADE, 0, 0, 0, SHADE
530 #define G_CC_REFLECTRGBDECALA ENVIRONMENT, 0, TEXEL0, SHADE, 0, 0, 0, TEXEL0
531 
532 #define G_CC_HILITERGB PRIMITIVE, SHADE, TEXEL0, SHADE, 0, 0, 0, SHADE
533 #define G_CC_HILITERGBA PRIMITIVE, SHADE, TEXEL0, SHADE, PRIMITIVE, SHADE, TEXEL0, SHADE
534 #define G_CC_HILITERGBDECALA PRIMITIVE, SHADE, TEXEL0, SHADE, 0, 0, 0, TEXEL0
535 
536 #define G_CC_SHADEDECALA 0, 0, 0, SHADE, 0, 0, 0, TEXEL0
537 #define G_CC_SHADEFADEA 0, 0, 0, SHADE, 0, 0, 0, ENVIRONMENT
538 
539 #define G_CC_BLENDPE PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, SHADE, 0
540 #define G_CC_BLENDPEDECALA PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, 0, 0, 0, TEXEL0
541 
542 /* oddball modes */
543 #define _G_CC_BLENDPE ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, TEXEL0, 0, SHADE, 0
544 #define _G_CC_BLENDPEDECALA ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, 0, 0, 0, TEXEL0
545 #define _G_CC_TWOCOLORTEX PRIMITIVE, SHADE, TEXEL0, SHADE, 0, 0, 0, SHADE
546 /* used for 1-cycle sparse mip-maps, primitive color has color of lowest LOD */
547 #define _G_CC_SPARSEST PRIMITIVE, TEXEL0, LOD_FRACTION, TEXEL0, PRIMITIVE, TEXEL0, LOD_FRACTION, TEXEL0
548 #define G_CC_TEMPLERP TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0, TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0
549 
550 /* typical CC cycle 1 modes, usually followed by other cycle 2 modes */
551 #define G_CC_TRILERP TEXEL1, TEXEL0, LOD_FRACTION, TEXEL0, TEXEL1, TEXEL0, LOD_FRACTION, TEXEL0
552 #define G_CC_INTERFERENCE TEXEL0, 0, TEXEL1, 0, TEXEL0, 0, TEXEL1, 0
553 
554 /*
555  * One-cycle color convert operation
556  */
557 #define G_CC_1CYUV2RGB TEXEL0, K4, K5, TEXEL0, 0, 0, 0, SHADE
558 
559 /*
560  * NOTE: YUV2RGB expects TF step1 color conversion to occur in 2nd clock.
561  * Therefore, CC looks for step1 results in TEXEL1
562  */
563 #define G_CC_YUV2RGB TEXEL1, K4, K5, TEXEL1, 0, 0, 0, 0
564 
565 /* typical CC cycle 2 modes */
566 #define G_CC_PASS2 0, 0, 0, COMBINED, 0, 0, 0, COMBINED
567 #define G_CC_MODULATEI2 COMBINED, 0, SHADE, 0, 0, 0, 0, SHADE
568 #define G_CC_MODULATEIA2 COMBINED, 0, SHADE, 0, COMBINED, 0, SHADE, 0
569 #define G_CC_MODULATERGB2 G_CC_MODULATEI2
570 #define G_CC_MODULATERGBA2 G_CC_MODULATEIA2
571 #define G_CC_MODULATEI_PRIM2 COMBINED, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE
572 #define G_CC_MODULATEIA_PRIM2 COMBINED, 0, PRIMITIVE, 0, COMBINED, 0, PRIMITIVE, 0
573 #define G_CC_MODULATERGB_PRIM2 G_CC_MODULATEI_PRIM2
574 #define G_CC_MODULATERGBA_PRIM2 G_CC_MODULATEIA_PRIM2
575 #define G_CC_DECALRGB2 0, 0, 0, COMBINED, 0, 0, 0, SHADE
576 /*
577  * ?
578 #define G_CC_DECALRGBA2 COMBINED, SHADE, COMBINED_ALPHA, SHADE, 0, 0, 0, SHADE
579 */
580 #define G_CC_BLENDI2 ENVIRONMENT, SHADE, COMBINED, SHADE, 0, 0, 0, SHADE
581 #define G_CC_BLENDIA2 ENVIRONMENT, SHADE, COMBINED, SHADE, COMBINED, 0, SHADE, 0
582 #define G_CC_CHROMA_KEY2 TEXEL0, CENTER, SCALE, 0, 0, 0, 0, 0
583 #define G_CC_HILITERGB2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, 0, 0, 0, SHADE
584 #define G_CC_HILITERGBA2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, ENVIRONMENT, COMBINED, TEXEL0, COMBINED
585 #define G_CC_HILITERGBDECALA2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, 0, 0, 0, TEXEL0
586 #define G_CC_HILITERGBPASSA2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, 0, 0, 0, COMBINED
587 
588 /*
589  * G_SETOTHERMODE_L sft: shift count
590  */
591 #define G_MDSFT_ALPHACOMPARE 0
592 #define G_MDSFT_ZSRCSEL 2
593 #define G_MDSFT_RENDERMODE 3
594 #define G_MDSFT_BLENDER 16
595 
596 /*
597  * G_SETOTHERMODE_H sft: shift count
598  */
599 #define G_MDSFT_BLENDMASK 0 /* unsupported */
600 #define G_MDSFT_ALPHADITHER 4
601 #define G_MDSFT_RGBDITHER 6
602 
603 #define G_MDSFT_COMBKEY 8
604 #define G_MDSFT_TEXTCONV 9
605 #define G_MDSFT_TEXTFILT 12
606 #define G_MDSFT_TEXTLUT 14
607 #define G_MDSFT_TEXTLOD 16
608 #define G_MDSFT_TEXTDETAIL 17
609 #define G_MDSFT_TEXTPERSP 19
610 #define G_MDSFT_CYCLETYPE 20
611 #define G_MDSFT_COLORDITHER 22 /* unsupported in HW 2.0 */
612 #define G_MDSFT_PIPELINE 23
613 
614 /* G_SETOTHERMODE_H gPipelineMode */
615 #define G_PM_1PRIMITIVE (1 << G_MDSFT_PIPELINE)
616 #define G_PM_NPRIMITIVE (0 << G_MDSFT_PIPELINE)
617 
618 /* G_SETOTHERMODE_H gSetCycleType */
619 #define G_CYC_1CYCLE (0 << G_MDSFT_CYCLETYPE)
620 #define G_CYC_2CYCLE (1 << G_MDSFT_CYCLETYPE)
621 #define G_CYC_COPY (2 << G_MDSFT_CYCLETYPE)
622 #define G_CYC_FILL (3 << G_MDSFT_CYCLETYPE)
623 
624 /* G_SETOTHERMODE_H gSetTexturePersp */
625 #define G_TP_NONE (0 << G_MDSFT_TEXTPERSP)
626 #define G_TP_PERSP (1 << G_MDSFT_TEXTPERSP)
627 
628 /* G_SETOTHERMODE_H gSetTextureDetail */
629 #define G_TD_CLAMP (0 << G_MDSFT_TEXTDETAIL)
630 #define G_TD_SHARPEN (1 << G_MDSFT_TEXTDETAIL)
631 #define G_TD_DETAIL (2 << G_MDSFT_TEXTDETAIL)
632 
633 /* G_SETOTHERMODE_H gSetTextureLOD */
634 #define G_TL_TILE (0 << G_MDSFT_TEXTLOD)
635 #define G_TL_LOD (1 << G_MDSFT_TEXTLOD)
636 
637 /* G_SETOTHERMODE_H gSetTextureLUT */
638 #define G_TT_NONE (0 << G_MDSFT_TEXTLUT)
639 #define G_TT_RGBA16 (2 << G_MDSFT_TEXTLUT)
640 #define G_TT_IA16 (3 << G_MDSFT_TEXTLUT)
641 
642 /* G_SETOTHERMODE_H gSetTextureFilter */
643 #define G_TF_POINT (0 << G_MDSFT_TEXTFILT)
644 #define G_TF_AVERAGE (3 << G_MDSFT_TEXTFILT)
645 #define G_TF_BILERP (2 << G_MDSFT_TEXTFILT)
646 
647 /* G_SETOTHERMODE_H gSetTextureConvert */
648 #define G_TC_CONV (0 << G_MDSFT_TEXTCONV)
649 #define G_TC_FILTCONV (5 << G_MDSFT_TEXTCONV)
650 #define G_TC_FILT (6 << G_MDSFT_TEXTCONV)
651 
652 /* G_SETOTHERMODE_H gSetCombineKey */
653 #define G_CK_NONE (0 << G_MDSFT_COMBKEY)
654 #define G_CK_KEY (1 << G_MDSFT_COMBKEY)
655 
656 /* G_SETOTHERMODE_H gSetColorDither */
657 #define G_CD_MAGICSQ (0 << G_MDSFT_RGBDITHER)
658 #define G_CD_BAYER (1 << G_MDSFT_RGBDITHER)
659 #define G_CD_NOISE (2 << G_MDSFT_RGBDITHER)
660 
661 #ifndef _HW_VERSION_1
662 #define G_CD_DISABLE (3 << G_MDSFT_RGBDITHER)
663 #define G_CD_ENABLE G_CD_NOISE /* HW 1.0 compatibility mode */
664 #else
665 #define G_CD_ENABLE (1 << G_MDSFT_COLORDITHER)
666 #define G_CD_DISABLE (0 << G_MDSFT_COLORDITHER)
667 #endif
668 
669 /* G_SETOTHERMODE_H gSetAlphaDither */
670 #define G_AD_PATTERN (0 << G_MDSFT_ALPHADITHER)
671 #define G_AD_NOTPATTERN (1 << G_MDSFT_ALPHADITHER)
672 #define G_AD_NOISE (2 << G_MDSFT_ALPHADITHER)
673 #define G_AD_DISABLE (3 << G_MDSFT_ALPHADITHER)
674 
675 /* G_SETOTHERMODE_L gSetAlphaCompare */
676 #define G_AC_NONE (0 << G_MDSFT_ALPHACOMPARE)
677 #define G_AC_THRESHOLD (1 << G_MDSFT_ALPHACOMPARE)
678 #define G_AC_DITHER (3 << G_MDSFT_ALPHACOMPARE)
679 
680 /* G_SETOTHERMODE_L gSetDepthSource */
681 #define G_ZS_PIXEL (0 << G_MDSFT_ZSRCSEL)
682 #define G_ZS_PRIM (1 << G_MDSFT_ZSRCSEL)
683 
684 /* G_SETOTHERMODE_L gSetRenderMode */
685 #define AA_EN 0x8
686 #define Z_CMP 0x10
687 #define Z_UPD 0x20
688 #define IM_RD 0x40
689 #define CLR_ON_CVG 0x80
690 #define CVG_DST_CLAMP 0
691 #define CVG_DST_WRAP 0x100
692 #define CVG_DST_FULL 0x200
693 #define CVG_DST_SAVE 0x300
694 #define ZMODE_OPA 0
695 #define ZMODE_INTER 0x400
696 #define ZMODE_XLU 0x800
697 #define ZMODE_DEC 0xc00
698 #define CVG_X_ALPHA 0x1000
699 #define ALPHA_CVG_SEL 0x2000
700 #define FORCE_BL 0x4000
701 #define TEX_EDGE 0x0000 /* used to be 0x8000 */
702 
703 #define G_BL_CLR_IN 0
704 #define G_BL_CLR_MEM 1
705 #define G_BL_CLR_BL 2
706 #define G_BL_CLR_FOG 3
707 #define G_BL_1MA 0
708 #define G_BL_A_MEM 1
709 #define G_BL_A_IN 0
710 #define G_BL_A_FOG 1
711 #define G_BL_A_SHADE 2
712 #define G_BL_1 2
713 #define G_BL_0 3
714 
715 #define GBL_c1(m1a, m1b, m2a, m2b) \
716  (m1a) << 30 | (m1b) << 26 | (m2a) << 22 | (m2b) << 18
717 #define GBL_c2(m1a, m1b, m2a, m2b) \
718  (m1a) << 28 | (m1b) << 24 | (m2a) << 20 | (m2b) << 16
719 
720 #define RM_AA_ZB_OPA_SURF(clk) \
721  AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \
722  ZMODE_OPA | ALPHA_CVG_SEL | \
723  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
724 
725 #define RM_RA_ZB_OPA_SURF(clk) \
726  AA_EN | Z_CMP | Z_UPD | CVG_DST_CLAMP | \
727  ZMODE_OPA | ALPHA_CVG_SEL | \
728  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
729 
730 #define RM_AA_ZB_XLU_SURF(clk) \
731  AA_EN | Z_CMP | IM_RD | CVG_DST_WRAP | CLR_ON_CVG | \
732  FORCE_BL | ZMODE_XLU | \
733  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
734 
735 #define RM_AA_ZB_OPA_DECAL(clk) \
736  AA_EN | Z_CMP | IM_RD | CVG_DST_WRAP | ALPHA_CVG_SEL | \
737  ZMODE_DEC | \
738  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
739 
740 #define RM_RA_ZB_OPA_DECAL(clk) \
741  AA_EN | Z_CMP | CVG_DST_WRAP | ALPHA_CVG_SEL | \
742  ZMODE_DEC | \
743  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
744 
745 #define RM_AA_ZB_XLU_DECAL(clk) \
746  AA_EN | Z_CMP | IM_RD | CVG_DST_WRAP | CLR_ON_CVG | \
747  FORCE_BL | ZMODE_DEC | \
748  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
749 
750 #define RM_AA_ZB_OPA_INTER(clk) \
751  AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \
752  ALPHA_CVG_SEL | ZMODE_INTER | \
753  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
754 
755 #define RM_RA_ZB_OPA_INTER(clk) \
756  AA_EN | Z_CMP | Z_UPD | CVG_DST_CLAMP | \
757  ALPHA_CVG_SEL | ZMODE_INTER | \
758  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
759 
760 #define RM_AA_ZB_XLU_INTER(clk) \
761  AA_EN | Z_CMP | IM_RD | CVG_DST_WRAP | CLR_ON_CVG | \
762  FORCE_BL | ZMODE_INTER | \
763  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
764 
765 #define RM_AA_ZB_XLU_LINE(clk) \
766  AA_EN | Z_CMP | IM_RD | CVG_DST_CLAMP | CVG_X_ALPHA | \
767  ALPHA_CVG_SEL | FORCE_BL | ZMODE_XLU | \
768  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
769 
770 #define RM_AA_ZB_DEC_LINE(clk) \
771  AA_EN | Z_CMP | IM_RD | CVG_DST_SAVE | CVG_X_ALPHA | \
772  ALPHA_CVG_SEL | FORCE_BL | ZMODE_DEC | \
773  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
774 
775 #define RM_AA_ZB_TEX_EDGE(clk) \
776  AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \
777  CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE | \
778  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
779 
780 #define RM_AA_ZB_TEX_INTER(clk) \
781  AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \
782  CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_INTER | TEX_EDGE | \
783  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
784 
785 #define RM_AA_ZB_SUB_SURF(clk) \
786  AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_FULL | \
787  ZMODE_OPA | ALPHA_CVG_SEL | \
788  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
789 
790 #define RM_AA_ZB_PCL_SURF(clk) \
791  AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \
792  ZMODE_OPA | G_AC_DITHER | \
793  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
794 
795 #define RM_AA_ZB_OPA_TERR(clk) \
796  AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \
797  ZMODE_OPA | ALPHA_CVG_SEL | \
798  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
799 
800 #define RM_AA_ZB_TEX_TERR(clk) \
801  AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \
802  CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE | \
803  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
804 
805 #define RM_AA_ZB_SUB_TERR(clk) \
806  AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_FULL | \
807  ZMODE_OPA | ALPHA_CVG_SEL | \
808  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
809 
810 
811 #define RM_AA_OPA_SURF(clk) \
812  AA_EN | IM_RD | CVG_DST_CLAMP | \
813  ZMODE_OPA | ALPHA_CVG_SEL | \
814  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
815 
816 #define RM_RA_OPA_SURF(clk) \
817  AA_EN | CVG_DST_CLAMP | \
818  ZMODE_OPA | ALPHA_CVG_SEL | \
819  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
820 
821 #define RM_AA_XLU_SURF(clk) \
822  AA_EN | IM_RD | CVG_DST_WRAP | CLR_ON_CVG | FORCE_BL | \
823  ZMODE_OPA | \
824  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
825 
826 #define RM_AA_XLU_LINE(clk) \
827  AA_EN | IM_RD | CVG_DST_CLAMP | CVG_X_ALPHA | \
828  ALPHA_CVG_SEL | FORCE_BL | ZMODE_OPA | \
829  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
830 
831 #define RM_AA_DEC_LINE(clk) \
832  AA_EN | IM_RD | CVG_DST_FULL | CVG_X_ALPHA | \
833  ALPHA_CVG_SEL | FORCE_BL | ZMODE_OPA | \
834  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
835 
836 #define RM_AA_TEX_EDGE(clk) \
837  AA_EN | IM_RD | CVG_DST_CLAMP | \
838  CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE | \
839  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
840 
841 #define RM_AA_SUB_SURF(clk) \
842  AA_EN | IM_RD | CVG_DST_FULL | \
843  ZMODE_OPA | ALPHA_CVG_SEL | \
844  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
845 
846 #define RM_AA_PCL_SURF(clk) \
847  AA_EN | IM_RD | CVG_DST_CLAMP | \
848  ZMODE_OPA | G_AC_DITHER | \
849  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
850 
851 #define RM_AA_OPA_TERR(clk) \
852  AA_EN | IM_RD | CVG_DST_CLAMP | \
853  ZMODE_OPA | ALPHA_CVG_SEL | \
854  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
855 
856 #define RM_AA_TEX_TERR(clk) \
857  AA_EN | IM_RD | CVG_DST_CLAMP | \
858  CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE | \
859  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
860 
861 #define RM_AA_SUB_TERR(clk) \
862  AA_EN | IM_RD | CVG_DST_FULL | \
863  ZMODE_OPA | ALPHA_CVG_SEL | \
864  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
865 
866 
867 #define RM_ZB_OPA_SURF(clk) \
868  Z_CMP | Z_UPD | CVG_DST_FULL | ALPHA_CVG_SEL | \
869  ZMODE_OPA | \
870  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
871 
872 #define RM_ZB_XLU_SURF(clk) \
873  Z_CMP | IM_RD | CVG_DST_FULL | FORCE_BL | ZMODE_XLU | \
874  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
875 
876 #define RM_ZB_OPA_DECAL(clk) \
877  Z_CMP | CVG_DST_FULL | ALPHA_CVG_SEL | ZMODE_DEC | \
878  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
879 
880 #define RM_ZB_XLU_DECAL(clk) \
881  Z_CMP | IM_RD | CVG_DST_FULL | FORCE_BL | ZMODE_DEC | \
882  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
883 
884 #define RM_ZB_CLD_SURF(clk) \
885  Z_CMP | IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_XLU | \
886  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
887 
888 #define RM_ZB_OVL_SURF(clk) \
889  Z_CMP | IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_DEC | \
890  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
891 
892 #define RM_ZB_PCL_SURF(clk) \
893  Z_CMP | Z_UPD | CVG_DST_FULL | ZMODE_OPA | \
894  G_AC_DITHER | \
895  GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
896 
897 
898 #define RM_OPA_SURF(clk) \
899  CVG_DST_CLAMP | FORCE_BL | ZMODE_OPA | \
900  GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
901 
902 #define RM_XLU_SURF(clk) \
903  IM_RD | CVG_DST_FULL | FORCE_BL | ZMODE_OPA | \
904  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
905 
906 #define RM_TEX_EDGE(clk) \
907  CVG_DST_CLAMP | CVG_X_ALPHA | ALPHA_CVG_SEL | FORCE_BL |\
908  ZMODE_OPA | TEX_EDGE | AA_EN | \
909  GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
910 
911 #define RM_CLD_SURF(clk) \
912  IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_OPA | \
913  GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
914 
915 #define RM_PCL_SURF(clk) \
916  CVG_DST_FULL | FORCE_BL | ZMODE_OPA | \
917  G_AC_DITHER | \
918  GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
919 
920 #define RM_ADD(clk) \
921  IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_OPA | \
922  GBL_c##clk(G_BL_CLR_IN, G_BL_A_FOG, G_BL_CLR_MEM, G_BL_1)
923 
924 #define RM_NOOP(clk) \
925  GBL_c##clk(0, 0, 0, 0)
926 
927 #define RM_VISCVG(clk) \
928  IM_RD | FORCE_BL | \
929  GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_BL, G_BL_A_MEM)
930 
931 /* for rendering to an 8-bit framebuffer */
932 #define RM_OPA_CI(clk) \
933  CVG_DST_CLAMP | ZMODE_OPA | \
934  GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
935 
936 /* Custom version of RM_AA_ZB_XLU_SURF with Z_UPD */
937 #define RM_CUSTOM_AA_ZB_XLU_SURF(clk) \
938  RM_AA_ZB_XLU_SURF(clk) | Z_UPD
939 
940 
941 #define G_RM_AA_ZB_OPA_SURF RM_AA_ZB_OPA_SURF(1)
942 #define G_RM_AA_ZB_OPA_SURF2 RM_AA_ZB_OPA_SURF(2)
943 #define G_RM_AA_ZB_XLU_SURF RM_AA_ZB_XLU_SURF(1)
944 #define G_RM_AA_ZB_XLU_SURF2 RM_AA_ZB_XLU_SURF(2)
945 #define G_RM_AA_ZB_OPA_DECAL RM_AA_ZB_OPA_DECAL(1)
946 #define G_RM_AA_ZB_OPA_DECAL2 RM_AA_ZB_OPA_DECAL(2)
947 #define G_RM_AA_ZB_XLU_DECAL RM_AA_ZB_XLU_DECAL(1)
948 #define G_RM_AA_ZB_XLU_DECAL2 RM_AA_ZB_XLU_DECAL(2)
949 #define G_RM_AA_ZB_OPA_INTER RM_AA_ZB_OPA_INTER(1)
950 #define G_RM_AA_ZB_OPA_INTER2 RM_AA_ZB_OPA_INTER(2)
951 #define G_RM_AA_ZB_XLU_INTER RM_AA_ZB_XLU_INTER(1)
952 #define G_RM_AA_ZB_XLU_INTER2 RM_AA_ZB_XLU_INTER(2)
953 #define G_RM_AA_ZB_XLU_LINE RM_AA_ZB_XLU_LINE(1)
954 #define G_RM_AA_ZB_XLU_LINE2 RM_AA_ZB_XLU_LINE(2)
955 #define G_RM_AA_ZB_DEC_LINE RM_AA_ZB_DEC_LINE(1)
956 #define G_RM_AA_ZB_DEC_LINE2 RM_AA_ZB_DEC_LINE(2)
957 #define G_RM_AA_ZB_TEX_EDGE RM_AA_ZB_TEX_EDGE(1)
958 #define G_RM_AA_ZB_TEX_EDGE2 RM_AA_ZB_TEX_EDGE(2)
959 #define G_RM_AA_ZB_TEX_INTER RM_AA_ZB_TEX_INTER(1)
960 #define G_RM_AA_ZB_TEX_INTER2 RM_AA_ZB_TEX_INTER(2)
961 #define G_RM_AA_ZB_SUB_SURF RM_AA_ZB_SUB_SURF(1)
962 #define G_RM_AA_ZB_SUB_SURF2 RM_AA_ZB_SUB_SURF(2)
963 #define G_RM_AA_ZB_PCL_SURF RM_AA_ZB_PCL_SURF(1)
964 #define G_RM_AA_ZB_PCL_SURF2 RM_AA_ZB_PCL_SURF(2)
965 #define G_RM_AA_ZB_OPA_TERR RM_AA_ZB_OPA_TERR(1)
966 #define G_RM_AA_ZB_OPA_TERR2 RM_AA_ZB_OPA_TERR(2)
967 #define G_RM_AA_ZB_TEX_TERR RM_AA_ZB_TEX_TERR(1)
968 #define G_RM_AA_ZB_TEX_TERR2 RM_AA_ZB_TEX_TERR(2)
969 #define G_RM_AA_ZB_SUB_TERR RM_AA_ZB_SUB_TERR(1)
970 #define G_RM_AA_ZB_SUB_TERR2 RM_AA_ZB_SUB_TERR(2)
971 
972 #define G_RM_RA_ZB_OPA_SURF RM_RA_ZB_OPA_SURF(1)
973 #define G_RM_RA_ZB_OPA_SURF2 RM_RA_ZB_OPA_SURF(2)
974 #define G_RM_RA_ZB_OPA_DECAL RM_RA_ZB_OPA_DECAL(1)
975 #define G_RM_RA_ZB_OPA_DECAL2 RM_RA_ZB_OPA_DECAL(2)
976 #define G_RM_RA_ZB_OPA_INTER RM_RA_ZB_OPA_INTER(1)
977 #define G_RM_RA_ZB_OPA_INTER2 RM_RA_ZB_OPA_INTER(2)
978 
979 #define G_RM_AA_OPA_SURF RM_AA_OPA_SURF(1)
980 #define G_RM_AA_OPA_SURF2 RM_AA_OPA_SURF(2)
981 #define G_RM_AA_XLU_SURF RM_AA_XLU_SURF(1)
982 #define G_RM_AA_XLU_SURF2 RM_AA_XLU_SURF(2)
983 #define G_RM_AA_XLU_LINE RM_AA_XLU_LINE(1)
984 #define G_RM_AA_XLU_LINE2 RM_AA_XLU_LINE(2)
985 #define G_RM_AA_DEC_LINE RM_AA_DEC_LINE(1)
986 #define G_RM_AA_DEC_LINE2 RM_AA_DEC_LINE(2)
987 #define G_RM_AA_TEX_EDGE RM_AA_TEX_EDGE(1)
988 #define G_RM_AA_TEX_EDGE2 RM_AA_TEX_EDGE(2)
989 #define G_RM_AA_SUB_SURF RM_AA_SUB_SURF(1)
990 #define G_RM_AA_SUB_SURF2 RM_AA_SUB_SURF(2)
991 #define G_RM_AA_PCL_SURF RM_AA_PCL_SURF(1)
992 #define G_RM_AA_PCL_SURF2 RM_AA_PCL_SURF(2)
993 #define G_RM_AA_OPA_TERR RM_AA_OPA_TERR(1)
994 #define G_RM_AA_OPA_TERR2 RM_AA_OPA_TERR(2)
995 #define G_RM_AA_TEX_TERR RM_AA_TEX_TERR(1)
996 #define G_RM_AA_TEX_TERR2 RM_AA_TEX_TERR(2)
997 #define G_RM_AA_SUB_TERR RM_AA_SUB_TERR(1)
998 #define G_RM_AA_SUB_TERR2 RM_AA_SUB_TERR(2)
999 
1000 #define G_RM_RA_OPA_SURF RM_RA_OPA_SURF(1)
1001 #define G_RM_RA_OPA_SURF2 RM_RA_OPA_SURF(2)
1002 
1003 #define G_RM_ZB_OPA_SURF RM_ZB_OPA_SURF(1)
1004 #define G_RM_ZB_OPA_SURF2 RM_ZB_OPA_SURF(2)
1005 #define G_RM_ZB_XLU_SURF RM_ZB_XLU_SURF(1)
1006 #define G_RM_ZB_XLU_SURF2 RM_ZB_XLU_SURF(2)
1007 #define G_RM_ZB_OPA_DECAL RM_ZB_OPA_DECAL(1)
1008 #define G_RM_ZB_OPA_DECAL2 RM_ZB_OPA_DECAL(2)
1009 #define G_RM_ZB_XLU_DECAL RM_ZB_XLU_DECAL(1)
1010 #define G_RM_ZB_XLU_DECAL2 RM_ZB_XLU_DECAL(2)
1011 #define G_RM_ZB_CLD_SURF RM_ZB_CLD_SURF(1)
1012 #define G_RM_ZB_CLD_SURF2 RM_ZB_CLD_SURF(2)
1013 #define G_RM_ZB_OVL_SURF RM_ZB_OVL_SURF(1)
1014 #define G_RM_ZB_OVL_SURF2 RM_ZB_OVL_SURF(2)
1015 #define G_RM_ZB_PCL_SURF RM_ZB_PCL_SURF(1)
1016 #define G_RM_ZB_PCL_SURF2 RM_ZB_PCL_SURF(2)
1017 
1018 #define G_RM_OPA_SURF RM_OPA_SURF(1)
1019 #define G_RM_OPA_SURF2 RM_OPA_SURF(2)
1020 #define G_RM_XLU_SURF RM_XLU_SURF(1)
1021 #define G_RM_XLU_SURF2 RM_XLU_SURF(2)
1022 #define G_RM_CLD_SURF RM_CLD_SURF(1)
1023 #define G_RM_CLD_SURF2 RM_CLD_SURF(2)
1024 #define G_RM_TEX_EDGE RM_TEX_EDGE(1)
1025 #define G_RM_TEX_EDGE2 RM_TEX_EDGE(2)
1026 #define G_RM_PCL_SURF RM_PCL_SURF(1)
1027 #define G_RM_PCL_SURF2 RM_PCL_SURF(2)
1028 #define G_RM_ADD RM_ADD(1)
1029 #define G_RM_ADD2 RM_ADD(2)
1030 #define G_RM_NOOP RM_NOOP(1)
1031 #define G_RM_NOOP2 RM_NOOP(2)
1032 #define G_RM_VISCVG RM_VISCVG(1)
1033 #define G_RM_VISCVG2 RM_VISCVG(2)
1034 #define G_RM_OPA_CI RM_OPA_CI(1)
1035 #define G_RM_OPA_CI2 RM_OPA_CI(2)
1036 
1037 #define G_RM_CUSTOM_AA_ZB_XLU_SURF RM_CUSTOM_AA_ZB_XLU_SURF(1)
1038 #define G_RM_CUSTOM_AA_ZB_XLU_SURF2 RM_CUSTOM_AA_ZB_XLU_SURF(2)
1039 
1040 
1041 #define G_RM_FOG_SHADE_A GBL_c1(G_BL_CLR_FOG, G_BL_A_SHADE, G_BL_CLR_IN, G_BL_1MA)
1042 #define G_RM_FOG_PRIM_A GBL_c1(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_IN, G_BL_1MA)
1043 #define G_RM_PASS GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
1044 
1045 /*
1046  * G_SETCONVERT: K0-5
1047  */
1048 #define G_CV_K0 175
1049 #define G_CV_K1 -43
1050 #define G_CV_K2 -89
1051 #define G_CV_K3 222
1052 #define G_CV_K4 114
1053 #define G_CV_K5 42
1054 
1055 /*
1056  * G_SETSCISSOR: interlace mode
1057  */
1058 #define G_SC_NON_INTERLACE 0
1059 #define G_SC_ODD_INTERLACE 3
1060 #define G_SC_EVEN_INTERLACE 2
1061 
1062 /* flags to inhibit pushing of the display list (on branch) */
1063 #define G_DL_PUSH 0x00
1064 #define G_DL_NOPUSH 0x01
1065 
1066 /*
1067  * BEGIN C-specific section: (typedef's)
1068  */
1069 #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
1070 
1071 /*
1072  * Data Structures
1073  *
1074  * NOTE:
1075  * The DMA transfer hardware requires 64-bit aligned, 64-bit multiple-
1076  * sized transfers. This important hardware optimization is unfortunately
1077  * reflected in the programming interface, with some structures
1078  * padded and alignment enforced.
1079  *
1080  * Since structures are aligned to the boundary of the "worst-case"
1081  * element, we can't depend on the C compiler to align things
1082  * properly.
1083  *
1084  * 64-bit structure alignment is enforced by wrapping structures with
1085  * unions that contain a dummy "long long int". Why this works is
1086  * explained in the ANSI C Spec, or on page 186 of the second edition
1087  * of K&R, "The C Programming Language".
1088  *
1089  * The price we pay for this is a little awkwardness referencing the
1090  * structures through the union. There is no memory penalty, since
1091  * all the structures are at least 64-bits the dummy alignment field
1092  * does not increase the size of the union.
1093  *
1094  * Static initialization of these union structures works because
1095  * the ANSI C spec states that static initialization for unions
1096  * works by using the first union element. We put the dummy alignment
1097  * field last for this reason.
1098  *
1099  * (it's possible a newer 64-bit compiler from MIPS might make this
1100  * easier with a flag, but we can't wait for it...)
1101  *
1102  */
1103 
1104 /*
1105  * Vertex (set up for use with colors)
1106  */
1107 typedef struct {
1108  short ob[3]; /* x, y, z */
1109  unsigned short flag;
1110  short tc[2]; /* texture coord */
1111  unsigned char cn[4]; /* color & alpha */
1112 } Vtx_t;
1113 
1114 /*
1115  * Vertex (set up for use with normals)
1116  */
1117 typedef struct {
1118  short ob[3]; /* x, y, z */
1119  unsigned short flag;
1120  short tc[2]; /* texture coord */
1121  signed char n[3]; /* normal */
1122  unsigned char a; /* alpha */
1123 } Vtx_tn;
1124 
1125 typedef union {
1126  Vtx_t v; /* Use this one for colors */
1127  Vtx_tn n; /* Use this one for normals */
1128  long long int force_structure_alignment;
1129 } Vtx;
1130 
1131 /*
1132  * Sprite structure
1133  */
1134 
1135 typedef struct {
1136  void *SourceImagePointer;
1137  void *TlutPointer;
1138  short Stride;
1139  short SubImageWidth;
1140  short SubImageHeight;
1141  char SourceImageType;
1142  char SourceImageBitSize;
1143  short SourceImageOffsetS;
1144  short SourceImageOffsetT;
1145  /* 20 bytes for above */
1146 
1147  /* padding to bring structure size to 64 bit allignment */
1148  char dummy[4];
1149 
1150 } uSprite_t;
1151 
1152 typedef union {
1153  uSprite_t s;
1154 
1155  /* Need to make sure this is 64 bit aligned */
1156  long long int force_structure_allignment[3];
1157 } uSprite;
1158 
1159 /*
1160  * Triangle face
1161  */
1162 typedef struct {
1163  unsigned char flag;
1164  unsigned char v[3];
1165 } Tri;
1166 
1167 /*
1168  * 4x4 matrix, fixed point s15.16 format.
1169  * First 8 words are integer portion of the 4x4 matrix
1170  * Last 8 words are the fraction portion of the 4x4 matrix
1171  */
1172 typedef s32 Mtx_t[4][4];
1173 
1174 typedef union {
1175  Mtx_t m;
1176  long long int force_structure_alignment;
1177 } Mtx;
1178 
1179 /*
1180  * Viewport
1181  */
1182 
1183 /*
1184  *
1185  * This magic value is the maximum INTEGER z-range of the hardware
1186  * (there are also 16-bits of fraction, which are introduced during
1187  * any transformations). This is not just a good idea, it's the law.
1188  * Feeding the hardware eventual z-coordinates (after any transforms
1189  * or scaling) bigger than this, will not work.
1190  *
1191  * This number is DIFFERENT than G_MAXFBZ, which is the maximum value
1192  * you want to use to initialize the z-buffer.
1193  *
1194  * The reason these are different is mildly interesting, but too long
1195  * to explain here. It is basically the result of optimizations in the
1196  * hardware. A more generic API might hide this detail from the users,
1197  * but we don't have the ucode to do that...
1198  *
1199  */
1200 #define G_MAXZ 0x03ff /* 10 bits of integer screen-Z precision */
1201 
1202 /*
1203  * The viewport structure elements have 2 bits of fraction, necessary
1204  * to accomodate the sub-pixel positioning scaling for the hardware.
1205  * This can also be exploited to handle odd-sized viewports.
1206  *
1207  * Accounting for these fractional bits, using the default projection
1208  * and viewing matrices, the viewport structure is initialized thusly:
1209  *
1210  * (SCREEN_WD/2)*4, (SCREEN_HT/2)*4, G_MAXZ, 0,
1211  * (SCREEN_WD/2)*4, (SCREEN_HT/2)*4, 0, 0,
1212  */
1213 typedef struct {
1214  short vscale[4]; /* scale, 2 bits fraction */
1215  short vtrans[4]; /* translate, 2 bits fraction */
1216  /* both the above arrays are padded to 64-bit boundary */
1217 } Vp_t;
1218 
1219 typedef union {
1220  Vp_t vp;
1221  long long int force_structure_alignment;
1222 } Vp;
1223 
1224 /*
1225  * MOVEMEM indices
1226  *
1227  * Each of these indexes an entry in a dmem table
1228  * which points to a 1-4 word block of dmem in
1229  * which to store a 1-4 word DMA.
1230  *
1231  */
1232 #ifdef F3DEX_GBI_2
1233 /* 0,4 are reserved by G_MTX */
1234 # define G_MV_MMTX 2
1235 # define G_MV_PMTX 6
1236 # define G_MV_VIEWPORT 8
1237 # define G_MV_LIGHT 10
1238 # define G_MV_POINT 12
1239 # define G_MV_MATRIX 14 /* NOTE: this is in moveword table */
1240 # define G_MVO_LOOKATX (0*24)
1241 # define G_MVO_LOOKATY (1*24)
1242 # define G_MVO_L0 (2*24)
1243 # define G_MVO_L1 (3*24)
1244 # define G_MVO_L2 (4*24)
1245 # define G_MVO_L3 (5*24)
1246 # define G_MVO_L4 (6*24)
1247 # define G_MVO_L5 (7*24)
1248 # define G_MVO_L6 (8*24)
1249 # define G_MVO_L7 (9*24)
1250 #else /* F3DEX_GBI_2 */
1251 # define G_MV_VIEWPORT 0x80
1252 # define G_MV_LOOKATY 0x82
1253 # define G_MV_LOOKATX 0x84
1254 # define G_MV_L0 0x86
1255 # define G_MV_L1 0x88
1256 # define G_MV_L2 0x8a
1257 # define G_MV_L3 0x8c
1258 # define G_MV_L4 0x8e
1259 # define G_MV_L5 0x90
1260 # define G_MV_L6 0x92
1261 # define G_MV_L7 0x94
1262 # define G_MV_TXTATT 0x96
1263 # define G_MV_MATRIX_1 0x9e /* NOTE: this is in moveword table */
1264 # define G_MV_MATRIX_2 0x98
1265 # define G_MV_MATRIX_3 0x9a
1266 # define G_MV_MATRIX_4 0x9c
1267 #endif /* F3DEX_GBI_2 */
1268 
1269 /*
1270  * MOVEWORD indices
1271  *
1272  * Each of these indexes an entry in a dmem table
1273  * which points to a word in dmem in dmem where
1274  * an immediate word will be stored.
1275  *
1276  */
1277 #define G_MW_MATRIX 0x00 /* NOTE: also used by movemem */
1278 #define G_MW_NUMLIGHT 0x02
1279 #define G_MW_CLIP 0x04
1280 #define G_MW_SEGMENT 0x06
1281 #define G_MW_FOG 0x08
1282 #define G_MW_LIGHTCOL 0x0a
1283 #ifdef F3DEX_GBI_2
1284 # define G_MW_FORCEMTX 0x0c
1285 #else /* F3DEX_GBI_2 */
1286 # define G_MW_POINTS 0x0c
1287 #endif /* F3DEX_GBI_2 */
1288 #define G_MW_PERSPNORM 0x0e
1289 
1290 /*
1291  * These are offsets from the address in the dmem table
1292  */
1293 #define G_MWO_NUMLIGHT 0x00
1294 #define G_MWO_CLIP_RNX 0x04
1295 #define G_MWO_CLIP_RNY 0x0c
1296 #define G_MWO_CLIP_RPX 0x14
1297 #define G_MWO_CLIP_RPY 0x1c
1298 #define G_MWO_SEGMENT_0 0x00
1299 #define G_MWO_SEGMENT_1 0x01
1300 #define G_MWO_SEGMENT_2 0x02
1301 #define G_MWO_SEGMENT_3 0x03
1302 #define G_MWO_SEGMENT_4 0x04
1303 #define G_MWO_SEGMENT_5 0x05
1304 #define G_MWO_SEGMENT_6 0x06
1305 #define G_MWO_SEGMENT_7 0x07
1306 #define G_MWO_SEGMENT_8 0x08
1307 #define G_MWO_SEGMENT_9 0x09
1308 #define G_MWO_SEGMENT_A 0x0a
1309 #define G_MWO_SEGMENT_B 0x0b
1310 #define G_MWO_SEGMENT_C 0x0c
1311 #define G_MWO_SEGMENT_D 0x0d
1312 #define G_MWO_SEGMENT_E 0x0e
1313 #define G_MWO_SEGMENT_F 0x0f
1314 #define G_MWO_FOG 0x00
1315 #define G_MWO_aLIGHT_1 0x00
1316 #define G_MWO_bLIGHT_1 0x04
1317 #ifdef F3DEX_GBI_2
1318 #define G_MWO_aLIGHT_2 0x18
1319 #define G_MWO_bLIGHT_2 0x1c
1320 #define G_MWO_aLIGHT_3 0x30
1321 #define G_MWO_bLIGHT_3 0x34
1322 #define G_MWO_aLIGHT_4 0x48
1323 #define G_MWO_bLIGHT_4 0x4c
1324 #define G_MWO_aLIGHT_5 0x60
1325 #define G_MWO_bLIGHT_5 0x64
1326 #define G_MWO_aLIGHT_6 0x78
1327 #define G_MWO_bLIGHT_6 0x7c
1328 #define G_MWO_aLIGHT_7 0x90
1329 #define G_MWO_bLIGHT_7 0x94
1330 #define G_MWO_aLIGHT_8 0xa8
1331 #define G_MWO_bLIGHT_8 0xac
1332 #else
1333 #define G_MWO_aLIGHT_2 0x20
1334 #define G_MWO_bLIGHT_2 0x24
1335 #define G_MWO_aLIGHT_3 0x40
1336 #define G_MWO_bLIGHT_3 0x44
1337 #define G_MWO_aLIGHT_4 0x60
1338 #define G_MWO_bLIGHT_4 0x64
1339 #define G_MWO_aLIGHT_5 0x80
1340 #define G_MWO_bLIGHT_5 0x84
1341 #define G_MWO_aLIGHT_6 0xa0
1342 #define G_MWO_bLIGHT_6 0xa4
1343 #define G_MWO_aLIGHT_7 0xc0
1344 #define G_MWO_bLIGHT_7 0xc4
1345 #define G_MWO_aLIGHT_8 0xe0
1346 #define G_MWO_bLIGHT_8 0xe4
1347 #endif
1348 #define G_MWO_MATRIX_XX_XY_I 0x00
1349 #define G_MWO_MATRIX_XZ_XW_I 0x04
1350 #define G_MWO_MATRIX_YX_YY_I 0x08
1351 #define G_MWO_MATRIX_YZ_YW_I 0x0c
1352 #define G_MWO_MATRIX_ZX_ZY_I 0x10
1353 #define G_MWO_MATRIX_ZZ_ZW_I 0x14
1354 #define G_MWO_MATRIX_WX_WY_I 0x18
1355 #define G_MWO_MATRIX_WZ_WW_I 0x1c
1356 #define G_MWO_MATRIX_XX_XY_F 0x20
1357 #define G_MWO_MATRIX_XZ_XW_F 0x24
1358 #define G_MWO_MATRIX_YX_YY_F 0x28
1359 #define G_MWO_MATRIX_YZ_YW_F 0x2c
1360 #define G_MWO_MATRIX_ZX_ZY_F 0x30
1361 #define G_MWO_MATRIX_ZZ_ZW_F 0x34
1362 #define G_MWO_MATRIX_WX_WY_F 0x38
1363 #define G_MWO_MATRIX_WZ_WW_F 0x3c
1364 #define G_MWO_POINT_RGBA 0x10
1365 #define G_MWO_POINT_ST 0x14
1366 #define G_MWO_POINT_XYSCREEN 0x18
1367 #define G_MWO_POINT_ZSCREEN 0x1c
1368 
1369 /*
1370  * Light structure.
1371  *
1372  * Note: only directional (infinite) lights are currently supported.
1373  *
1374  * Note: the weird order is for the DMEM alignment benefit of
1375  * the microcode.
1376  *
1377  */
1378 
1379 typedef struct {
1380  unsigned char col[3]; /* diffuse light value (rgba) */
1381  char pad1;
1382  unsigned char colc[3]; /* copy of diffuse light value (rgba) */
1383  char pad2;
1384  signed char dir[3]; /* direction of light (normalized) */
1385  char pad3;
1386 } Light_t;
1387 
1388 typedef struct {
1389  unsigned char col[3]; /* ambient light value (rgba) */
1390  char pad1;
1391  unsigned char colc[3]; /* copy of ambient light value (rgba) */
1392  char pad2;
1393 } Ambient_t;
1394 
1395 typedef struct {
1396  int x1,y1,x2,y2; /* texture offsets for highlight 1/2 */
1397 } Hilite_t;
1398 
1399 typedef union {
1400  Light_t l;
1401  long long int force_structure_alignment[2];
1402 } Light;
1403 
1404 typedef union {
1405  Ambient_t l;
1406  long long int force_structure_alignment[1];
1407 } Ambient;
1408 
1409 typedef struct {
1410  Ambient a;
1411  Light l[7];
1412 } Lightsn;
1413 
1414 typedef struct {
1415  Ambient a;
1416  Light l[1];
1417 } Lights0;
1418 
1419 typedef struct {
1420  Ambient a;
1421  Light l[1];
1422 } Lights1;
1423 
1424 typedef struct {
1425  Ambient a;
1426  Light l[2];
1427 } Lights2;
1428 
1429 typedef struct {
1430  Ambient a;
1431  Light l[3];
1432 } Lights3;
1433 
1434 typedef struct {
1435  Ambient a;
1436  Light l[4];
1437 } Lights4;
1438 
1439 typedef struct {
1440  Ambient a;
1441  Light l[5];
1442 } Lights5;
1443 
1444 typedef struct {
1445  Ambient a;
1446  Light l[6];
1447 } Lights6;
1448 
1449 typedef struct {
1450  Ambient a;
1451  Light l[7];
1452 } Lights7;
1453 
1454 typedef struct {
1455  Light l[2];
1456 } LookAt;
1457 
1458 typedef union {
1459  Hilite_t h;
1460  long int force_structure_alignment[4];
1461 } Hilite;
1462 
1463 #define gdSPDefLights0(ar,ag,ab) \
1464  { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \
1465  {{{ { 0, 0, 0},0,{ 0, 0, 0},0,{ 0, 0, 0},0}}} }
1466 #define gdSPDefLights1(ar,ag,ab,r1,g1,b1,x1,y1,z1) \
1467  { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \
1468  {{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}} }
1469 #define gdSPDefLights2(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2) \
1470  { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \
1471  {{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \
1472  {{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}} }
1473 #define gdSPDefLights3(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2,r3,g3,b3,x3,y3,z3) \
1474  { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \
1475  {{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \
1476  {{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}, \
1477  {{ {r3,g3,b3},0,{r3,g3,b3},0,{x3,y3,z3},0}}} }
1478 #define gdSPDefLights4(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2,r3,g3,b3,x3,y3,z3,r4,g4,b4,x4,y4,z4) \
1479  { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \
1480  {{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \
1481  {{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}, \
1482  {{ {r3,g3,b3},0,{r3,g3,b3},0,{x3,y3,z3},0}}, \
1483  {{ {r4,g4,b4},0,{r4,g4,b4},0,{x4,y4,z4},0}}} }
1484 #define gdSPDefLights5(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2,r3,g3,b3,x3,y3,z3,r4,g4,b4,x4,y4,z4,r5,g5,b5,x5,y5,z5) \
1485  { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \
1486  {{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \
1487  {{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}, \
1488  {{ {r3,g3,b3},0,{r3,g3,b3},0,{x3,y3,z3},0}}, \
1489  {{ {r4,g4,b4},0,{r4,g4,b4},0,{x4,y4,z4},0}}, \
1490  {{ {r5,g5,b5},0,{r5,g5,b5},0,{x5,y5,z5},0}}} }
1491 
1492 
1493 #define gdSPDefLights6(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2,r3,g3,b3,x3,y3,z3,r4,g4,b4,x4,y4,z4,r5,g5,b5,x5,y5,z5,r6,g6,b6,x6,y6,z6) \
1494  { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \
1495  {{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \
1496  {{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}, \
1497  {{ {r3,g3,b3},0,{r3,g3,b3},0,{x3,y3,z3},0}}, \
1498  {{ {r4,g4,b4},0,{r4,g4,b4},0,{x4,y4,z4},0}}, \
1499  {{ {r5,g5,b5},0,{r5,g5,b5},0,{x5,y5,z5},0}}, \
1500  {{ {r6,g6,b6},0,{r6,g6,b6},0,{x6,y6,z6},0}}} }
1501 
1502 
1503 #define gdSPDefLights7(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2,r3,g3,b3,x3,y3,z3,r4,g4,b4,x4,y4,z4,r5,g5,b5,x5,y5,z5,r6,g6,b6,x6,y6,z6,r7,g7,b7,x7,y7,z7) \
1504  { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \
1505  {{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \
1506  {{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}, \
1507  {{ {r3,g3,b3},0,{r3,g3,b3},0,{x3,y3,z3},0}}, \
1508  {{ {r4,g4,b4},0,{r4,g4,b4},0,{x4,y4,z4},0}}, \
1509  {{ {r5,g5,b5},0,{r5,g5,b5},0,{x5,y5,z5},0}}, \
1510  {{ {r6,g6,b6},0,{r6,g6,b6},0,{x6,y6,z6},0}}, \
1511  {{ {r7,g7,b7},0,{r7,g7,b7},0,{x7,y7,z7},0}}} }
1512 
1513 
1514 #define gdSPDefLookAt(rightx,righty,rightz,upx,upy,upz) \
1515  { {{ {{0,0,0},0,{0,0,0},0,{rightx,righty,rightz},0}}, \
1516  { {{0,0x80,0},0,{0,0x80,0},0,{upx,upy,upz},0}}} }
1517 
1518 /* Don't declare these for F3D_OLD to avoid bss reordering */
1519 #ifndef F3D_OLD
1520 /*
1521  * Graphics DMA Packet
1522  */
1523 typedef struct {
1524  int cmd:8;
1525  unsigned int par:8;
1526  unsigned int len:16;
1527  uintptr_t addr;
1528 } Gdma;
1529 
1530 /*
1531  * Graphics Immediate Mode Packet types
1532  */
1533 typedef struct {
1534  int cmd:8;
1535  int pad:24;
1536  Tri tri;
1537 } Gtri;
1538 
1539 typedef struct {
1540  int cmd:8;
1541  int pad1:24;
1542  int pad2:24;
1543  unsigned char param:8;
1544 } Gpopmtx;
1545 
1546 /*
1547  * typedef struct {
1548  * int cmd:8;
1549  * int pad0:24;
1550  * int pad1:4;
1551  * int number:4;
1552  * int base:24;
1553  * } Gsegment;
1554  */
1555 typedef struct {
1556  int cmd:8;
1557  int pad0:8;
1558  int mw_index:8;
1559  int number:8;
1560  int pad1:8;
1561  int base:24;
1562 } Gsegment;
1563 
1564 typedef struct {
1565  int cmd:8;
1566  int pad0:8;
1567  int sft:8;
1568  int len:8;
1569  unsigned int data:32;
1570 } GsetothermodeL;
1571 
1572 typedef struct {
1573  int cmd:8;
1574  int pad0:8;
1575  int sft:8;
1576  int len:8;
1577  unsigned int data:32;
1578 } GsetothermodeH;
1579 
1580 typedef struct {
1581  unsigned char cmd;
1582  unsigned char lodscale;
1583  unsigned char tile;
1584  unsigned char on;
1585  unsigned short s;
1586  unsigned short t;
1587 } Gtexture;
1588 
1589 typedef struct {
1590  int cmd:8;
1591  int pad:24;
1592  Tri line;
1593 } Gline3D;
1594 
1595 typedef struct {
1596  int cmd:8;
1597  int pad1:24;
1598  short int pad2;
1599  short int scale;
1600 } Gperspnorm;
1601 
1602 
1603 /*
1604  * RDP Packet types
1605  */
1606 typedef struct {
1607  int cmd:8;
1608  unsigned int fmt:3;
1609  unsigned int siz:2;
1610  unsigned int pad:7;
1611  unsigned int wd:12; /* really only 10 bits, extra */
1612  uintptr_t dram; /* to account for 1024 */
1613 } Gsetimg;
1614 
1615 typedef struct {
1616  int cmd:8;
1617  unsigned int muxs0:24;
1618  unsigned int muxs1:32;
1619 } Gsetcombine;
1620 
1621 typedef struct {
1622  int cmd:8;
1623  unsigned char pad;
1624  unsigned char prim_min_level;
1625  unsigned char prim_level;
1626  unsigned long color;
1627 } Gsetcolor;
1628 
1629 typedef struct {
1630  int cmd:8;
1631  int x0:10;
1632  int x0frac:2;
1633  int y0:10;
1634  int y0frac:2;
1635  unsigned int pad:8;
1636  int x1:10;
1637  int x1frac:2;
1638  int y1:10;
1639  int y1frac:2;
1640 } Gfillrect;
1641 
1642 typedef struct {
1643  int cmd:8;
1644  unsigned int fmt:3;
1645  unsigned int siz:2;
1646  unsigned int pad0:1;
1647  unsigned int line:9;
1648  unsigned int tmem:9;
1649  unsigned int pad1:5;
1650  unsigned int tile:3;
1651  unsigned int palette:4;
1652  unsigned int ct:1;
1653  unsigned int mt:1;
1654  unsigned int maskt:4;
1655  unsigned int shiftt:4;
1656  unsigned int cs:1;
1657  unsigned int ms:1;
1658  unsigned int masks:4;
1659  unsigned int shifts:4;
1660 } Gsettile;
1661 
1662 typedef struct {
1663  int cmd:8;
1664  unsigned int sl:12;
1665  unsigned int tl:12;
1666  int pad:5;
1667  unsigned int tile:3;
1668  unsigned int sh:12;
1669  unsigned int th:12;
1670 } Gloadtile;
1671 
1672 typedef Gloadtile Gloadblock;
1673 
1674 typedef Gloadtile Gsettilesize;
1675 
1676 typedef Gloadtile Gloadtlut;
1677 
1678 typedef struct {
1679  unsigned int cmd:8; /* command */
1680  unsigned int xl:12; /* X coordinate of upper left */
1681  unsigned int yl:12; /* Y coordinate of upper left */
1682  unsigned int pad1:5; /* Padding */
1683  unsigned int tile:3; /* Tile descriptor index */
1684  unsigned int xh:12; /* X coordinate of lower right */
1685  unsigned int yh:12; /* Y coordinate of lower right */
1686  unsigned int s:16; /* S texture coord at top left */
1687  unsigned int t:16; /* T texture coord at top left */
1688  unsigned int dsdx:16;/* Change in S per change in X */
1689  unsigned int dtdy:16;/* Change in T per change in Y */
1690 } Gtexrect;
1691 
1692 /*
1693  * Textured rectangles are 128 bits not 64 bits
1694  */
1695 typedef struct {
1696  unsigned long w0;
1697  unsigned long w1;
1698  unsigned long w2;
1699  unsigned long w3;
1700 } TexRect;
1701 #endif
1702 
1703 #define MakeTexRect(xh,yh,flip,tile,xl,yl,s,t,dsdx,dtdy) \
1704  G_TEXRECT, xh, yh, 0, flip, 0, tile, xl, yl, s, t, dsdx, dtdy
1705 
1706 /*
1707  * Generic Gfx Packet
1708  */
1709 typedef struct {
1710  uintptr_t w0;
1711  uintptr_t w1;
1712 } Gwords;
1713 
1714 /*
1715  * This union is the fundamental type of the display list.
1716  * It is, by law, exactly 64 bits in size.
1717  *
1718  * (Edit: except on 64-bit, where it is exactly 128 bit. On little-endian or
1719  * 64-bit systems, only the 'words' member may be accessed; the rest of the
1720  * structs don't have matching layouts for now.)
1721  */
1722 
1723 typedef union {
1724  Gwords words;
1725 #if !defined(F3D_OLD) && IS_BIG_ENDIAN && !IS_64_BIT
1726  Gdma dma;
1727  Gtri tri;
1728  Gline3D line;
1729  Gpopmtx popmtx;
1730  Gsegment segment;
1731  GsetothermodeH setothermodeH;
1732  GsetothermodeL setothermodeL;
1733  Gtexture texture;
1734  Gperspnorm perspnorm;
1735  Gsetimg setimg;
1736  Gsetcombine setcombine;
1737  Gsetcolor setcolor;
1738  Gfillrect fillrect; /* use for setscissor also */
1739  Gsettile settile;
1740  Gloadtile loadtile; /* use for loadblock also, th is dxt */
1741  Gsettilesize settilesize;
1742  Gloadtlut loadtlut;
1743 #endif
1744  long long int force_structure_alignment;
1745 } Gfx;
1746 
1747 /*
1748  * Macros to assemble the graphics display list
1749  */
1750 
1751 /*
1752  * DMA macros
1753  */
1754 #define gDma0p(pkt, c, s, l) \
1755 { \
1756  Gfx *_g = (Gfx *)(pkt); \
1757  \
1758  _g->words.w0 = _SHIFTL((c), 24, 8) | _SHIFTL((l), 0, 24); \
1759  _g->words.w1 = (uintptr_t)(s); \
1760 }
1761 
1762 #define gsDma0p(c, s, l) \
1763 {{ \
1764  _SHIFTL((c), 24, 8) | _SHIFTL((l), 0, 24), (uintptr_t)(s) \
1765 }}
1766 
1767 #define gDma1p(pkt, c, s, l, p) \
1768 { \
1769  Gfx *_g = (Gfx *)(pkt); \
1770  \
1771  _g->words.w0 = (_SHIFTL((c), 24, 8) | _SHIFTL((p), 16, 8) | \
1772  _SHIFTL((l), 0, 16)); \
1773  _g->words.w1 = (uintptr_t)(s); \
1774 }
1775 
1776 #define gsDma1p(c, s, l, p) \
1777 {{ \
1778  (_SHIFTL((c), 24, 8) | _SHIFTL((p), 16, 8) | \
1779  _SHIFTL((l), 0, 16)), \
1780  (uintptr_t)(s) \
1781 }}
1782 
1783 #define gDma2p(pkt, c, adrs, len, idx, ofs) \
1784 { \
1785  Gfx *_g = (Gfx *)(pkt); \
1786  _g->words.w0 = (_SHIFTL((c),24,8)|_SHIFTL(((len)-1)/8,19,5)| \
1787  _SHIFTL((ofs)/8,8,8)|_SHIFTL((idx),0,8)); \
1788  _g->words.w1 = (uintptr_t)(adrs); \
1789 }
1790 #define gsDma2p(c, adrs, len, idx, ofs) \
1791 {{ \
1792  (_SHIFTL((c),24,8)|_SHIFTL(((len)-1)/8,19,5)| \
1793  _SHIFTL((ofs)/8,8,8)|_SHIFTL((idx),0,8)), \
1794  (uintptr_t)(adrs) \
1795 }}
1796 
1797 #define gSPNoOp(pkt) gDma0p(pkt, G_SPNOOP, 0, 0)
1798 #define gsSPNoOp() gsDma0p(G_SPNOOP, 0, 0)
1799 
1800 #ifdef F3DEX_GBI_2
1801 # define gSPMatrix(pkt, m, p) \
1802  gDma2p((pkt),G_MTX,(m),sizeof(Mtx),(p)^G_MTX_PUSH,0)
1803 # define gsSPMatrix(m, p) \
1804  gsDma2p( G_MTX,(m),sizeof(Mtx),(p)^G_MTX_PUSH,0)
1805 #else /* F3DEX_GBI_2 */
1806 # define gSPMatrix(pkt, m, p) gDma1p(pkt, G_MTX, m, sizeof(Mtx), p)
1807 # define gsSPMatrix(m, p) gsDma1p(G_MTX, m, sizeof(Mtx), p)
1808 #endif /* F3DEX_GBI_2 */
1809 
1810 #if defined(F3DEX_GBI_2)
1811 /*
1812  * F3DEX_GBI_2: G_VTX GBI format was changed.
1813  *
1814  * +--------+----+---+---+----+------+-+
1815  * G_VTX | cmd:8 |0000| n:8 |0000|v0+n:7|0|
1816  * +-+---+--+----+---+---+----+------+-+
1817  * | |seg| address |
1818  * +-+---+-----------------------------+
1819  */
1820 # define gSPVertex(pkt, v, n, v0) \
1821 { \
1822  Gfx *_g = (Gfx *)(pkt); \
1823  _g->words.w0 = \
1824  _SHIFTL(G_VTX,24,8)|_SHIFTL((n),12,8)|_SHIFTL((v0)+(n),1,7); \
1825  _g->words.w1 = (uintptr_t)(v); \
1826 }
1827 # define gsSPVertex(v, n, v0) \
1828 {{ \
1829  (_SHIFTL(G_VTX,24,8)|_SHIFTL((n),12,8)|_SHIFTL((v0)+(n),1,7)), \
1830  (uintptr_t)(v) \
1831 }}
1832 #elif (defined(F3DEX_GBI)||defined(F3DLP_GBI))
1833 /*
1834  * F3DEX_GBI: G_VTX GBI format was changed to support 64 vertice.
1835  *
1836  * +--------+--------+------+----------+
1837  * G_VTX | cmd:8 | v0:8 | n:6 |length:10 |
1838  * +-+---+--+--------+------+----------+
1839  * | |seg| address |
1840  * +-+---+-----------------------------+
1841  */
1842 # define gSPVertex(pkt, v, n, v0) \
1843  gDma1p((pkt),G_VTX,(v),((n)<<10)|(sizeof(Vtx)*(n)-1),(v0)*2)
1844 # define gsSPVertex(v, n, v0) \
1845  gsDma1p(G_VTX,(v),((n)<<10)|(sizeof(Vtx)*(n)-1),(v0)*2)
1846 #else
1847 # define gSPVertex(pkt, v, n, v0) \
1848  gDma1p(pkt, G_VTX, v, sizeof(Vtx)*(n),((n)-1)<<4|(v0))
1849 # define gsSPVertex(v, n, v0) \
1850  gsDma1p(G_VTX, v, sizeof(Vtx)*(n), ((n)-1)<<4|(v0))
1851 #endif
1852 
1853 
1854 #ifdef F3DEX_GBI_2
1855 # define gSPViewport(pkt, v) \
1856  gDma2p((pkt), G_MOVEMEM, (v), sizeof(Vp), G_MV_VIEWPORT, 0)
1857 # define gsSPViewport(v) \
1858  gsDma2p( G_MOVEMEM, (v), sizeof(Vp), G_MV_VIEWPORT, 0)
1859 #else /* F3DEX_GBI_2 */
1860 # define gSPViewport(pkt,v) \
1861  gDma1p((pkt), G_MOVEMEM, (v), sizeof(Vp), G_MV_VIEWPORT)
1862 # define gsSPViewport(v) \
1863  gsDma1p( G_MOVEMEM, (v), sizeof(Vp), G_MV_VIEWPORT)
1864 #endif /* F3DEX_GBI_2 */
1865 
1866 #define gSPDisplayList(pkt,dl) gDma1p(pkt,G_DL,dl,0,G_DL_PUSH)
1867 #define gsSPDisplayList( dl) gsDma1p( G_DL,dl,0,G_DL_PUSH)
1868 
1869 #define gSPBranchList(pkt,dl) gDma1p(pkt,G_DL,dl,0,G_DL_NOPUSH)
1870 #define gsSPBranchList( dl) gsDma1p( G_DL,dl,0,G_DL_NOPUSH)
1871 
1872 #define gSPSprite2DBase(pkt, s) gDma1p(pkt, G_SPRITE2D_BASE, s, sizeof(uSprite), 0)
1873 #define gsSPSprite2DBase(s) gsDma1p(G_SPRITE2D_BASE, s, sizeof(uSprite), 0)
1874 
1875 /*
1876  * RSP short command (no DMA required) macros
1877  */
1878 #define gImmp0(pkt, c) \
1879 { \
1880  Gfx *_g = (Gfx *)(pkt); \
1881  \
1882  _g->words.w0 = _SHIFTL((c), 24, 8); \
1883 }
1884 
1885 #define gsImmp0(c) \
1886 {{ \
1887  _SHIFTL((c), 24, 8) \
1888 }}
1889 
1890 #define gImmp1(pkt, c, p0) \
1891 { \
1892  Gfx *_g = (Gfx *)(pkt); \
1893  \
1894  _g->words.w0 = _SHIFTL((c), 24, 8); \
1895  _g->words.w1 = (uintptr_t)(p0); \
1896 }
1897 
1898 #define gsImmp1(c, p0) \
1899 {{ \
1900  _SHIFTL((c), 24, 8), (uintptr_t)(p0) \
1901 }}
1902 
1903 #define gImmp2(pkt, c, p0, p1) \
1904 { \
1905  Gfx *_g = (Gfx *)(pkt); \
1906  \
1907  _g->words.w0 = _SHIFTL((c), 24, 8); \
1908  _g->words.w1 = _SHIFTL((p0), 16, 16) | _SHIFTL((p1), 8, 8); \
1909 }
1910 
1911 #define gsImmp2(c, p0, p1) \
1912 {{ \
1913  _SHIFTL((c), 24, 8), _SHIFTL((p0), 16, 16) | _SHIFTL((p1), 8, 8)\
1914 }}
1915 
1916 #define gImmp3(pkt, c, p0, p1, p2) \
1917 { \
1918  Gfx *_g = (Gfx *)(pkt); \
1919  \
1920  _g->words.w0 = _SHIFTL((c), 24, 8); \
1921  _g->words.w1 = (_SHIFTL((p0), 16, 16) | _SHIFTL((p1), 8, 8) | \
1922  _SHIFTL((p2), 0, 8)); \
1923 }
1924 
1925 #define gsImmp3(c, p0, p1, p2) \
1926 {{ \
1927  _SHIFTL((c), 24, 8), (_SHIFTL((p0), 16, 16) | \
1928  _SHIFTL((p1), 8, 8) | _SHIFTL((p2), 0, 8))\
1929 }}
1930 
1931 #define gImmp21(pkt, c, p0, p1, dat) \
1932 { \
1933  Gfx *_g = (Gfx *)(pkt); \
1934  \
1935  _g->words.w0 = (_SHIFTL((c), 24, 8) | _SHIFTL((p0), 8, 16) | \
1936  _SHIFTL((p1), 0, 8)); \
1937  _g->words.w1 = (uintptr_t) (dat); \
1938 }
1939 
1940 #define gsImmp21(c, p0, p1, dat) \
1941 {{ \
1942  _SHIFTL((c), 24, 8) | _SHIFTL((p0), 8, 16) | _SHIFTL((p1), 0, 8),\
1943  (uintptr_t) (dat) \
1944 }}
1945 
1946 #ifdef F3DEX_GBI_2
1947 #define gMoveWd(pkt, index, offset, data) \
1948  gDma1p((pkt), G_MOVEWORD, data, offset, index)
1949 #define gsMoveWd( index, offset, data) \
1950  gsDma1p( G_MOVEWORD, data, offset, index)
1951 #else /* F3DEX_GBI_2 */
1952 #define gMoveWd(pkt, index, offset, data) \
1953  gImmp21((pkt), G_MOVEWORD, offset, index, data)
1954 #define gsMoveWd( index, offset, data) \
1955  gsImmp21( G_MOVEWORD, offset, index, data)
1956 #endif /* F3DEX_GBI_2 */
1957 
1958 /* Sprite immediate macros, there is also a sprite dma macro above */
1959 
1960 #define gSPSprite2DScaleFlip(pkt, sx, sy, fx, fy) \
1961 { \
1962  Gfx *_g = (Gfx *)(pkt); \
1963  \
1964  _g->words.w0 = (_SHIFTL(G_SPRITE2D_SCALEFLIP, 24, 8) | \
1965  _SHIFTL((fx), 8, 8) | \
1966  _SHIFTL((fy), 0, 8)); \
1967  _g->words.w1 = (_SHIFTL((sx), 16, 16) | \
1968  _SHIFTL((sy), 0, 16)); \
1969 }
1970 
1971 #define gsSPSprite2DScaleFlip(sx, sy, fx, fy) \
1972 {{ \
1973  (_SHIFTL(G_SPRITE2D_SCALEFLIP, 24, 8) | \
1974  _SHIFTL((fx), 8, 8) | \
1975  _SHIFTL((fy), 0, 8)), \
1976  (_SHIFTL((sx), 16, 16) | \
1977  _SHIFTL((sy), 0, 16)) \
1978 }}
1979 
1980 #define gSPSprite2DDraw(pkt, px, py) \
1981 { \
1982  Gfx *_g = (Gfx *)(pkt); \
1983  \
1984  _g->words.w0 = (_SHIFTL(G_SPRITE2D_DRAW, 24, 8)); \
1985  _g->words.w1 = (_SHIFTL((px), 16, 16) | \
1986  _SHIFTL((py), 0, 16)); \
1987 }
1988 
1989 #define gsSPSprite2DDraw(px, py) \
1990 {{ \
1991  (_SHIFTL(G_SPRITE2D_DRAW, 24, 8)), \
1992  (_SHIFTL((px), 16, 16) | \
1993  _SHIFTL((py), 0, 16)) \
1994 }}
1995 
1996 
1997 /*
1998  * Note: the SP1Triangle() and line macros multiply the vertex indices
1999  * by 10, this is an optimization for the microcode.
2000  */
2001 #if (defined(F3DLP_GBI)||defined(F3DEX_GBI))
2002 # define __gsSP1Triangle_w1(v0, v1, v2) \
2003  (_SHIFTL((v0)*2,16,8)|_SHIFTL((v1)*2,8,8)|_SHIFTL((v2)*2,0,8))
2004 # define __gsSP1Triangle_w1f(v0, v1, v2, flag) \
2005  (((flag) == 0) ? __gsSP1Triangle_w1(v0, v1, v2): \
2006  ((flag) == 1) ? __gsSP1Triangle_w1(v1, v2, v0): \
2007  __gsSP1Triangle_w1(v2, v0, v1))
2008 # define __gsSPLine3D_w1(v0, v1, wd) \
2009  (_SHIFTL((v0)*2,16,8)|_SHIFT((v1)*2,8,8)|_SHIFT((wd),0,8))
2010 # define __gsSPLine3D_w1f(v0, v1, wd, flag) \
2011  (((flag) == 0) ? __gsSPLine3D_w1(v0, v1, wd): \
2012  __gsSPLine3D_w1(v1, v0, wd))
2013 
2014 // Only used on old F3DEX revisions, removed on latest revisions.
2015 #define __gsSP1Quadrangle_w1(v0, v1, v2, v3) \
2016  (_SHIFTL((v3)*2,24,8)|_SHIFTL((v0)*2,16,8)|\
2017  _SHIFTL((v1)*2,8,8)|_SHIFTL((v2)*2,0,8))
2018 
2019 # define __gsSP1Quadrangle_w1f(v0, v1, v2, v3, flag) \
2020  (((flag) == 0) ? __gsSP1Triangle_w1(v0, v1, v2): \
2021  ((flag) == 1) ? __gsSP1Triangle_w1(v1, v2, v3): \
2022  ((flag) == 2) ? __gsSP1Triangle_w1(v2, v3, v0): \
2023  __gsSP1Triangle_w1(v3, v0, v1))
2024 # define __gsSP1Quadrangle_w2f(v0, v1, v2, v3, flag) \
2025  (((flag) == 0) ? __gsSP1Triangle_w1(v0, v2, v3): \
2026  ((flag) == 1) ? __gsSP1Triangle_w1(v1, v3, v0): \
2027  ((flag) == 2) ? __gsSP1Triangle_w1(v2, v0, v1): \
2028  __gsSP1Triangle_w1(v3, v1, v2))
2029 #else
2030 # define __gsSP1Triangle_w1f(v0, v1, v2, flag) \
2031  (_SHIFTL((flag), 24,8)|_SHIFTL((v0)*10,16,8)| \
2032  _SHIFTL((v1)*10, 8,8)|_SHIFTL((v2)*10, 0,8))
2033 # define __gsSPLine3D_w1f(v0, v1, wd, flag) \
2034  (_SHIFTL((flag), 24,8)|_SHIFTL((v0)*10,16,8)| \
2035  _SHIFTL((v1)*10, 8,8)|_SHIFTL((wd), 0,8))
2036 #endif
2037 
2038 #ifdef F3DEX_GBI_2
2039 /***
2040  *** 1 Triangle
2041  ***/
2042 #define gSP1Triangle(pkt, v0, v1, v2, flag) \
2043 { \
2044  Gfx *_g = (Gfx *)(pkt); \
2045  \
2046  _g->words.w0 = _SHIFTL(G_TRI1, 24, 8)| \
2047  __gsSP1Triangle_w1f(v0, v1, v2, flag); \
2048  _g->words.w1 = 0; \
2049 }
2050 #define gsSP1Triangle(v0, v1, v2, flag) \
2051 {{ \
2052  _SHIFTL(G_TRI1, 24, 8)|__gsSP1Triangle_w1f(v0, v1, v2, flag), \
2053  0 \
2054 }}
2055 
2056 /***
2057  *** Line
2058  ***/
2059 #define gSPLine3D(pkt, v0, v1, flag) \
2060 { \
2061  Gfx *_g = (Gfx *)(pkt); \
2062  \
2063  _g->words.w0 = _SHIFTL(G_LINE3D, 24, 8)| \
2064  __gsSPLine3D_w1f(v0, v1, 0, flag); \
2065  _g->words.w1 = 0; \
2066 }
2067 #define gsSPLine3D(v0, v1, flag) \
2068 {{ \
2069  _SHIFTL(G_LINE3D, 24, 8)|__gsSPLine3D_w1f(v0, v1, 0, flag), \
2070  0 \
2071 }}
2072 
2073 /***
2074  *** LineW
2075  ***/
2076 /* these macros are the same as SPLine3D, except they have an
2077  * additional parameter for width. The width is added to the "minimum"
2078  * thickness, which is 1.5 pixels. The units for width are in
2079  * half-pixel units, so a width of 1 translates to (.5 + 1.5) or
2080  * a 2.0 pixels wide line.
2081  */
2082 #define gSPLineW3D(pkt, v0, v1, wd, flag) \
2083 { \
2084  Gfx *_g = (Gfx *)(pkt); \
2085  \
2086  _g->words.w0 = _SHIFTL(G_LINE3D, 24, 8)| \
2087  __gsSPLine3D_w1f(v0, v1, wd, flag); \
2088  _g->words.w1 = 0; \
2089 }
2090 #define gsSPLineW3D(v0, v1, wd, flag) \
2091 {{ \
2092  _SHIFTL(G_LINE3D, 24, 8)|__gsSPLine3D_w1f(v0, v1, wd, flag), \
2093  0 \
2094 }}
2095 
2096 /***
2097  *** 1 Quadrangle
2098  ***/
2099 #define gSP1Quadrangle(pkt, v0, v1, v2, v3, flag) \
2100 { \
2101  Gfx *_g = (Gfx *)(pkt); \
2102  \
2103  _g->words.w0 = (_SHIFTL(G_QUAD, 24, 8)| \
2104  __gsSP1Quadrangle_w1f(v0, v1, v2, v3, flag)); \
2105  _g->words.w1 = __gsSP1Quadrangle_w2f(v0, v1, v2, v3, flag); \
2106 }
2107 
2108 #define gsSP1Quadrangle(v0, v1, v2, v3, flag) \
2109 {{ \
2110  (_SHIFTL(G_QUAD, 24, 8)| \
2111  __gsSP1Quadrangle_w1f(v0, v1, v2, v3, flag)), \
2112  __gsSP1Quadrangle_w2f(v0, v1, v2, v3, flag) \
2113 }}
2114 #else /* F3DEX_GBI_2 */
2115 
2116 /***
2117  *** 1 Triangle
2118  ***/
2119 #define gSP1Triangle(pkt, v0, v1, v2, flag) \
2120 { \
2121  Gfx *_g = (Gfx *)(pkt); \
2122  \
2123  _g->words.w0 = _SHIFTL(G_TRI1, 24, 8); \
2124  _g->words.w1 = __gsSP1Triangle_w1f(v0, v1, v2, flag); \
2125 }
2126 #define gsSP1Triangle(v0, v1, v2, flag) \
2127 {{ \
2128  _SHIFTL(G_TRI1, 24, 8), \
2129  __gsSP1Triangle_w1f(v0, v1, v2, flag) \
2130 }}
2131 
2132 /***
2133  *** Line
2134  ***/
2135 #define gSPLine3D(pkt, v0, v1, flag) \
2136 { \
2137  Gfx *_g = (Gfx *)(pkt); \
2138  \
2139  _g->words.w0 = _SHIFTL(G_LINE3D, 24, 8); \
2140  _g->words.w1 = __gsSPLine3D_w1f(v0, v1, 0, flag); \
2141 }
2142 #define gsSPLine3D(v0, v1, flag) \
2143 {{ \
2144  _SHIFTL(G_LINE3D, 24, 8), \
2145  __gsSPLine3D_w1f(v0, v1, 0, flag) \
2146 }}
2147 
2148 /***
2149  *** LineW
2150  ***/
2151 /* these macros are the same as SPLine3D, except they have an
2152  * additional parameter for width. The width is added to the "minimum"
2153  * thickness, which is 1.5 pixels. The units for width are in
2154  * half-pixel units, so a width of 1 translates to (.5 + 1.5) or
2155  * a 2.0 pixels wide line.
2156  */
2157 #define gSPLineW3D(pkt, v0, v1, wd, flag) \
2158 { \
2159  Gfx *_g = (Gfx *)(pkt); \
2160  \
2161  _g->words.w0 = _SHIFTL(G_LINE3D, 24, 8); \
2162  _g->words.w1 = __gsSPLine3D_w1f(v0, v1, wd, flag); \
2163 }
2164 #define gsSPLineW3D(v0, v1, wd, flag) \
2165 {{ \
2166  _SHIFTL(G_LINE3D, 24, 8), \
2167  __gsSPLine3D_w1f(v0, v1, wd, flag) \
2168 }}
2169 
2170 // Early revision of quadrangle command uses G_QUAD instead of G_TRI2.
2171 // It does not have a flag argument, this was added for compatibility.
2172 // MK64: Appears to only be used in startup_logo.inc.c
2173 #ifdef F3D_OLD
2174 /***
2175  *** 1 Quadrangle
2176  ***/
2177 #define gSP1Quadrangle(v0, v1, v2, v3, flag) \
2178 {{ \
2179  Gfx *_g = (Gfx *)(pkt); \
2180  \
2181  _g->words.w0 = _SHIFTL(G_QUAD, 24, 8); \
2182  _g->words.w1 = __gsSP1Quadrangle_w1(v0, v1, v2, v3); \
2183 }}
2184 
2185 #define gsSP1Quadrangle(v0, v1, v2, v3, flag) \
2186 {{ \
2187  _SHIFTL(G_QUAD, 24, 8), \
2188  __gsSP1Quadrangle_w1(v0, v1, v2, v3) \
2189 }}
2190 #else
2191 /***
2192  *** 1 Quadrangle
2193  ***/
2194 #define gSP1Quadrangle(pkt, v0, v1, v2, v3, flag) \
2195 { \
2196  Gfx *_g = (Gfx *)(pkt); \
2197  \
2198  _g->words.w0 = (_SHIFTL(G_TRI2, 24, 8)| \
2199  __gsSP1Quadrangle_w1f(v0, v1, v2, v3, flag)); \
2200  _g->words.w1 = __gsSP1Quadrangle_w2f(v0, v1, v2, v3, flag); \
2201 }
2202 
2203 #define gsSP1Quadrangle(v0, v1, v2, v3, flag) \
2204 {{ \
2205  (_SHIFTL(G_TRI2, 24, 8)| \
2206  __gsSP1Quadrangle_w1f(v0, v1, v2, v3, flag)), \
2207  __gsSP1Quadrangle_w2f(v0, v1, v2, v3, flag) \
2208 }}
2209 #endif
2210 #endif /* F3DEX_GBI_2 */
2211 
2212 #if (defined(F3DLP_GBI)||defined(F3DEX_GBI))
2213 /***
2214  *** 2 Triangles
2215  ***/
2216 #define gSP2Triangles(pkt, v00, v01, v02, flag0, v10, v11, v12, flag1) \
2217 { \
2218  Gfx *_g = (Gfx *)(pkt); \
2219  \
2220  _g->words.w0 = (_SHIFTL(G_TRI2, 24, 8)| \
2221  __gsSP1Triangle_w1f(v00, v01, v02, flag0)); \
2222  _g->words.w1 = __gsSP1Triangle_w1f(v10, v11, v12, flag1); \
2223 }
2224 
2225 #define gsSP2Triangles(v00, v01, v02, flag0, v10, v11, v12, flag1) \
2226 {{ \
2227  (_SHIFTL(G_TRI2, 24, 8)| \
2228  __gsSP1Triangle_w1f(v00, v01, v02, flag0)), \
2229  __gsSP1Triangle_w1f(v10, v11, v12, flag1) \
2230 }}
2231 #else
2232 #define gSP2Triangles(pkt, v00, v01, v02, flag0, v10, v11, v12, flag1) \
2233 { \
2234  gSP1Triangle(pkt, v00, v01, v02, flag0); \
2235  gSP1Triangle(pkt, v10, v11, v12, flag1); \
2236 }
2237 #define gsSP2Triangles(v00, v01, v02, flag0, v10, v11, v12, flag1) \
2238  gsSP1Triangle(v00, v01, v02, flag0), \
2239  gsSP1Triangle(v10, v11, v12, flag1)
2240 #endif /* F3DEX_GBI/F3DLP_GBI */
2241 
2242 #ifndef F3D_OLD
2243 #if (defined(F3DEX_GBI)||defined(F3DLP_GBI))
2244 #define gSPCullDisplayList(pkt,vstart,vend) \
2245 { \
2246  Gfx *_g = (Gfx *)(pkt); \
2247  \
2248  _g->words.w0 = _SHIFTL(G_CULLDL, 24, 8) | \
2249  _SHIFTL((vstart)*2, 0, 16); \
2250  _g->words.w1 = _SHIFTL((vend)*2, 0, 16); \
2251 }
2252 
2253 #define gsSPCullDisplayList(vstart,vend) \
2254 {{ \
2255  _SHIFTL(G_CULLDL, 24, 8) | _SHIFTL((vstart)*2, 0, 16), \
2256  _SHIFTL((vend)*2, 0, 16) \
2257 }}
2258 #endif
2259 #else /* F3D_OLD */
2260 #define gSPCullDisplayList(pkt,vstart,vend) \
2261 { \
2262  Gfx *_g = (Gfx *)(pkt); \
2263  \
2264  _g->words.w0 = _SHIFTL(G_CULLDL, 24, 8) | \
2265  ((0x0f & (vstart))*40); \
2266  _g->words.w1 = (unsigned int)((0x0f & ((vend)+1))*40); \
2267 }
2268 
2269 #define gsSPCullDisplayList(vstart,vend) \
2270 {{ \
2271  _SHIFTL(G_CULLDL, 24, 8) | ((0x0f & (vstart))*40), \
2272  ((0x0f & ((vend)+1))*40) \
2273 }}
2274 #endif
2275 
2276 #define gSPSegment(pkt, segment, base) \
2277  gMoveWd(pkt, G_MW_SEGMENT, (segment)*4, base)
2278 #define gsSPSegment(segment, base) \
2279  gsMoveWd( G_MW_SEGMENT, (segment)*4, base)
2280 
2281 /*
2282  * Clipping Macros
2283  */
2284 #define FR_NEG_FRUSTRATIO_1 0x00000001
2285 #define FR_POS_FRUSTRATIO_1 0x0000ffff
2286 #define FR_NEG_FRUSTRATIO_2 0x00000002
2287 #define FR_POS_FRUSTRATIO_2 0x0000fffe
2288 #define FR_NEG_FRUSTRATIO_3 0x00000003
2289 #define FR_POS_FRUSTRATIO_3 0x0000fffd
2290 #define FR_NEG_FRUSTRATIO_4 0x00000004
2291 #define FR_POS_FRUSTRATIO_4 0x0000fffc
2292 #define FR_NEG_FRUSTRATIO_5 0x00000005
2293 #define FR_POS_FRUSTRATIO_5 0x0000fffb
2294 #define FR_NEG_FRUSTRATIO_6 0x00000006
2295 #define FR_POS_FRUSTRATIO_6 0x0000fffa
2296 /*
2297  * r should be one of: FRUSTRATIO_1, FRUSTRATIO_2, FRUSTRATIO_3, ... FRUSTRATIO_6
2298  */
2299 #define gSPClipRatio(pkt, r) \
2300 { \
2301  gMoveWd(pkt, G_MW_CLIP, G_MWO_CLIP_RNX, FR_NEG_##r); \
2302  gMoveWd(pkt, G_MW_CLIP, G_MWO_CLIP_RNY, FR_NEG_##r); \
2303  gMoveWd(pkt, G_MW_CLIP, G_MWO_CLIP_RPX, FR_POS_##r); \
2304  gMoveWd(pkt, G_MW_CLIP, G_MWO_CLIP_RPY, FR_POS_##r); \
2305 }
2306 
2307 #define gsSPClipRatio(r) \
2308  gsMoveWd(G_MW_CLIP, G_MWO_CLIP_RNX, FR_NEG_##r), \
2309  gsMoveWd(G_MW_CLIP, G_MWO_CLIP_RNY, FR_NEG_##r), \
2310  gsMoveWd(G_MW_CLIP, G_MWO_CLIP_RPX, FR_POS_##r), \
2311  gsMoveWd(G_MW_CLIP, G_MWO_CLIP_RPY, FR_POS_##r)
2312 
2313 /*
2314  * Insert values into Matrix
2315  *
2316  * where = element of matrix (byte offset)
2317  * num = new element (32 bit value replacing 2 int or 2 frac matrix
2318  * componants
2319  */
2320 #ifdef F3DEX_GBI_2
2321 #define gSPInsertMatrix(pkt, where, num) \
2322  ERROR!! gSPInsertMatrix is no longer supported.
2323 #define gsSPInsertMatrix(where, num) \
2324  ERROR!! gsSPInsertMatrix is no longer supported.
2325 #else
2326 #define gSPInsertMatrix(pkt, where, num) \
2327  gMoveWd(pkt, G_MW_MATRIX, where, num)
2328 #define gsSPInsertMatrix(where, num) \
2329  gsMoveWd(G_MW_MATRIX, where, num)
2330 #endif
2331 
2332 /*
2333  * Load new matrix directly
2334  *
2335  * mptr = pointer to matrix
2336  */
2337 #ifdef F3DEX_GBI_2
2338 #define gSPForceMatrix(pkt, mptr) \
2339 { gDma2p((pkt),G_MOVEMEM,(mptr),sizeof(Mtx),G_MV_MATRIX,0); \
2340  gMoveWd((pkt), G_MW_FORCEMTX,0,0x00010000); \
2341 }
2342 #define gsSPForceMatrix(mptr) \
2343  gsDma2p(G_MOVEMEM,(mptr),sizeof(Mtx),G_MV_MATRIX,0), \
2344  gsMoveWd(G_MW_FORCEMTX,0,0x00010000)
2345 
2346 #else /* F3DEX_GBI_2 */
2347 #define gSPForceMatrix(pkt, mptr) \
2348 { \
2349  gDma1p(pkt, G_MOVEMEM, mptr, 16, G_MV_MATRIX_1); \
2350  gDma1p(pkt, G_MOVEMEM, (char *)(mptr)+16, 16, G_MV_MATRIX_2); \
2351  gDma1p(pkt, G_MOVEMEM, (char *)(mptr)+32, 16, G_MV_MATRIX_3); \
2352  gDma1p(pkt, G_MOVEMEM, (char *)(mptr)+48, 16, G_MV_MATRIX_4); \
2353 }
2354 #define gsSPForceMatrix(mptr) \
2355  gsDma1p( G_MOVEMEM, mptr, 16, G_MV_MATRIX_1), \
2356  gsDma1p( G_MOVEMEM, (char *)(mptr)+16, 16, G_MV_MATRIX_2), \
2357  gsDma1p( G_MOVEMEM, (char *)(mptr)+32, 16, G_MV_MATRIX_3), \
2358  gsDma1p( G_MOVEMEM, (char *)(mptr)+48, 16, G_MV_MATRIX_4)
2359 #endif /* F3DEX_GBI_2 */
2360 
2361 /*
2362  * Insert values into Points
2363  *
2364  * point = point number 0-15
2365  * where = which element of point to modify (byte offset into point)
2366  * num = new value (32 bit)
2367  */
2368 #if (defined(F3DEX_GBI)||defined(F3DLP_GBI))
2369 # define gSPModifyVertex(pkt, vtx, where, val) \
2370 { \
2371  Gfx *_g = (Gfx *)(pkt); \
2372  _g->words.w0 = (_SHIFTL(G_MODIFYVTX,24,8)| \
2373  _SHIFTL((where),16,8)|_SHIFTL((vtx)*2,0,16)); \
2374  _g->words.w1 = (unsigned int)(val); \
2375 }
2376 # define gsSPModifyVertex(vtx, where, val) \
2377 {{ \
2378  _SHIFTL(G_MODIFYVTX,24,8)| \
2379  _SHIFTL((where),16,8)|_SHIFTL((vtx)*2,0,16), \
2380  (unsigned int)(val) \
2381 }}
2382 #else
2383 # define gSPModifyVertex(pkt, vtx, where, val) \
2384  gMoveWd(pkt, G_MW_POINTS, (vtx)*40+(where), val)
2385 # define gsSPModifyVertex(vtx, where, val) \
2386  gsMoveWd(G_MW_POINTS, (vtx)*40+(where), val)
2387 #endif
2388 
2389 #if (defined(F3DEX_GBI)||defined(F3DLP_GBI))
2390 /*
2391  * gSPBranchLessZ Branch DL if (vtx.z) less than or equal (zval).
2392  *
2393  * dl = DL branch to
2394  * vtx = Vertex
2395  * zval = Screen depth
2396  * near = Near plane
2397  * far = Far plane
2398  * flag = G_BZ_PERSP or G_BZ_ORTHO
2399  */
2400 
2401 #define G_BZ_PERSP 0
2402 #define G_BZ_ORTHO 1
2403 
2404 #define G_DEPTOZSrg(zval, near, far, flag, zmin, zmax) \
2405 (((unsigned int)FTOFIX32(((flag) == G_BZ_PERSP ? \
2406  (1.0f-(float)(near)/(float)(zval)) / \
2407  (1.0f-(float)(near)/(float)(far )) : \
2408  ((float)(zval) - (float)(near)) / \
2409  ((float)(far ) - (float)(near))))) * \
2410  (((int)((zmax) - (zmin)))&~1) + (int)FTOFIX32(zmin))
2411 
2412 #define G_DEPTOZS(zval, near, far, flag) \
2413  G_DEPTOZSrg(zval, near, far, flag, 0, G_MAXZ)
2414 
2415 #define gSPBranchLessZrg(pkt, dl, vtx, zval, near, far, flag, zmin, zmax) \
2416 { \
2417  Gfx *_g = (Gfx *)(pkt); \
2418  _g->words.w0 = _SHIFTL(G_RDPHALF_1,24,8); \
2419  _g->words.w1 = (uintptr_t)(dl); \
2420  _g = (Gfx *)(pkt); \
2421  _g->words.w0 = (_SHIFTL(G_BRANCH_Z,24,8)| \
2422  _SHIFTL((vtx)*5,12,12)|_SHIFTL((vtx)*2,0,12)); \
2423  _g->words.w1 = G_DEPTOZSrg(zval, near, far, flag, zmin, zmax); \
2424 }
2425 
2426 #define gsSPBranchLessZrg(dl, vtx, zval, near, far, flag, zmin, zmax) \
2427 {{ _SHIFTL(G_RDPHALF_1,24,8), \
2428  (uintptr_t)(dl), }}, \
2429 {{ _SHIFTL(G_BRANCH_Z,24,8)|_SHIFTL((vtx)*5,12,12)|_SHIFTL((vtx)*2,0,12),\
2430  G_DEPTOZSrg(zval, near, far, flag, zmin, zmax), }}
2431 
2432 #define gSPBranchLessZ(pkt, dl, vtx, zval, near, far, flag) \
2433  gSPBranchLessZrg(pkt, dl, vtx, zval, near, far, flag, 0, G_MAXZ)
2434 #define gsSPBranchLessZ(dl, vtx, zval, near, far, flag) \
2435  gsSPBranchLessZrg(dl, vtx, zval, near, far, flag, 0, G_MAXZ)
2436 
2437 /*
2438  * gSPBranchLessZraw Branch DL if (vtx.z) less than or equal (raw zval).
2439  *
2440  * dl = DL branch to
2441  * vtx = Vertex
2442  * zval = Raw value of screen depth
2443  */
2444 #define gSPBranchLessZraw(pkt, dl, vtx, zval) \
2445 { \
2446  Gfx *_g = (Gfx *)(pkt); \
2447  _g->words.w0 = _SHIFTL(G_RDPHALF_1,24,8); \
2448  _g->words.w1 = (uintptr_t)(dl); \
2449  _g = (Gfx *)(pkt); \
2450  _g->words.w0 = (_SHIFTL(G_BRANCH_Z,24,8)| \
2451  _SHIFTL((vtx)*5,12,12)|_SHIFTL((vtx)*2,0,12)); \
2452  _g->words.w1 = (unsigned int)(zval); \
2453 }
2454 
2455 #define gsSPBranchLessZraw(dl, vtx, zval) \
2456 {{ _SHIFTL(G_RDPHALF_1,24,8), \
2457  (uintptr_t)(dl), }}, \
2458 {{ _SHIFTL(G_BRANCH_Z,24,8)|_SHIFTL((vtx)*5,12,12)|_SHIFTL((vtx)*2,0,12),\
2459  (unsigned int)(zval), }}
2460 
2461 /*
2462  * gSPLoadUcode RSP loads specified ucode.
2463  *
2464  * uc_start = ucode text section start
2465  * uc_dstart = ucode data section start
2466  */
2467 #define gSPLoadUcodeEx(pkt, uc_start, uc_dstart, uc_dsize) \
2468 { \
2469  Gfx *_g = (Gfx *)(pkt); \
2470  _g->words.w0 = _SHIFTL(G_RDPHALF_1,24,8); \
2471  _g->words.w1 = (uintptr_t)(uc_dstart); \
2472  _g = (Gfx *)(pkt); \
2473  _g->words.w0 = (_SHIFTL(G_LOAD_UCODE,24,8)| \
2474  _SHIFTL((int)(uc_dsize)-1,0,16)); \
2475  _g->words.w1 = (uintptr_t)(uc_start); \
2476 }
2477 
2478 #define gsSPLoadUcodeEx(uc_start, uc_dstart, uc_dsize) \
2479 {{ _SHIFTL(G_RDPHALF_1,24,8), \
2480  (uintptr_t)(uc_dstart), }}, \
2481 {{ _SHIFTL(G_LOAD_UCODE,24,8)| \
2482  _SHIFTL((int)(uc_dsize)-1,0,16), \
2483  (uintptr_t)(uc_start), }}
2484 
2485 #define gSPLoadUcode(pkt, uc_start, uc_dstart) \
2486  gSPLoadUcodeEx((pkt), (uc_start), (uc_dstart), SP_UCODE_DATA_SIZE)
2487 #define gsSPLoadUcode(uc_start, uc_dstart) \
2488  gsSPLoadUcodeEx((uc_start), (uc_dstart), SP_UCODE_DATA_SIZE)
2489 
2490 #define gSPLoadUcodeL(pkt, ucode) \
2491  gSPLoadUcode((pkt), OS_K0_TO_PHYSICAL(&##ucode##TextStart), \
2492  OS_K0_TO_PHYSICAL(&##ucode##DataStart))
2493 #define gsSPLoadUcodeL(ucode) \
2494  gsSPLoadUcode(OS_K0_TO_PHYSICAL(&##ucode##TextStart), \
2495  OS_K0_TO_PHYSICAL(&##ucode##DataStart))
2496 #endif
2497 
2498 #ifdef F3DEX_GBI_2
2499 /*
2500  * gSPDma_io DMA to/from DMEM/IMEM for DEBUG.
2501  */
2502 #define gSPDma_io(pkt, flag, dmem, dram, size) \
2503 { \
2504  Gfx *_g = (Gfx *)(pkt); \
2505  _g->words.w0 = _SHIFTL(G_DMA_IO,24,8)|_SHIFTL((flag),23,1)| \
2506  _SHIFTL((dmem)/8,13,10)|_SHIFTL((size)-1,0,12); \
2507  _g->words.w1 = (uintptr_t)(dram); \
2508 }
2509 
2510 #define gsSPDma_io(flag, dmem, dram, size) \
2511 {{ \
2512  _SHIFTL(G_DMA_IO,24,8)|_SHIFTL((flag),23,1)| \
2513  _SHIFTL((dmem)/8,13,10)|_SHIFTL((size)-1,0,12), \
2514  (uintptr_t)(dram) \
2515 }}
2516 
2517 #define gSPDmaRead(pkt,dmem,dram,size) gSPDma_io((pkt),0,(dmem),(dram),(size))
2518 #define gsSPDmaRead(dmem,dram,size) gsSPDma_io(0,(dmem),(dram),(size))
2519 #define gSPDmaWrite(pkt,dmem,dram,size) gSPDma_io((pkt),1,(dmem),(dram),(size))
2520 #define gsSPDmaWrite(dmem,dram,size) gsSPDma_io(1,(dmem),(dram),(size))
2521 #endif
2522 
2523 /*
2524  * Lighting Macros
2525  */
2526 #ifdef F3DEX_GBI_2
2527 # define NUML(n) ((n)*24)
2528 #else
2529 # define NUML(n) (((n)+1)*32 + 0x80000000)
2530 #endif
2531 #define NUMLIGHTS_0 1
2532 #define NUMLIGHTS_1 1
2533 #define NUMLIGHTS_2 2
2534 #define NUMLIGHTS_3 3
2535 #define NUMLIGHTS_4 4
2536 #define NUMLIGHTS_5 5
2537 #define NUMLIGHTS_6 6
2538 #define NUMLIGHTS_7 7
2539 /*
2540  * n should be one of: NUMLIGHTS_0, NUMLIGHTS_1, ..., NUMLIGHTS_7
2541  * NOTE: in addition to the number of directional lights specified,
2542  * there is always 1 ambient light
2543  */
2544 #define gSPNumLights(pkt, n) \
2545  gMoveWd(pkt, G_MW_NUMLIGHT, G_MWO_NUMLIGHT, NUML(n))
2546 #define gsSPNumLights(n) \
2547  gsMoveWd( G_MW_NUMLIGHT, G_MWO_NUMLIGHT, NUML(n))
2548 
2549 #define LIGHT_1 1
2550 #define LIGHT_2 2
2551 #define LIGHT_3 3
2552 #define LIGHT_4 4
2553 #define LIGHT_5 5
2554 #define LIGHT_6 6
2555 #define LIGHT_7 7
2556 #define LIGHT_8 8
2557 /*
2558  * l should point to a Light struct
2559  * n should be one of: LIGHT_1, LIGHT_2, ..., LIGHT_8
2560  * NOTE: the highest numbered light is always the ambient light (eg if there are
2561  * 3 directional lights defined: gsSPNumLights(NUMLIGHTS_3), then lights
2562  * LIGHT_1 through LIGHT_3 will be the directional lights and light
2563  * LIGHT_4 will be the ambient light.
2564  */
2565 #ifdef F3DEX_GBI_2
2566 # define gSPLight(pkt, l, n) \
2567  gDma2p((pkt),G_MOVEMEM,(l),sizeof(Light),G_MV_LIGHT,(n)*24+24)
2568 # define gsSPLight(l, n) \
2569  gsDma2p( G_MOVEMEM,(l),sizeof(Light),G_MV_LIGHT,(n)*24+24)
2570 #else /* F3DEX_GBI_2 */
2571 # define gSPLight(pkt, l, n) \
2572  gDma1p(pkt, G_MOVEMEM, l, sizeof(Light),((n)-1)*2+G_MV_L0)
2573 # define gsSPLight(l, n) \
2574  gsDma1p( G_MOVEMEM, l, sizeof(Light),((n)-1)*2+G_MV_L0)
2575 #endif /* F3DEX_GBI_2 */
2576 
2577 /*
2578  * gSPLightColor changes color of light without recalculating light direction
2579  * col is a 32 bit word with r,g,b,a (alpha is ignored)
2580  * n should be one of LIGHT_1, LIGHT_2, ..., LIGHT_8
2581  */
2582 #define gSPLightColor(pkt, n, col) \
2583 { \
2584  gMoveWd(pkt, G_MW_LIGHTCOL, G_MWO_a##n, col); \
2585  gMoveWd(pkt, G_MW_LIGHTCOL, G_MWO_b##n, col); \
2586 }
2587 #define gsSPLightColor(n, col) \
2588  gsMoveWd(G_MW_LIGHTCOL, G_MWO_a##n, col), \
2589  gsMoveWd(G_MW_LIGHTCOL, G_MWO_b##n, col)
2590 
2591 /* These macros use a structure "name" which is init'd with the gdSPDefLights macros*/
2592 
2593 #define gSPSetLights0(pkt,name) \
2594 { \
2595  gSPNumLights(pkt,NUMLIGHTS_0); \
2596  gSPLight(pkt,&name.l[0],1); \
2597  gSPLight(pkt,&name.a,2); \
2598 }
2599 #define gsSPSetLights0(name) \
2600  gsSPNumLights(NUMLIGHTS_0), \
2601  gsSPLight(&name.l[0],1), \
2602  gsSPLight(&name.a,2)
2603 
2604 #define gSPSetLights1(pkt,name) \
2605 { \
2606  gSPNumLights(pkt,NUMLIGHTS_1); \
2607  gSPLight(pkt,&name.l[0],1); \
2608  gSPLight(pkt,&name.a,2); \
2609 }
2610 #define gsSPSetLights1(name) \
2611  gsSPNumLights(NUMLIGHTS_1), \
2612  gsSPLight(&name.l[0],1), \
2613  gsSPLight(&name.a,2)
2614 
2615 #define gSPSetLights2(pkt,name) \
2616 { \
2617  gSPNumLights(pkt,NUMLIGHTS_2); \
2618  gSPLight(pkt,&name.l[0],1); \
2619  gSPLight(pkt,&name.l[1],2); \
2620  gSPLight(pkt,&name.a,3); \
2621 }
2622 #define gsSPSetLights2(name) \
2623  gsSPNumLights(NUMLIGHTS_2), \
2624  gsSPLight(&name.l[0],1), \
2625  gsSPLight(&name.l[1],2), \
2626  gsSPLight(&name.a,3)
2627 
2628 #define gSPSetLights3(pkt,name) \
2629 { \
2630  gSPNumLights(pkt,NUMLIGHTS_3); \
2631  gSPLight(pkt,&name.l[0],1); \
2632  gSPLight(pkt,&name.l[1],2); \
2633  gSPLight(pkt,&name.l[2],3); \
2634  gSPLight(pkt,&name.a,4); \
2635 }
2636 #define gsSPSetLights3(name) \
2637  gsSPNumLights(NUMLIGHTS_3), \
2638  gsSPLight(&name.l[0],1), \
2639  gsSPLight(&name.l[1],2), \
2640  gsSPLight(&name.l[2],3), \
2641  gsSPLight(&name.a,4)
2642 
2643 #define gSPSetLights4(pkt,name) \
2644 { \
2645  gSPNumLights(pkt,NUMLIGHTS_4); \
2646  gSPLight(pkt,&name.l[0],1); \
2647  gSPLight(pkt,&name.l[1],2); \
2648  gSPLight(pkt,&name.l[2],3); \
2649  gSPLight(pkt,&name.l[3],4); \
2650  gSPLight(pkt,&name.a,5); \
2651 }
2652 #define gsSPSetLights4(name) \
2653  gsSPNumLights(NUMLIGHTS_4), \
2654  gsSPLight(&name.l[0],1), \
2655  gsSPLight(&name.l[1],2), \
2656  gsSPLight(&name.l[2],3), \
2657  gsSPLight(&name.l[3],4), \
2658  gsSPLight(&name.a,5)
2659 
2660 #define gSPSetLights5(pkt,name) \
2661 { \
2662  gSPNumLights(pkt,NUMLIGHTS_5); \
2663  gSPLight(pkt,&name.l[0],1); \
2664  gSPLight(pkt,&name.l[1],2); \
2665  gSPLight(pkt,&name.l[2],3); \
2666  gSPLight(pkt,&name.l[3],4); \
2667  gSPLight(pkt,&name.l[4],5); \
2668  gSPLight(pkt,&name.a,6); \
2669 }
2670 
2671 #define gsSPSetLights5(name) \
2672  gsSPNumLights(NUMLIGHTS_5), \
2673  gsSPLight(&name.l[0],1), \
2674  gsSPLight(&name.l[1],2), \
2675  gsSPLight(&name.l[2],3), \
2676  gsSPLight(&name.l[3],4), \
2677  gsSPLight(&name.l[4],5), \
2678  gsSPLight(&name.a,6)
2679 
2680 #define gSPSetLights6(pkt,name) \
2681 { \
2682  gSPNumLights(pkt,NUMLIGHTS_6); \
2683  gSPLight(pkt,&name.l[0],1); \
2684  gSPLight(pkt,&name.l[1],2); \
2685  gSPLight(pkt,&name.l[2],3); \
2686  gSPLight(pkt,&name.l[3],4); \
2687  gSPLight(pkt,&name.l[4],5); \
2688  gSPLight(pkt,&name.l[5],6); \
2689  gSPLight(pkt,&name.a,7); \
2690 }
2691 
2692 #define gsSPSetLights6(name) \
2693  gsSPNumLights(NUMLIGHTS_6), \
2694  gsSPLight(&name.l[0],1), \
2695  gsSPLight(&name.l[1],2), \
2696  gsSPLight(&name.l[2],3), \
2697  gsSPLight(&name.l[3],4), \
2698  gsSPLight(&name.l[4],5), \
2699  gsSPLight(&name.l[5],6), \
2700  gsSPLight(&name.a,7)
2701 
2702 #define gSPSetLights7(pkt,name) \
2703 { \
2704  gSPNumLights(pkt,NUMLIGHTS_7); \
2705  gSPLight(pkt,&name.l[0],1); \
2706  gSPLight(pkt,&name.l[1],2); \
2707  gSPLight(pkt,&name.l[2],3); \
2708  gSPLight(pkt,&name.l[3],4); \
2709  gSPLight(pkt,&name.l[4],5); \
2710  gSPLight(pkt,&name.l[5],6); \
2711  gSPLight(pkt,&name.l[6],7); \
2712  gSPLight(pkt,&name.a,8); \
2713 }
2714 
2715 #define gsSPSetLights7(name) \
2716  gsSPNumLights(NUMLIGHTS_7), \
2717  gsSPLight(&name.l[0],1), \
2718  gsSPLight(&name.l[1],2), \
2719  gsSPLight(&name.l[2],3), \
2720  gsSPLight(&name.l[3],4), \
2721  gsSPLight(&name.l[4],5), \
2722  gsSPLight(&name.l[5],6), \
2723  gsSPLight(&name.l[6],7), \
2724  gsSPLight(&name.a,8)
2725 
2726 /*
2727  * Reflection/Hiliting Macros
2728  */
2729 #ifdef F3DEX_GBI_2
2730 # define gSPLookAtX(pkt, l) \
2731  gDma2p((pkt),G_MOVEMEM,(l),sizeof(Light),G_MV_LIGHT,G_MVO_LOOKATX)
2732 # define gsSPLookAtX(l) \
2733  gsDma2p( G_MOVEMEM,(l),sizeof(Light),G_MV_LIGHT,G_MVO_LOOKATX)
2734 # define gSPLookAtY(pkt, l) \
2735  gDma2p((pkt),G_MOVEMEM,(l),sizeof(Light),G_MV_LIGHT,G_MVO_LOOKATY)
2736 # define gsSPLookAtY(l) \
2737  gsDma2p( G_MOVEMEM,(l),sizeof(Light),G_MV_LIGHT,G_MVO_LOOKATY)
2738 #else /* F3DEX_GBI_2 */
2739 # define gSPLookAtX(pkt, l) \
2740  gDma1p(pkt, G_MOVEMEM, l, sizeof(Light),G_MV_LOOKATX)
2741 # define gsSPLookAtX(l) \
2742  gsDma1p( G_MOVEMEM, l, sizeof(Light),G_MV_LOOKATX)
2743 # define gSPLookAtY(pkt, l) \
2744  gDma1p(pkt, G_MOVEMEM, l, sizeof(Light),G_MV_LOOKATY)
2745 # define gsSPLookAtY(l) \
2746  gsDma1p( G_MOVEMEM, l, sizeof(Light),G_MV_LOOKATY)
2747 #endif /* F3DEX_GBI_2 */
2748 
2749 #define gSPLookAt(pkt, la) \
2750 { \
2751  gSPLookAtX(pkt,la) \
2752  gSPLookAtY(pkt,(char *)(la)+16) \
2753 }
2754 #define gsSPLookAt(la) \
2755  gsSPLookAtX(la), \
2756  gsSPLookAtY((char *)(la)+16)
2757 
2758 #define gDPSetHilite1Tile(pkt, tile, hilite, width, height) \
2759  gDPSetTileSize(pkt, tile, (hilite)->h.x1 & 0xfff, (hilite)->h.y1 & 0xfff, \
2760  ((((width)-1)*4)+(hilite)->h.x1) & 0xfff, ((((height)-1)*4)+(hilite)->h.y1) & 0xfff)
2761 
2762 #define gDPSetHilite2Tile(pkt, tile, hilite, width, height) \
2763  gDPSetTileSize(pkt, tile, (hilite)->h.x2 & 0xfff, (hilite)->h.y2 & 0xfff, \
2764  ((((width)-1)*4)+(hilite)->h.x2) & 0xfff, ((((height)-1)*4)+(hilite)->h.y2) & 0xfff)
2765 
2766 
2767 /*
2768  * FOG macros
2769  * fm = z multiplier
2770  * fo = z offset
2771  * FOG FORMULA: alpha(fog) = (eyespace z) * fm + fo CLAMPED 0 to 255
2772  * note: (eyespace z) ranges -1 to 1
2773  *
2774  * Alternate method of setting fog:
2775  * min, max: range 0 to 1000: 0=nearplane, 1000=farplane
2776  * min is where fog begins (usually less than max and often 0)
2777  * max is where fog is thickest (usually 1000)
2778  *
2779  */
2780 #define gSPFogFactor(pkt, fm, fo) \
2781  gMoveWd(pkt, G_MW_FOG, G_MWO_FOG, \
2782  (_SHIFTL(fm,16,16) | _SHIFTL(fo,0,16)))
2783 
2784 #define gsSPFogFactor(fm, fo) \
2785  gsMoveWd(G_MW_FOG, G_MWO_FOG, \
2786  (_SHIFTL(fm,16,16) | _SHIFTL(fo,0,16)))
2787 
2788 #define gSPFogPosition(pkt, min, max) \
2789  gMoveWd(pkt, G_MW_FOG, G_MWO_FOG, \
2790  (_SHIFTL((128000/((max)-(min))),16,16) | \
2791  _SHIFTL(((500-(min))*256/((max)-(min))),0,16)))
2792 
2793 #define gsSPFogPosition(min, max) \
2794  gsMoveWd(G_MW_FOG, G_MWO_FOG, \
2795  (_SHIFTL((128000/((max)-(min))),16,16) | \
2796  _SHIFTL(((500-(min))*256/((max)-(min))),0,16)))
2797 
2798 #ifdef F3DEX_GBI_2
2799 /*
2800  * Macros to turn texture on/off
2801  */
2802 # define gSPTexture(pkt, s, t, level, tile, on) \
2803 { \
2804  Gfx *_g = (Gfx *)(pkt); \
2805  \
2806  _g->words.w0 = (_SHIFTL(G_TEXTURE,24,8) | \
2807  _SHIFTL(BOWTIE_VAL,16,8) | \
2808  _SHIFTL((level),11,3) | _SHIFTL((tile),8,3) | \
2809  _SHIFTL((on),1,7)); \
2810  _g->words.w1 = (_SHIFTL((s),16,16) | _SHIFTL((t),0,16)); \
2811 }
2812 # define gsSPTexture(s, t, level, tile, on) \
2813 {{ \
2814  (_SHIFTL(G_TEXTURE,24,8) | _SHIFTL(BOWTIE_VAL,16,8) | \
2815  _SHIFTL((level),11,3) | _SHIFTL((tile),8,3) | _SHIFTL((on),1,7)),\
2816  (_SHIFTL((s),16,16) | _SHIFTL((t),0,16)) \
2817 }}
2818 /*
2819  * Different version of SPTexture macro, has an additional parameter
2820  * which is currently reserved in the microcode.
2821  */
2822 # define gSPTextureL(pkt, s, t, level, xparam, tile, on) \
2823 { \
2824  Gfx *_g = (Gfx *)(pkt); \
2825  \
2826  _g->words.w0 = (_SHIFTL(G_TEXTURE,24,8) | \
2827  _SHIFTL((xparam),16,8) | \
2828  _SHIFTL((level),11,3) | _SHIFTL((tile),8,3) | \
2829  _SHIFTL((on),1,7)); \
2830  _g->words.w1 = (_SHIFTL((s),16,16) | _SHIFTL((t),0,16)); \
2831 }
2832 # define gsSPTextureL(s, t, level, xparam, tile, on) \
2833 {{ \
2834  (_SHIFTL(G_TEXTURE,24,8) | _SHIFTL((xparam),16,8) | \
2835  _SHIFTL((level),11,3) | _SHIFTL((tile),8,3) | _SHIFTL((on),1,7)),\
2836  (_SHIFTL((s),16,16) | _SHIFTL((t),0,16)) \
2837 }}
2838 #else
2839 /*
2840  * Macros to turn texture on/off
2841  */
2842 # define gSPTexture(pkt, s, t, level, tile, on) \
2843 { \
2844  Gfx *_g = (Gfx *)(pkt); \
2845  \
2846  _g->words.w0 = (_SHIFTL(G_TEXTURE,24,8)|_SHIFTL(BOWTIE_VAL,16,8)|\
2847  _SHIFTL((level),11,3)|_SHIFTL((tile),8,3)| \
2848  _SHIFTL((on),0,8)); \
2849  _g->words.w1 = (_SHIFTL((s),16,16)|_SHIFTL((t),0,16)); \
2850 }
2851 # define gsSPTexture(s, t, level, tile, on) \
2852 {{ \
2853  (_SHIFTL(G_TEXTURE,24,8)|_SHIFTL(BOWTIE_VAL,16,8)| \
2854  _SHIFTL((level),11,3)|_SHIFTL((tile),8,3)|_SHIFTL((on),0,8)), \
2855  (_SHIFTL((s),16,16)|_SHIFTL((t),0,16)) \
2856 }}
2857 /*
2858  * Different version of SPTexture macro, has an additional parameter
2859  * which is currently reserved in the microcode.
2860  */
2861 # define gSPTextureL(pkt, s, t, level, xparam, tile, on) \
2862 { \
2863  Gfx *_g = (Gfx *)(pkt); \
2864  \
2865  _g->words.w0 = (_SHIFTL(G_TEXTURE,24,8)|_SHIFTL((xparam),16,8)| \
2866  _SHIFTL((level),11,3)|_SHIFTL((tile),8,3)| \
2867  _SHIFTL((on),0,8)); \
2868  _g->words.w1 = (_SHIFTL((s),16,16)|_SHIFTL((t),0,16)); \
2869 }
2870 # define gsSPTextureL(s, t, level, xparam, tile, on) \
2871 {{ \
2872  (_SHIFTL(G_TEXTURE,24,8)|_SHIFTL((xparam),16,8)| \
2873  _SHIFTL((level),11,3)|_SHIFTL((tile),8,3)|_SHIFTL((on),0,8)), \
2874  (_SHIFTL((s),16,16)|_SHIFTL((t),0,16)) \
2875 }}
2876 #endif
2877 
2878 #ifndef F3D_OLD
2879 # define gSPPerspNormalize(pkt, s) gMoveWd(pkt, G_MW_PERSPNORM, 0, (s))
2880 # define gsSPPerspNormalize(s) gsMoveWd( G_MW_PERSPNORM, 0, (s))
2881 #else
2882 # define gSPPerspNormalize(pkt, s) \
2883 { \
2884  Gfx *_g = (Gfx *)(pkt); \
2885  \
2886  _g->words.w0 = _SHIFTL(G_RDPHALF_1, 24, 8); \
2887  _g->words.w1 = (s); \
2888 }
2889 # define gsSPPerspNormalize(s) \
2890 {{ \
2891  _SHIFTL(G_RDPHALF_1, 24, 8), \
2892  (s) \
2893 }}
2894 #endif
2895 
2896 #ifdef F3DEX_GBI_2
2897 # define gSPPopMatrixN(pkt, n, num) gDma2p((pkt),G_POPMTX,(num)*64,64,2,0)
2898 # define gsSPPopMatrixN(n, num) gsDma2p( G_POPMTX,(num)*64,64,2,0)
2899 # define gSPPopMatrix(pkt, n) gSPPopMatrixN((pkt), (n), 1)
2900 # define gsSPPopMatrix(n) gsSPPopMatrixN( (n), 1)
2901 #else /* F3DEX_GBI_2 */
2902 # define gSPPopMatrix(pkt, n) gImmp1(pkt, G_POPMTX, n)
2903 # define gsSPPopMatrix(n) gsImmp1( G_POPMTX, n)
2904 #endif /* F3DEX_GBI_2 */
2905 
2906 #define gSPEndDisplayList(pkt) \
2907 { \
2908  Gfx *_g = (Gfx *)(pkt); \
2909  \
2910  _g->words.w0 = _SHIFTL(G_ENDDL, 24, 8); \
2911  _g->words.w1 = 0; \
2912 }
2913 
2914 #define gsSPEndDisplayList() \
2915 {{ \
2916  _SHIFTL(G_ENDDL, 24, 8), 0 \
2917 }}
2918 
2919 #ifdef F3DEX_GBI_2
2920 /*
2921  * One gSPGeometryMode(pkt,c,s) GBI is equal to these two GBIs.
2922  *
2923  * gSPClearGeometryMode(pkt,c)
2924  * gSPSetGeometryMode(pkt,s)
2925  *
2926  * gSPLoadGeometryMode(pkt, word) sets GeometryMode directly.
2927  */
2928 #define gSPGeometryMode(pkt, c, s) \
2929 { \
2930  Gfx *_g = (Gfx *)(pkt); \
2931  _g->words.w0 = _SHIFTL(G_GEOMETRYMODE,24,8)|_SHIFTL(~(u32)(c),0,24);\
2932  _g->words.w1 = (u32)(s); \
2933 }
2934 
2935 #define gsSPGeometryMode(c, s) \
2936 {{ \
2937  (_SHIFTL(G_GEOMETRYMODE,24,8)|_SHIFTL(~(u32)(c),0,24)),(u32)(s) \
2938 }}
2939 #define gSPSetGeometryMode(pkt, word) gSPGeometryMode((pkt),0,(word))
2940 #define gsSPSetGeometryMode(word) gsSPGeometryMode(0,(word))
2941 #define gSPClearGeometryMode(pkt, word) gSPGeometryMode((pkt),(word),0)
2942 #define gsSPClearGeometryMode(word) gsSPGeometryMode((word),0)
2943 #define gSPLoadGeometryMode(pkt, word) gSPGeometryMode((pkt),-1,(word))
2944 #define gsSPLoadGeometryMode(word) gsSPGeometryMode(-1,(word))
2945 #define gsSPGeometryModeSetFirst(c, s) gsSPGeometryMode(c, s)
2946 #else /* F3DEX_GBI_2 */
2947 #define gSPSetGeometryMode(pkt, word) \
2948 { \
2949  Gfx *_g = (Gfx *)(pkt); \
2950  \
2951  _g->words.w0 = _SHIFTL(G_SETGEOMETRYMODE, 24, 8); \
2952  _g->words.w1 = (unsigned int)(word); \
2953 }
2954 
2955 #define gsSPSetGeometryMode(word) \
2956 {{ \
2957  _SHIFTL(G_SETGEOMETRYMODE, 24, 8), (unsigned int)(word) \
2958 }}
2959 
2960 #define gSPClearGeometryMode(pkt, word) \
2961 { \
2962  Gfx *_g = (Gfx *)(pkt); \
2963  \
2964  _g->words.w0 = _SHIFTL(G_CLEARGEOMETRYMODE, 24, 8); \
2965  _g->words.w1 = (unsigned int)(word); \
2966 }
2967 
2968 #define gsSPClearGeometryMode(word) \
2969 {{ \
2970  _SHIFTL(G_CLEARGEOMETRYMODE, 24, 8), (unsigned int)(word) \
2971 }}
2972 
2973 /*
2974  * gsSPGeometryMode
2975  * In Fast3DEX2 it is better to use this, as the RSP geometry mode
2976  * is able to be set and cleared in a single command.
2977  */
2978 #define gsSPGeometryMode(c, s) \
2979  gsSPClearGeometryMode(c), \
2980  gsSPSetGeometryMode(s)
2981 #define gsSPGeometryModeSetFirst(c, s) \
2982  gsSPSetGeometryMode(s), \
2983  gsSPClearGeometryMode(c)
2984 #endif /* F3DEX_GBI_2 */
2985 
2986 #ifdef F3DEX_GBI_2
2987 #define gSPSetOtherMode(pkt, cmd, sft, len, data) \
2988 { \
2989  Gfx *_g = (Gfx *)(pkt); \
2990  _g->words.w0 = (_SHIFTL(cmd,24,8)|_SHIFTL(32-(sft)-(len),8,8)| \
2991  _SHIFTL((len)-1,0,8)); \
2992  _g->words.w1 = (unsigned int)(data); \
2993 }
2994 
2995 #define gsSPSetOtherMode(cmd, sft, len, data) \
2996 {{ \
2997  _SHIFTL(cmd,24,8)|_SHIFTL(32-(sft)-(len),8,8)|_SHIFTL((len)-1,0,8), \
2998  (unsigned int)(data) \
2999 }}
3000 #else
3001 #define gSPSetOtherMode(pkt, cmd, sft, len, data) \
3002 { \
3003  Gfx *_g = (Gfx *)(pkt); \
3004  \
3005  _g->words.w0 = (_SHIFTL(cmd, 24, 8) | _SHIFTL(sft, 8, 8) | \
3006  _SHIFTL(len, 0, 8)); \
3007  _g->words.w1 = (unsigned int)(data); \
3008 }
3009 
3010 #define gsSPSetOtherMode(cmd, sft, len, data) \
3011 {{ \
3012  _SHIFTL(cmd, 24, 8) | _SHIFTL(sft, 8, 8) | _SHIFTL(len, 0, 8), \
3013  (unsigned int)(data) \
3014 }}
3015 #endif
3016 
3017 /*
3018  * RDP setothermode register commands - register shadowed in RSP
3019  */
3020 #define gDPPipelineMode(pkt, mode) \
3021  gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_PIPELINE, 1, mode)
3022 #define gsDPPipelineMode(mode) \
3023  gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_PIPELINE, 1, mode)
3024 
3025 #define gDPSetCycleType(pkt, type) \
3026  gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_CYCLETYPE, 2, type)
3027 #define gsDPSetCycleType(type) \
3028  gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_CYCLETYPE, 2, type)
3029 
3030 #define gDPSetTexturePersp(pkt, type) \
3031  gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTPERSP, 1, type)
3032 #define gsDPSetTexturePersp(type) \
3033  gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_TEXTPERSP, 1, type)
3034 
3035 #define gDPSetTextureDetail(pkt, type) \
3036  gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTDETAIL, 2, type)
3037 #define gsDPSetTextureDetail(type) \
3038  gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_TEXTDETAIL, 2, type)
3039 
3040 #define gDPSetTextureLOD(pkt, type) \
3041  gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTLOD, 1, type)
3042 #define gsDPSetTextureLOD(type) \
3043  gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_TEXTLOD, 1, type)
3044 
3045 #define gDPSetTextureLUT(pkt, type) \
3046  gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTLUT, 2, type)
3047 #define gsDPSetTextureLUT(type) \
3048  gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_TEXTLUT, 2, type)
3049 
3050 #define gDPSetTextureFilter(pkt, type) \
3051  gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTFILT, 2, type)
3052 #define gsDPSetTextureFilter(type) \
3053  gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_TEXTFILT, 2, type)
3054 
3055 #define gDPSetTextureConvert(pkt, type) \
3056  gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTCONV, 3, type)
3057 #define gsDPSetTextureConvert(type) \
3058  gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_TEXTCONV, 3, type)
3059 
3060 #define gDPSetCombineKey(pkt, type) \
3061  gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_COMBKEY, 1, type)
3062 #define gsDPSetCombineKey(type) \
3063  gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_COMBKEY, 1, type)
3064 
3065 #ifndef _HW_VERSION_1
3066 #define gDPSetColorDither(pkt, mode) \
3067  gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_RGBDITHER, 2, mode)
3068 #define gsDPSetColorDither(mode) \
3069  gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_RGBDITHER, 2, mode)
3070 #else
3071 #define gDPSetColorDither(pkt, mode) \
3072  gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_COLORDITHER, 1, mode)
3073 #define gsDPSetColorDither(mode) \
3074  gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_COLORDITHER, 1, mode)
3075 #endif
3076 
3077 #ifndef _HW_VERSION_1
3078 #define gDPSetAlphaDither(pkt, mode) \
3079  gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_ALPHADITHER, 2, mode)
3080 #define gsDPSetAlphaDither(mode) \
3081  gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_ALPHADITHER, 2, mode)
3082 #endif
3083 
3084 /* 'blendmask' is not supported anymore.
3085  * The bits are reserved for future use.
3086  * Fri May 26 13:45:55 PDT 1995
3087  */
3088 #define gDPSetBlendMask(pkt, mask) gDPNoOp(pkt)
3089 #define gsDPSetBlendMask(mask) gsDPNoOp()
3090 
3091 #define gDPSetAlphaCompare(pkt, type) \
3092  gSPSetOtherMode(pkt, G_SETOTHERMODE_L, G_MDSFT_ALPHACOMPARE, 2, type)
3093 #define gsDPSetAlphaCompare(type) \
3094  gsSPSetOtherMode(G_SETOTHERMODE_L, G_MDSFT_ALPHACOMPARE, 2, type)
3095 
3096 #define gDPSetDepthSource(pkt, src) \
3097  gSPSetOtherMode(pkt, G_SETOTHERMODE_L, G_MDSFT_ZSRCSEL, 1, src)
3098 #define gsDPSetDepthSource(src) \
3099  gsSPSetOtherMode(G_SETOTHERMODE_L, G_MDSFT_ZSRCSEL, 1, src)
3100 
3101 #define gDPSetRenderMode(pkt, c0, c1) \
3102  gSPSetOtherMode(pkt, G_SETOTHERMODE_L, G_MDSFT_RENDERMODE, 29, \
3103  (c0) | (c1))
3104 #define gsDPSetRenderMode(c0, c1) \
3105  gsSPSetOtherMode(G_SETOTHERMODE_L, G_MDSFT_RENDERMODE, 29, \
3106  (c0) | (c1))
3107 
3108 #define gSetImage(pkt, cmd, fmt, siz, width, i) \
3109 { \
3110  Gfx *_g = (Gfx *)(pkt); \
3111  \
3112  _g->words.w0 = _SHIFTL(cmd, 24, 8) | _SHIFTL(fmt, 21, 3) | \
3113  _SHIFTL(siz, 19, 2) | _SHIFTL((width)-1, 0, 12); \
3114  _g->words.w1 = (uintptr_t)(i); \
3115 }
3116 
3117 #define gsSetImage(cmd, fmt, siz, width, i) \
3118 {{ \
3119  _SHIFTL(cmd, 24, 8) | _SHIFTL(fmt, 21, 3) | \
3120  _SHIFTL(siz, 19, 2) | _SHIFTL((width)-1, 0, 12), \
3121  (uintptr_t)(i) \
3122 }}
3123 
3124 #define gDPSetColorImage(pkt, f, s, w, i) gSetImage(pkt, G_SETCIMG, f, s, w, i)
3125 #define gsDPSetColorImage(f, s, w, i) gsSetImage(G_SETCIMG, f, s, w, i)
3126 
3127 
3128 /* use these for new code */
3129 #define gDPSetDepthImage(pkt, i) gSetImage(pkt, G_SETZIMG, 0, 0, 1, i)
3130 #define gsDPSetDepthImage(i) gsSetImage(G_SETZIMG, 0, 0, 1, i)
3131 /* kept for compatibility */
3132 #define gDPSetMaskImage(pkt, i) gDPSetDepthImage(pkt, i)
3133 #define gsDPSetMaskImage(i) gsDPSetDepthImage(i)
3134 
3135 #define gDPSetTextureImage(pkt, f, s, w, i) gSetImage(pkt, G_SETTIMG, f, s, w, i)
3136 #define gsDPSetTextureImage(f, s, w, i) gsSetImage(G_SETTIMG, f, s, w, i)
3137 
3138 /*
3139  * RDP macros
3140  */
3141 
3142 #define gDPSetCombine(pkt, muxs0, muxs1) \
3143 { \
3144  Gfx *_g = (Gfx *)(pkt); \
3145  \
3146  _g->words.w0 = _SHIFTL(G_SETCOMBINE, 24, 8) | _SHIFTL(muxs0, 0, 24);\
3147  _g->words.w1 = (unsigned int)(muxs1); \
3148 }
3149 
3150 #define gsDPSetCombine(muxs0, muxs1) \
3151 {{ \
3152  _SHIFTL(G_SETCOMBINE, 24, 8) | _SHIFTL(muxs0, 0, 24), \
3153  (unsigned int)(muxs1) \
3154 }}
3155 
3156 #define GCCc0w0(saRGB0, mRGB0, saA0, mA0) \
3157  (_SHIFTL((saRGB0), 20, 4) | _SHIFTL((mRGB0), 15, 5) | \
3158  _SHIFTL((saA0), 12, 3) | _SHIFTL((mA0), 9, 3))
3159 
3160 #define GCCc1w0(saRGB1, mRGB1) \
3161  (_SHIFTL((saRGB1), 5, 4) | _SHIFTL((mRGB1), 0, 5))
3162 
3163 #define GCCc0w1(sbRGB0, aRGB0, sbA0, aA0) \
3164  (_SHIFTL((sbRGB0), 28, 4) | _SHIFTL((aRGB0), 15, 3) | \
3165  _SHIFTL((sbA0), 12, 3) | _SHIFTL((aA0), 9, 3))
3166 
3167 #define GCCc1w1(sbRGB1, saA1, mA1, aRGB1, sbA1, aA1) \
3168  (_SHIFTL((sbRGB1), 24, 4) | _SHIFTL((saA1), 21, 3) | \
3169  _SHIFTL((mA1), 18, 3) | _SHIFTL((aRGB1), 6, 3) | \
3170  _SHIFTL((sbA1), 3, 3) | _SHIFTL((aA1), 0, 3))
3171 
3172 #define gDPSetCombineLERP(pkt, a0, b0, c0, d0, Aa0, Ab0, Ac0, Ad0, \
3173  a1, b1, c1, d1, Aa1, Ab1, Ac1, Ad1) \
3174 { \
3175  Gfx *_g = (Gfx *)(pkt); \
3176  \
3177  _g->words.w0 = _SHIFTL(G_SETCOMBINE, 24, 8) | \
3178  _SHIFTL(GCCc0w0(G_CCMUX_##a0, G_CCMUX_##c0, \
3179  G_ACMUX_##Aa0, G_ACMUX_##Ac0) | \
3180  GCCc1w0(G_CCMUX_##a1, G_CCMUX_##c1), \
3181  0, 24); \
3182  _g->words.w1 = (unsigned int)(GCCc0w1(G_CCMUX_##b0, \
3183  G_CCMUX_##d0, \
3184  G_ACMUX_##Ab0, \
3185  G_ACMUX_##Ad0) | \
3186  GCCc1w1(G_CCMUX_##b1, \
3187  G_ACMUX_##Aa1, \
3188  G_ACMUX_##Ac1, \
3189  G_CCMUX_##d1, \
3190  G_ACMUX_##Ab1, \
3191  G_ACMUX_##Ad1)); \
3192 }
3193 
3194 #define gsDPSetCombineLERP(a0, b0, c0, d0, Aa0, Ab0, Ac0, Ad0, \
3195  a1, b1, c1, d1, Aa1, Ab1, Ac1, Ad1) \
3196 {{ \
3197  _SHIFTL(G_SETCOMBINE, 24, 8) | \
3198  _SHIFTL(GCCc0w0(G_CCMUX_##a0, G_CCMUX_##c0, \
3199  G_ACMUX_##Aa0, G_ACMUX_##Ac0) | \
3200  GCCc1w0(G_CCMUX_##a1, G_CCMUX_##c1), 0, 24), \
3201  (unsigned int)(GCCc0w1(G_CCMUX_##b0, G_CCMUX_##d0, \
3202  G_ACMUX_##Ab0, G_ACMUX_##Ad0) | \
3203  GCCc1w1(G_CCMUX_##b1, G_ACMUX_##Aa1, \
3204  G_ACMUX_##Ac1, G_CCMUX_##d1, \
3205  G_ACMUX_##Ab1, G_ACMUX_##Ad1)) \
3206 }}
3207 
3208 /*
3209  * SetCombineMode macros are NOT redunant. It allow the C preprocessor
3210  * to substitute single parameter which includes commas in the token and
3211  * rescan for higher parameter count macro substitution.
3212  *
3213  * eg. gsDPSetCombineMode(G_CC_MODULATE, G_CC_MODULATE) turns into
3214  * gsDPSetCombineLERP(TEXEL0, 0, SHADE, 0, TEXEL0, 0, SHADE, 0,
3215  * TEXEL0, 0, SHADE, 0, TEXEL0, 0, SHADE, 0)
3216  */
3217 
3218 #define gDPSetCombineMode(pkt, a, b) gDPSetCombineLERP(pkt, a, b)
3219 #define gsDPSetCombineMode(a, b) gsDPSetCombineLERP(a, b)
3220 
3221 #define gDPSetColor(pkt, c, d) \
3222 { \
3223  Gfx *_g = (Gfx *)(pkt); \
3224  \
3225  _g->words.w0 = _SHIFTL(c, 24, 8); \
3226  _g->words.w1 = (unsigned int)(d); \
3227 }
3228 
3229 #define gsDPSetColor(c, d) \
3230 {{ \
3231  _SHIFTL(c, 24, 8), (unsigned int)(d) \
3232 }}
3233 
3234 #define DPRGBColor(pkt, cmd, r, g, b, a) \
3235  gDPSetColor(pkt, cmd, \
3236  (_SHIFTL(r, 24, 8) | _SHIFTL(g, 16, 8) | \
3237  _SHIFTL(b, 8, 8) | _SHIFTL(a, 0, 8)))
3238 #define sDPRGBColor(cmd, r, g, b, a) \
3239  gsDPSetColor(cmd, \
3240  (_SHIFTL(r, 24, 8) | _SHIFTL(g, 16, 8) | \
3241  _SHIFTL(b, 8, 8) | _SHIFTL(a, 0, 8)))
3242 
3243 #define gDPSetEnvColor(pkt, r, g, b, a) \
3244  DPRGBColor(pkt, G_SETENVCOLOR, r,g,b,a)
3245 #define gsDPSetEnvColor(r, g, b, a) \
3246  sDPRGBColor(G_SETENVCOLOR, r,g,b,a)
3247 #define gDPSetBlendColor(pkt, r, g, b, a) \
3248  DPRGBColor(pkt, G_SETBLENDCOLOR, r,g,b,a)
3249 #define gsDPSetBlendColor(r, g, b, a) \
3250  sDPRGBColor(G_SETBLENDCOLOR, r,g,b,a)
3251 #define gDPSetFogColor(pkt, r, g, b, a) \
3252  DPRGBColor(pkt, G_SETFOGCOLOR, r,g,b,a)
3253 #define gsDPSetFogColor(r, g, b, a) \
3254  sDPRGBColor(G_SETFOGCOLOR, r,g,b,a)
3255 #define gDPSetFillColor(pkt, d) \
3256  gDPSetColor(pkt, G_SETFILLCOLOR, (d))
3257 #define gsDPSetFillColor(d) \
3258  gsDPSetColor(G_SETFILLCOLOR, (d))
3259 
3260 #define gDPSetPrimDepth(pkt, z, dz) \
3261  gDPSetColor(pkt, G_SETPRIMDEPTH, \
3262  _SHIFTL(z, 16, 16) | _SHIFTL(dz, 0, 16))
3263 #define gsDPSetPrimDepth(z, dz) \
3264  gsDPSetColor(G_SETPRIMDEPTH, _SHIFTL(z, 16, 16) | \
3265  _SHIFTL(dz, 0, 16))
3266 
3267 #define gDPSetPrimColor(pkt, m, l, r, g, b, a) \
3268 { \
3269  Gfx *_g = (Gfx *)(pkt); \
3270  \
3271  _g->words.w0 = (_SHIFTL(G_SETPRIMCOLOR, 24, 8) | \
3272  _SHIFTL(m, 8, 8) | _SHIFTL(l, 0, 8)); \
3273  _g->words.w1 = (_SHIFTL(r, 24, 8) | _SHIFTL(g, 16, 8) | \
3274  _SHIFTL(b, 8, 8) | _SHIFTL(a, 0, 8)); \
3275 }
3276 
3277 #define gsDPSetPrimColor(m, l, r, g, b, a) \
3278 {{ \
3279  (_SHIFTL(G_SETPRIMCOLOR, 24, 8) | _SHIFTL(m, 8, 8) | \
3280  _SHIFTL(l, 0, 8)), \
3281  (_SHIFTL(r, 24, 8) | _SHIFTL(g, 16, 8) | _SHIFTL(b, 8, 8) | \
3282  _SHIFTL(a, 0, 8)) \
3283 }}
3284 
3285 /*
3286  * gDPSetOtherMode (This is for expert user.)
3287  *
3288  * This command makes all othermode parameters set.
3289  * Do not use this command in the same DL with another g*SPSetOtherMode DLs.
3290  *
3291  * [Usage]
3292  * gDPSetOtherMode(pkt, modeA, modeB)
3293  *
3294  * 'modeA' is described all parameters of GroupA GBI command.
3295  * 'modeB' is also described all parameters of GroupB GBI command.
3296  *
3297  * GroupA:
3298  * gDPPipelineMode, gDPSetCycleType, gSPSetTexturePersp,
3299  * gDPSetTextureDetail, gDPSetTextureLOD, gDPSetTextureLUT,
3300  * gDPSetTextureFilter, gDPSetTextureConvert, gDPSetCombineKey,
3301  * gDPSetColorDither, gDPSetAlphaDither
3302  *
3303  * GroupB:
3304  * gDPSetAlphaCompare, gDPSetDepthSource, gDPSetRenderMode
3305  *
3306  * Use 'OR' operation to get modeA and modeB.
3307  *
3308  * modeA = G_PM_* | G_CYC_* | G_TP_* | G_TD_* | G_TL_* | G_TT_* | G_TF_*
3309  * G_TC_* | G_CK_* | G_CD_* | G_AD_*;
3310  *
3311  * modeB = G_AC_* | G_ZS_* | G_RM_* | G_RM_*2;
3312  */
3313 #define gDPSetOtherMode(pkt, mode0, mode1) \
3314 { \
3315  Gfx *_g = (Gfx *)(pkt); \
3316  \
3317  _g->words.w0 = _SHIFTL(G_RDPSETOTHERMODE,24,8)|_SHIFTL(mode0,0,24);\
3318  _g->words.w1 = (unsigned int)(mode1); \
3319 }
3320 
3321 #define gsDPSetOtherMode(mode0, mode1) \
3322 {{ \
3323  _SHIFTL(G_RDPSETOTHERMODE,24,8)|_SHIFTL(mode0,0,24), \
3324  (unsigned int)(mode1) \
3325 }}
3326 
3327 /*
3328  * Texturing macros
3329  */
3330 
3331 /* These are also defined defined above for Sprite Microcode */
3332 
3333 #define G_TX_LOADTILE 7
3334 #define G_TX_RENDERTILE 0
3335 
3336 #define G_TX_NOMIRROR 0
3337 #define G_TX_WRAP 0
3338 #define G_TX_MIRROR 0x1
3339 #define G_TX_CLAMP 0x2
3340 #define G_TX_NOMASK 0
3341 #define G_TX_NOLOD 0
3342 
3343 
3344 #ifndef MAX
3345 #define MAX(a, b) ((a) > (b) ? (a) : (b))
3346 #endif
3347 
3348 #ifndef MIN
3349 #define MIN(a, b) ((a) < (b) ? (a) : (b))
3350 #endif
3351 /*
3352  * Dxt is the inverse of the number of 64-bit words in a line of
3353  * the texture being loaded using the load_block command. If
3354  * there are any 1's to the right of the 11th fractional bit,
3355  * dxt should be rounded up. The following macros accomplish
3356  * this. The 4b macros are a special case since 4-bit textures
3357  * are loaded as 8-bit textures. Dxt is fixed point 1.11. RJM
3358  */
3359 #define G_TX_DXT_FRAC 11
3360 
3361 /*
3362  * For RCP 2.0, the maximum number of texels that can be loaded
3363  * using a load_block command is 2048. In order to load the total
3364  * 4kB of Tmem, change the texel size when loading to be G_IM_SIZ_16b,
3365  * then change the tile to the proper texel size after the load.
3366  * The g*DPLoadTextureBlock macros already do this, so this change
3367  * will be transparent if you use these macros. If you use
3368  * the g*DPLoadBlock macros directly, you will need to handle this
3369  * tile manipulation yourself. RJM.
3370  */
3371 #ifdef _HW_VERSION_1
3372 #define G_TX_LDBLK_MAX_TXL 4095
3373 #else
3374 #define G_TX_LDBLK_MAX_TXL 2047
3375 #endif /* _HW_VERSION_1 */
3376 
3377 #define TXL2WORDS(txls, b_txl) MAX(1, ((txls)*(b_txl)/8))
3378 #define CALC_DXT(width, b_txl) \
3379  (((1 << G_TX_DXT_FRAC) + TXL2WORDS(width, b_txl) - 1) / \
3380  TXL2WORDS(width, b_txl))
3381 
3382 #define TXL2WORDS_4b(txls) MAX(1, ((txls)/16))
3383 #define CALC_DXT_4b(width) \
3384  (((1 << G_TX_DXT_FRAC) + TXL2WORDS_4b(width) - 1) / \
3385  TXL2WORDS_4b(width))
3386 
3387 #define gDPLoadTileGeneric(pkt, c, tile, uls, ult, lrs, lrt) \
3388 { \
3389  Gfx *_g = (Gfx *)(pkt); \
3390  \
3391  _g->words.w0 = _SHIFTL(c, 24, 8) | _SHIFTL(uls, 12, 12) | \
3392  _SHIFTL(ult, 0, 12); \
3393  _g->words.w1 = _SHIFTL(tile, 24, 3) | _SHIFTL(lrs, 12, 12) | \
3394  _SHIFTL(lrt, 0, 12); \
3395 }
3396 
3397 #define gsDPLoadTileGeneric(c, tile, uls, ult, lrs, lrt) \
3398 {{ \
3399  _SHIFTL(c, 24, 8) | _SHIFTL(uls, 12, 12) | _SHIFTL(ult, 0, 12), \
3400  _SHIFTL(tile, 24, 3) | _SHIFTL(lrs, 12, 12) | _SHIFTL(lrt, 0, 12)\
3401 }}
3402 
3403 #define gDPSetTileSize(pkt, t, uls, ult, lrs, lrt) \
3404  gDPLoadTileGeneric(pkt, G_SETTILESIZE, t, uls, ult, lrs, lrt)
3405 #define gsDPSetTileSize(t, uls, ult, lrs, lrt) \
3406  gsDPLoadTileGeneric(G_SETTILESIZE, t, uls, ult, lrs, lrt)
3407 #define gDPLoadTile(pkt, t, uls, ult, lrs, lrt) \
3408  gDPLoadTileGeneric(pkt, G_LOADTILE, t, uls, ult, lrs, lrt)
3409 #define gsDPLoadTile(t, uls, ult, lrs, lrt) \
3410  gsDPLoadTileGeneric(G_LOADTILE, t, uls, ult, lrs, lrt)
3411 
3412 #define gDPSetTile(pkt, fmt, siz, line, tmem, tile, palette, cmt, \
3413  maskt, shiftt, cms, masks, shifts) \
3414 { \
3415  Gfx *_g = (Gfx *)(pkt); \
3416  \
3417  _g->words.w0 = _SHIFTL(G_SETTILE, 24, 8) | _SHIFTL(fmt, 21, 3) |\
3418  _SHIFTL(siz, 19, 2) | _SHIFTL(line, 9, 9) | \
3419  _SHIFTL(tmem, 0, 9); \
3420  _g->words.w1 = _SHIFTL(tile, 24, 3) | _SHIFTL(palette, 20, 4) | \
3421  _SHIFTL(cmt, 18, 2) | _SHIFTL(maskt, 14, 4) | \
3422  _SHIFTL(shiftt, 10, 4) |_SHIFTL(cms, 8, 2) | \
3423  _SHIFTL(masks, 4, 4) | _SHIFTL(shifts, 0, 4); \
3424 }
3425 
3426 #define gsDPSetTile(fmt, siz, line, tmem, tile, palette, cmt, \
3427  maskt, shiftt, cms, masks, shifts) \
3428 {{ \
3429  (_SHIFTL(G_SETTILE, 24, 8) | _SHIFTL(fmt, 21, 3) | \
3430  _SHIFTL(siz, 19, 2) | _SHIFTL(line, 9, 9) | _SHIFTL(tmem, 0, 9)),\
3431  (_SHIFTL(tile, 24, 3) | _SHIFTL(palette, 20, 4) | \
3432  _SHIFTL(cmt, 18, 2) | _SHIFTL(maskt, 14, 4) | \
3433  _SHIFTL(shiftt, 10, 4) | _SHIFTL(cms, 8, 2) | \
3434  _SHIFTL(masks, 4, 4) | _SHIFTL(shifts, 0, 4)) \
3435 }}
3436 
3437 /*
3438  * For RCP 2.0, the maximum number of texels that can be loaded
3439  * using a load_block command is 2048. In order to load the total
3440  * 4kB of Tmem, change the texel size when loading to be G_IM_SIZ_16b,
3441  * then change the tile to the proper texel size after the load.
3442  * The g*DPLoadTextureBlock macros already do this, so this change
3443  * will be transparent if you use these macros. If you use
3444  * the g*DPLoadBlock macros directly, you will need to handle this
3445  * tile manipulation yourself. RJM.
3446  */
3447 #define gDPLoadBlock(pkt, tile, uls, ult, lrs, dxt) \
3448 { \
3449  Gfx *_g = (Gfx *)(pkt); \
3450  \
3451  _g->words.w0 = (_SHIFTL(G_LOADBLOCK, 24, 8) | \
3452  _SHIFTL(uls, 12, 12) | _SHIFTL(ult, 0, 12)); \
3453  _g->words.w1 = (_SHIFTL(tile, 24, 3) | \
3454  _SHIFTL((MIN(lrs,G_TX_LDBLK_MAX_TXL)), 12, 12) |\
3455  _SHIFTL(dxt, 0, 12)); \
3456 }
3457 
3458 #define gsDPLoadBlock(tile, uls, ult, lrs, dxt) \
3459 {{ \
3460  (_SHIFTL(G_LOADBLOCK, 24, 8) | _SHIFTL(uls, 12, 12) | \
3461  _SHIFTL(ult, 0, 12)), \
3462  (_SHIFTL(tile, 24, 3) | \
3463  _SHIFTL((MIN(lrs,G_TX_LDBLK_MAX_TXL)), 12, 12) | \
3464  _SHIFTL(dxt, 0, 12)) \
3465 }}
3466 
3467 #define gDPLoadTLUTCmd(pkt, tile, count) \
3468 { \
3469  Gfx *_g = (Gfx *)pkt; \
3470  \
3471  _g->words.w0 = _SHIFTL(G_LOADTLUT, 24, 8); \
3472  _g->words.w1 = _SHIFTL((tile), 24, 3) | _SHIFTL((count), 14, 10);\
3473 }
3474 
3475 #define gsDPLoadTLUTCmd(tile, count) \
3476 {{ \
3477  _SHIFTL(G_LOADTLUT, 24, 8), \
3478  _SHIFTL((tile), 24, 3) | _SHIFTL((count), 14, 10) \
3479 }}
3480 
3481 #define gDPLoadTextureBlock(pkt, timg, fmt, siz, width, height, \
3482  pal, cms, cmt, masks, maskt, shifts, shiftt) \
3483 { \
3484  gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \
3485  gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, 0, G_TX_LOADTILE, \
3486  0 , cmt, maskt, shiftt, cms, masks, shifts); \
3487  gDPLoadSync(pkt); \
3488  gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
3489  (((width)*(height) + siz##_INCR) >> siz##_SHIFT) -1, \
3490  CALC_DXT(width, siz##_BYTES)); \
3491  gDPPipeSync(pkt); \
3492  gDPSetTile(pkt, fmt, siz, \
3493  (((width) * siz##_LINE_BYTES)+7)>>3, 0, \
3494  G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \
3495  shifts); \
3496  gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \
3497  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3498  ((height)-1) << G_TEXTURE_IMAGE_FRAC) \
3499 }
3500 
3501 #define gDPLoadTextureBlockYuv(pkt, timg, fmt, siz, width, height, \
3502  pal, cms, cmt, masks, maskt, shifts, shiftt) \
3503 { \
3504  gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \
3505  gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, 0, G_TX_LOADTILE, \
3506  0 , cmt, maskt, shiftt, cms, masks, shifts); \
3507  gDPLoadSync(pkt); \
3508  gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
3509  (((width)*(height) + siz##_INCR) >> siz##_SHIFT) -1, \
3510  CALC_DXT(width, siz##_BYTES)); \
3511  gDPPipeSync(pkt); \
3512  gDPSetTile(pkt, fmt, siz, \
3513  (((width) * 1)+7)>>3, 0, \
3514  G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \
3515  shifts); \
3516  gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \
3517  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3518  ((height)-1) << G_TEXTURE_IMAGE_FRAC) \
3519 }
3520 
3521 /* Load fix rww 27jun95 */
3522 /* The S at the end means odd lines are already word Swapped */
3523 
3524 #define gDPLoadTextureBlockS(pkt, timg, fmt, siz, width, height, \
3525  pal, cms, cmt, masks, maskt, shifts, shiftt) \
3526 { \
3527  gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \
3528  gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, 0, G_TX_LOADTILE, \
3529  0 , cmt, maskt, shiftt, cms, masks, shifts); \
3530  gDPLoadSync(pkt); \
3531  gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
3532  (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1,0); \
3533  gDPPipeSync(pkt); \
3534  gDPSetTile(pkt, fmt, siz, \
3535  (((width) * siz##_LINE_BYTES)+7)>>3, 0, \
3536  G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \
3537  shifts); \
3538  gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \
3539  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3540  ((height)-1) << G_TEXTURE_IMAGE_FRAC) \
3541 }
3542 
3543 /*
3544  * Allow tmem address and render tile to be specified.
3545  * The S at the end means odd lines are already word Swapped
3546  */
3547 #define gDPLoadMultiBlockS(pkt, timg, tmem, rtile, fmt, siz, width, \
3548  height, pal, cms, cmt, masks, maskt, shifts, shiftt) \
3549 { \
3550  gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \
3551  gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, tmem, G_TX_LOADTILE, \
3552  0 , cmt, maskt, shiftt, cms, masks, shifts); \
3553  gDPLoadSync(pkt); \
3554  gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
3555  (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1,0); \
3556  gDPPipeSync(pkt); \
3557  gDPSetTile(pkt, fmt, siz, \
3558  (((width) * siz##_LINE_BYTES)+7)>>3, tmem, \
3559  rtile, pal, cmt, maskt, shiftt, cms, masks, \
3560  shifts); \
3561  gDPSetTileSize(pkt, rtile, 0, 0, \
3562  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3563  ((height)-1) << G_TEXTURE_IMAGE_FRAC) \
3564 }
3565 
3566 
3567 #define gDPLoadTextureBlockYuvS(pkt, timg, fmt, siz, width, height, \
3568  pal, cms, cmt, masks, maskt, shifts, shiftt) \
3569 { \
3570  gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \
3571  gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, 0, G_TX_LOADTILE, \
3572  0 , cmt, maskt, shiftt, cms, masks, shifts); \
3573  gDPLoadSync(pkt); \
3574  gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
3575  (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1,0); \
3576  gDPPipeSync(pkt); \
3577  gDPSetTile(pkt, fmt, siz, \
3578  (((width) * 1)+7)>>3, 0, \
3579  G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \
3580  shifts); \
3581  gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \
3582  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3583  ((height)-1) << G_TEXTURE_IMAGE_FRAC) \
3584 }
3585 
3586 /*
3587  * allows tmem address to be specified
3588  */
3589 #define _gDPLoadTextureBlock(pkt, timg, tmem, fmt, siz, width, height, \
3590  pal, cms, cmt, masks, maskt, shifts, shiftt) \
3591 { \
3592  gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \
3593  gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, tmem, G_TX_LOADTILE, \
3594  0, cmt, maskt, shiftt, cms, masks, shifts); \
3595  gDPLoadSync(pkt); \
3596  gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
3597  (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1, \
3598  CALC_DXT(width, siz##_BYTES)); \
3599  gDPPipeSync(pkt); \
3600  gDPSetTile(pkt, fmt, siz, (((width) * siz##_LINE_BYTES)+7)>>3, \
3601  tmem, G_TX_RENDERTILE, pal, cmt, \
3602  maskt, shiftt, cms, masks, shifts); \
3603  gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \
3604  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3605  ((height)-1) << G_TEXTURE_IMAGE_FRAC) \
3606 }
3607 
3608 /*
3609  * allows tmem address and render tile to be specified
3610  */
3611 #define _gDPLoadTextureBlockTile(pkt, timg, tmem, rtile, fmt, siz, width, \
3612  height, pal, cms, cmt, masks, maskt, shifts, shiftt) \
3613 { \
3614  gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \
3615  gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, tmem, G_TX_LOADTILE, 0,\
3616  cmt, maskt, shiftt, cms, masks, shifts); \
3617  gDPLoadSync(pkt); \
3618  gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
3619  (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1, \
3620  CALC_DXT(width, siz##_BYTES)); \
3621  gDPPipeSync(pkt); \
3622  gDPSetTile(pkt, fmt, siz, (((width) * siz##_LINE_BYTES)+7)>>3, \
3623  tmem, rtile, pal, cmt, \
3624  maskt, shiftt, cms, masks, shifts); \
3625  gDPSetTileSize(pkt, rtile, 0, 0, \
3626  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3627  ((height)-1) << G_TEXTURE_IMAGE_FRAC) \
3628 }
3629 
3630 /*
3631  * allows tmem address and render tile to be specified
3632  */
3633 #define gDPLoadMultiBlock(pkt, timg, tmem, rtile, fmt, siz, width, \
3634  height, pal, cms, cmt, masks, maskt, shifts, shiftt) \
3635 { \
3636  gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \
3637  gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, tmem, G_TX_LOADTILE, 0,\
3638  cmt, maskt, shiftt, cms, masks, shifts); \
3639  gDPLoadSync(pkt); \
3640  gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
3641  (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1, \
3642  CALC_DXT(width, siz##_BYTES)); \
3643  gDPPipeSync(pkt); \
3644  gDPSetTile(pkt, fmt, siz, (((width) * siz##_LINE_BYTES)+7)>>3, \
3645  tmem, rtile, pal, cmt, \
3646  maskt, shiftt, cms, masks, shifts); \
3647  gDPSetTileSize(pkt, rtile, 0, 0, \
3648  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3649  ((height)-1) << G_TEXTURE_IMAGE_FRAC) \
3650 }
3651 
3652 #define gsDPLoadTextureBlock(timg, fmt, siz, width, height, \
3653  pal, cms, cmt, masks, maskt, shifts, shiftt) \
3654  \
3655  gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \
3656  gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, 0, \
3657  G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, \
3658  masks, shifts), \
3659  gsDPLoadSync(), \
3660  gsDPLoadBlock(G_TX_LOADTILE, 0, 0, \
3661  (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1, \
3662  CALC_DXT(width, siz##_BYTES)), \
3663  gsDPPipeSync(), \
3664  gsDPSetTile(fmt, siz, ((((width) * siz##_LINE_BYTES)+7)>>3), 0, \
3665  G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \
3666  shifts), \
3667  gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, \
3668  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3669  ((height)-1) << G_TEXTURE_IMAGE_FRAC)
3670 
3671 /* Here is the static form of the pre-swapped texture block loading */
3672 /* See gDPLoadTextureBlockS() for reference. Basically, just don't
3673  calculate DxT, use 0 */
3674 
3675 #define gsDPLoadTextureBlockS(timg, fmt, siz, width, height, \
3676  pal, cms, cmt, masks, maskt, shifts, shiftt) \
3677  \
3678  gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \
3679  gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, 0, G_TX_LOADTILE, 0 , \
3680  cmt, maskt,shiftt, cms, masks, shifts), \
3681  gsDPLoadSync(), \
3682  gsDPLoadBlock(G_TX_LOADTILE, 0, 0, \
3683  (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1, 0 ),\
3684  gsDPPipeSync(), \
3685  gsDPSetTile(fmt, siz, ((((width) * siz##_LINE_BYTES)+7)>>3), 0, \
3686  G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \
3687  shifts), \
3688  gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, \
3689  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3690  ((height)-1) << G_TEXTURE_IMAGE_FRAC)
3691 
3692 /*
3693  * Allow tmem address to be specified
3694  */
3695 #define _gsDPLoadTextureBlock(timg, tmem, fmt, siz, width, height, \
3696  pal, cms, cmt, masks, maskt, shifts, shiftt) \
3697  \
3698  gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \
3699  gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, tmem, G_TX_LOADTILE, \
3700  0 , cmt, maskt, shiftt, cms, masks, shifts), \
3701  gsDPLoadSync(), \
3702  gsDPLoadBlock(G_TX_LOADTILE, 0, 0, \
3703  (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1, \
3704  CALC_DXT(width, siz##_BYTES)), \
3705  gsDPPipeSync(), \
3706  gsDPSetTile(fmt, siz, \
3707  ((((width) * siz##_LINE_BYTES)+7)>>3), tmem, \
3708  G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \
3709  shifts), \
3710  gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, \
3711  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3712  ((height)-1) << G_TEXTURE_IMAGE_FRAC)
3713 
3714 
3715 /*
3716  * Allow tmem address and render_tile to be specified
3717  */
3718 #define _gsDPLoadTextureBlockTile(timg, tmem, rtile, fmt, siz, width, \
3719  height, pal, cms, cmt, masks, maskt, shifts, shiftt) \
3720  \
3721  gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \
3722  gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, tmem, G_TX_LOADTILE, \
3723  0 , cmt, maskt, shiftt, cms, masks, shifts), \
3724  gsDPLoadSync(), \
3725  gsDPLoadBlock(G_TX_LOADTILE, 0, 0, \
3726  (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1, \
3727  CALC_DXT(width, siz##_BYTES)), \
3728  gsDPPipeSync(), \
3729  gsDPSetTile(fmt, siz, \
3730  ((((width) * siz##_LINE_BYTES)+7)>>3), tmem, \
3731  rtile, pal, cmt, maskt, shiftt, cms, masks, \
3732  shifts), \
3733  gsDPSetTileSize(rtile, 0, 0, \
3734  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3735  ((height)-1) << G_TEXTURE_IMAGE_FRAC)
3736 
3737 
3738 /*
3739  * Allow tmem address and render_tile to be specified, useful when loading
3740  * mutilple tiles at a time.
3741  */
3742 #define gsDPLoadMultiBlock(timg, tmem, rtile, fmt, siz, width, \
3743  height, pal, cms, cmt, masks, maskt, shifts, shiftt) \
3744  \
3745  gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \
3746  gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, tmem, G_TX_LOADTILE, \
3747  0 , cmt, maskt, shiftt, cms, masks, shifts), \
3748  gsDPLoadSync(), \
3749  gsDPLoadBlock(G_TX_LOADTILE, 0, 0, \
3750  (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1, \
3751  CALC_DXT(width, siz##_BYTES)), \
3752  gsDPPipeSync(), \
3753  gsDPSetTile(fmt, siz, \
3754  ((((width) * siz##_LINE_BYTES)+7)>>3), tmem, \
3755  rtile, pal, cmt, maskt, shiftt, cms, masks, \
3756  shifts), \
3757  gsDPSetTileSize(rtile, 0, 0, \
3758  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3759  ((height)-1) << G_TEXTURE_IMAGE_FRAC)
3760 
3761 /*
3762  * Allows tmem and render tile to be specified. Useful when loading
3763  * several tiles at a time.
3764  *
3765  * Here is the static form of the pre-swapped texture block loading
3766  * See gDPLoadTextureBlockS() for reference. Basically, just don't
3767  * calculate DxT, use 0
3768  */
3769 
3770 #define gsDPLoadMultiBlockS(timg, tmem, rtile, fmt, siz, width, height, \
3771  pal, cms, cmt, masks, maskt, shifts, shiftt) \
3772  \
3773  gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \
3774  gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, tmem, G_TX_LOADTILE, 0 , \
3775  cmt, maskt,shiftt, cms, masks, shifts), \
3776  gsDPLoadSync(), \
3777  gsDPLoadBlock(G_TX_LOADTILE, 0, 0, \
3778  (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1, 0 ),\
3779  gsDPPipeSync(), \
3780  gsDPSetTile(fmt, siz, ((((width) * siz##_LINE_BYTES)+7)>>3), tmem,\
3781  rtile, pal, cmt, maskt, shiftt, cms, masks, \
3782  shifts), \
3783  gsDPSetTileSize(rtile, 0, 0, \
3784  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3785  ((height)-1) << G_TEXTURE_IMAGE_FRAC)
3786 
3787 
3788 #define gDPLoadTextureBlock_4b(pkt, timg, fmt, width, height, \
3789  pal, cms, cmt, masks, maskt, shifts, shiftt) \
3790 { \
3791  gDPSetTextureImage(pkt, fmt, G_IM_SIZ_16b, 1, timg); \
3792  gDPSetTile(pkt, fmt, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, \
3793  cmt, maskt, shiftt, cms, masks, shifts); \
3794  gDPLoadSync(pkt); \
3795  gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
3796  (((width)*(height)+3)>>2)-1, \
3797  CALC_DXT_4b(width)); \
3798  gDPPipeSync(pkt); \
3799  gDPSetTile(pkt, fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), 0, \
3800  G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \
3801  shifts); \
3802  gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \
3803  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3804  ((height)-1) << G_TEXTURE_IMAGE_FRAC) \
3805 }
3806 
3807 /* Load fix rww 27jun95 */
3808 /* The S at the end means odd lines are already word Swapped */
3809 
3810 #define gDPLoadTextureBlock_4bS(pkt, timg, fmt, width, height, \
3811  pal, cms, cmt, masks, maskt, shifts, shiftt) \
3812 { \
3813  gDPSetTextureImage(pkt, fmt, G_IM_SIZ_16b, 1, timg); \
3814  gDPSetTile(pkt, fmt, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, \
3815  cmt, maskt, shiftt, cms, masks, shifts); \
3816  gDPLoadSync(pkt); \
3817  gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
3818  (((width)*(height)+3)>>2)-1, 0 ); \
3819  gDPPipeSync(pkt); \
3820  gDPSetTile(pkt, fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), 0, \
3821  G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \
3822  shifts); \
3823  gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \
3824  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3825  ((height)-1) << G_TEXTURE_IMAGE_FRAC) \
3826 }
3827 
3828 /*
3829  * 4-bit load block. Useful when loading multiple tiles
3830  */
3831 #define gDPLoadMultiBlock_4b(pkt, timg, tmem, rtile, fmt, width, height,\
3832  pal, cms, cmt, masks, maskt, shifts, shiftt) \
3833 { \
3834  gDPSetTextureImage(pkt, fmt, G_IM_SIZ_16b, 1, timg); \
3835  gDPSetTile(pkt, fmt, G_IM_SIZ_16b, 0, tmem, G_TX_LOADTILE, 0, \
3836  cmt, maskt, shiftt, cms, masks, shifts); \
3837  gDPLoadSync(pkt); \
3838  gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
3839  (((width)*(height)+3)>>2)-1, \
3840  CALC_DXT_4b(width)); \
3841  gDPPipeSync(pkt); \
3842  gDPSetTile(pkt, fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), tmem, \
3843  rtile, pal, cmt, maskt, shiftt, cms, masks, \
3844  shifts); \
3845  gDPSetTileSize(pkt, rtile, 0, 0, \
3846  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3847  ((height)-1) << G_TEXTURE_IMAGE_FRAC) \
3848 }
3849 
3850 /*
3851  * 4-bit load block. Allows tmem and render tile to be specified. Useful when
3852  * loading multiple tiles. The S means odd lines are already word swapped.
3853  */
3854 #define gDPLoadMultiBlock_4bS(pkt, timg, tmem, rtile, fmt, width, height,\
3855  pal, cms, cmt, masks, maskt, shifts, shiftt) \
3856 { \
3857  gDPSetTextureImage(pkt, fmt, G_IM_SIZ_16b, 1, timg); \
3858  gDPSetTile(pkt, fmt, G_IM_SIZ_16b, 0, tmem, G_TX_LOADTILE, 0, \
3859  cmt, maskt, shiftt, cms, masks, shifts); \
3860  gDPLoadSync(pkt); \
3861  gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
3862  (((width)*(height)+3)>>2)-1, 0 ); \
3863  gDPPipeSync(pkt); \
3864  gDPSetTile(pkt, fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), tmem, \
3865  rtile, pal, cmt, maskt, shiftt, cms, masks, \
3866  shifts); \
3867  gDPSetTileSize(pkt, rtile, 0, 0, \
3868  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3869  ((height)-1) << G_TEXTURE_IMAGE_FRAC) \
3870 }
3871 
3872 
3873 #define _gDPLoadTextureBlock_4b(pkt, timg, tmem, fmt, width, height, \
3874  pal, cms, cmt, masks, maskt, shifts, shiftt) \
3875 { \
3876  gDPSetTextureImage(pkt, fmt, G_IM_SIZ_16b, 1, timg); \
3877  gDPSetTile(pkt, fmt, G_IM_SIZ_16b, 0, tmem, G_TX_LOADTILE, 0, \
3878  cmt, maskt, shiftt, cms, masks, shifts); \
3879  gDPLoadSync(pkt); \
3880  gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
3881  (((width)*(height)+3)>>2)-1, \
3882  CALC_DXT_4b(width)); \
3883  gDPPipeSync(pkt); \
3884  gDPSetTile(pkt, fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), tmem, \
3885  G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \
3886  shifts); \
3887  gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \
3888  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3889  ((height)-1) << G_TEXTURE_IMAGE_FRAC) \
3890 }
3891 
3892 #define gsDPLoadTextureBlock_4b(timg, fmt, width, height, \
3893  pal, cms, cmt, masks, maskt, shifts, shiftt) \
3894  \
3895  gsDPSetTextureImage(fmt, G_IM_SIZ_16b, 1, timg), \
3896  gsDPSetTile(fmt, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0 , cmt, \
3897  maskt, shiftt, cms, masks, shifts), \
3898  gsDPLoadSync(), \
3899  gsDPLoadBlock(G_TX_LOADTILE, 0, 0, (((width)*(height)+3)>>2)-1, \
3900  CALC_DXT_4b(width)), \
3901  gsDPPipeSync(), \
3902  gsDPSetTile(fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), 0, \
3903  G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \
3904  shifts), \
3905  gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, \
3906  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3907  ((height)-1) << G_TEXTURE_IMAGE_FRAC)
3908 
3909 #define gsDPLoadTextureBlock_4bS(timg, fmt, width, height, \
3910  pal, cms, cmt, masks, maskt, shifts, shiftt) \
3911  \
3912  gsDPSetTextureImage(fmt, G_IM_SIZ_16b, 1, timg), \
3913  gsDPSetTile(fmt, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0 , cmt, \
3914  maskt, shiftt, cms, masks, shifts), \
3915  gsDPLoadSync(), \
3916  gsDPLoadBlock(G_TX_LOADTILE, 0, 0, (((width)*(height)+3)>>2)-1,0),\
3917  gsDPPipeSync(), \
3918  gsDPSetTile(fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), 0, \
3919  G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \
3920  shifts), \
3921  gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, \
3922  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3923  ((height)-1) << G_TEXTURE_IMAGE_FRAC)
3924 
3925 /*
3926  * 4-bit load block. Allows tmem address and render tile to be specified.
3927  * Useful when loading multiple tiles.
3928  */
3929 #define gsDPLoadMultiBlock_4b(timg, tmem, rtile, fmt, width, height, \
3930  pal, cms, cmt, masks, maskt, shifts, shiftt) \
3931  \
3932  gsDPSetTextureImage(fmt, G_IM_SIZ_16b, 1, timg), \
3933  gsDPSetTile(fmt, G_IM_SIZ_16b, 0, tmem, G_TX_LOADTILE, 0 , cmt, \
3934  maskt, shiftt, cms, masks, shifts), \
3935  gsDPLoadSync(), \
3936  gsDPLoadBlock(G_TX_LOADTILE, 0, 0, (((width)*(height)+3)>>2)-1, \
3937  CALC_DXT_4b(width)), \
3938  gsDPPipeSync(), \
3939  gsDPSetTile(fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), tmem, \
3940  rtile, pal, cmt, maskt, shiftt, cms, masks, \
3941  shifts), \
3942  gsDPSetTileSize(rtile, 0, 0, \
3943  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3944  ((height)-1) << G_TEXTURE_IMAGE_FRAC)
3945 
3946 
3947 /*
3948  * 4-bit load block. Allows tmem address and render tile to be specified.
3949  * Useful when loading multiple tiles. S means odd lines are already swapped.
3950  */
3951 #define gsDPLoadMultiBlock_4bS(timg, tmem, rtile, fmt, width, height, \
3952  pal, cms, cmt, masks, maskt, shifts, shiftt) \
3953  \
3954  gsDPSetTextureImage(fmt, G_IM_SIZ_16b, 1, timg), \
3955  gsDPSetTile(fmt, G_IM_SIZ_16b, 0, tmem, G_TX_LOADTILE, 0 , cmt, \
3956  maskt, shiftt, cms, masks, shifts), \
3957  gsDPLoadSync(), \
3958  gsDPLoadBlock(G_TX_LOADTILE, 0, 0, (((width)*(height)+3)>>2)-1,0),\
3959  gsDPPipeSync(), \
3960  gsDPSetTile(fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), tmem, \
3961  rtile, pal, cmt, maskt, shiftt, cms, masks, \
3962  shifts), \
3963  gsDPSetTileSize(rtile, 0, 0, \
3964  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3965  ((height)-1) << G_TEXTURE_IMAGE_FRAC)
3966 
3967 
3968 /*
3969  * Allows tmem address to be specified
3970  */
3971 #define _gsDPLoadTextureBlock_4b(timg, tmem, fmt, width, height, \
3972  pal, cms, cmt, masks, maskt, shifts, shiftt) \
3973  \
3974  gsDPSetTextureImage(fmt, G_IM_SIZ_16b, 1, timg), \
3975  gsDPSetTile(fmt, G_IM_SIZ_16b, 0, tmem, G_TX_LOADTILE, 0 , cmt, \
3976  maskt, shiftt, cms, masks, shifts), \
3977  gsDPLoadSync(), \
3978  gsDPLoadBlock(G_TX_LOADTILE, 0, 0, (((width)*(height)+3)>>2)-1, \
3979  CALC_DXT_4b(width)), \
3980  gsDPPipeSync(), \
3981  gsDPSetTile(fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), tmem, \
3982  G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \
3983  shifts), \
3984  gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, \
3985  ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
3986  ((height)-1) << G_TEXTURE_IMAGE_FRAC)
3987 
3988 #ifndef _HW_VERSION_1
3989 
3990 #define gDPLoadTextureTile(pkt, timg, fmt, siz, width, height, \
3991  uls, ult, lrs, lrt, pal, \
3992  cms, cmt, masks, maskt, shifts, shiftt) \
3993 { \
3994  gDPSetTextureImage(pkt, fmt, siz, width, timg); \
3995  gDPSetTile(pkt, fmt, siz, \
3996  (((((lrs)-(uls)+1) * siz##_TILE_BYTES)+7)>>3), 0, \
3997  G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, masks, \
3998  shifts); \
3999  gDPLoadSync(pkt); \
4000  gDPLoadTile( pkt, G_TX_LOADTILE, \
4001  (uls)<<G_TEXTURE_IMAGE_FRAC, \
4002  (ult)<<G_TEXTURE_IMAGE_FRAC, \
4003  (lrs)<<G_TEXTURE_IMAGE_FRAC, \
4004  (lrt)<<G_TEXTURE_IMAGE_FRAC); \
4005  gDPPipeSync(pkt); \
4006  gDPSetTile(pkt, fmt, siz, \
4007  (((((lrs)-(uls)+1) * siz##_LINE_BYTES)+7)>>3), 0, \
4008  G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \
4009  shifts); \
4010  gDPSetTileSize(pkt, G_TX_RENDERTILE, \
4011  (uls)<<G_TEXTURE_IMAGE_FRAC, \
4012  (ult)<<G_TEXTURE_IMAGE_FRAC, \
4013  (lrs)<<G_TEXTURE_IMAGE_FRAC, \
4014  (lrt)<<G_TEXTURE_IMAGE_FRAC) \
4015 }
4016 
4017 #else /******** WORKAROUND hw 1 load tile bug ********/
4018 
4019 #define gDPLoadTextureTile(pkt, timg, fmt, siz, width, height, \
4020  uls, ult, lrs, lrt, pal, \
4021  cms, cmt, masks, maskt, shifts, shiftt) \
4022  \
4023 { \
4024  int _loadtile_i, _loadtile_nw; Gfx *_loadtile_temp = pkt; \
4025  guDPLoadTextureTile(_loadtile_temp, timg, fmt, siz, \
4026  width, height, \
4027  uls, ult, lrs, lrt, pal, \
4028  cms, cmt, masks, maskt, shifts, shiftt); \
4029  _loadtile_nw = guGetDPLoadTextureTileSz(ult, lrt) - 1; \
4030  for(_loadtile_i = 0; _loadtile_i < _loadtile_nw; _loadtile_i++) \
4031  pkt; \
4032 }
4033 
4034 #endif /* HW_VERSION_1 */
4035 
4036 /*
4037  * Load texture tile. Allows tmem address and render tile to be specified.
4038  * Useful for loading multiple tiles.
4039  */
4040 #define gDPLoadMultiTile(pkt, timg, tmem, rtile, fmt, siz, width, height,\
4041  uls, ult, lrs, lrt, pal, \
4042  cms, cmt, masks, maskt, shifts, shiftt) \
4043 { \
4044  gDPSetTextureImage(pkt, fmt, siz, width, timg); \
4045  gDPSetTile(pkt, fmt, siz, \
4046  (((((lrs)-(uls)+1) * siz##_TILE_BYTES)+7)>>3), tmem, \
4047  G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, masks, \
4048  shifts); \
4049  gDPLoadSync(pkt); \
4050  gDPLoadTile( pkt, G_TX_LOADTILE, \
4051  (uls)<<G_TEXTURE_IMAGE_FRAC, \
4052  (ult)<<G_TEXTURE_IMAGE_FRAC, \
4053  (lrs)<<G_TEXTURE_IMAGE_FRAC, \
4054  (lrt)<<G_TEXTURE_IMAGE_FRAC); \
4055  gDPPipeSync(pkt); \
4056  gDPSetTile(pkt, fmt, siz, \
4057  (((((lrs)-(uls)+1) * siz##_LINE_BYTES)+7)>>3), tmem, \
4058  rtile, pal, cmt, maskt, shiftt, cms, masks, \
4059  shifts); \
4060  gDPSetTileSize(pkt, rtile, \
4061  (uls)<<G_TEXTURE_IMAGE_FRAC, \
4062  (ult)<<G_TEXTURE_IMAGE_FRAC, \
4063  (lrs)<<G_TEXTURE_IMAGE_FRAC, \
4064  (lrt)<<G_TEXTURE_IMAGE_FRAC) \
4065 }
4066 
4067 
4068 #define gsDPLoadTextureTile(timg, fmt, siz, width, height, \
4069  uls, ult, lrs, lrt, pal, \
4070  cms, cmt, masks, maskt, shifts, shiftt) \
4071  \
4072  gsDPSetTextureImage(fmt, siz, width, timg), \
4073  gsDPSetTile(fmt, siz, \
4074  (((((lrs)-(uls)+1) * siz##_TILE_BYTES)+7)>>3), 0, \
4075  G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, masks, \
4076  shifts), \
4077  gsDPLoadSync(), \
4078  gsDPLoadTile( G_TX_LOADTILE, \
4079  (uls)<<G_TEXTURE_IMAGE_FRAC, \
4080  (ult)<<G_TEXTURE_IMAGE_FRAC, \
4081  (lrs)<<G_TEXTURE_IMAGE_FRAC, \
4082  (lrt)<<G_TEXTURE_IMAGE_FRAC), \
4083  gsDPPipeSync(), \
4084  gsDPSetTile(fmt, siz, \
4085  (((((lrs)-(uls)+1) * siz##_LINE_BYTES)+7)>>3), 0, \
4086  G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks,\
4087  shifts), \
4088  gsDPSetTileSize(G_TX_RENDERTILE, \
4089  (uls)<<G_TEXTURE_IMAGE_FRAC, \
4090  (ult)<<G_TEXTURE_IMAGE_FRAC, \
4091  (lrs)<<G_TEXTURE_IMAGE_FRAC, \
4092  (lrt)<<G_TEXTURE_IMAGE_FRAC)
4093 
4094 /*
4095  * Load texture tile. Allows tmem address and render tile to be specified.
4096  * Useful for loading multiple tiles.
4097  */
4098 #define gsDPLoadMultiTile(timg, tmem, rtile, fmt, siz, width, height, \
4099  uls, ult, lrs, lrt, pal, \
4100  cms, cmt, masks, maskt, shifts, shiftt) \
4101  \
4102  gsDPSetTextureImage(fmt, siz, width, timg), \
4103  gsDPSetTile(fmt, siz, \
4104  (((((lrs)-(uls)+1) * siz##_TILE_BYTES)+7)>>3), \
4105  tmem, G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, \
4106  masks, shifts), \
4107  gsDPLoadSync(), \
4108  gsDPLoadTile( G_TX_LOADTILE, \
4109  (uls)<<G_TEXTURE_IMAGE_FRAC, \
4110  (ult)<<G_TEXTURE_IMAGE_FRAC, \
4111  (lrs)<<G_TEXTURE_IMAGE_FRAC, \
4112  (lrt)<<G_TEXTURE_IMAGE_FRAC), \
4113  gsDPPipeSync(), \
4114  gsDPSetTile(fmt, siz, \
4115  (((((lrs)-(uls)+1) * siz##_LINE_BYTES)+7)>>3), \
4116  tmem, rtile, pal, cmt, maskt, shiftt, cms, masks, \
4117  shifts), \
4118  gsDPSetTileSize(rtile, \
4119  (uls)<<G_TEXTURE_IMAGE_FRAC, \
4120  (ult)<<G_TEXTURE_IMAGE_FRAC, \
4121  (lrs)<<G_TEXTURE_IMAGE_FRAC, \
4122  (lrt)<<G_TEXTURE_IMAGE_FRAC)
4123 
4124 #define gDPLoadTextureTile_4b(pkt, timg, fmt, width, height, \
4125  uls, ult, lrs, lrt, pal, \
4126  cms, cmt, masks, maskt, shifts, shiftt) \
4127 { \
4128  gDPSetTextureImage(pkt, fmt, G_IM_SIZ_8b, ((width)>>1), timg); \
4129  gDPSetTile(pkt, fmt, G_IM_SIZ_8b, \
4130  (((((lrs)-(uls)+1)>>1)+7)>>3), 0, \
4131  G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, masks, \
4132  shifts); \
4133  gDPLoadSync(pkt); \
4134  gDPLoadTile( pkt, G_TX_LOADTILE, \
4135  (uls)<<(G_TEXTURE_IMAGE_FRAC-1), \
4136  (ult)<<(G_TEXTURE_IMAGE_FRAC), \
4137  (lrs)<<(G_TEXTURE_IMAGE_FRAC-1), \
4138  (lrt)<<(G_TEXTURE_IMAGE_FRAC)); \
4139  gDPPipeSync(pkt); \
4140  gDPSetTile(pkt, fmt, G_IM_SIZ_4b, \
4141  (((((lrs)-(uls)+1)>>1)+7)>>3), 0, \
4142  G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, \
4143  masks, shifts); \
4144  gDPSetTileSize(pkt, G_TX_RENDERTILE, \
4145  (uls)<<G_TEXTURE_IMAGE_FRAC, \
4146  (ult)<<G_TEXTURE_IMAGE_FRAC, \
4147  (lrs)<<G_TEXTURE_IMAGE_FRAC, \
4148  (lrt)<<G_TEXTURE_IMAGE_FRAC) \
4149 }
4150 
4151 /*
4152  * Load texture tile. Allows tmem address and render tile to be specified.
4153  * Useful for loading multiple tiles.
4154  */
4155 #define gDPLoadMultiTile_4b(pkt, timg, tmem, rtile, fmt, width, height, \
4156  uls, ult, lrs, lrt, pal, \
4157  cms, cmt, masks, maskt, shifts, shiftt) \
4158 { \
4159  gDPSetTextureImage(pkt, fmt, G_IM_SIZ_8b, ((width)>>1), timg); \
4160  gDPSetTile(pkt, fmt, G_IM_SIZ_8b, \
4161  (((((lrs)-(uls)+1)>>1)+7)>>3), tmem, \
4162  G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, masks, \
4163  shifts); \
4164  gDPLoadSync(pkt); \
4165  gDPLoadTile( pkt, G_TX_LOADTILE, \
4166  (uls)<<(G_TEXTURE_IMAGE_FRAC-1), \
4167  (ult)<<(G_TEXTURE_IMAGE_FRAC), \
4168  (lrs)<<(G_TEXTURE_IMAGE_FRAC-1), \
4169  (lrt)<<(G_TEXTURE_IMAGE_FRAC)); \
4170  gDPPipeSync(pkt); \
4171  gDPSetTile(pkt, fmt, G_IM_SIZ_4b, \
4172  (((((lrs)-(uls)+1)>>1)+7)>>3), tmem, \
4173  rtile, pal, cmt, maskt, shiftt, cms, masks, \
4174  shifts); \
4175  gDPSetTileSize(pkt, rtile, \
4176  (uls)<<G_TEXTURE_IMAGE_FRAC, \
4177  (ult)<<G_TEXTURE_IMAGE_FRAC, \
4178  (lrs)<<G_TEXTURE_IMAGE_FRAC, \
4179  (lrt)<<G_TEXTURE_IMAGE_FRAC) \
4180 }
4181 
4182 #define gsDPLoadTextureTile_4b(timg, fmt, width, height, \
4183  uls, ult, lrs, lrt, pal, \
4184  cms, cmt, masks, maskt, shifts, shiftt) \
4185  \
4186  gsDPSetTextureImage(fmt, G_IM_SIZ_8b, ((width)>>1), timg), \
4187  gsDPSetTile(fmt, G_IM_SIZ_8b, (((((lrs)-(uls)+1)>>1)+7)>>3), 0, \
4188  G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, masks, \
4189  shifts), \
4190  gsDPLoadSync(), \
4191  gsDPLoadTile( G_TX_LOADTILE, \
4192  (uls)<<(G_TEXTURE_IMAGE_FRAC-1), \
4193  (ult)<<(G_TEXTURE_IMAGE_FRAC), \
4194  (lrs)<<(G_TEXTURE_IMAGE_FRAC-1), \
4195  (lrt)<<(G_TEXTURE_IMAGE_FRAC)), \
4196  gsDPPipeSync(), \
4197  gsDPSetTile(fmt, G_IM_SIZ_4b, (((((lrs)-(uls)+1)>>1)+7)>>3), 0, \
4198  G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \
4199  shifts), \
4200  gsDPSetTileSize(G_TX_RENDERTILE, \
4201  (uls)<<G_TEXTURE_IMAGE_FRAC, \
4202  (ult)<<G_TEXTURE_IMAGE_FRAC, \
4203  (lrs)<<G_TEXTURE_IMAGE_FRAC, \
4204  (lrt)<<G_TEXTURE_IMAGE_FRAC)
4205 
4206 /*
4207  * Load texture tile. Allows tmem address and render tile to be specified.
4208  * Useful for loading multiple tiles.
4209  */
4210 #define gsDPLoadMultiTile_4b(timg, tmem, rtile, fmt, width, height, \
4211  uls, ult, lrs, lrt, pal, \
4212  cms, cmt, masks, maskt, shifts, shiftt) \
4213  \
4214  gsDPSetTextureImage(fmt, G_IM_SIZ_8b, ((width)>>1), timg), \
4215  gsDPSetTile(fmt, G_IM_SIZ_8b, (((((lrs)-(uls)+1)>>1)+7)>>3), \
4216  tmem, G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, \
4217  masks, shifts), \
4218  gsDPLoadSync(), \
4219  gsDPLoadTile( G_TX_LOADTILE, \
4220  (uls)<<(G_TEXTURE_IMAGE_FRAC-1), \
4221  (ult)<<(G_TEXTURE_IMAGE_FRAC), \
4222  (lrs)<<(G_TEXTURE_IMAGE_FRAC-1), \
4223  (lrt)<<(G_TEXTURE_IMAGE_FRAC)), \
4224  gsDPPipeSync(), \
4225  gsDPSetTile(fmt, G_IM_SIZ_4b, (((((lrs)-(uls)+1)>>1)+7)>>3), \
4226  tmem, rtile, pal, cmt, maskt, shiftt, cms, masks, \
4227  shifts), \
4228  gsDPSetTileSize(rtile, \
4229  (uls)<<G_TEXTURE_IMAGE_FRAC, \
4230  (ult)<<G_TEXTURE_IMAGE_FRAC, \
4231  (lrs)<<G_TEXTURE_IMAGE_FRAC, \
4232  (lrt)<<G_TEXTURE_IMAGE_FRAC)
4233 
4234 /*
4235  * Load a 16-entry palette (for 4-bit CI textures)
4236  * Assumes a 16 entry tlut is being loaded, palette # is 0-15
4237  */
4238 #ifndef _HW_VERSION_1
4239 
4240 #define gDPLoadTLUT_pal16(pkt, pal, dram) \
4241 { \
4242  gDPSetTextureImage(pkt, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dram); \
4243  gDPTileSync(pkt); \
4244  gDPSetTile(pkt, 0, 0, 0, (256+(((pal)&0xf)*16)), \
4245  G_TX_LOADTILE, 0 , 0, 0, 0, 0, 0, 0); \
4246  gDPLoadSync(pkt); \
4247  gDPLoadTLUTCmd(pkt, G_TX_LOADTILE, 15); \
4248  gDPPipeSync(pkt) \
4249 }
4250 
4251 #else /* **** WORKAROUND hardware 1 load_tlut bug ****** */
4252 
4253 #define gDPLoadTLUT_pal16(pkt, pal, dram) \
4254  \
4255  _gDPLoadTextureBlock(pkt, dram, (256+(((pal)&0xf)*16)), \
4256  G_IM_FMT_RGBA, G_IM_SIZ_16b, 4*16, 1, \
4257  pal, 0, 0, 0, 0, 0, 0)
4258 
4259 #endif /* _HW_VERSION_1 */
4260 
4261 
4262 /*
4263  * Load a 16-entry palette (for 4-bit CI textures)
4264  * Assumes a 16 entry tlut is being loaded, palette # is 0-15
4265  */
4266 #ifndef _HW_VERSION_1
4267 
4268 #define gsDPLoadTLUT_pal16(pal, dram) \
4269  \
4270  gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dram), \
4271  gsDPTileSync(), \
4272  gsDPSetTile(0, 0, 0, (256+(((pal)&0xf)*16)), \
4273  G_TX_LOADTILE, 0 , 0, 0, 0, 0, 0, 0), \
4274  gsDPLoadSync(), \
4275  gsDPLoadTLUTCmd(G_TX_LOADTILE, 15), \
4276  gsDPPipeSync()
4277 
4278 #else /* **** WORKAROUND hardware 1 load_tlut bug ****** */
4279 
4280 #define gsDPLoadTLUT_pal16(pal, dram) \
4281  \
4282  _gsDPLoadTextureBlock(dram, (256+(((pal)&0xf)*16)), \
4283  G_IM_FMT_RGBA, G_IM_SIZ_16b, 4*16, 1, \
4284  pal, 0, 0, 0, 0, 0, 0)
4285 
4286 #endif /* _HW_VERSION_1 */
4287 
4288 /*
4289  * Load a 256-entry palette (for 8-bit CI textures)
4290  * Assumes a 256 entry tlut is being loaded, palette # is not used
4291  */
4292 #ifndef _HW_VERSION_1
4293 
4294 #define gDPLoadTLUT_pal256(pkt, dram) \
4295 { \
4296  gDPSetTextureImage(pkt, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dram); \
4297  gDPTileSync(pkt); \
4298  gDPSetTile(pkt, 0, 0, 0, 256, \
4299  G_TX_LOADTILE, 0 , 0, 0, 0, 0, 0, 0); \
4300  gDPLoadSync(pkt); \
4301  gDPLoadTLUTCmd(pkt, G_TX_LOADTILE, 255); \
4302  gDPPipeSync(pkt) \
4303 }
4304 
4305 #else /* **** WORKAROUND hardware 1 load_tlut bug ****** */
4306 
4307 #define gDPLoadTLUT_pal256(pkt, dram) \
4308  \
4309  _gDPLoadTextureBlock(pkt, dram, 256, \
4310  G_IM_FMT_RGBA, G_IM_SIZ_16b, 4*256, 1, \
4311  0, 0, 0, 0, 0, 0, 0)
4312 
4313 
4314 #endif /* _HW_VERSION_1 */
4315 
4316 
4317 #ifndef _HW_VERSION_1
4318 
4319 #define gsDPLoadTLUT_pal256(dram) \
4320  \
4321  gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dram), \
4322  gsDPTileSync(), \
4323  gsDPSetTile(0, 0, 0, 256, \
4324  G_TX_LOADTILE, 0 , 0, 0, 0, 0, 0, 0), \
4325  gsDPLoadSync(), \
4326  gsDPLoadTLUTCmd(G_TX_LOADTILE, 255), \
4327  gsDPPipeSync()
4328 
4329 #else /* **** WORKAROUND hardware 1 load_tlut bug ****** */
4330 
4331 #define gsDPLoadTLUT_pal256(dram) \
4332  \
4333  _gsDPLoadTextureBlock(dram, 256, \
4334  G_IM_FMT_RGBA, G_IM_SIZ_16b, 4*256, 1, \
4335  0, 0, 0, 0, 0, 0, 0)
4336 
4337 #endif /* _HW_VERSION_1 */
4338 
4339 
4340 #ifndef _HW_VERSION_1
4341 
4342 #define gDPLoadTLUT(pkt, count, tmemaddr, dram) \
4343 { \
4344  gDPSetTextureImage(pkt, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dram); \
4345  gDPTileSync(pkt); \
4346  gDPSetTile(pkt, 0, 0, 0, tmemaddr, \
4347  G_TX_LOADTILE, 0 , 0, 0, 0, 0, 0, 0); \
4348  gDPLoadSync(pkt); \
4349  gDPLoadTLUTCmd(pkt, G_TX_LOADTILE, ((count)-1)); \
4350  gDPPipeSync(pkt); \
4351 }
4352 
4353 #else /* **** WORKAROUND hardware 1 load_tlut bug ****** */
4354 
4355 #define gDPLoadTLUT(pkt, count, tmemaddr, dram) \
4356  \
4357  _gDPLoadTextureBlock(pkt, dram, tmemaddr, \
4358  G_IM_FMT_RGBA, G_IM_SIZ_16b, 4, count, \
4359  0, 0, 0, 0, 0, 0, 0)
4360 
4361 #endif /* _HW_VERSION_1 */
4362 
4363 
4364 #ifndef _HW_VERSION_1
4365 
4366 #define gsDPLoadTLUT(count, tmemaddr, dram) \
4367  \
4368  gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dram), \
4369  gsDPTileSync(), \
4370  gsDPSetTile(0, 0, 0, tmemaddr, \
4371  G_TX_LOADTILE, 0 , 0, 0, 0, 0, 0, 0), \
4372  gsDPLoadSync(), \
4373  gsDPLoadTLUTCmd(G_TX_LOADTILE, ((count)-1)), \
4374  gsDPPipeSync()
4375 
4376 #else /* **** WORKAROUND hardware 1 load_tlut bug ****** */
4377 #define gsDPLoadTLUT(count, tmemaddr, dram) \
4378  \
4379  _gsDPLoadTextureBlock(dram, tmemaddr, \
4380  G_IM_FMT_RGBA, G_IM_SIZ_16b, 4, count, \
4381  0, 0, 0, 0, 0, 0, 0)
4382 
4383 #endif /* _HW_VERSION_1 */
4384 
4385 #define gDPSetScissor(pkt, mode, ulx, uly, lrx, lry) \
4386 { \
4387  Gfx *_g = (Gfx *)pkt; \
4388  \
4389  _g->words.w0 = _SHIFTL(G_SETSCISSOR, 24, 8) | \
4390  _SHIFTL((int)((float)(ulx)*4.0F), 12, 12) | \
4391  _SHIFTL((int)((float)(uly)*4.0F), 0, 12); \
4392  _g->words.w1 = _SHIFTL(mode, 24, 2) | \
4393  _SHIFTL((int)((float)(lrx)*4.0F), 12, 12) | \
4394  _SHIFTL((int)((float)(lry)*4.0F), 0, 12); \
4395 }
4396 
4397 
4398 #define gDPSetScissorFrac(pkt, mode, ulx, uly, lrx, lry) \
4399 { \
4400  Gfx *_g = (Gfx *)pkt; \
4401  \
4402  _g->words.w0 = _SHIFTL(G_SETSCISSOR, 24, 8) | \
4403  _SHIFTL((int)((ulx)), 12, 12) | \
4404  _SHIFTL((int)((uly)), 0, 12); \
4405  _g->words.w1 = _SHIFTL(mode, 24, 2) | \
4406  _SHIFTL((int)((lrx)), 12, 12) | \
4407  _SHIFTL((int)((lry)), 0, 12); \
4408 }
4409 
4410 #define gsDPSetScissor(mode, ulx, uly, lrx, lry) \
4411 {{ \
4412  _SHIFTL(G_SETSCISSOR, 24, 8) | \
4413  _SHIFTL((int)((float)(ulx)*4.0F), 12, 12) | \
4414  _SHIFTL((int)((float)(uly)*4.0F), 0, 12), \
4415  _SHIFTL(mode, 24, 2) | \
4416  _SHIFTL((int)((float)(lrx)*4.0F), 12, 12) | \
4417  _SHIFTL((int)((float)(lry)*4.0F), 0, 12) \
4418 }}
4419 
4420 #define gsDPSetScissorFrac(mode, ulx, uly, lrx, lry) \
4421 {{ \
4422  _SHIFTL(G_SETSCISSOR, 24, 8) | \
4423  _SHIFTL((int)((ulx)), 12, 12) | \
4424  _SHIFTL((int)((uly)), 0, 12), \
4425  _SHIFTL(mode, 24, 2) | \
4426  _SHIFTL((int)(lrx), 12, 12) | \
4427  _SHIFTL((int)(lry), 0, 12) \
4428 }}
4429 
4430 /* Fraction never used in fill */
4431 #define gDPFillRectangle(pkt, ulx, uly, lrx, lry) \
4432 { \
4433  Gfx *_g = (Gfx *)(pkt); \
4434  \
4435  _g->words.w0 = (_SHIFTL(G_FILLRECT, 24, 8) | \
4436  _SHIFTL((lrx), 14, 10) | _SHIFTL((lry), 2, 10));\
4437  _g->words.w1 = (_SHIFTL((ulx), 14, 10) | _SHIFTL((uly), 2, 10));\
4438 }
4439 
4440 #define gsDPFillRectangle(ulx, uly, lrx, lry) \
4441 {{ \
4442  (_SHIFTL(G_FILLRECT, 24, 8) | _SHIFTL((lrx), 14, 10) | \
4443  _SHIFTL((lry), 2, 10)), \
4444  (_SHIFTL((ulx), 14, 10) | _SHIFTL((uly), 2, 10)) \
4445 }}
4446 
4447 /* like gDPFillRectangle but accepts negative arguments */
4448 #define gDPScisFillRectangle(pkt, ulx, uly, lrx, lry) \
4449 { \
4450  Gfx *_g = (Gfx *)(pkt); \
4451  \
4452  _g->words.w0 = (_SHIFTL(G_FILLRECT, 24, 8) | \
4453  _SHIFTL(MAX((lrx),0), 14, 10) | \
4454  _SHIFTL(MAX((lry),0), 2, 10)); \
4455  _g->words.w1 = (_SHIFTL(MAX((ulx),0), 14, 10) | \
4456  _SHIFTL(MAX((uly),0), 2, 10)); \
4457 }
4458 
4459 #define gDPSetConvert(pkt, k0, k1, k2, k3, k4, k5) \
4460 { \
4461  Gfx *_g = (Gfx *)(pkt); \
4462  \
4463  _g->words.w0 = (_SHIFTL(G_SETCONVERT, 24, 8) | \
4464  _SHIFTL(k0, 13, 9) | _SHIFTL(k1, 4, 9) | \
4465  _SHIFTR(k2, 5, 4)); \
4466  _g->words.w1 = (_SHIFTL(k2, 27, 5) | _SHIFTL(k3, 18, 9) | \
4467  _SHIFTL(k4, 9, 9) | _SHIFTL(k5, 0, 9)); \
4468 }
4469 
4470 #define gsDPSetConvert(k0, k1, k2, k3, k4, k5) \
4471 {{ \
4472  (_SHIFTL(G_SETCONVERT, 24, 8) | \
4473  _SHIFTL(k0, 13, 9) | _SHIFTL(k1, 4, 9) | _SHIFTR(k2, 5, 4)), \
4474  (_SHIFTL(k2, 27, 5) | _SHIFTL(k3, 18, 9) | _SHIFTL(k4, 9, 9) | \
4475  _SHIFTL(k5, 0, 9)) \
4476 }}
4477 
4478 #define gDPSetKeyR(pkt, cR, sR, wR) \
4479 { \
4480  Gfx *_g = (Gfx *)(pkt); \
4481  \
4482  _g->words.w0 = _SHIFTL(G_SETKEYR, 24, 8); \
4483  _g->words.w1 = (_SHIFTL(wR, 16, 12) | _SHIFTL(cR, 8, 8) | \
4484  _SHIFTL(sR, 0, 8)); \
4485 }
4486 
4487 #define gsDPSetKeyR(cR, sR, wR) \
4488 {{ \
4489  _SHIFTL(G_SETKEYR, 24, 8), \
4490  _SHIFTL(wR, 16, 12) | _SHIFTL(cR, 8, 8) | _SHIFTL(sR, 0, 8) \
4491 }}
4492 
4493 #define gDPSetKeyGB(pkt, cG, sG, wG, cB, sB, wB) \
4494 { \
4495  Gfx *_g = (Gfx *)(pkt); \
4496  \
4497  _g->words.w0 = (_SHIFTL(G_SETKEYGB, 24, 8) | \
4498  _SHIFTL(wG, 12, 12) | _SHIFTL(wB, 0, 12)); \
4499  _g->words.w1 = (_SHIFTL(cG, 24, 8) | _SHIFTL(sG, 16, 8) | \
4500  _SHIFTL(cB, 8, 8) | _SHIFTL(sB, 0, 8)); \
4501 }
4502 
4503 #define gsDPSetKeyGB(cG, sG, wG, cB, sB, wB) \
4504 {{ \
4505  (_SHIFTL(G_SETKEYGB, 24, 8) | _SHIFTL(wG, 12, 12) | \
4506  _SHIFTL(wB, 0, 12)), \
4507  (_SHIFTL(cG, 24, 8) | _SHIFTL(sG, 16, 8) | _SHIFTL(cB, 8, 8) | \
4508  _SHIFTL(sB, 0, 8)) \
4509 }}
4510 
4511 #define gDPNoParam(pkt, cmd) \
4512 { \
4513  Gfx *_g = (Gfx *)(pkt); \
4514  \
4515  _g->words.w0 = _SHIFTL(cmd, 24, 8); \
4516  _g->words.w1 = 0; \
4517 }
4518 
4519 #define gsDPNoParam(cmd) \
4520 {{ \
4521  _SHIFTL(cmd, 24, 8), 0 \
4522 }}
4523 
4524 #define gDPParam(pkt, cmd, param) \
4525 { \
4526  Gfx *_g = (Gfx *)(pkt); \
4527  \
4528  _g->words.w0 = _SHIFTL(cmd, 24, 8); \
4529  _g->words.w1 = (param); \
4530 }
4531 
4532 #define gsDPParam(cmd, param) \
4533 {{ \
4534  _SHIFTL(cmd, 24, 8), (param) \
4535 }}
4536 
4537 /* Notice that textured rectangles are 128-bit commands, therefore
4538  * gsDPTextureRectangle() should not be used in display lists
4539  * under normal circumstances (use gsSPTextureRectangle()).
4540  * That is also why there is no gDPTextureRectangle() macros.
4541  */
4542 #define gsDPTextureRectangle(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
4543 {{ \
4544  (_SHIFTL(G_TEXRECT, 24, 8) | _SHIFTL(xh, 12, 12) | \
4545  _SHIFTL(yh, 0, 12)), \
4546  (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | _SHIFTL(yl, 0, 12)), \
4547 }}, \
4548 {{ \
4549  _SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16), \
4550  _SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16) \
4551 }}
4552 
4553 #define gDPTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy)\
4554 { \
4555  Gfx *_g = (Gfx *)(pkt); \
4556  if (pkt); \
4557  _g->words.w0 = (_SHIFTL(G_TEXRECT, 24, 8) | _SHIFTL(xh, 12, 12) | \
4558  _SHIFTL(yh, 0, 12)); \
4559  _g->words.w1 = (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | \
4560  _SHIFTL(yl, 0, 12)); \
4561  _g ++; \
4562  _g->words.w0 = (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16)); \
4563  _g->words.w1 = (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)); \
4564 }
4565 
4566 #define gsDPTextureRectangleFlip(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
4567 {{ \
4568  (_SHIFTL(G_TEXRECTFLIP, 24, 8) | _SHIFTL(xh, 12, 12) | \
4569  _SHIFTL(yh, 0, 12)), \
4570  (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | _SHIFTL(yl, 0, 12)), \
4571 }}, \
4572 {{ \
4573  _SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16), \
4574  _SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16) \
4575 }}
4576 
4577 #define gDPTextureRectangleFlip(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy)\
4578 { \
4579  Gfx *_g = (Gfx *)(pkt); \
4580  if (pkt); \
4581  _g->words.w0 = (_SHIFTL(G_TEXRECTFLIP, 24, 8) | _SHIFTL(xh, 12, 12) | \
4582  _SHIFTL(yh, 0, 12)); \
4583  _g->words.w1 = (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | \
4584  _SHIFTL(yl, 0, 12)); \
4585  _g ++; \
4586  _g->words.w0 = (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16)); \
4587  _g->words.w1 = (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)); \
4588 }
4589 
4590 #ifdef F3D_OLD
4591 # define gSPTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy)\
4592 { \
4593  Gfx *_g = (Gfx *)(pkt); \
4594  \
4595  _g->words.w0 = (_SHIFTL(G_TEXRECT, 24, 8) | _SHIFTL(xh, 12, 12) | \
4596  _SHIFTL(yh, 0, 12)); \
4597  _g->words.w1 = (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | \
4598  _SHIFTL(yl, 0, 12)); \
4599  gImmp1(pkt, G_RDPHALF_2, (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16))); \
4600  gImmp1(pkt, G_RDPHALF_CONT, (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)));\
4601 }
4602 
4603 #define gsSPTextureRectangle(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
4604  {{(_SHIFTL(G_TEXRECT, 24, 8) | _SHIFTL(xh, 12, 12) | _SHIFTL(yh, 0, 12)),\
4605  (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | _SHIFTL(yl, 0, 12))}}, \
4606  gsImmp1(G_RDPHALF_2, (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16))), \
4607  gsImmp1(G_RDPHALF_CONT, (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)))
4608 
4609 /* like gSPTextureRectangle but accepts negative position arguments */
4610 # define gSPScisTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
4611 { \
4612  Gfx *_g = (Gfx *)(pkt); \
4613  \
4614  _g->words.w0 = (_SHIFTL(G_TEXRECT, 24, 8) | \
4615  _SHIFTL(MAX((s16)(xh),0), 12, 12) | \
4616  _SHIFTL(MAX((s16)(yh),0), 0, 12)); \
4617  _g->words.w1 = (_SHIFTL((tile), 24, 3) | \
4618  _SHIFTL(MAX((s16)(xl),0), 12, 12) | \
4619  _SHIFTL(MAX((s16)(yl),0), 0, 12)); \
4620  gImmp1(pkt, G_RDPHALF_2, \
4621  (_SHIFTL(((s) - \
4622  (((s16)(xl) < 0) ? \
4623  (((s16)(dsdx) < 0) ? \
4624  (MAX((((s16)(xl)*(s16)(dsdx))>>7),0)) : \
4625  (MIN((((s16)(xl)*(s16)(dsdx))>>7),0))) : 0)), \
4626  16, 16) | \
4627  _SHIFTL(((t) - \
4628  (((yl) < 0) ? \
4629  (((s16)(dtdy) < 0) ? \
4630  (MAX((((s16)(yl)*(s16)(dtdy))>>7),0)) : \
4631  (MIN((((s16)(yl)*(s16)(dtdy))>>7),0))) : 0)), \
4632  0, 16))); \
4633  gImmp1(pkt, G_RDPHALF_CONT, (_SHIFTL((dsdx), 16, 16) | \
4634  _SHIFTL((dtdy), 0, 16))); \
4635 }
4636 
4637 # define gsSPTextureRectangleFlip(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
4638  {{(_SHIFTL(G_TEXRECTFLIP, 24, 8) | _SHIFTL(xh, 12, 12) | \
4639  _SHIFTL(yh, 0, 12)), \
4640  (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | _SHIFTL(yl, 0, 12))}}, \
4641  gsImmp1(G_RDPHALF_2, (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16))), \
4642  gsImmp1(G_RDPHALF_CONT, (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)))
4643 
4644 # define gSPTextureRectangleFlip(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
4645 { \
4646  Gfx *_g = (Gfx *)(pkt); \
4647  \
4648  _g->words.w0 = (_SHIFTL(G_TEXRECTFLIP, 24, 8) | _SHIFTL(xh, 12, 12) |\
4649  _SHIFTL(yh, 0, 12)); \
4650  _g->words.w1 = (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | \
4651  _SHIFTL(yl, 0, 12)); \
4652  gImmp1(pkt, G_RDPHALF_2, (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16))); \
4653  gImmp1(pkt, G_RDPHALF_CONT, (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16))); \
4654 }
4655 #else
4656 # define gSPTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy)\
4657 { \
4658  Gfx *_g = (Gfx *)(pkt); \
4659  \
4660  _g->words.w0 = (_SHIFTL(G_TEXRECT, 24, 8) | _SHIFTL(xh, 12, 12) | \
4661  _SHIFTL(yh, 0, 12)); \
4662  _g->words.w1 = (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | \
4663  _SHIFTL(yl, 0, 12)); \
4664  gImmp1(pkt, G_RDPHALF_1, (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16))); \
4665  gImmp1(pkt, G_RDPHALF_2, (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)));\
4666 }
4667 
4668 #define gsSPTextureRectangle(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
4669  {{(_SHIFTL(G_TEXRECT, 24, 8) | _SHIFTL(xh, 12, 12) | _SHIFTL(yh, 0, 12)),\
4670  (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | _SHIFTL(yl, 0, 12))}}, \
4671  gsImmp1(G_RDPHALF_1, (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16))), \
4672  gsImmp1(G_RDPHALF_2, (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)))
4673 
4674 /* like gSPTextureRectangle but accepts negative position arguments */
4675 # define gSPScisTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
4676 { \
4677  Gfx *_g = (Gfx *)(pkt); \
4678  \
4679  _g->words.w0 = (_SHIFTL(G_TEXRECT, 24, 8) | \
4680  _SHIFTL(MAX((s16)(xh),0), 12, 12) | \
4681  _SHIFTL(MAX((s16)(yh),0), 0, 12)); \
4682  _g->words.w1 = (_SHIFTL((tile), 24, 3) | \
4683  _SHIFTL(MAX((s16)(xl),0), 12, 12) | \
4684  _SHIFTL(MAX((s16)(yl),0), 0, 12)); \
4685  gImmp1(pkt, G_RDPHALF_1, \
4686  (_SHIFTL(((s) - \
4687  (((s16)(xl) < 0) ? \
4688  (((s16)(dsdx) < 0) ? \
4689  (MAX((((s16)(xl)*(s16)(dsdx))>>7),0)) : \
4690  (MIN((((s16)(xl)*(s16)(dsdx))>>7),0))) : 0)), \
4691  16, 16) | \
4692  _SHIFTL(((t) - \
4693  (((yl) < 0) ? \
4694  (((s16)(dtdy) < 0) ? \
4695  (MAX((((s16)(yl)*(s16)(dtdy))>>7),0)) : \
4696  (MIN((((s16)(yl)*(s16)(dtdy))>>7),0))) : 0)), \
4697  0, 16))); \
4698  gImmp1(pkt, G_RDPHALF_2, (_SHIFTL((dsdx), 16, 16) | \
4699  _SHIFTL((dtdy), 0, 16))); \
4700 }
4701 
4702 # define gsSPTextureRectangleFlip(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
4703  {{(_SHIFTL(G_TEXRECTFLIP, 24, 8) | _SHIFTL(xh, 12, 12) | \
4704  _SHIFTL(yh, 0, 12)), \
4705  (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | _SHIFTL(yl, 0, 12))}}, \
4706  gsImmp1(G_RDPHALF_1, (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16))), \
4707  gsImmp1(G_RDPHALF_2, (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)))
4708 
4709 # define gSPTextureRectangleFlip(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
4710 { \
4711  Gfx *_g = (Gfx *)(pkt); \
4712  \
4713  _g->words.w0 = (_SHIFTL(G_TEXRECTFLIP, 24, 8) | _SHIFTL(xh, 12, 12) |\
4714  _SHIFTL(yh, 0, 12)); \
4715  _g->words.w1 = (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | \
4716  _SHIFTL(yl, 0, 12)); \
4717  gImmp1(pkt, G_RDPHALF_1, (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16))); \
4718  gImmp1(pkt, G_RDPHALF_2, (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16))); \
4719 }
4720 #endif
4721 
4722 #define gsDPWord(wordhi, wordlo) \
4723  gsImmp1(G_RDPHALF_1, (uintptr_t)(wordhi)), \
4724  gsImmp1(G_RDPHALF_2, (uintptr_t)(wordlo))
4725 
4726 #define gDPWord(pkt, wordhi, wordlo) \
4727 { \
4728  Gfx *_g = (Gfx *)(pkt); \
4729  \
4730  gImmp1(pkt, G_RDPHALF_1, (uintptr_t)(wordhi)); \
4731  gImmp1(pkt, G_RDPHALF_2, (uintptr_t)(wordlo)); \
4732 }
4733 
4734 #define gDPFullSync(pkt) gDPNoParam(pkt, G_RDPFULLSYNC)
4735 #define gsDPFullSync() gsDPNoParam(G_RDPFULLSYNC)
4736 #define gDPTileSync(pkt) gDPNoParam(pkt, G_RDPTILESYNC)
4737 #define gsDPTileSync() gsDPNoParam(G_RDPTILESYNC)
4738 #define gDPPipeSync(pkt) gDPNoParam(pkt, G_RDPPIPESYNC)
4739 #define gsDPPipeSync() gsDPNoParam(G_RDPPIPESYNC)
4740 #define gDPLoadSync(pkt) gDPNoParam(pkt, G_RDPLOADSYNC)
4741 #define gsDPLoadSync() gsDPNoParam(G_RDPLOADSYNC)
4742 #define gDPNoOp(pkt) gDPNoParam(pkt, G_NOOP)
4743 #define gsDPNoOp() gsDPNoParam(G_NOOP)
4744 #define gDPNoOpTag(pkt, tag) gDPParam(pkt, G_NOOP, tag)
4745 #define gsDPNoOpTag(tag) gsDPParam(G_NOOP, tag)
4746 
4747 #endif /* _LANGUAGE_C */
4748 
4749 
4750 #endif /* _GBI_H_ */
signed int s32
Definition: ultratypes.h:15