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