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