F3DEX3
Loading...
Searching...
No Matches
gbi.h
Go to the documentation of this file.
1
6/* List of options; the documentation for each is where it is used below. */
7/* #define REQUIRE_SEMICOLONS_AFTER_GBI_COMMANDS */ /* recommended */
8/* #define NO_SYNCS_IN_TEXTURE_LOADS */ /* see documentation */
9/* #define F3DEX2_SEGMENTS */ /* see documentation */
10/* #define DISABLE_AA */ /* developer taste */
11/* #define RISKY_RDP_SYNCS */ /* see documentation */
12/* #define KAZE_GBI_HACKS */ /* not recommended unless you are Kaze */
13
14#include "ultra64/mbi.h"
15
16#ifndef F3DEX3_H
17#define F3DEX3_H
18
19#define F3DEX_GBI_2 1
20#define F3DEX_GBI_PL 1
21#define F3DEX_GBI_3 1
22
23#ifdef REQUIRE_SEMICOLONS_AFTER_GBI_COMMANDS
24/* OoT style, semicolons required after using macros, cleaner code. If modding
25SM64, will have to fix a few places the codebase omits the semicolons. */
26#define _DW(macro) do {macro} while (0)
27#else
28/* SM64 style, semicolons optional, uglier code, will produce tens of thousands
29of warnings if you use -Wpedantic. */
30#define _DW(macro) macro
31#endif
32
33/*
34 * The following commands are the "generated" RDP commands; the user
35 * never sees them, the RSP microcode generates them.
36 * edge, shade, texture, zbuff bits: estz
37 */
38#define G_TRI_FILL 0xC8 /* fill triangle: 11001000 */
39#define G_TRI_SHADE 0xCC /* shade triangle: 11001100 */
40#define G_TRI_TXTR 0xCA /* texture triangle: 11001010 */
41#define G_TRI_SHADE_TXTR 0xCE /* shade, texture triangle: 11001110 */
42#define G_TRI_FILL_ZBUFF 0xC9 /* fill, zbuff triangle: 11001001 */
43#define G_TRI_SHADE_ZBUFF 0xCD /* shade, zbuff triangle: 11001101 */
44#define G_TRI_TXTR_ZBUFF 0xCB /* texture, zbuff triangle: 11001011 */
45#define G_TRI_SHADE_TXTR_ZBUFF 0xCF /* shade, txtr, zbuff trngl: 11001111 */
46
47/* masks to create the above: */
48#define G_RDP_TRI_FILL_MASK 0x08
49#define G_RDP_TRI_SHADE_MASK 0x04
50#define G_RDP_TRI_TXTR_MASK 0x02
51#define G_RDP_TRI_ZBUFF_MASK 0x01
52
53/*
54 * GBI commands in order
55 */
56/*#define G_SPECIAL_3 0xD3 no-op in F3DEX2 */
57/*#define G_SPECIAL_2 0xD4 no-op in F3DEX2 */
58/*#define G_SPECIAL_1 0xD5 triggered MVP recalculation, not supported in F3DEX3 */
59#define G_MEMSET 0xD5
60#define G_DMA_IO 0xD6
61#define G_TEXTURE 0xD7
62#define G_POPMTX 0xD8
63#define G_GEOMETRYMODE 0xD9
64#define G_MTX 0xDA
65#define G_MOVEWORD 0xDB
66#define G_MOVEMEM 0xDC
67#define G_LOAD_UCODE 0xDD
68#define G_DL 0xDE
69#define G_ENDDL 0xDF
70#define G_SPNOOP 0xE0
71#define G_RDPHALF_1 0xE1
72#define G_SETOTHERMODE_L 0xE2
73#define G_SETOTHERMODE_H 0xE3
74#define G_TEXRECT 0xE4
75#define G_TEXRECTFLIP 0xE5
76#define G_RDPLOADSYNC 0xE6
77#define G_RDPPIPESYNC 0xE7
78#define G_RDPTILESYNC 0xE8
79#define G_RDPFULLSYNC 0xE9
80#define G_SETKEYGB 0xEA
81#define G_SETKEYR 0xEB
82#define G_SETCONVERT 0xEC
83#define G_SETSCISSOR 0xED
84#define G_SETPRIMDEPTH 0xEE
85#define G_RDPSETOTHERMODE 0xEF
86#define G_LOADTLUT 0xF0
87#define G_RDPHALF_2 0xF1
88#define G_SETTILESIZE 0xF2
89#define G_LOADBLOCK 0xF3
90#define G_LOADTILE 0xF4
91#define G_SETTILE 0xF5
92#define G_FILLRECT 0xF6
93#define G_SETFILLCOLOR 0xF7
94#define G_SETFOGCOLOR 0xF8
95#define G_SETBLENDCOLOR 0xF9
96#define G_SETPRIMCOLOR 0xFA
97#define G_SETENVCOLOR 0xFB
98#define G_SETCOMBINE 0xFC
99#define G_SETTIMG 0xFD
100#define G_SETZIMG 0xFE
101#define G_SETCIMG 0xFF
102#define G_NOOP 0x00
103#define G_VTX 0x01
104#define G_MODIFYVTX 0x02
105#define G_CULLDL 0x03
106#define G_BRANCH_WZ 0x04
107#define G_TRI1 0x05
108#define G_TRI2 0x06
109#define G_QUAD 0x07
110#define G_TRISTRIP 0x08 /* = G_LINE3D was a no-op in F3DEX2, has been removed */
111#define G_TRIFAN 0x09
112#define G_LIGHTTORDP 0x0A
113#define G_RELSEGMENT 0x0B
114
115/* names differ between F3DEX2 and F3DZEX */
116#define G_BRANCH_Z G_BRANCH_WZ
117#define G_BRANCH_W G_BRANCH_WZ
118
119/*
120 * RSP command argument and misc defines
121 */
122
123/* Maximum number of transformed vertices kept in buffer in RSP DMEM */
124#define G_MAX_VERTS 56
125
126/* Maximum number of directional / point lights, not counting ambient */
127#define G_MAX_LIGHTS 9
128
129/* Maximum number of display list commands loaded at once into RSP DMEM */
130#define G_INPUT_BUFFER_CMDS 21
131
132/*
133 * flags for G_SETGEOMETRYMODE
134 *
135 * Note that flat shading, i.e. not G_SHADING_SMOOTH, sets shade RGB for all
136 * three verts to the value of the first vertex in the triangle. Shade alpha is
137 * still separate for each vertex, which is desired behavior for fog but not for
138 * any other F3DEX3 effects which use shade alpha.
139 */
140#define G_ZBUFFER 0x00000001
141#define G_TEXTURE_ENABLE 0x00000000 /* actually 2, but controlled by SPTexture */
142#define G_SHADE 0x00000004
143#define G_AMBOCCLUSION 0x00000040
144#define G_ATTROFFSET_ST_ENABLE 0x00000100
145#define G_CULL_NEITHER 0x00000000
146#define G_CULL_FRONT 0x00000200
147#define G_CULL_BACK 0x00000400
148#define G_CULL_BOTH 0x00000600 /* useless but supported */
149#define G_PACKED_NORMALS 0x00000800
150#define G_LIGHTTOALPHA 0x00001000
151#define G_LIGHTING_SPECULAR 0x00002000
152#define G_FRESNEL_COLOR 0x00004000
153#define G_FRESNEL_ALPHA 0x00008000
154#define G_FOG 0x00010000
155#define G_LIGHTING 0x00020000
156#define G_TEXTURE_GEN 0x00040000
157#define G_TEXTURE_GEN_LINEAR 0x00080000
158#define G_LOD 0x00100000 /* Ignored by all F3DEX* variants */
159#define G_SHADING_SMOOTH 0x00200000
160#define G_LIGHTING_POSITIONAL 0x00400000 /* Ignored by F3DEX3, assumed always on */
161#define G_CLIPPING 0x00800000 /* Ignored by all F3DEX* variants */
162
163/* See SPDisplayList / SPBranchList */
164#define G_DL_PUSH 0
165#define G_DL_NOPUSH 1
166
167/* See SPMatrix */
172#define G_MTX_MODELVIEW 0x00 /* matrix types */
177#define G_MTX_PROJECTION 0x04
182#define G_MTX_MUL 0x00 /* concat or load */
187#define G_MTX_LOAD 0x02
192#define G_MTX_NOPUSH 0x00 /* push or not */
197#define G_MTX_PUSH 0x01
198
199/* See SPNormalsMode */
200#define G_NORMALS_MODE_FAST 0x00
201#define G_NORMALS_MODE_AUTO 0x01
202#define G_NORMALS_MODE_MANUAL 0x02
203
204/* See SPAlphaCompareCull */
205#define G_ALPHA_COMPARE_CULL_DISABLE 0
206#define G_ALPHA_COMPARE_CULL_BELOW 1
207#define G_ALPHA_COMPARE_CULL_ABOVE -1
208
209/*
210 * MOVEMEM indices
211 * Each of these indexes an entry in a dmem table which points to an arbitrarily
212 * sized block of dmem in which to store the result of a DMA.
213 */
214#define G_MV_TEMPMTX0 0 /* for internal use by G_MTX multiply mode */
215#define G_MV_MMTX 2
216#define G_MV_TEMPMTX1 4 /* for internal use by G_MTX multiply mode */
217#define G_MV_VPMTX 6
218#define G_MV_VIEWPORT 8
219#define G_MV_LIGHT 10
220/* G_MV_POINT is no longer supported because the internal vertex format is no
221longer a multiple of 8 (DMA word). This was not used in any command anyway. */
222/* G_MV_MATRIX is no longer supported because there is no MVP matrix in F3DEX3. */
223#define G_MV_PMTX G_MV_VPMTX /* backwards compatibility */
224
225/*
226 * MOVEWORD indices
227 * Each of these indexes an entry in a dmem table which points to a word in dmem
228 * where an immediate word will be stored.
229 */
230#define G_MW_FX 0x00 /* replaces G_MW_MATRIX which is no longer supported */
231#define G_MW_NUMLIGHT 0x02
232/* nothing for 0x04; G_MW_CLIP is no longer supported */
233#define G_MW_SEGMENT 0x06
234#define G_MW_FOG 0x08
235#define G_MW_LIGHTCOL 0x0A
236/* G_MW_FORCEMTX is no longer supported because there is no MVP matrix in F3DEX3. */
237/* G_MW_PERSPNORM is removed; perspective norm is now set via G_MW_FX. */
238
239#define G_MW_HALFWORD_FLAG 0x8000 /* indicates store 2 bytes instead of 4 */
240
241/*
242 * These are offsets from the address in the dmem table
243 */
244#define G_MWO_NUMLIGHT 0x00
245#define G_MWO_FOG 0x00
246
247#define G_MWO_SEGMENT_0 0x00
248#define G_MWO_SEGMENT_1 0x01
249#define G_MWO_SEGMENT_2 0x02
250#define G_MWO_SEGMENT_3 0x03
251#define G_MWO_SEGMENT_4 0x04
252#define G_MWO_SEGMENT_5 0x05
253#define G_MWO_SEGMENT_6 0x06
254#define G_MWO_SEGMENT_7 0x07
255#define G_MWO_SEGMENT_8 0x08
256#define G_MWO_SEGMENT_9 0x09
257#define G_MWO_SEGMENT_A 0x0A
258#define G_MWO_SEGMENT_B 0x0B
259#define G_MWO_SEGMENT_C 0x0C
260#define G_MWO_SEGMENT_D 0x0D
261#define G_MWO_SEGMENT_E 0x0E
262#define G_MWO_SEGMENT_F 0x0F
263
264/* These are deprecated and no longer needed. */
265#define G_MWO_aLIGHT_1 0x00
266#define G_MWO_bLIGHT_1 0x04
267#define G_MWO_aLIGHT_2 0x10
268#define G_MWO_bLIGHT_2 0x14
269#define G_MWO_aLIGHT_3 0x20
270#define G_MWO_bLIGHT_3 0x24
271#define G_MWO_aLIGHT_4 0x30
272#define G_MWO_bLIGHT_4 0x34
273#define G_MWO_aLIGHT_5 0x40
274#define G_MWO_bLIGHT_5 0x44
275#define G_MWO_aLIGHT_6 0x50
276#define G_MWO_bLIGHT_6 0x54
277#define G_MWO_aLIGHT_7 0x60
278#define G_MWO_bLIGHT_7 0x64
279#define G_MWO_aLIGHT_8 0x70
280#define G_MWO_bLIGHT_8 0x74
281#define G_MWO_aLIGHT_9 0x80
282#define G_MWO_bLIGHT_9 0x84
283#define G_MWO_aLIGHT_10 0x90
284#define G_MWO_bLIGHT_10 0x94
285
290#define G_MWO_POINT_RGBA 0x10
295#define G_MWO_POINT_ST 0x14
301#define G_MWO_POINT_XYSCREEN 0x18
307#define G_MWO_POINT_ZSCREEN 0x1C
308
309#define G_MWO_AO_AMBIENT 0x00
310#define G_MWO_AO_DIRECTIONAL 0x02
311#define G_MWO_AO_POINT 0x04
312#define G_MWO_PERSPNORM 0x06
313#define G_MWO_FRESNEL_SCALE 0x0C
314#define G_MWO_FRESNEL_OFFSET 0x0E
315#define G_MWO_ATTR_OFFSET_S 0x10
316#define G_MWO_ATTR_OFFSET_T 0x12
317#define G_MWO_ALPHA_COMPARE_CULL 0x14
318#define G_MWO_NORMALS_MODE 0x16
319#define G_MWO_LAST_MAT_DL_ADDR 0x18
320
321/*
322 * RDP command argument defines
323 */
324
325/*
326 * Coordinate shift values, number of bits of fraction
327 */
328#define G_TEXTURE_IMAGE_FRAC 2
329#define G_TEXTURE_SCALE_FRAC 16
330#define G_SCALE_FRAC 8
331#define G_ROTATE_FRAC 16
332
333/*
334 * Maximum z-buffer value, used to initialize the z-buffer.
335 * Note : this number is NOT the viewport z-scale constant.
336 * See the comment next to G_MAXZ for more info.
337 */
338#define G_MAXFBZ 0x3FFF /* 3b exp, 11b mantissa */
339
340#define GPACK_RGBA5551(r, g, b, a) \
341 ((((r) << 8) & 0xF800) | \
342 (((g) << 3) & 0x07C0) | \
343 (((b) >> 2) & 0x003E) | \
344 ((a) & 1))
345
346#define GPACK_IA16(i, a) (((i) << 8) | (a))
347
348#define GPACK_ZDZ(z, dz) (((z) << 2) | (dz))
349
350/*
351 * G_SETIMG fmt: set image formats
352 */
353#define G_IM_FMT_RGBA 0
354#define G_IM_FMT_YUV 1
355#define G_IM_FMT_CI 2
356#define G_IM_FMT_IA 3
357#define G_IM_FMT_I 4
358
359/*
360 * G_SETIMG siz: set image pixel size
361 */
362#define G_IM_SIZ_4b 0
363#define G_IM_SIZ_8b 1
364#define G_IM_SIZ_16b 2
365#define G_IM_SIZ_32b 3
366#define G_IM_SIZ_DD 5
367
368#define G_IM_SIZ_4b_BYTES 0
369#define G_IM_SIZ_4b_TILE_BYTES G_IM_SIZ_4b_BYTES
370#define G_IM_SIZ_4b_LINE_BYTES G_IM_SIZ_4b_BYTES
371
372#define G_IM_SIZ_8b_BYTES 1
373#define G_IM_SIZ_8b_TILE_BYTES G_IM_SIZ_8b_BYTES
374#define G_IM_SIZ_8b_LINE_BYTES G_IM_SIZ_8b_BYTES
375
376#define G_IM_SIZ_16b_BYTES 2
377#define G_IM_SIZ_16b_TILE_BYTES G_IM_SIZ_16b_BYTES
378#define G_IM_SIZ_16b_LINE_BYTES G_IM_SIZ_16b_BYTES
379
380#define G_IM_SIZ_32b_BYTES 4
381#define G_IM_SIZ_32b_TILE_BYTES 2
382#define G_IM_SIZ_32b_LINE_BYTES 2
383
384#define G_IM_SIZ_4b_LOAD_BLOCK G_IM_SIZ_16b
385#define G_IM_SIZ_8b_LOAD_BLOCK G_IM_SIZ_16b
386#define G_IM_SIZ_16b_LOAD_BLOCK G_IM_SIZ_16b
387#define G_IM_SIZ_32b_LOAD_BLOCK G_IM_SIZ_32b
388
389#define G_IM_SIZ_4b_SHIFT 2
390#define G_IM_SIZ_8b_SHIFT 1
391#define G_IM_SIZ_16b_SHIFT 0
392#define G_IM_SIZ_32b_SHIFT 0
393
394#define G_IM_SIZ_4b_INCR 3
395#define G_IM_SIZ_8b_INCR 1
396#define G_IM_SIZ_16b_INCR 0
397#define G_IM_SIZ_32b_INCR 0
398
399/*
400 * G_SETCOMBINE: color combine modes
401 */
402/* Color combiner constants: */
403#define G_CCMUX_COMBINED 0
404#define G_CCMUX_TEXEL0 1
405#define G_CCMUX_TEXEL1 2
406#define G_CCMUX_PRIMITIVE 3
407#define G_CCMUX_SHADE 4
408#define G_CCMUX_ENVIRONMENT 5
409#define G_CCMUX_CENTER 6
410#define G_CCMUX_SCALE 6
411#define G_CCMUX_COMBINED_ALPHA 7
412#define G_CCMUX_TEXEL0_ALPHA 8
413#define G_CCMUX_TEXEL1_ALPHA 9
414#define G_CCMUX_PRIMITIVE_ALPHA 10
415#define G_CCMUX_SHADE_ALPHA 11
416#define G_CCMUX_ENV_ALPHA 12
417#define G_CCMUX_LOD_FRACTION 13
418#define G_CCMUX_PRIM_LOD_FRAC 14
419#define G_CCMUX_NOISE 7
420#define G_CCMUX_K4 7
421#define G_CCMUX_K5 15
422#define G_CCMUX_1 6
423#define G_CCMUX_0 31
424
425/* Alpha combiner constants: */
426#define G_ACMUX_COMBINED 0
427#define G_ACMUX_TEXEL0 1
428#define G_ACMUX_TEXEL1 2
429#define G_ACMUX_PRIMITIVE 3
430#define G_ACMUX_SHADE 4
431#define G_ACMUX_ENVIRONMENT 5
432#define G_ACMUX_LOD_FRACTION 0
433#define G_ACMUX_PRIM_LOD_FRAC 6
434#define G_ACMUX_1 6
435#define G_ACMUX_0 7
436
437/* typical CC cycle 1 modes */
438
439/* typical CC cycle 1 modes */
440#define G_CC_PRIMITIVE 0, 0, 0, PRIMITIVE, 0, 0, 0, PRIMITIVE
441#define G_CC_SHADE 0, 0, 0, SHADE, 0, 0, 0, SHADE
442
443#define G_CC_MODULATEI TEXEL0, 0, SHADE, 0, 0, 0, 0, SHADE
444#define G_CC_MODULATEIDECALA TEXEL0, 0, SHADE, 0, 0, 0, 0, TEXEL0
445#define G_CC_MODULATEIFADE TEXEL0, 0, SHADE, 0, 0, 0, 0, ENVIRONMENT
446
447#define G_CC_MODULATERGB G_CC_MODULATEI
448#define G_CC_MODULATERGBDECALA G_CC_MODULATEIDECALA
449#define G_CC_MODULATERGBFADE G_CC_MODULATEIFADE
450
451#define G_CC_MODULATEIA TEXEL0, 0, SHADE, 0, TEXEL0, 0, SHADE, 0
452#define G_CC_MODULATEIFADEA TEXEL0, 0, SHADE, 0, TEXEL0, 0, ENVIRONMENT, 0
453
454#define G_CC_MODULATEFADE TEXEL0, 0, SHADE, 0, ENVIRONMENT, 0, TEXEL0, 0
455
456#define G_CC_MODULATERGBA G_CC_MODULATEIA
457#define G_CC_MODULATERGBFADEA G_CC_MODULATEIFADEA
458
459#define G_CC_MODULATEI_PRIM TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE
460#define G_CC_MODULATEIA_PRIM TEXEL0, 0, PRIMITIVE, 0, TEXEL0, 0, PRIMITIVE, 0
461#define G_CC_MODULATEIDECALA_PRIM TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, TEXEL0
462
463#define G_CC_MODULATERGB_PRIM G_CC_MODULATEI_PRIM
464#define G_CC_MODULATERGBA_PRIM G_CC_MODULATEIA_PRIM
465#define G_CC_MODULATERGBDECALA_PRIM G_CC_MODULATEIDECALA_PRIM
466
467#define G_CC_FADE SHADE, 0, ENVIRONMENT, 0, SHADE, 0, ENVIRONMENT, 0
468#define G_CC_FADEA TEXEL0, 0, ENVIRONMENT, 0, TEXEL0, 0, ENVIRONMENT, 0
469
470#define G_CC_DECALRGB 0, 0, 0, TEXEL0, 0, 0, 0, SHADE
471#define G_CC_DECALRGBA 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0
472#define G_CC_DECALFADE 0, 0, 0, TEXEL0, 0, 0, 0, ENVIRONMENT
473
474#define G_CC_DECALFADEA 0, 0, 0, TEXEL0, TEXEL0, 0, ENVIRONMENT, 0
475
476#define G_CC_BLENDI ENVIRONMENT, SHADE, TEXEL0, SHADE, 0, 0, 0, SHADE
477#define G_CC_BLENDIA ENVIRONMENT, SHADE, TEXEL0, SHADE, TEXEL0, 0, SHADE, 0
478#define G_CC_BLENDIDECALA ENVIRONMENT, SHADE, TEXEL0, SHADE, 0, 0, 0, TEXEL0
479
480#define G_CC_BLENDRGBA TEXEL0, SHADE, TEXEL0_ALPHA, SHADE, 0, 0, 0, SHADE
481#define G_CC_BLENDRGBDECALA TEXEL0, SHADE, TEXEL0_ALPHA, SHADE, 0, 0, 0, TEXEL0
482#define G_CC_BLENDRGBFADEA TEXEL0, SHADE, TEXEL0_ALPHA, SHADE, 0, 0, 0, ENVIRONMENT
483
484#define G_CC_ADDRGB TEXEL0, 0, TEXEL0, SHADE, 0, 0, 0, SHADE
485#define G_CC_ADDRGBDECALA TEXEL0, 0, TEXEL0, SHADE, 0, 0, 0, TEXEL0
486#define G_CC_ADDRGBFADE TEXEL0, 0, TEXEL0, SHADE, 0, 0, 0, ENVIRONMENT
487
488#define G_CC_REFLECTRGB ENVIRONMENT, 0, TEXEL0, SHADE, 0, 0, 0, SHADE
489#define G_CC_REFLECTRGBDECALA ENVIRONMENT, 0, TEXEL0, SHADE, 0, 0, 0, TEXEL0
490
491#define G_CC_HILITERGB PRIMITIVE, SHADE, TEXEL0, SHADE, 0, 0, 0, SHADE
492#define G_CC_HILITERGBA PRIMITIVE, SHADE, TEXEL0, SHADE, PRIMITIVE, SHADE, TEXEL0, SHADE
493#define G_CC_HILITERGBDECALA PRIMITIVE, SHADE, TEXEL0, SHADE, 0, 0, 0, TEXEL0
494
495#define G_CC_SHADEDECALA 0, 0, 0, SHADE, 0, 0, 0, TEXEL0
496#define G_CC_SHADEFADEA 0, 0, 0, SHADE, 0, 0, 0, ENVIRONMENT
497
498#define G_CC_BLENDPE PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, SHADE, 0
499#define G_CC_BLENDPEDECALA PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, 0, 0, 0, TEXEL0
500
501/* oddball modes */
502#define _G_CC_BLENDPE ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, TEXEL0, 0, SHADE, 0
503#define _G_CC_BLENDPEDECALA ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, 0, 0, 0, TEXEL0
504#define _G_CC_TWOCOLORTEX PRIMITIVE, SHADE, TEXEL0, SHADE, 0, 0, 0, SHADE
505/* used for 1-cycle sparse mip-maps, primitive color has color of lowest LOD */
506#define _G_CC_SPARSEST PRIMITIVE, TEXEL0, LOD_FRACTION, TEXEL0, PRIMITIVE, TEXEL0, LOD_FRACTION, TEXEL0
507#define G_CC_TEMPLERP TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0, TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0
508
509/* typical CC cycle 1 modes, usually followed by other cycle 2 modes */
510#define G_CC_TRILERP TEXEL1, TEXEL0, LOD_FRACTION, TEXEL0, TEXEL1, TEXEL0, LOD_FRACTION, TEXEL0
511#define G_CC_INTERFERENCE TEXEL0, 0, TEXEL1, 0, TEXEL0, 0, TEXEL1, 0
512
513
514/*
515 * One-cycle color convert operation
516 */
517#define G_CC_1CYUV2RGB TEXEL0, K4, K5, TEXEL0, 0, 0, 0, SHADE
518
519/*
520 * NOTE: YUV2RGB expects TF step1 color conversion to occur in 2nd clock.
521 * Therefore, CC looks for step1 results in TEXEL1
522 */
523#define G_CC_YUV2RGB TEXEL1, K4, K5, TEXEL1, 0, 0, 0, 0
524
525/* typical CC cycle 2 modes */
526#define G_CC_PASS2 0, 0, 0, COMBINED, 0, 0, 0, COMBINED
527#define G_CC_MODULATEI2 COMBINED, 0, SHADE, 0, 0, 0, 0, SHADE
528#define G_CC_MODULATEIA2 COMBINED, 0, SHADE, 0, COMBINED, 0, SHADE, 0
529#define G_CC_MODULATERGB2 G_CC_MODULATEI2
530#define G_CC_MODULATERGBA2 G_CC_MODULATEIA2
531#define G_CC_MODULATEI_PRIM2 COMBINED, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE
532#define G_CC_MODULATEIA_PRIM2 COMBINED, 0, PRIMITIVE, 0, COMBINED, 0, PRIMITIVE, 0
533#define G_CC_MODULATERGB_PRIM2 G_CC_MODULATEI_PRIM2
534#define G_CC_MODULATERGBA_PRIM2 G_CC_MODULATEIA_PRIM2
535#define G_CC_DECALRGB2 0, 0, 0, COMBINED, 0, 0, 0, SHADE
536/*
537 * ?
538#define G_CC_DECALRGBA2 COMBINED, SHADE, COMBINED_ALPHA, SHADE, 0, 0, 0, SHADE
539*/
540#define G_CC_BLENDI2 ENVIRONMENT, SHADE, COMBINED, SHADE, 0, 0, 0, SHADE
541#define G_CC_BLENDIA2 ENVIRONMENT, SHADE, COMBINED, SHADE, COMBINED, 0, SHADE, 0
542#define G_CC_CHROMA_KEY2 TEXEL0, CENTER, SCALE, 0, 0, 0, 0, 0
543#define G_CC_HILITERGB2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, 0, 0, 0, SHADE
544#define G_CC_HILITERGBA2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, ENVIRONMENT, COMBINED, TEXEL0, COMBINED
545#define G_CC_HILITERGBDECALA2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, 0, 0, 0, TEXEL0
546#define G_CC_HILITERGBPASSA2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, 0, 0, 0, COMBINED
547
548/*
549 * G_SETOTHERMODE_L sft: shift count
550 */
551#define G_MDSFT_ALPHACOMPARE 0
552#define G_MDSFT_ZSRCSEL 2
553#define G_MDSFT_RENDERMODE 3
554#define G_MDSFT_BLENDER 16
555
556/*
557 * G_SETOTHERMODE_H sft: shift count
558 */
559#define G_MDSFT_ALPHADITHER 4
560#define G_MDSFT_RGBDITHER 6
561#define G_MDSFT_COMBKEY 8
562#define G_MDSFT_TEXTCONV 9
563#define G_MDSFT_TEXTFILT 12
564#define G_MDSFT_TEXTLUT 14
565#define G_MDSFT_TEXTLOD 16
566#define G_MDSFT_TEXTDETAIL 17
567#define G_MDSFT_TEXTPERSP 19
568#define G_MDSFT_CYCLETYPE 20
569#define G_MDSFT_COLORDITHER 22 /* Needed for OoT ucode_disas even though HW 1.0 only */
570#define G_MDSFT_PIPELINE 23
571
572/* G_SETOTHERMODE_H gPipelineMode */
573#define G_PM_1PRIMITIVE (1 << G_MDSFT_PIPELINE)
574#define G_PM_NPRIMITIVE (0 << G_MDSFT_PIPELINE)
575
576/* G_SETOTHERMODE_H gSetCycleType */
577#define G_CYC_1CYCLE (0 << G_MDSFT_CYCLETYPE)
578#define G_CYC_2CYCLE (1 << G_MDSFT_CYCLETYPE)
579#define G_CYC_COPY (2 << G_MDSFT_CYCLETYPE)
580#define G_CYC_FILL (3 << G_MDSFT_CYCLETYPE)
581
582/* G_SETOTHERMODE_H gSetTexturePersp */
583#define G_TP_NONE (0 << G_MDSFT_TEXTPERSP)
584#define G_TP_PERSP (1 << G_MDSFT_TEXTPERSP)
585
586/* G_SETOTHERMODE_H gSetTextureDetail */
587#define G_TD_CLAMP (0 << G_MDSFT_TEXTDETAIL)
588#define G_TD_SHARPEN (1 << G_MDSFT_TEXTDETAIL)
589#define G_TD_DETAIL (2 << G_MDSFT_TEXTDETAIL)
590
591/* G_SETOTHERMODE_H gSetTextureLOD */
592#define G_TL_TILE (0 << G_MDSFT_TEXTLOD)
593#define G_TL_LOD (1 << G_MDSFT_TEXTLOD)
594
595/* G_SETOTHERMODE_H gSetTextureLUT */
596#define G_TT_NONE (0 << G_MDSFT_TEXTLUT)
597#define G_TT_RGBA16 (2 << G_MDSFT_TEXTLUT)
598#define G_TT_IA16 (3 << G_MDSFT_TEXTLUT)
599
600/* G_SETOTHERMODE_H gSetTextureFilter */
601#define G_TF_POINT (0 << G_MDSFT_TEXTFILT)
602#define G_TF_AVERAGE (3 << G_MDSFT_TEXTFILT)
603#define G_TF_BILERP (2 << G_MDSFT_TEXTFILT)
604
605/* G_SETOTHERMODE_H gSetTextureConvert */
606#define G_TC_CONV (0 << G_MDSFT_TEXTCONV)
607#define G_TC_FILTCONV (5 << G_MDSFT_TEXTCONV)
608#define G_TC_FILT (6 << G_MDSFT_TEXTCONV)
609
610/* G_SETOTHERMODE_H gSetCombineKey */
611#define G_CK_NONE (0 << G_MDSFT_COMBKEY)
612#define G_CK_KEY (1 << G_MDSFT_COMBKEY)
613
614/* G_SETOTHERMODE_H gSetColorDither */
615#define G_CD_MAGICSQ (0 << G_MDSFT_RGBDITHER)
616#define G_CD_BAYER (1 << G_MDSFT_RGBDITHER)
617#define G_CD_NOISE (2 << G_MDSFT_RGBDITHER)
618#define G_CD_DISABLE (3 << G_MDSFT_RGBDITHER)
619
620/* G_SETOTHERMODE_H gSetAlphaDither */
621#define G_AD_PATTERN (0 << G_MDSFT_ALPHADITHER)
622#define G_AD_NOTPATTERN (1 << G_MDSFT_ALPHADITHER)
623#define G_AD_NOISE (2 << G_MDSFT_ALPHADITHER)
624#define G_AD_DISABLE (3 << G_MDSFT_ALPHADITHER)
625
626/* G_SETOTHERMODE_L gSetAlphaCompare */
627#define G_AC_NONE (0 << G_MDSFT_ALPHACOMPARE)
628#define G_AC_THRESHOLD (1 << G_MDSFT_ALPHACOMPARE)
629#define G_AC_DITHER (3 << G_MDSFT_ALPHACOMPARE)
630
631/* G_SETOTHERMODE_L gSetDepthSource */
632#define G_ZS_PIXEL (0 << G_MDSFT_ZSRCSEL)
633#define G_ZS_PRIM (1 << G_MDSFT_ZSRCSEL)
634
635#ifdef DISABLE_AA
636/* Disables antialiasing in all preset rendermodes, saving RDP time. Note that
637this does NOT disable antialiasing in manually written rendermodes, e.g.
638exported from fast64 with advanced options enabled. We can't redefine the real
639IM_RD because IM_RD is needed for transparency also, and we can't distinguish
640between a manually written rendermode using IM_RD for transparency and one using
641it for antialiasing. */
642#define AA_DEF 0
643#define RD_DEF 0
644#else
645#define AA_DEF AA_EN
646#define RD_DEF IM_RD
647#endif
648
649/* G_SETOTHERMODE_L gSetRenderMode */
650#define AA_EN 0x0008
651#define Z_CMP 0x0010
652#define Z_UPD 0x0020
653#define IM_RD 0x0040
654#define CLR_ON_CVG 0x0080
655#define CVG_DST_CLAMP 0x0000
656#define CVG_DST_WRAP 0x0100
657#define CVG_DST_FULL 0x0200
658#define CVG_DST_SAVE 0x0300
659#define ZMODE_OPA 0x0000
660#define ZMODE_INTER 0x0400
661#define ZMODE_XLU 0x0800
662#define ZMODE_DEC 0x0C00
663#define CVG_X_ALPHA 0x1000
664#define ALPHA_CVG_SEL 0x2000
665#define FORCE_BL 0x4000
666#define TEX_EDGE 0x0000 /* not in HW V2; is 0x8000 in older HW */
667
668#define G_BL_CLR_IN 0
669#define G_BL_CLR_MEM 1
670#define G_BL_CLR_BL 2
671#define G_BL_CLR_FOG 3
672#define G_BL_1MA 0
673#define G_BL_A_MEM 1
674#define G_BL_A_IN 0
675#define G_BL_A_FOG 1
676#define G_BL_A_SHADE 2
677#define G_BL_1 2
678#define G_BL_0 3
679
680#define GBL_c1(m1a, m1b, m2a, m2b) \
681 (m1a) << 30 | (m1b) << 26 | (m2a) << 22 | (m2b) << 18
682#define GBL_c2(m1a, m1b, m2a, m2b) \
683 (m1a) << 28 | (m1b) << 24 | (m2a) << 20 | (m2b) << 16
684
685#define RM_AA_ZB_OPA_SURF(clk) \
686 AA_DEF | Z_CMP | Z_UPD | RD_DEF | CVG_DST_CLAMP | \
687 ZMODE_OPA | ALPHA_CVG_SEL | \
688 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
689
690#define RM_RA_ZB_OPA_SURF(clk) \
691 AA_DEF | Z_CMP | Z_UPD | CVG_DST_CLAMP | \
692 ZMODE_OPA | ALPHA_CVG_SEL | \
693 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
694
695#define RM_AA_ZB_XLU_SURF(clk) \
696 AA_DEF | Z_CMP | IM_RD | CVG_DST_WRAP | CLR_ON_CVG | \
697 FORCE_BL | ZMODE_XLU | \
698 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
699
700#define RM_AA_ZB_OPA_DECAL(clk) \
701 AA_DEF | Z_CMP | RD_DEF | CVG_DST_WRAP | ALPHA_CVG_SEL | \
702 ZMODE_DEC | \
703 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
704
705#define RM_RA_ZB_OPA_DECAL(clk) \
706 AA_DEF | Z_CMP | CVG_DST_WRAP | ALPHA_CVG_SEL | \
707 ZMODE_DEC | \
708 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
709
710#define RM_AA_ZB_XLU_DECAL(clk) \
711 AA_DEF | Z_CMP | IM_RD | CVG_DST_WRAP | CLR_ON_CVG | \
712 FORCE_BL | ZMODE_DEC | \
713 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
714
715#define RM_AA_ZB_OPA_INTER(clk) \
716 AA_DEF | Z_CMP | Z_UPD | RD_DEF | CVG_DST_CLAMP | \
717 ALPHA_CVG_SEL | ZMODE_INTER | \
718 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
719
720#define RM_RA_ZB_OPA_INTER(clk) \
721 AA_DEF | Z_CMP | Z_UPD | CVG_DST_CLAMP | \
722 ALPHA_CVG_SEL | ZMODE_INTER | \
723 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
724
725#define RM_AA_ZB_XLU_INTER(clk) \
726 AA_DEF | Z_CMP | IM_RD | CVG_DST_WRAP | CLR_ON_CVG | \
727 FORCE_BL | ZMODE_INTER | \
728 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
729
730#define RM_AA_ZB_XLU_LINE(clk) \
731 AA_DEF | Z_CMP | IM_RD | CVG_DST_CLAMP | CVG_X_ALPHA | \
732 ALPHA_CVG_SEL | 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_DEC_LINE(clk) \
736 AA_DEF | Z_CMP | IM_RD | CVG_DST_SAVE | CVG_X_ALPHA | \
737 ALPHA_CVG_SEL | FORCE_BL | ZMODE_DEC | \
738 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
739
740/* Note that this uses AA_EN not AA_DEF */
741#define RM_AA_ZB_TEX_EDGE(clk) \
742 AA_EN | Z_CMP | Z_UPD | RD_DEF | CVG_DST_CLAMP | \
743 CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE | \
744 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
745
746#define RM_AA_ZB_TEX_INTER(clk) \
747 AA_DEF | Z_CMP | Z_UPD | RD_DEF | CVG_DST_CLAMP | \
748 CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_INTER | TEX_EDGE | \
749 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
750
751#define RM_AA_ZB_SUB_SURF(clk) \
752 AA_DEF | Z_CMP | Z_UPD | IM_RD | CVG_DST_FULL | \
753 ZMODE_OPA | ALPHA_CVG_SEL | \
754 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
755
756#define RM_AA_ZB_PCL_SURF(clk) \
757 AA_DEF | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \
758 ZMODE_OPA | G_AC_DITHER | \
759 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
760
761#define RM_AA_ZB_OPA_TERR(clk) \
762 AA_DEF | Z_CMP | Z_UPD | RD_DEF | CVG_DST_CLAMP | \
763 ZMODE_OPA | ALPHA_CVG_SEL | \
764 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
765
766#define RM_AA_ZB_TEX_TERR(clk) \
767 AA_DEF | Z_CMP | Z_UPD | RD_DEF | CVG_DST_CLAMP | \
768 CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE | \
769 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
770
771#define RM_AA_ZB_SUB_TERR(clk) \
772 AA_DEF | Z_CMP | Z_UPD | IM_RD | CVG_DST_FULL | \
773 ZMODE_OPA | ALPHA_CVG_SEL | \
774 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
775
776
777#define RM_AA_OPA_SURF(clk) \
778 AA_DEF | RD_DEF | CVG_DST_CLAMP | \
779 ZMODE_OPA | ALPHA_CVG_SEL | \
780 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
781
782#define RM_RA_OPA_SURF(clk) \
783 AA_DEF | CVG_DST_CLAMP | \
784 ZMODE_OPA | ALPHA_CVG_SEL | \
785 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
786
787#define RM_AA_XLU_SURF(clk) \
788 AA_DEF | IM_RD | CVG_DST_WRAP | CLR_ON_CVG | FORCE_BL | \
789 ZMODE_OPA | \
790 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
791
792#define RM_AA_XLU_LINE(clk) \
793 AA_DEF | IM_RD | CVG_DST_CLAMP | CVG_X_ALPHA | \
794 ALPHA_CVG_SEL | FORCE_BL | ZMODE_OPA | \
795 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
796
797#define RM_AA_DEC_LINE(clk) \
798 AA_DEF | IM_RD | CVG_DST_FULL | CVG_X_ALPHA | \
799 ALPHA_CVG_SEL | FORCE_BL | ZMODE_OPA | \
800 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
801
802/* Note that this uses AA_EN not AA_DEF */
803#define RM_AA_TEX_EDGE(clk) \
804 AA_EN | RD_DEF | CVG_DST_CLAMP | \
805 CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE | \
806 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
807
808#define RM_AA_SUB_SURF(clk) \
809 AA_DEF | IM_RD | CVG_DST_FULL | \
810 ZMODE_OPA | ALPHA_CVG_SEL | \
811 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
812
813#define RM_AA_PCL_SURF(clk) \
814 AA_DEF | IM_RD | CVG_DST_CLAMP | \
815 ZMODE_OPA | G_AC_DITHER | \
816 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
817
818#define RM_AA_OPA_TERR(clk) \
819 AA_DEF | RD_DEF | CVG_DST_CLAMP | \
820 ZMODE_OPA | ALPHA_CVG_SEL | \
821 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
822
823#define RM_AA_TEX_TERR(clk) \
824 AA_DEF | RD_DEF | CVG_DST_CLAMP | \
825 CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE | \
826 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
827
828#define RM_AA_SUB_TERR(clk) \
829 AA_DEF | IM_RD | CVG_DST_FULL | \
830 ZMODE_OPA | ALPHA_CVG_SEL | \
831 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
832
833
834#define RM_ZB_OPA_SURF(clk) \
835 Z_CMP | Z_UPD | CVG_DST_FULL | ALPHA_CVG_SEL | \
836 ZMODE_OPA | \
837 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
838
839#define RM_ZB_XLU_SURF(clk) \
840 Z_CMP | IM_RD | CVG_DST_FULL | FORCE_BL | ZMODE_XLU | \
841 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
842
843#define RM_ZB_OPA_DECAL(clk) \
844 Z_CMP | CVG_DST_FULL | ALPHA_CVG_SEL | ZMODE_DEC | \
845 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
846
847#define RM_ZB_XLU_DECAL(clk) \
848 Z_CMP | IM_RD | CVG_DST_FULL | FORCE_BL | ZMODE_DEC | \
849 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
850
851#define RM_ZB_CLD_SURF(clk) \
852 Z_CMP | IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_XLU | \
853 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
854
855#define RM_ZB_OVL_SURF(clk) \
856 Z_CMP | IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_DEC | \
857 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
858
859#define RM_ZB_PCL_SURF(clk) \
860 Z_CMP | Z_UPD | CVG_DST_FULL | ZMODE_OPA | \
861 G_AC_DITHER | \
862 GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
863
864
865#define RM_OPA_SURF(clk) \
866 CVG_DST_CLAMP | FORCE_BL | ZMODE_OPA | \
867 GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
868
869#define RM_XLU_SURF(clk) \
870 IM_RD | CVG_DST_FULL | FORCE_BL | ZMODE_OPA | \
871 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
872
873#define RM_TEX_EDGE(clk) \
874 CVG_DST_CLAMP | CVG_X_ALPHA | ALPHA_CVG_SEL | FORCE_BL | \
875 ZMODE_OPA | TEX_EDGE | AA_EN | \
876 GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
877
878#define RM_CLD_SURF(clk) \
879 IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_OPA | \
880 GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
881
882#define RM_PCL_SURF(clk) \
883 CVG_DST_FULL | FORCE_BL | ZMODE_OPA | \
884 G_AC_DITHER | \
885 GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
886
887#define RM_ADD(clk) \
888 IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_OPA | \
889 GBL_c##clk(G_BL_CLR_IN, G_BL_A_FOG, G_BL_CLR_MEM, G_BL_1)
890
891#define RM_NOOP(clk) \
892 GBL_c##clk(0, 0, 0, 0)
893
894#define RM_VISCVG(clk) \
895 IM_RD | FORCE_BL | \
896 GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_BL, G_BL_A_MEM)
897
898/* for rendering to an 8-bit framebuffer */
899#define RM_OPA_CI(clk) \
900 CVG_DST_CLAMP | ZMODE_OPA | \
901 GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
902
903/* Custom version of RM_AA_ZB_XLU_SURF with Z_UPD */
904#define RM_CUSTOM_AA_ZB_XLU_SURF(clk) \
905 RM_AA_ZB_XLU_SURF(clk) | Z_UPD
906
907#define G_RM_CUSTOM_AA_ZB_XLU_SURF RM_CUSTOM_AA_ZB_XLU_SURF(1)
908#define G_RM_CUSTOM_AA_ZB_XLU_SURF2 RM_CUSTOM_AA_ZB_XLU_SURF(2)
909
910#define G_RM_AA_ZB_OPA_SURF RM_AA_ZB_OPA_SURF(1)
911#define G_RM_AA_ZB_OPA_SURF2 RM_AA_ZB_OPA_SURF(2)
912#define G_RM_AA_ZB_XLU_SURF RM_AA_ZB_XLU_SURF(1)
913#define G_RM_AA_ZB_XLU_SURF2 RM_AA_ZB_XLU_SURF(2)
914#define G_RM_AA_ZB_OPA_DECAL RM_AA_ZB_OPA_DECAL(1)
915#define G_RM_AA_ZB_OPA_DECAL2 RM_AA_ZB_OPA_DECAL(2)
916#define G_RM_AA_ZB_XLU_DECAL RM_AA_ZB_XLU_DECAL(1)
917#define G_RM_AA_ZB_XLU_DECAL2 RM_AA_ZB_XLU_DECAL(2)
918#define G_RM_AA_ZB_OPA_INTER RM_AA_ZB_OPA_INTER(1)
919#define G_RM_AA_ZB_OPA_INTER2 RM_AA_ZB_OPA_INTER(2)
920#define G_RM_AA_ZB_XLU_INTER RM_AA_ZB_XLU_INTER(1)
921#define G_RM_AA_ZB_XLU_INTER2 RM_AA_ZB_XLU_INTER(2)
922#define G_RM_AA_ZB_XLU_LINE RM_AA_ZB_XLU_LINE(1)
923#define G_RM_AA_ZB_XLU_LINE2 RM_AA_ZB_XLU_LINE(2)
924#define G_RM_AA_ZB_DEC_LINE RM_AA_ZB_DEC_LINE(1)
925#define G_RM_AA_ZB_DEC_LINE2 RM_AA_ZB_DEC_LINE(2)
926#define G_RM_AA_ZB_TEX_EDGE RM_AA_ZB_TEX_EDGE(1)
927#define G_RM_AA_ZB_TEX_EDGE2 RM_AA_ZB_TEX_EDGE(2)
928#define G_RM_AA_ZB_TEX_INTER RM_AA_ZB_TEX_INTER(1)
929#define G_RM_AA_ZB_TEX_INTER2 RM_AA_ZB_TEX_INTER(2)
930#define G_RM_AA_ZB_SUB_SURF RM_AA_ZB_SUB_SURF(1)
931#define G_RM_AA_ZB_SUB_SURF2 RM_AA_ZB_SUB_SURF(2)
932#define G_RM_AA_ZB_PCL_SURF RM_AA_ZB_PCL_SURF(1)
933#define G_RM_AA_ZB_PCL_SURF2 RM_AA_ZB_PCL_SURF(2)
934#define G_RM_AA_ZB_OPA_TERR RM_AA_ZB_OPA_TERR(1)
935#define G_RM_AA_ZB_OPA_TERR2 RM_AA_ZB_OPA_TERR(2)
936#define G_RM_AA_ZB_TEX_TERR RM_AA_ZB_TEX_TERR(1)
937#define G_RM_AA_ZB_TEX_TERR2 RM_AA_ZB_TEX_TERR(2)
938#define G_RM_AA_ZB_SUB_TERR RM_AA_ZB_SUB_TERR(1)
939#define G_RM_AA_ZB_SUB_TERR2 RM_AA_ZB_SUB_TERR(2)
940
941#define G_RM_RA_ZB_OPA_SURF RM_RA_ZB_OPA_SURF(1)
942#define G_RM_RA_ZB_OPA_SURF2 RM_RA_ZB_OPA_SURF(2)
943#define G_RM_RA_ZB_OPA_DECAL RM_RA_ZB_OPA_DECAL(1)
944#define G_RM_RA_ZB_OPA_DECAL2 RM_RA_ZB_OPA_DECAL(2)
945#define G_RM_RA_ZB_OPA_INTER RM_RA_ZB_OPA_INTER(1)
946#define G_RM_RA_ZB_OPA_INTER2 RM_RA_ZB_OPA_INTER(2)
947
948#define G_RM_AA_OPA_SURF RM_AA_OPA_SURF(1)
949#define G_RM_AA_OPA_SURF2 RM_AA_OPA_SURF(2)
950#define G_RM_AA_XLU_SURF RM_AA_XLU_SURF(1)
951#define G_RM_AA_XLU_SURF2 RM_AA_XLU_SURF(2)
952#define G_RM_AA_XLU_LINE RM_AA_XLU_LINE(1)
953#define G_RM_AA_XLU_LINE2 RM_AA_XLU_LINE(2)
954#define G_RM_AA_DEC_LINE RM_AA_DEC_LINE(1)
955#define G_RM_AA_DEC_LINE2 RM_AA_DEC_LINE(2)
956#define G_RM_AA_TEX_EDGE RM_AA_TEX_EDGE(1)
957#define G_RM_AA_TEX_EDGE2 RM_AA_TEX_EDGE(2)
958#define G_RM_AA_SUB_SURF RM_AA_SUB_SURF(1)
959#define G_RM_AA_SUB_SURF2 RM_AA_SUB_SURF(2)
960#define G_RM_AA_PCL_SURF RM_AA_PCL_SURF(1)
961#define G_RM_AA_PCL_SURF2 RM_AA_PCL_SURF(2)
962#define G_RM_AA_OPA_TERR RM_AA_OPA_TERR(1)
963#define G_RM_AA_OPA_TERR2 RM_AA_OPA_TERR(2)
964#define G_RM_AA_TEX_TERR RM_AA_TEX_TERR(1)
965#define G_RM_AA_TEX_TERR2 RM_AA_TEX_TERR(2)
966#define G_RM_AA_SUB_TERR RM_AA_SUB_TERR(1)
967#define G_RM_AA_SUB_TERR2 RM_AA_SUB_TERR(2)
968
969#define G_RM_RA_OPA_SURF RM_RA_OPA_SURF(1)
970#define G_RM_RA_OPA_SURF2 RM_RA_OPA_SURF(2)
971
972#define G_RM_ZB_OPA_SURF RM_ZB_OPA_SURF(1)
973#define G_RM_ZB_OPA_SURF2 RM_ZB_OPA_SURF(2)
974#define G_RM_ZB_XLU_SURF RM_ZB_XLU_SURF(1)
975#define G_RM_ZB_XLU_SURF2 RM_ZB_XLU_SURF(2)
976#define G_RM_ZB_OPA_DECAL RM_ZB_OPA_DECAL(1)
977#define G_RM_ZB_OPA_DECAL2 RM_ZB_OPA_DECAL(2)
978#define G_RM_ZB_XLU_DECAL RM_ZB_XLU_DECAL(1)
979#define G_RM_ZB_XLU_DECAL2 RM_ZB_XLU_DECAL(2)
980#define G_RM_ZB_CLD_SURF RM_ZB_CLD_SURF(1)
981#define G_RM_ZB_CLD_SURF2 RM_ZB_CLD_SURF(2)
982#define G_RM_ZB_OVL_SURF RM_ZB_OVL_SURF(1)
983#define G_RM_ZB_OVL_SURF2 RM_ZB_OVL_SURF(2)
984#define G_RM_ZB_PCL_SURF RM_ZB_PCL_SURF(1)
985#define G_RM_ZB_PCL_SURF2 RM_ZB_PCL_SURF(2)
986
987#define G_RM_OPA_SURF RM_OPA_SURF(1)
988#define G_RM_OPA_SURF2 RM_OPA_SURF(2)
989#define G_RM_XLU_SURF RM_XLU_SURF(1)
990#define G_RM_XLU_SURF2 RM_XLU_SURF(2)
991#define G_RM_CLD_SURF RM_CLD_SURF(1)
992#define G_RM_CLD_SURF2 RM_CLD_SURF(2)
993#define G_RM_TEX_EDGE RM_TEX_EDGE(1)
994#define G_RM_TEX_EDGE2 RM_TEX_EDGE(2)
995#define G_RM_PCL_SURF RM_PCL_SURF(1)
996#define G_RM_PCL_SURF2 RM_PCL_SURF(2)
997#define G_RM_ADD RM_ADD(1)
998#define G_RM_ADD2 RM_ADD(2)
999#define G_RM_NOOP RM_NOOP(1)
1000#define G_RM_NOOP2 RM_NOOP(2)
1001#define G_RM_VISCVG RM_VISCVG(1)
1002#define G_RM_VISCVG2 RM_VISCVG(2)
1003#define G_RM_OPA_CI RM_OPA_CI(1)
1004#define G_RM_OPA_CI2 RM_OPA_CI(2)
1005
1006
1007#define G_RM_FOG_SHADE_A GBL_c1(G_BL_CLR_FOG, G_BL_A_SHADE, G_BL_CLR_IN, G_BL_1MA)
1008#define G_RM_FOG_PRIM_A GBL_c1(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_IN, G_BL_1MA)
1009#define G_RM_PASS GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
1010
1011/*
1012 * G_SETCONVERT: K0-5
1013 */
1014#define G_CV_K0 175
1015#define G_CV_K1 -43
1016#define G_CV_K2 -89
1017#define G_CV_K3 222
1018#define G_CV_K4 114
1019#define G_CV_K5 42
1020
1021/*
1022 * G_SETSCISSOR: interlace mode
1023 */
1024#define G_SC_NON_INTERLACE 0
1025#define G_SC_ODD_INTERLACE 3
1026#define G_SC_EVEN_INTERLACE 2
1027
1028/*
1029 * Data Structures
1030 */
1031
1035typedef struct {
1036 short ob[3];
1037 unsigned short flag;
1038 short tc[2];
1039 unsigned char cn[4];
1040} Vtx_t;
1041
1045typedef struct {
1046 short ob[3];
1047 unsigned short flag;
1048 short tc[2];
1049 signed char n[3];
1050 unsigned char a;
1051} Vtx_tn;
1052
1056typedef union {
1057 Vtx_t v;
1060} Vtx;
1061
1062typedef struct {
1063 short pos[3];
1064 short pad;
1065} PlainVtx_t;
1066
1067typedef union {
1068 PlainVtx_t c;
1069 long long int force_structure_alignment;
1070} PlainVtx;
1071
1075typedef struct {
1076 unsigned char flag;
1077 unsigned char v[3];
1078} Tri;
1079
1085typedef long int Mtx_t[4][4];
1086typedef union {
1087 Mtx_t m;
1088 struct {
1089 u16 intPart[4][4];
1090 u16 fracPart[4][4];
1091 };
1092 long long int force_structure_alignment;
1093} Mtx;
1094
1095#define IPART(x) (((s32)((x) * 0x10000) >> 16) & 0xFFFF)
1096#define FPART(x) ((s32)((x) * 0x10000) & 0xFFFF)
1097
1098#define gdSPDefMtx( \
1099 xx, xy, xz, xw, \
1100 yx, yy, yz, yw, \
1101 zx, zy, zz, zw, \
1102 wx, wy, wz, ww) \
1103 { { \
1104 (IPART(xx) << 16) | IPART(yx), \
1105 (IPART(zx) << 16) | IPART(wx), \
1106 (IPART(xy) << 16) | IPART(yy), \
1107 (IPART(zy) << 16) | IPART(wy), \
1108 (IPART(xz) << 16) | IPART(yz), \
1109 (IPART(zz) << 16) | IPART(wz), \
1110 (IPART(xw) << 16) | IPART(yw), \
1111 (IPART(zw) << 16) | IPART(ww), \
1112 (FPART(xx) << 16) | FPART(yx), \
1113 (FPART(zx) << 16) | FPART(wx), \
1114 (FPART(xy) << 16) | FPART(yy), \
1115 (FPART(zy) << 16) | FPART(wy), \
1116 (FPART(xz) << 16) | FPART(yz), \
1117 (FPART(zz) << 16) | FPART(wz), \
1118 (FPART(xw) << 16) | FPART(yw), \
1119 (FPART(zw) << 16) | FPART(ww), \
1120 } }
1121
1122/*
1123 * Viewport
1124 */
1125
1160#define G_MAXZ Error_please_update_viewport_Z_and_Y_see_GBI
1161
1165#define G_NEW_MAXZ 0x7FFF
1166
1178typedef struct {
1179 short vscale[4];
1180 short vtrans[4];
1181 /* both the above arrays are padded to 64-bit boundary */
1182} Vp_t;
1183
1184typedef union {
1185 Vp_t vp;
1186 long long int force_structure_alignment[2];
1187} Vp;
1188
1195typedef struct {
1196 unsigned char col[3];
1197 unsigned char type;
1198 unsigned char colc[3];
1199 char pad2;
1200 signed char dir[3];
1201 char pad3;
1202 char pad4[3];
1203 unsigned char size;
1204} Light_t;
1205
1212typedef struct {
1213 unsigned char col[3];
1214 unsigned char kc;
1215 unsigned char colc[3];
1216 unsigned char kl;
1217 short pos[3];
1218 unsigned char kq;
1219 unsigned char size;
1220} PointLight_t;
1221
1225typedef struct {
1226 unsigned char col[3];
1227 char pad1;
1228 unsigned char colc[3];
1229 char pad2;
1230} Ambient_t;
1231
1232typedef struct {
1233 signed char dir[3];
1234 char pad1;
1235} LookAt_t;
1236
1237typedef struct {
1238 LookAt_t l;
1239} LookAtWrapper;
1240
1241typedef struct {
1242 /* texture offsets for highlight 1/2 */
1243 int x1;
1244 int y1;
1245 int x2;
1246 int y2;
1247} Hilite_t;
1248
1249typedef struct {
1250 short c0;
1251 short c1;
1252 short c2;
1253 short c3;
1254 short c4;
1255 short c5;
1256 short c6;
1257 short c7;
1258 short kx;
1259 short ky;
1260 short kz;
1261 short kc;
1262} OcclusionPlane_t;
1263
1264typedef struct {
1265 struct {
1266 short x;
1267 short y;
1268 short z;
1269 } v[4];
1270 float weight;
1271} OcclusionPlaneCandidate;
1272
1273typedef union {
1274 Light_t l;
1275 PointLight_t p;
1276 long long int force_structure_alignment[2];
1277} Light;
1278
1279typedef union {
1280 Ambient_t l;
1281 long long int force_structure_alignment[1];
1282} Ambient;
1283
1284typedef union {
1285 LookAtWrapper l[2];
1286 long long int force_structure_alignment[1];
1287} LookAt;
1288
1289typedef union {
1290 Hilite_t h;
1291 long int force_structure_alignment;
1292} Hilite;
1293
1294typedef union {
1295 OcclusionPlane_t o;
1296 short c[12];
1297 long long int force_structure_alignment[3];
1298} OcclusionPlane;
1299
1300typedef struct {
1301 Light l[9];
1302 Ambient a;
1303} Lightsn;
1304
1305typedef struct {
1306 /* F3DEX3 properly supports zero lights, unlike F3DEX2 where you need
1307 to include one black directional light. */
1308 Ambient a;
1309} Lights0;
1310
1311typedef struct {
1312 Light l[1];
1313 Ambient a;
1314} Lights1;
1315
1316typedef struct {
1317 Light l[2];
1318 Ambient a;
1319} Lights2;
1320
1321typedef struct {
1322 Light l[3];
1323 Ambient a;
1324} Lights3;
1325
1326typedef struct {
1327 Light l[4];
1328 Ambient a;
1329} Lights4;
1330
1331typedef struct {
1332 Light l[5];
1333 Ambient a;
1334} Lights5;
1335
1336typedef struct {
1337 Light l[6];
1338 Ambient a;
1339} Lights6;
1340
1341typedef struct {
1342 Light l[7];
1343 Ambient a;
1344} Lights7;
1345
1346typedef struct {
1347 Light l[8];
1348 Ambient a;
1349} Lights8;
1350
1351typedef struct {
1352 Light l[9];
1353 Ambient a;
1354} Lights9;
1355
1356#define gDefAmbient(r, g, b) \
1357 {{ \
1358 { (r), (g), (b) }, 0, \
1359 { (r), (g), (b) }, 0, \
1360 }}
1361
1362#define gDefLight(r, g, b, x, y, z) \
1363 {{ \
1364 { (r), (g), (b) }, 0, \
1365 { (r), (g), (b) }, 0, \
1366 { (x), (y), (z) }, 0, \
1367 { 0, 0, 0 }, 0, \
1368 }}
1369
1370#define gdSPDefLights0(ar, ag, ab) \
1371 { \
1372 gDefAmbient(ar, ag, ab), \
1373 }
1374
1375#define gdSPDefLights1(ar, ag, ab, \
1376 r1, g1, b1, x1, y1, z1) \
1377 { \
1378 { \
1379 gDefLight(r1, g1, b1, x1, y1, z1), \
1380 }, \
1381 gDefAmbient(ar, ag, ab), \
1382 }
1383
1384#define gdSPDefLights2(ar, ag, ab, \
1385 r1, g1, b1, x1, y1, z1, \
1386 r2, g2, b2, x2, y2, z2) \
1387 { \
1388 { \
1389 gDefLight(r1, g1, b1, x1, y1, z1), \
1390 gDefLight(r2, g2, b2, x2, y2, z2), \
1391 }, \
1392 gDefAmbient(ar, ag, ab), \
1393 }
1394
1395#define gdSPDefLights3(ar, ag, ab, \
1396 r1, g1, b1, x1, y1, z1, \
1397 r2, g2, b2, x2, y2, z2) \
1398 r3, g3, b3, x3, y3, z3) \
1399 { \
1400 { \
1401 gDefLight(r1, g1, b1, x1, y1, z1), \
1402 gDefLight(r2, g2, b2, x2, y2, z2), \
1403 gDefLight(r3, g3, b3, x3, y3, z3), \
1404 }, \
1405 gDefAmbient(ar, ag, ab), \
1406 }
1407
1408#define gdSPDefLights4(ar, ag, ab, \
1409 r1, g1, b1, x1, y1, z1, \
1410 r2, g2, b2, x2, y2, z2, \
1411 r3, g3, b3, x3, y3, z3, \
1412 r4, g4, b4, x4, y4, z4) \
1413 { \
1414 { \
1415 gDefLight(r1, g1, b1, x1, y1, z1), \
1416 gDefLight(r2, g2, b2, x2, y2, z2), \
1417 gDefLight(r3, g3, b3, x3, y3, z3), \
1418 gDefLight(r4, g4, b4, x4, y4, z4), \
1419 }, \
1420 gDefAmbient(ar, ag, ab), \
1421 }
1422
1423#define gdSPDefLights5(ar, ag, ab, \
1424 r1, g1, b1, x1, y1, z1, \
1425 r2, g2, b2, x2, y2, z2, \
1426 r3, g3, b3, x3, y3, z3, \
1427 r4, g4, b4, x4, y4, z4, \
1428 r5, g5, b5, x5, y5, z5) \
1429 { \
1430 { \
1431 gDefLight(r1, g1, b1, x1, y1, z1), \
1432 gDefLight(r2, g2, b2, x2, y2, z2), \
1433 gDefLight(r3, g3, b3, x3, y3, z3), \
1434 gDefLight(r4, g4, b4, x4, y4, z4), \
1435 gDefLight(r5, g5, b5, x5, y5, z5), \
1436 }, \
1437 gDefAmbient(ar, ag, ab), \
1438 }
1439
1440#define gdSPDefLights6(ar, ag, ab, \
1441 r1, g1, b1, x1, y1, z1, \
1442 r2, g2, b2, x2, y2, z2, \
1443 r3, g3, b3, x3, y3, z3, \
1444 r4, g4, b4, x4, y4, z4, \
1445 r5, g5, b5, x5, y5, z5, \
1446 r6, g6, b6, x6, y6, z6) \
1447 { \
1448 { \
1449 gDefLight(r1, g1, b1, x1, y1, z1), \
1450 gDefLight(r2, g2, b2, x2, y2, z2), \
1451 gDefLight(r3, g3, b3, x3, y3, z3), \
1452 gDefLight(r4, g4, b4, x4, y4, z4), \
1453 gDefLight(r5, g5, b5, x5, y5, z5), \
1454 gDefLight(r6, g6, b6, x6, y6, z6), \
1455 }, \
1456 gDefAmbient(ar, ag, ab), \
1457 }
1458
1459#define gdSPDefLights7(ar, ag, ab, \
1460 r1, g1, b1, x1, y1, z1, \
1461 r2, g2, b2, x2, y2, z2, \
1462 r3, g3, b3, x3, y3, z3, \
1463 r4, g4, b4, x4, y4, z4, \
1464 r5, g5, b5, x5, y5, z5, \
1465 r6, g6, b6, x6, y6, z6, \
1466 r7, g7, b7, x7, y7, z7) \
1467 { \
1468 { \
1469 gDefLight(r1, g1, b1, x1, y1, z1), \
1470 gDefLight(r2, g2, b2, x2, y2, z2), \
1471 gDefLight(r3, g3, b3, x3, y3, z3), \
1472 gDefLight(r4, g4, b4, x4, y4, z4), \
1473 gDefLight(r5, g5, b5, x5, y5, z5), \
1474 gDefLight(r6, g6, b6, x6, y6, z6), \
1475 gDefLight(r7, g7, b7, x7, y7, z7), \
1476 }, \
1477 gDefAmbient(ar, ag, ab), \
1478 }
1479
1480#define gdSPDefLights8(ar, ag, ab, \
1481 r1, g1, b1, x1, y1, z1, \
1482 r2, g2, b2, x2, y2, z2, \
1483 r3, g3, b3, x3, y3, z3, \
1484 r4, g4, b4, x4, y4, z4, \
1485 r5, g5, b5, x5, y5, z5, \
1486 r6, g6, b6, x6, y6, z6, \
1487 r7, g7, b7, x7, y7, z7, \
1488 r8, g8, b8, x8, y8, z8) \
1489 { \
1490 { \
1491 gDefLight(r1, g1, b1, x1, y1, z1), \
1492 gDefLight(r2, g2, b2, x2, y2, z2), \
1493 gDefLight(r3, g3, b3, x3, y3, z3), \
1494 gDefLight(r4, g4, b4, x4, y4, z4), \
1495 gDefLight(r5, g5, b5, x5, y5, z5), \
1496 gDefLight(r6, g6, b6, x6, y6, z6), \
1497 gDefLight(r7, g7, b7, x7, y7, z7), \
1498 gDefLight(r8, g8, b8, x8, y8, z8), \
1499 }, \
1500 gDefAmbient(ar, ag, ab), \
1501 }
1502
1503#define gdSPDefLights9(ar, ag, ab, \
1504 r1, g1, b1, x1, y1, z1, \
1505 r2, g2, b2, x2, y2, z2, \
1506 r3, g3, b3, x3, y3, z3, \
1507 r4, g4, b4, x4, y4, z4, \
1508 r5, g5, b5, x5, y5, z5, \
1509 r6, g6, b6, x6, y6, z6, \
1510 r7, g7, b7, x7, y7, z7, \
1511 r8, g8, b8, x8, y8, z8, \
1512 r9, g9, b9, x9, y9, z9) \
1513 { \
1514 { \
1515 gDefLight(r1, g1, b1, x1, y1, z1), \
1516 gDefLight(r2, g2, b2, x2, y2, z2), \
1517 gDefLight(r3, g3, b3, x3, y3, z3), \
1518 gDefLight(r4, g4, b4, x4, y4, z4), \
1519 gDefLight(r5, g5, b5, x5, y5, z5), \
1520 gDefLight(r6, g6, b6, x6, y6, z6), \
1521 gDefLight(r7, g7, b7, x7, y7, z7), \
1522 gDefLight(r8, g8, b8, x8, y8, z8), \
1523 gDefLight(r9, g9, b9, x9, y9, z9), \
1524 }, \
1525 gDefAmbient(ar, ag, ab), \
1526 }
1527
1528#define gDefPointLight(r, g, b, x, y, z, kc, kl, kq) \
1529 {{ \
1530 { (r1), (g1), (b1) }, (kc), \
1531 { (r1), (g1), (b1) }, (kl), \
1532 { (x1), (y1), (z1) }, (kq), \
1533 0, \
1534 }}
1535
1536#define gdSPDefPointLights0(ar, ag, ab) \
1537 { \
1538 gDefAmbient(ar, ag, ab), \
1539 }
1540
1541#define gdSPDefPointLights1(ar, ag, ab, \
1542 r1, g1, b1, x1, y1, z1, c1, l1, q1) \
1543 { \
1544 { \
1545 gDefPointLight(r1, g1, b1, x1, y1, z1, c1, l1, q1), \
1546 }, \
1547 gDefAmbient(ar, ag, ab), \
1548 }
1549
1550#define gdSPDefPointLights2(ar, ag, ab, \
1551 r1, g1, b1, x1, y1, z1, c1, l1, q1, \
1552 r2, g2, b2, x2, y2, z2, c2, l2, q2) \
1553 { \
1554 { \
1555 gDefPointLight(r1, g1, b1, x1, y1, z1, c1, l1, q1), \
1556 gDefPointLight(r2, g2, b2, x2, y2, z2, c2, l2, q2), \
1557 }, \
1558 gDefAmbient(ar, ag, ab), \
1559 }
1560
1561#define gdSPDefPointLights3(ar, ag, ab, \
1562 r1, g1, b1, x1, y1, z1, c1, l1, q1, \
1563 r2, g2, b2, x2, y2, z2, c2, l2, q2, \
1564 r3, g3, b3, x3, y3, z3, c3, l3, q3) \
1565 { \
1566 { \
1567 gDefPointLight(r1, g1, b1, x1, y1, z1, c1, l1, q1), \
1568 gDefPointLight(r2, g2, b2, x2, y2, z2, c2, l2, q2), \
1569 gDefPointLight(r3, g3, b3, x3, y3, z3, c3, l3, q3), \
1570 }, \
1571 gDefAmbient(ar, ag, ab), \
1572 }
1573
1574#define gdSPDefPointLights4(ar, ag, ab, \
1575 r1, g1, b1, x1, y1, z1, c1, l1, q1, \
1576 r2, g2, b2, x2, y2, z2, c2, l2, q2, \
1577 r3, g3, b3, x3, y3, z3, c3, l3, q3, \
1578 r4, g4, b4, x4, y4, z4, c4, l4, q4) \
1579 { \
1580 { \
1581 gDefPointLight(r1, g1, b1, x1, y1, z1, c1, l1, q1), \
1582 gDefPointLight(r2, g2, b2, x2, y2, z2, c2, l2, q2), \
1583 gDefPointLight(r3, g3, b3, x3, y3, z3, c3, l3, q3), \
1584 gDefPointLight(r4, g4, b4, x4, y4, z4, c4, l4, q4), \
1585 }, \
1586 gDefAmbient(ar, ag, ab), \
1587 }
1588
1589#define gdSPDefPointLights5(ar, ag, ab, \
1590 r1, g1, b1, x1, y1, z1, c1, l1, q1, \
1591 r2, g2, b2, x2, y2, z2, c2, l2, q2, \
1592 r3, g3, b3, x3, y3, z3, c3, l3, q3, \
1593 r4, g4, b4, x4, y4, z4, c4, l4, q4, \
1594 r5, g5, b5, x5, y5, z5, c5, l5, q5) \
1595 { \
1596 { \
1597 gDefPointLight(r1, g1, b1, x1, y1, z1, c1, l1, q1), \
1598 gDefPointLight(r2, g2, b2, x2, y2, z2, c2, l2, q2), \
1599 gDefPointLight(r3, g3, b3, x3, y3, z3, c3, l3, q3), \
1600 gDefPointLight(r4, g4, b4, x4, y4, z4, c4, l4, q4), \
1601 gDefPointLight(r5, g5, b5, x5, y5, z5, c5, l5, q5), \
1602 }, \
1603 gDefAmbient(ar, ag, ab), \
1604 }
1605
1606#define gdSPDefPointLights6(ar, ag, ab, \
1607 r1, g1, b1, x1, y1, z1, c1, l1, q1, \
1608 r2, g2, b2, x2, y2, z2, c2, l2, q2, \
1609 r3, g3, b3, x3, y3, z3, c3, l3, q3, \
1610 r4, g4, b4, x4, y4, z4, c4, l4, q4, \
1611 r5, g5, b5, x5, y5, z5, c5, l5, q5, \
1612 r6, g6, b6, x6, y6, z6, c6, l6, q6) \
1613 { \
1614 { \
1615 gDefPointLight(r1, g1, b1, x1, y1, z1, c1, l1, q1), \
1616 gDefPointLight(r2, g2, b2, x2, y2, z2, c2, l2, q2), \
1617 gDefPointLight(r3, g3, b3, x3, y3, z3, c3, l3, q3), \
1618 gDefPointLight(r4, g4, b4, x4, y4, z4, c4, l4, q4), \
1619 gDefPointLight(r5, g5, b5, x5, y5, z5, c5, l5, q5), \
1620 gDefPointLight(r6, g6, b6, x6, y6, z6, c6, l6, q6), \
1621 }, \
1622 gDefAmbient(ar, ag, ab), \
1623 }
1624
1625#define gdSPDefPointLights7(ar, ag, ab, \
1626 r1, g1, b1, x1, y1, z1, c1, l1, q1, \
1627 r2, g2, b2, x2, y2, z2, c2, l2, q2, \
1628 r3, g3, b3, x3, y3, z3, c3, l3, q3, \
1629 r4, g4, b4, x4, y4, z4, c4, l4, q4, \
1630 r5, g5, b5, x5, y5, z5, c5, l5, q5, \
1631 r6, g6, b6, x6, y6, z6, c6, l6, q6, \
1632 r7, g7, b7, x7, y7, z7, c7, l7, q7) \
1633 { \
1634 { \
1635 gDefPointLight(r1, g1, b1, x1, y1, z1, c1, l1, q1), \
1636 gDefPointLight(r2, g2, b2, x2, y2, z2, c2, l2, q2), \
1637 gDefPointLight(r3, g3, b3, x3, y3, z3, c3, l3, q3), \
1638 gDefPointLight(r4, g4, b4, x4, y4, z4, c4, l4, q4), \
1639 gDefPointLight(r5, g5, b5, x5, y5, z5, c5, l5, q5), \
1640 gDefPointLight(r6, g6, b6, x6, y6, z6, c6, l6, q6), \
1641 gDefPointLight(r7, g7, b7, x7, y7, z7, c7, l7, q7), \
1642 }, \
1643 gDefAmbient(ar, ag, ab), \
1644 }
1645
1646#define gdSPDefPointLights8(ar, ag, ab, \
1647 r1, g1, b1, x1, y1, z1, c1, l1, q1, \
1648 r2, g2, b2, x2, y2, z2, c2, l2, q2, \
1649 r3, g3, b3, x3, y3, z3, c3, l3, q3, \
1650 r4, g4, b4, x4, y4, z4, c4, l4, q4, \
1651 r5, g5, b5, x5, y5, z5, c5, l5, q5, \
1652 r6, g6, b6, x6, y6, z6, c6, l6, q6, \
1653 r7, g7, b7, x7, y7, z7, c7, l7, q7, \
1654 r8, g8, b8, x8, y8, z8, c8, l8, q8) \
1655 { \
1656 { \
1657 gDefPointLight(r1, g1, b1, x1, y1, z1, c1, l1, q1), \
1658 gDefPointLight(r2, g2, b2, x2, y2, z2, c2, l2, q2), \
1659 gDefPointLight(r3, g3, b3, x3, y3, z3, c3, l3, q3), \
1660 gDefPointLight(r4, g4, b4, x4, y4, z4, c4, l4, q4), \
1661 gDefPointLight(r5, g5, b5, x5, y5, z5, c5, l5, q5), \
1662 gDefPointLight(r6, g6, b6, x6, y6, z6, c6, l6, q6), \
1663 gDefPointLight(r7, g7, b7, x7, y7, z7, c7, l7, q7), \
1664 gDefPointLight(r8, g8, b8, x8, y8, z8, c8, l8, q8), \
1665 }, \
1666 gDefAmbient(ar, ag, ab), \
1667 }
1668
1669#define gdSPDefPointLights9(ar, ag, ab, \
1670 r1, g1, b1, x1, y1, z1, c1, l1, q1, \
1671 r2, g2, b2, x2, y2, z2, c2, l2, q2, \
1672 r3, g3, b3, x3, y3, z3, c3, l3, q3, \
1673 r4, g4, b4, x4, y4, z4, c4, l4, q4, \
1674 r5, g5, b5, x5, y5, z5, c5, l5, q5, \
1675 r6, g6, b6, x6, y6, z6, c6, l6, q6, \
1676 r7, g7, b7, x7, y7, z7, c7, l7, q7, \
1677 r8, g8, b8, x8, y8, z8, c8, l8, q8, \
1678 r9, g9, b9, x9, y9, z9, c9, l9, q9) \
1679 { \
1680 { \
1681 gDefPointLight(r1, g1, b1, x1, y1, z1, c1, l1, q1), \
1682 gDefPointLight(r2, g2, b2, x2, y2, z2, c2, l2, q2), \
1683 gDefPointLight(r3, g3, b3, x3, y3, z3, c3, l3, q3), \
1684 gDefPointLight(r4, g4, b4, x4, y4, z4, c4, l4, q4), \
1685 gDefPointLight(r5, g5, b5, x5, y5, z5, c5, l5, q5), \
1686 gDefPointLight(r6, g6, b6, x6, y6, z6, c6, l6, q6), \
1687 gDefPointLight(r7, g7, b7, x7, y7, z7, c7, l7, q7), \
1688 gDefPointLight(r8, g8, b8, x8, y8, z8, c8, l8, q8), \
1689 gDefPointLight(r9, g9, b9, x9, y9, z9, c9, l9, q9), \
1690 }, \
1691 gDefAmbient(ar, ag, ab), \
1692 }
1693
1694#define gdSPDefLookAt(rightx, righty, rightz, upx, upy, upz) \
1695 { \
1696 {{{ rightx, righty, rightz }, 0 }}, \
1697 {{{ upx, upy, upz }, 0 }}, \
1698 }
1699
1700typedef struct {
1701 int cmd : 8;
1702 unsigned int type : 8;
1703 unsigned int len : 16;
1704 union {
1705 /* The exact form of this callback is intentionally left unspecified, a display list
1706 parser may choose the return value and parameters so long as it is consistent. */
1707 void (*callback)();
1708 const char* str;
1709 unsigned int u32;
1710 float f32;
1711 void* addr;
1712 } value;
1713} Gnoop;
1714
1718typedef struct {
1719 int cmd : 8;
1720 unsigned int par : 8;
1721 unsigned int len : 16;
1722 unsigned int addr;
1723} Gdma;
1724
1728typedef struct {
1729 int cmd : 8;
1730 unsigned int len : 8;
1731 unsigned int ofs : 8;
1732 unsigned int par : 8;
1733 unsigned int addr;
1734} Gdma2;
1735
1739typedef struct {
1740 int cmd : 8;
1741 unsigned int index : 8;
1742 unsigned int offset : 16;
1743 unsigned int data;
1744} Gmovewd;
1745
1749typedef struct {
1750 int cmd : 8;
1751 unsigned int size : 8;
1752 unsigned int offset : 8;
1753 unsigned int index : 8;
1754 unsigned int data;
1755} Gmovemem;
1756
1760typedef struct {
1761 int cmd : 8;
1762 int pad : 24;
1763 Tri tri;
1764} Gtri;
1765
1766typedef struct {
1767 Tri tri1; /* flag is the command byte */
1768 Tri tri2;
1769} Gtri2;
1770
1771typedef struct {
1772 Tri tri1; /* flag is the command byte */
1773 Tri tri2;
1774} Gquad;
1775
1776typedef struct {
1777 int cmd : 8;
1778 unsigned int pad : 8;
1779 unsigned short vstart_x2;
1780 unsigned short pad2;
1781 unsigned short vend_x2;
1782} Gcull;
1783
1784typedef struct {
1785 int cmd : 8;
1786 unsigned int pad : 24;
1787 unsigned short z;
1788 unsigned short dz;
1789} Gsetprimdepth;
1790
1791typedef struct {
1792 int cmd : 8;
1793 int pad1 : 24;
1794 unsigned int param;
1795} Gpopmtx;
1796
1797typedef struct {
1798 int cmd : 8;
1799 int mw_index : 8;
1800 int pad0 : 8;
1801 int number : 8;
1802 int pad1 : 8;
1803 int base : 24;
1804} Gsegment;
1805
1806typedef struct {
1807 int cmd : 8;
1808 int pad0 : 8;
1809 unsigned int sft : 8;
1810 unsigned int len : 8;
1811 unsigned int data : 32;
1812} GsetothermodeL;
1813
1814typedef struct {
1815 int cmd : 8;
1816 int pad0 : 8;
1817 unsigned int sft : 8;
1818 unsigned int len : 8;
1819 unsigned int data : 32;
1820} GsetothermodeH;
1821
1822typedef struct {
1823 unsigned char cmd;
1824 unsigned char lodscale;
1825 unsigned char pad : 2;
1826 unsigned char level : 3;
1827 unsigned char tile : 3;
1828 unsigned char on;
1829 unsigned short s;
1830 unsigned short t;
1831} Gtexture;
1832
1833typedef struct {
1834 int cmd : 8;
1835 int pad1 : 24;
1836 short int pad2;
1837 short int scale;
1838} Gperspnorm;
1839
1840
1844typedef struct {
1845 int cmd : 8;
1846 unsigned int fmt : 3;
1847 unsigned int siz : 2;
1848 unsigned int pad : 7;
1849 unsigned int wd : 12; /* really only 10 bits, extra */
1850 unsigned int dram; /* to account for 1024 */
1851} Gsetimg;
1852
1853typedef struct {
1854 int cmd : 8;
1855 /* muxs0 */
1856 unsigned int a0 : 4;
1857 unsigned int c0 : 5;
1858 unsigned int Aa0 : 3;
1859 unsigned int Ac0 : 3;
1860 unsigned int a1 : 4;
1861 unsigned int c1 : 5;
1862 /* muxs1 */
1863 unsigned int b0 : 4;
1864 unsigned int b1 : 4;
1865 unsigned int Aa1 : 3;
1866 unsigned int Ac1 : 3;
1867 unsigned int d0 : 3;
1868 unsigned int Ab0 : 3;
1869 unsigned int Ad0 : 3;
1870 unsigned int d1 : 3;
1871 unsigned int Ab1 : 3;
1872 unsigned int Ad1 : 3;
1873} Gsetcombine;
1874
1875typedef struct {
1876 int cmd : 8;
1877 unsigned char pad;
1878 unsigned char prim_min_level;
1879 unsigned char prim_level;
1880 union {
1881 unsigned long color;
1882 struct {
1883 unsigned char r;
1884 unsigned char g;
1885 unsigned char b;
1886 unsigned char a;
1887 };
1888 };
1889} Gsetcolor;
1890
1891typedef struct {
1892 int cmd : 8;
1893 int x0 : 10;
1894 int x0frac : 2;
1895 int y0 : 10;
1896 int y0frac : 2;
1897 unsigned int pad : 8;
1898 int x1 : 10;
1899 int x1frac : 2;
1900 int y1 : 10;
1901 int y1frac : 2;
1902} Gfillrect;
1903
1904typedef struct {
1905 int cmd : 8;
1906 unsigned int fmt : 3;
1907 unsigned int siz : 2;
1908 unsigned int pad0 : 1;
1909 unsigned int line : 9;
1910 unsigned int tmem : 9;
1911 unsigned int pad1 : 5;
1912 unsigned int tile : 3;
1913 unsigned int palette : 4;
1914 unsigned int ct : 1;
1915 unsigned int mt : 1;
1916 unsigned int maskt : 4;
1917 unsigned int shiftt : 4;
1918 unsigned int cs : 1;
1919 unsigned int ms : 1;
1920 unsigned int masks : 4;
1921 unsigned int shifts : 4;
1922} Gsettile;
1923
1924typedef struct {
1925 int cmd : 8;
1926 unsigned int sl : 12;
1927 unsigned int tl : 12;
1928 int pad : 5;
1929 unsigned int tile : 3;
1930 unsigned int sh : 12;
1931 unsigned int th : 12;
1932} Gloadtile;
1933
1934typedef Gloadtile Gloadblock;
1935
1936typedef Gloadtile Gsettilesize;
1937
1938typedef Gloadtile Gloadtlut;
1939
1940typedef struct {
1941 unsigned int cmd : 8; /* command */
1942 unsigned int xl : 12; /* X coordinate of upper left */
1943 unsigned int yl : 12; /* Y coordinate of upper left */
1944 unsigned int pad1 : 5; /* Padding */
1945 unsigned int tile : 3; /* Tile descriptor index */
1946 unsigned int xh : 12; /* X coordinate of lower right */
1947 unsigned int yh : 12; /* Y coordinate of lower right */
1948 unsigned int s : 16; /* S texture coord at top left */
1949 unsigned int t : 16; /* T texture coord at top left */
1950 unsigned int dsdx : 16; /* Change in S per change in X */
1951 unsigned int dtdy : 16; /* Change in T per change in Y */
1952} Gtexrect;
1953
1954#define MakeTexRect(xh,yh,flip,tile,xl,yl,s,t,dsdx,dtdy) \
1955 G_TEXRECT, xh, yh, 0, flip, 0, tile, xl, yl, s, t, dsdx, dtdy
1956
1960typedef struct {
1961 unsigned long w0;
1962 unsigned long w1;
1963 unsigned long w2;
1964 unsigned long w3;
1965} TexRect;
1966
1967typedef struct {
1968 int cmd : 8;
1969 unsigned int pad : 4;
1970 unsigned int len : 8; /* n */
1971 unsigned int pad2 : 4;
1972 unsigned char par; /* v0 */
1973 unsigned int addr;
1974} Gvtx;
1975
1979typedef struct {
1980 unsigned int w0;
1981 unsigned int w1;
1982} Gwords;
1983
1988typedef union {
1989 Gwords words;
1990 Gnoop noop;
1991 Gdma dma;
1992 Gdma2 dma2;
1993 Gvtx vtx;
1994 Gtri tri;
1995 Gtri2 tri2;
1996 Gquad quad;
1997 Gcull cull;
1998 Gmovewd movewd;
1999 Gmovemem movemem;
2000 Gpopmtx popmtx;
2001 Gsegment segment;
2002 GsetothermodeH setothermodeH;
2003 GsetothermodeL setothermodeL;
2004 Gtexture texture;
2005 Gperspnorm perspnorm;
2006 Gsetimg setimg;
2007 Gsetcombine setcombine;
2008 Gsetcolor setcolor;
2009 Gfillrect fillrect; /* use for setscissor also */
2010 Gsettile settile;
2011 Gloadtile loadtile; /* use for loadblock also, th is dxt */
2012 Gsettilesize settilesize;
2013 Gloadtlut loadtlut;
2014 Gsetprimdepth setprimdepth;
2015 long long int force_structure_alignment;
2016} Gfx;
2017
2018/*
2019 * Macros to assemble the graphics display list
2020 */
2021
2022/*
2023 * DMA macros
2024 */
2025#define gDma0p(pkt, c, s, l) \
2026_DW({ \
2027 Gfx *_g = (Gfx *)(pkt); \
2028 \
2029 _g->words.w0 = (_SHIFTL((c), 24, 8) | \
2030 _SHIFTL((l), 0, 24)); \
2031 _g->words.w1 = (unsigned int)(s); \
2032})
2033
2034#define gsDma0p(c, s, l) \
2035{ \
2036 (_SHIFTL((c), 24, 8) | \
2037 _SHIFTL((l), 0, 24)), \
2038 (unsigned int)(s) \
2039}
2040
2041#define gDma1p(pkt, c, s, l, p) \
2042_DW({ \
2043 Gfx *_g = (Gfx *)(pkt); \
2044 \
2045 _g->words.w0 = (_SHIFTL((c), 24, 8) | \
2046 _SHIFTL((p), 16, 8) | \
2047 _SHIFTL((l), 0, 16)); \
2048 _g->words.w1 = (unsigned int)(s); \
2049})
2050
2051#define gsDma1p(c, s, l, p) \
2052{ \
2053 (_SHIFTL((c), 24, 8) | \
2054 _SHIFTL((p), 16, 8) | \
2055 _SHIFTL((l), 0, 16)), \
2056 (unsigned int)(s) \
2057}
2058
2059#define gDma2p(pkt, c, adrs, len, idx, ofs) \
2060_DW({ \
2061 Gfx *_g = (Gfx *)(pkt); \
2062 \
2063 _g->words.w0 = (_SHIFTL((c), 24, 8) | \
2064 _SHIFTL(((len) - 1) / 8, 19, 5) | \
2065 _SHIFTL((ofs) / 8, 8, 8) | \
2066 _SHIFTL((idx), 0, 8)); \
2067 _g->words.w1 = (unsigned int)(adrs); \
2068})
2069
2070#define gsDma2p(c, adrs, len, idx, ofs) \
2071{ \
2072 (_SHIFTL((c), 24, 8) | \
2073 _SHIFTL(((len) - 1) / 8, 19, 5) | \
2074 _SHIFTL((ofs) / 8, 8, 8) | \
2075 _SHIFTL((idx), 0, 8)), \
2076 (unsigned int)(adrs) \
2077}
2078
2079#define gSPNoOp(pkt) gDma0p(pkt, G_SPNOOP, 0, 0)
2080#define gsSPNoOp() gsDma0p( G_SPNOOP, 0, 0)
2081
2140#define gSPMatrix(pkt, m, p) \
2141 gDma2p((pkt),G_MTX, (m), sizeof(Mtx), (p) ^ G_MTX_PUSH, 0)
2147#define gsSPMatrix(m, p) \
2148 gsDma2p( G_MTX, (m), sizeof(Mtx), (p) ^ G_MTX_PUSH, 0)
2149
2163#define gSPPopMatrixN(pkt, n, num) gDma2p((pkt), G_POPMTX, (num) * 64, 64, 2, 0)
2169#define gsSPPopMatrixN(n, num) gsDma2p( G_POPMTX, (num) * 64, 64, 2, 0)
2182#define gSPPopMatrix(pkt, n) gSPPopMatrixN((pkt), (n), 1)
2188#define gsSPPopMatrix(n) gsSPPopMatrixN( (n), 1)
2189
2215#define gSPVertex(pkt, v, n, v0) \
2216_DW({ \
2217 Gfx *_g = (Gfx *)(pkt); \
2218 \
2219 _g->words.w0 = (_SHIFTL(G_VTX, 24, 8) | \
2220 _SHIFTL((n), 12, 8) | \
2221 _SHIFTL((v0) + (n), 1, 7)); \
2222 _g->words.w1 = (unsigned int)(v); \
2223})
2224
2230#define gsSPVertex(v, n, v0) \
2231{ \
2232 (_SHIFTL(G_VTX, 24, 8) | \
2233 _SHIFTL((n), 12, 8) | \
2234 _SHIFTL((v0) + (n), 1, 7)), \
2235 (unsigned int)(v) \
2236}
2237
2238#define gSPViewport(pkt, v) \
2239 gDma2p((pkt), G_MOVEMEM, (v), sizeof(Vp), G_MV_VIEWPORT, 0)
2240#define gsSPViewport(v) \
2241 gsDma2p( G_MOVEMEM, (v), sizeof(Vp), G_MV_VIEWPORT, 0)
2242
2243/*
2244 * Display list control flow
2245 */
2246
2247#define _gSPDisplayListRaw(pkt,dl,hint) gDma1p(pkt, G_DL, dl, hint, G_DL_PUSH)
2248#define _gsSPDisplayListRaw( dl,hint) gsDma1p( G_DL, dl, hint, G_DL_PUSH)
2249
2250#define _gSPBranchListRaw(pkt,dl,hint) gDma1p(pkt, G_DL, dl, hint, G_DL_NOPUSH)
2251#define _gsSPBranchListRaw( dl,hint) gsDma1p( G_DL, dl, hint, G_DL_NOPUSH)
2252
2253#define _gSPEndDisplayListRaw(pkt,hint) gDma0p(pkt, G_ENDDL, 0, hint)
2254#define _gsSPEndDisplayListRaw(hint) gsDma0p( G_ENDDL, 0, hint)
2255
2256/*
2257 * Converts a total expected count of DL commands to a number of bytes to
2258 * initially NOT load into the DL command buffer.
2259 */
2260#define _DLHINTVALUE(count) \
2261 (((count) > 0 && ((count) % G_INPUT_BUFFER_CMDS) > 0) ? \
2262 ((G_INPUT_BUFFER_CMDS - ((count) % G_INPUT_BUFFER_CMDS)) << 3) : 0)
2263
2275#define gSPDisplayListHint(pkt, dl, count) _gSPDisplayListRaw(pkt, dl, _DLHINTVALUE(count))
2279#define gsSPDisplayListHint( dl, count) _gsSPDisplayListRaw( dl, _DLHINTVALUE(count))
2280
2284#define gSPBranchListHint(pkt, dl, count) _gSPBranchListRaw( pkt, dl, _DLHINTVALUE(count))
2285
2289#define gsSPBranchListHint( dl, count) _gsSPBranchListRaw( dl, _DLHINTVALUE(count))
2290
2294#define gSPEndDisplayListHint(pkt, count) _gSPEndDisplayListRaw( pkt, _DLHINTVALUE(count))
2295
2299#define gsSPEndDisplayListHint( count) _gsSPEndDisplayListRaw( _DLHINTVALUE(count))
2300
2304#define gSPDisplayList(pkt, dl) _gSPDisplayListRaw(pkt, dl, 0)
2308#define gsSPDisplayList( dl) _gsSPDisplayListRaw( dl, 0)
2309
2313#define gSPBranchList(pkt, dl) _gSPBranchListRaw( pkt, dl, 0)
2317#define gsSPBranchList( dl) _gsSPBranchListRaw( dl, 0)
2318
2322#define gSPEndDisplayList(pkt) _gSPEndDisplayListRaw( pkt, 0)
2326#define gsSPEndDisplayList( ) _gsSPEndDisplayListRaw( 0)
2327
2328
2335#define gSPLoadUcodeEx(pkt, uc_start, uc_dstart, uc_dsize) \
2336_DW({ \
2337 Gfx *_g = (Gfx *)(pkt); \
2338 \
2339 _g->words.w0 = _SHIFTL(G_RDPHALF_1, 24, 8); \
2340 _g->words.w1 = (unsigned int)(uc_dstart); \
2341 \
2342 _g = (Gfx *)(pkt); \
2343 \
2344 _g->words.w0 = (_SHIFTL(G_LOAD_UCODE, 24, 8) | \
2345 _SHIFTL((int)(uc_dsize) - 1, 0, 16)); \
2346 _g->words.w1 = (unsigned int)(uc_start); \
2347})
2348
2352#define gsSPLoadUcodeEx(uc_start, uc_dstart, uc_dsize) \
2353{ \
2354 _SHIFTL(G_RDPHALF_1, 24, 8), \
2355 (unsigned int)(uc_dstart), \
2356}, \
2357{ \
2358 (_SHIFTL(G_LOAD_UCODE, 24, 8) | \
2359 _SHIFTL((int)(uc_dsize) - 1, 0, 16)), \
2360 (unsigned int)(uc_start), \
2361}
2362
2363#define gSPLoadUcode(pkt, uc_start, uc_dstart) \
2364 gSPLoadUcodeEx((pkt), (uc_start), (uc_dstart), SP_UCODE_DATA_SIZE)
2365#define gsSPLoadUcode(uc_start, uc_dstart) \
2366 gsSPLoadUcodeEx((uc_start), (uc_dstart), SP_UCODE_DATA_SIZE)
2367
2368#define gSPLoadUcodeL(pkt, ucode) \
2369 gSPLoadUcode((pkt), OS_K0_TO_PHYSICAL(& ucode##TextStart), \
2370 OS_K0_TO_PHYSICAL(& ucode##DataStart))
2371#define gsSPLoadUcodeL(ucode) \
2372 gsSPLoadUcode( OS_K0_TO_PHYSICAL(& ucode##TextStart), \
2373 OS_K0_TO_PHYSICAL(& ucode##DataStart))
2374
2378#define gSPDma_io(pkt, flag, dmem, dram, size) \
2379_DW({ \
2380 Gfx *_g = (Gfx *)(pkt); \
2381 \
2382 _g->words.w0 = (_SHIFTL(G_DMA_IO, 24, 8) | \
2383 _SHIFTL((flag), 23, 1) | \
2384 _SHIFTL((dmem) / 8, 13, 10) | \
2385 _SHIFTL((size) - 1, 0, 12)); \
2386 _g->words.w1 = (unsigned int)(dram); \
2387})
2388
2392#define gsSPDma_io(flag, dmem, dram, size) \
2393{ \
2394 (_SHIFTL(G_DMA_IO, 24, 8) | \
2395 _SHIFTL((flag), 23, 1) | \
2396 _SHIFTL((dmem) / 8, 13, 10) | \
2397 _SHIFTL((size) - 1, 0, 12)), \
2398 (unsigned int)(dram) \
2399}
2400
2401#define gSPDmaRead(pkt,dmem,dram,size) gSPDma_io((pkt),0,(dmem),(dram),(size))
2402#define gsSPDmaRead(dmem,dram,size) gsSPDma_io( 0,(dmem),(dram),(size))
2403#define gSPDmaWrite(pkt,dmem,dram,size) gSPDma_io((pkt),1,(dmem),(dram),(size))
2404#define gsSPDmaWrite(dmem,dram,size) gsSPDma_io( 1,(dmem),(dram),(size))
2405
2416#define gSPMemset(pkt, dram, value, size) \
2417_DW({ \
2418 gImmp1(pkt, G_RDPHALF_1, ((value) & 0xFFFF)); \
2419 gDma0p(pkt, G_MEMSET, (dram), ((size) & 0xFFFFF0)); \
2420})
2421
2425#define gsSPMemset(pkt, dram, value, size) \
2426 gsImmp1(G_RDPHALF_1, ((value) & 0xFFFF)), \
2427 gsDma0p(G_MEMSET, (dram), ((size) & 0xFFFFF0))
2428
2432#define gImmp0(pkt, c) \
2433_DW({ \
2434 Gfx *_g = (Gfx *)(pkt); \
2435 \
2436 _g->words.w0 = _SHIFTL((c), 24, 8); \
2437})
2438
2442#define gsImmp0(c) \
2443{ \
2444 _SHIFTL((c), 24, 8) \
2445}
2446
2447#define gImmp1(pkt, c, p0) \
2448_DW({ \
2449 Gfx *_g = (Gfx *)(pkt); \
2450 \
2451 _g->words.w0 = _SHIFTL((c), 24, 8); \
2452 _g->words.w1 = (unsigned int)(p0); \
2453})
2454
2455#define gsImmp1(c, p0) \
2456{ \
2457 _SHIFTL((c), 24, 8), \
2458 (unsigned int)(p0) \
2459}
2460
2461#define gImmp2(pkt, c, p0, p1) \
2462_DW({ \
2463 Gfx *_g = (Gfx *)(pkt); \
2464 \
2465 _g->words.w0 = _SHIFTL((c), 24, 8); \
2466 _g->words.w1 = (_SHIFTL((p0), 16, 16) | \
2467 _SHIFTL((p1), 8, 8)); \
2468})
2469
2470#define gsImmp2(c, p0, p1) \
2471{ \
2472 _SHIFTL((c), 24, 8), \
2473 (_SHIFTL((p0), 16, 16) | \
2474 _SHIFTL((p1), 8, 8)) \
2475}
2476
2477#define gImmp3(pkt, c, p0, p1, p2) \
2478_DW({ \
2479 Gfx *_g = (Gfx *)(pkt); \
2480 \
2481 _g->words.w0 = _SHIFTL((c), 24, 8); \
2482 _g->words.w1 = (_SHIFTL((p0), 16, 16) | \
2483 _SHIFTL((p1), 8, 8) | \
2484 _SHIFTL((p2), 0, 8)); \
2485})
2486
2487#define gsImmp3(c, p0, p1, p2) \
2488{ \
2489 _SHIFTL((c), 24, 8), \
2490 (_SHIFTL((p0), 16, 16) | \
2491 _SHIFTL((p1), 8, 8) | \
2492 _SHIFTL((p2), 0, 8)) \
2493}
2494
2495#define gImmp21(pkt, c, p0, p1, dat) \
2496_DW({ \
2497 Gfx *_g = (Gfx *)(pkt); \
2498 \
2499 _g->words.w0 = (_SHIFTL((c), 24, 8) | \
2500 _SHIFTL((p0), 8, 16) | \
2501 _SHIFTL((p1), 0, 8)); \
2502 _g->words.w1 = (unsigned int) (dat); \
2503})
2504
2505#define gsImmp21(c, p0, p1, dat) \
2506{ \
2507 (_SHIFTL((c), 24, 8) | \
2508 _SHIFTL((p0), 8, 16) | \
2509 _SHIFTL((p1), 0, 8)), \
2510 (unsigned int) (dat) \
2511}
2512
2513#define gMoveWd(pkt, index, offset, data) \
2514 gDma1p((pkt), G_MOVEWORD, data, (offset & 0xFFF), index)
2515#define gsMoveWd( index, offset, data) \
2516 gsDma1p( G_MOVEWORD, data, (offset & 0xFFF), index)
2517
2518#define gMoveHalfwd(pkt, index, offset, data) \
2519 gDma1p((pkt), G_MOVEWORD, data, (offset & 0xFFF) | G_MW_HALFWORD_FLAG, index)
2520#define gsMoveHalfwd( index, offset, data) \
2521 gsDma1p( G_MOVEWORD, data, (offset & 0xFFF) | G_MW_HALFWORD_FLAG, index)
2522
2523
2524/*
2525 * Triangle commands
2526 */
2527
2528#define __gsSP1Triangle_w1(v0, v1, v2) \
2529 (_SHIFTL((v0) * 2, 16, 8) | \
2530 _SHIFTL((v1) * 2, 8, 8) | \
2531 _SHIFTL((v2) * 2, 0, 8))
2532
2533#define __gsSP1Triangle_w1f(v0, v1, v2, flag) \
2534 (((flag) == 0) ? __gsSP1Triangle_w1(v0, v1, v2) : \
2535 ((flag) == 1) ? __gsSP1Triangle_w1(v1, v2, v0) : \
2536 __gsSP1Triangle_w1(v2, v0, v1))
2537
2538#define __gsSP1Quadrangle_w1f(v0, v1, v2, v3, flag) \
2539 (((flag) == 0) ? __gsSP1Triangle_w1(v0, v1, v2) : \
2540 ((flag) == 1) ? __gsSP1Triangle_w1(v1, v2, v3) : \
2541 ((flag) == 2) ? __gsSP1Triangle_w1(v2, v3, v0) : \
2542 __gsSP1Triangle_w1(v3, v0, v1))
2543
2544#define __gsSP1Quadrangle_w2f(v0, v1, v2, v3, flag) \
2545 (((flag) == 0) ? __gsSP1Triangle_w1(v0, v2, v3) : \
2546 ((flag) == 1) ? __gsSP1Triangle_w1(v1, v3, v0) : \
2547 ((flag) == 2) ? __gsSP1Triangle_w1(v2, v0, v1) : \
2548 __gsSP1Triangle_w1(v3, v1, v2))
2549
2550
2554#define gSP1Triangle(pkt, v0, v1, v2, flag) \
2555_DW({ \
2556 Gfx *_g = (Gfx *)(pkt); \
2557 _g->words.w0 = (_SHIFTL(G_TRI1, 24, 8) | \
2558 __gsSP1Triangle_w1f(v0, v1, v2, flag)); \
2559 _g->words.w1 = 0; \
2560})
2564#define gsSP1Triangle(v0, v1, v2, flag) \
2565{ \
2566 (_SHIFTL(G_TRI1, 24, 8) | \
2567 __gsSP1Triangle_w1f(v0, v1, v2, flag)), \
2568 0 \
2569}
2570
2574#define gSP1Quadrangle(pkt, v0, v1, v2, v3, flag) \
2575_DW({ \
2576 Gfx *_g = (Gfx *)(pkt); \
2577 _g->words.w0 = (_SHIFTL(G_QUAD, 24, 8) | \
2578 __gsSP1Quadrangle_w1f(v0, v1, v2, v3, flag)); \
2579 _g->words.w1 = (__gsSP1Quadrangle_w2f(v0, v1, v2, v3, flag)); \
2580})
2581
2585#define gsSP1Quadrangle(v0, v1, v2, v3, flag) \
2586{ \
2587 (_SHIFTL(G_QUAD, 24, 8) | \
2588 __gsSP1Quadrangle_w1f(v0, v1, v2, v3, flag)), \
2589 __gsSP1Quadrangle_w2f(v0, v1, v2, v3, flag) \
2590}
2591
2595#define gSP2Triangles(pkt, v00, v01, v02, flag0, v10, v11, v12, flag1) \
2596_DW({ \
2597 Gfx *_g = (Gfx *)(pkt); \
2598 _g->words.w0 = (_SHIFTL(G_TRI2, 24, 8) | \
2599 __gsSP1Triangle_w1f(v00, v01, v02, flag0)); \
2600 _g->words.w1 = __gsSP1Triangle_w1f(v10, v11, v12, flag1); \
2601})
2602
2606#define gsSP2Triangles(v00, v01, v02, flag0, v10, v11, v12, flag1) \
2607{ \
2608 (_SHIFTL(G_TRI2, 24, 8) | \
2609 __gsSP1Triangle_w1f(v00, v01, v02, flag0)), \
2610 __gsSP1Triangle_w1f(v10, v11, v12, flag1) \
2611}
2612
2613/*
2614 * 5 Triangles base commands
2615 */
2616#define _gSP5Triangles(pkt, cmd, v1, v2, v3, v4, v5, v6, v7) \
2617_DW({ \
2618 Gfx *_g = (Gfx *)(pkt); \
2619 _g->words.w0 = (_SHIFTL(cmd, 24, 8) | \
2620 _SHIFTL((v1)*2, 16, 8) | \
2621 _SHIFTL((v2)*2, 8, 8) | \
2622 _SHIFTL((v3)*2, 0, 8)); \
2623 _g->words.w1 = (_SHIFTL((v4)*2, 24, 8) | \
2624 _SHIFTL((v5)*2, 16, 8) | \
2625 _SHIFTL((v6)*2, 8, 8) | \
2626 _SHIFTL((v7)*2, 0, 8)); \
2627})
2628#define _gsSP5Triangles(cmd, v1, v2, v3, v4, v5, v6, v7) \
2629{ \
2630 (_SHIFTL(cmd, 24, 8) | \
2631 _SHIFTL((v1)*2, 16, 8) | \
2632 _SHIFTL((v2)*2, 8, 8) | \
2633 _SHIFTL((v3)*2, 0, 8)), \
2634 (_SHIFTL((v4)*2, 24, 8) | \
2635 _SHIFTL((v5)*2, 16, 8) | \
2636 _SHIFTL((v6)*2, 8, 8) | \
2637 _SHIFTL((v7)*2, 0, 8)) \
2638}
2649#define gSPTriStrip(pkt, v1, v2, v3, v4, v5, v6, v7) \
2650 _gSP5Triangles(pkt, G_TRISTRIP, v1, v2, v3, v4, v5, v6, v7)
2654#define gsSPTriStrip(v1, v2, v3, v4, v5, v6, v7) \
2655 _gsSP5Triangles(G_TRISTRIP, v1, v2, v3, v4, v5, v6, v7)
2661#define gSPTriFan(pkt, v1, v2, v3, v4, v5, v6, v7) \
2662 _gSP5Triangles(pkt, G_TRIFAN, v1, v2, v3, v4, v5, v6, v7)
2666#define gsSPTriFan(v1, v2, v3, v4, v5, v6, v7) \
2667 _gsSP5Triangles(G_TRIFAN, v1, v2, v3, v4, v5, v6, v7)
2668
2669
2670/*
2671 * Moveword commands
2672 */
2673#ifdef F3DEX2_SEGMENTS
2674/* Use F3DEX2 style segment setup binary encoding. F3DEX3 supports both the
2675F3DEX2 encoding and the F3DEX3 encoding, but the former does not have the
2676relative segment resolution behavior. */
2677#define gSPSegment(pkt, segment, base) \
2678 gMoveWd(pkt, G_MW_SEGMENT, (segment) * 4, (base))
2679#define gsSPSegment(segment, base) \
2680 gsMoveWd( G_MW_SEGMENT, (segment) * 4, (base))
2681#else
2682/* F3DEX3 style segment setup, which resolves segment addresses relative to
2683other segments. */
2684#define gSPSegment(pkt, segment, base) \
2685 gDma1p((pkt), G_RELSEGMENT, (base), ((segment) * 4) & 0xFFF, G_MW_SEGMENT)
2686#define gsSPSegment(segment, base) \
2687 gsDma1p( G_RELSEGMENT, (base), ((segment) * 4) & 0xFFF, G_MW_SEGMENT)
2688#endif
2689
2690#define gSPPerspNormalize(pkt, s) gMoveHalfwd(pkt, G_MW_FX, G_MWO_PERSPNORM, (s))
2691#define gsSPPerspNormalize(s) gsMoveHalfwd( G_MW_FX, G_MWO_PERSPNORM, (s))
2692
2698#define gSPClipRatio(pkt, r) gSPNoOp(pkt)
2704#define gsSPClipRatio(r) gsSPNoOp()
2705
2712#define gSPForceMatrix(pkt, mptr) gSPNoOp(pkt)
2718#define gsSPForceMatrix(mptr) gsSPNoOp()
2719
2755#define gSPAmbOcclusionAmb(pkt, amb) gMoveHalfwd(pkt, G_MW_FX, G_MWO_AO_AMBIENT, amb)
2759#define gsSPAmbOcclusionAmb(amb) gsMoveHalfwd( G_MW_FX, G_MWO_AO_AMBIENT, amb)
2763#define gSPAmbOcclusionDir(pkt, dir) gMoveHalfwd(pkt, G_MW_FX, G_MWO_AO_DIRECTIONAL, dir)
2767#define gsSPAmbOcclusionDir(dir) gsMoveHalfwd( G_MW_FX, G_MWO_AO_DIRECTIONAL, dir)
2771#define gSPAmbOcclusionPoint(pkt, point) gMoveHalfwd(pkt, G_MW_FX, G_MWO_AO_POINT, point)
2775#define gsSPAmbOcclusionPoint(point) gsMoveHalfwd( G_MW_FX, G_MWO_AO_POINT, point)
2776
2777#define gSPAmbOcclusionAmbDir(pkt, amb, dir) \
2778 gMoveWd(pkt, G_MW_FX, G_MWO_AO_AMBIENT, \
2779 (_SHIFTL((amb), 16, 16) | _SHIFTL((dir), 0, 16)))
2780#define gsSPAmbOcclusionAmbDir(amb, dir) \
2781 gsMoveWd(G_MW_FX, G_MWO_AO_AMBIENT, \
2782 (_SHIFTL((amb), 16, 16) | _SHIFTL((dir), 0, 16)))
2783#define gSPAmbOcclusionDirPoint(pkt, dir, point) \
2784 gMoveWd(pkt, G_MW_FX, G_MWO_AO_DIRECTIONAL, \
2785 (_SHIFTL((dir), 16, 16) | _SHIFTL((point), 0, 16)))
2786#define gsSPAmbOcclusionDirPoint(dir, point) \
2787 gsMoveWd(G_MW_FX, G_MWO_AO_DIRECTIONAL, \
2788 (_SHIFTL((dir), 16, 16) | _SHIFTL((point), 0, 16)))
2789
2790#define gSPAmbOcclusion(pkt, amb, dir, point) \
2791_DW({ \
2792 gSPAmbOcclusionAmbDir(pkt, amb, dir); \
2793 gSPAmbOcclusionPoint(pkt, point); \
2794})
2795#define gsSPAmbOcclusion(amb, dir, point) \
2796 gsSPAmbOcclusionAmbDir(amb, dir), \
2797 gsSPAmbOcclusionPoint(point)
2798
2832#define gSPFresnelScale(pkt, scale) \
2833 gMoveHalfwd(pkt, G_MW_FX, G_MWO_FRESNEL_SCALE, scale)
2837#define gsSPFresnelScale(scale) \
2838 gsMoveHalfwd(G_MW_FX, G_MWO_FRESNEL_SCALE, scale)
2842#define gSPFresnelOffset(pkt, offset) \
2843 gMoveHalfwd(pkt, G_MW_FX, G_MWO_FRESNEL_OFFSET, offset)
2847#define gsSPFresnelOffset(offset) \
2848 gsMoveHalfwd(G_MW_FX, G_MWO_FRESNEL_OFFSET, offset)
2852#define gSPFresnel(pkt, scale, offset) \
2853 gMoveWd(pkt, G_MW_FX, G_MWO_FRESNEL_SCALE, \
2854 (_SHIFTL((scale), 16, 16) | _SHIFTL((offset), 0, 16)))
2858#define gsSPFresnel(scale, offset) \
2859 gsMoveWd(G_MW_FX, G_MWO_FRESNEL_SCALE, \
2860 (_SHIFTL((scale), 16, 16) | _SHIFTL((offset), 0, 16)))
2861
2870#define gSPAttrOffsetST(pkt, s, t) \
2871 gMoveWd(pkt, G_MW_FX, G_MWO_ATTR_OFFSET_S, \
2872 (_SHIFTL((s), 16, 16) | _SHIFTL((t), 0, 16)))
2876#define gsSPAttrOffsetST(s, t) \
2877 gsMoveWd(G_MW_FX, G_MWO_ATTR_OFFSET_S, \
2878 (_SHIFTL((s), 16, 16) | _SHIFTL((t), 0, 16)))
2879
2880
2917#define gSPAlphaCompareCull(pkt, mode, thresh) \
2918 gMoveHalfwd(pkt, G_MW_FX, G_MWO_ALPHA_COMPARE_CULL, \
2919 (_SHIFTL((mode), 8, 8) | _SHIFTL((thresh), 0, 8)))
2923#define gsSPAlphaCompareCull(mode, thresh) \
2924 gsMoveHalfwd(G_MW_FX, G_MWO_ALPHA_COMPARE_CULL, \
2925 (_SHIFTL((mode), 8, 8) | _SHIFTL((thresh), 0, 8)))
2926
2962#define gSPNormalsMode(pkt, mode) \
2963 gMoveHalfwd(pkt, G_MW_FX, G_MWO_NORMALS_MODE, (mode) & 0xFF)
2967#define gsSPNormalsMode(mode) \
2968 gsMoveHalfwd(G_MW_FX, G_MWO_NORMALS_MODE, (mode) & 0xFF)
2969
2998#define gSPDontSkipTexLoadsAcross(pkt) \
2999 gMoveWd(pkt, G_MW_FX, G_MWO_LAST_MAT_DL_ADDR, 0xFFFFFFFF)
3003#define gsSPDontSkipTexLoadsAcross() \
3004 gsMoveWd(G_MW_FX, G_MWO_LAST_MAT_DL_ADDR, 0xFFFFFFFF)
3005
3006typedef union {
3007 struct {
3008 s16 intPart[3][4];
3009 u16 fracPart[3][4];
3010 };
3011 long long int force_structure_alignment;
3012} MITMtx;
3013
3027#define gSPMITMatrix(pkt, mit) \
3028 gDma2p((pkt), G_MOVEMEM, (mit), sizeof(MITMtx), G_MV_MMTX, 0x80)
3032#define gsSPMITMatrix(mtx) \
3033 gsDma2p( G_MOVEMEM, (mit), sizeof(MITMtx), G_MV_MMTX, 0x80)
3034
3035
3085# define gSPModifyVertex(pkt, vtx, where, val) \
3086_DW({ \
3087 Gfx *_g = (Gfx *)(pkt); \
3088 \
3089 _g->words.w0 = (_SHIFTL(G_MODIFYVTX, 24, 8) | \
3090 _SHIFTL((where), 16, 8) | \
3091 _SHIFTL((vtx) * 2, 0, 16)); \
3092 _g->words.w1 = (unsigned int)(val); \
3093})
3099# define gsSPModifyVertex(vtx, where, val) \
3100{ \
3101 (_SHIFTL(G_MODIFYVTX, 24, 8) | \
3102 _SHIFTL((where), 16, 8) | \
3103 _SHIFTL((vtx) * 2, 0, 16)), \
3104 (unsigned int)(val) \
3105}
3106
3107/*
3108 * Display list optimization / object culling
3109 */
3110
3116#define gSPCullDisplayList(pkt,vstart,vend) \
3117_DW({ \
3118 Gfx *_g = (Gfx *)(pkt); \
3119 \
3120 _g->words.w0 = (_SHIFTL(G_CULLDL, 24, 8) | \
3121 _SHIFTL((vstart) * 2, 0, 16)); \
3122 _g->words.w1 = _SHIFTL((vend) * 2, 0, 16); \
3123})
3127#define gsSPCullDisplayList(vstart,vend) \
3128{ \
3129 (_SHIFTL(G_CULLDL, 24, 8) | \
3130 _SHIFTL((vstart) * 2, 0, 16)), \
3131 _SHIFTL((vend) * 2, 0, 16) \
3132}
3133
3134/*
3135 * gSPBranchLessZ Branch DL if (vtx.z) less than or equal (zval).
3136 * Note that this uses W in F3DZEX / CFG_G_BRANCH_W, in which case all the
3137 * Z calculations below are wrong and raw values must be used.
3138 *
3139 * dl = DL branch to
3140 * vtx = Vertex
3141 * zval = Screen depth
3142 * near = Near plane
3143 * far = Far plane
3144 * flag = G_BZ_PERSP or G_BZ_ORTHO
3145 */
3146
3147/* From gu.h */
3148#ifndef FTOFIX32
3149# define FTOFIX32(x) (long)((x) * (float)0x00010000)
3150#endif
3151
3152#define G_BZ_PERSP 0
3153#define G_BZ_ORTHO 1
3154
3155#define G_DEPTOZSrg(zval, near, far, flag, zmin, zmax) \
3156 (((unsigned int)FTOFIX32(((flag) == G_BZ_PERSP ? \
3157 (1.0f - (float)(near) / (float)(zval)) / \
3158 (1.0f - (float)(near) / (float)(far )) : \
3159 ((float)(zval) - (float)(near)) / \
3160 ((float)(far ) - (float)(near))))) * \
3161 (((int)((zmax) - (zmin))) & ~1) + (int)FTOFIX32(zmin))
3162
3163#define G_DEPTOZS(zval, near, far, flag) \
3164 G_DEPTOZSrg(zval, near, far, flag, 0, G_MAXZ)
3165
3166#define gSPBranchLessZrg(pkt, dl, vtx, zval, near, far, flag, zmin, zmax) \
3167_DW({ \
3168 Gfx *_g = (Gfx *)(pkt); \
3169 \
3170 _g->words.w0 = _SHIFTL(G_RDPHALF_1, 24, 8); \
3171 _g->words.w1 = (unsigned int)(dl); \
3172 \
3173 _g = (Gfx *)(pkt); \
3174 \
3175 _g->words.w0 = (_SHIFTL(G_BRANCH_Z, 24, 8) | \
3176 _SHIFTL((vtx) * 5, 12, 12) | \
3177 _SHIFTL((vtx) * 2, 0, 12)); \
3178 _g->words.w1 = G_DEPTOZSrg(zval, near, far, flag, zmin, zmax); \
3179})
3180
3181#define gsSPBranchLessZrg(dl, vtx, zval, near, far, flag, zmin, zmax) \
3182{ \
3183 _SHIFTL(G_RDPHALF_1, 24, 8), \
3184 (unsigned int)(dl), \
3185}, \
3186{ \
3187 (_SHIFTL(G_BRANCH_Z, 24, 8) | \
3188 _SHIFTL((vtx) * 5, 12, 12) | \
3189 _SHIFTL((vtx) * 2, 0, 12)), \
3190 G_DEPTOZSrg(zval, near, far, flag, zmin, zmax), \
3191}
3192
3193#define gSPBranchLessZ(pkt, dl, vtx, zval, near, far, flag) \
3194 gSPBranchLessZrg(pkt, dl, vtx, zval, near, far, flag, 0, G_MAXZ)
3195#define gsSPBranchLessZ(dl, vtx, zval, near, far, flag) \
3196 gsSPBranchLessZrg(dl, vtx, zval, near, far, flag, 0, G_MAXZ)
3197
3205#define gSPBranchLessZraw(pkt, dl, vtx, zval) \
3206_DW({ \
3207 Gfx *_g = (Gfx *)(pkt); \
3208 \
3209 _g->words.w0 = _SHIFTL(G_RDPHALF_1, 24, 8); \
3210 _g->words.w1 = (unsigned int)(dl); \
3211 \
3212 _g = (Gfx *)(pkt); \
3213 \
3214 _g->words.w0 = (_SHIFTL(G_BRANCH_Z, 24, 8) | \
3215 _SHIFTL((vtx) * 5, 12, 12) | \
3216 _SHIFTL((vtx) * 2, 0, 12)); \
3217 _g->words.w1 = (unsigned int)(zval); \
3218})
3219
3223#define gsSPBranchLessZraw(dl, vtx, zval) \
3224{ \
3225 _SHIFTL(G_RDPHALF_1, 24, 8), \
3226 (unsigned int)(dl), \
3227}, \
3228{ \
3229 (_SHIFTL(G_BRANCH_Z, 24, 8) | \
3230 _SHIFTL((vtx) * 5, 12, 12) | \
3231 _SHIFTL((vtx) * 2, 0, 12)), \
3232 (unsigned int)(zval), \
3233}
3234
3235
3236/*
3237 * Lighting Commands
3238 */
3239
3240#define NUML(n) ((n) * 0x10)
3241/*
3242 * F3DEX3 properly supports zero lights, so there is no need to use these macros
3243 * anymore.
3244 */
3245#define NUMLIGHTS_0 0
3246#define NUMLIGHTS_1 1
3247#define NUMLIGHTS_2 2
3248#define NUMLIGHTS_3 3
3249#define NUMLIGHTS_4 4
3250#define NUMLIGHTS_5 5
3251#define NUMLIGHTS_6 6
3252#define NUMLIGHTS_7 7
3253#define NUMLIGHTS_8 8
3254#define NUMLIGHTS_9 9
3255
3260#define gSPNumLights(pkt, n) \
3261 gMoveWd(pkt, G_MW_NUMLIGHT, G_MWO_NUMLIGHT, NUML(n))
3265#define gsSPNumLights(n) \
3266 gsMoveWd( G_MW_NUMLIGHT, G_MWO_NUMLIGHT, NUML(n))
3267
3268/* There is also no need to use these macros. */
3269#define LIGHT_1 1
3270#define LIGHT_2 2
3271#define LIGHT_3 3
3272#define LIGHT_4 4
3273#define LIGHT_5 5
3274#define LIGHT_6 6
3275#define LIGHT_7 7
3276#define LIGHT_8 8
3277#define LIGHT_9 9
3278#define LIGHT_10 10
3279
3280#define _LIGHT_TO_OFFSET(n) (((n) - 1) * 0x10 + 0x10) /* The + 0x10 skips cam pos and lookat */
3281
3293#define gSPLight(pkt, l, n) \
3294 gDma2p((pkt), G_MOVEMEM, (l), sizeof(Light), G_MV_LIGHT, _LIGHT_TO_OFFSET(n))
3298#define gsSPLight(l, n) \
3299 gsDma2p( G_MOVEMEM, (l), sizeof(Light), G_MV_LIGHT, _LIGHT_TO_OFFSET(n))
3300
3305#define gSPAmbient(pkt, l, n) \
3306 gDma2p((pkt), G_MOVEMEM, (l), sizeof(Ambient), G_MV_LIGHT, _LIGHT_TO_OFFSET(n))
3310#define gsSPAmbient(l, n) \
3311 gsDma2p( G_MOVEMEM, (l), sizeof(Ambient), G_MV_LIGHT, _LIGHT_TO_OFFSET(n))
3312
3321#define gSPLightColor(pkt, n, col) \
3322_DW({ \
3323 gMoveWd(pkt, G_MW_LIGHTCOL, ((((n) - 1) * 0x10) + 0), ((col) & 0xFFFFFF00)); \
3324 gMoveWd(pkt, G_MW_LIGHTCOL, ((((n) - 1) * 0x10) + 4), ((col) & 0xFFFFFF00)); \
3325})
3329#define gsSPLightColor(n, col) \
3330 gsMoveWd(G_MW_LIGHTCOL, ((((n) - 1) * 0x10) + 0), ((col) & 0xFFFFFF00)), \
3331 gsMoveWd(G_MW_LIGHTCOL, ((((n) - 1) * 0x10) + 4), ((col) & 0xFFFFFF00))
3332/*
3333 * Version for point lights. (col1 & 0xFF) must be set to the point light constant
3334 * factor (must be nonzero), and (col2 & 0xFF) must be set to the point light
3335 * linear factor.
3336 * n should be an integer 1-10 to apply to light 0-9.
3337 */
3338#define _gSPLightColor2(pkt, n, col1, col2) \
3339_DW({\
3340 gMoveWd(pkt, G_MW_LIGHTCOL, ((((n) - 1) * 0x10) + 0), col1); \
3341 gMoveWd(pkt, G_MW_LIGHTCOL, ((((n) - 1) * 0x10) + 4), col2); \
3342})
3343#define _gsSPLightColor2(n, col1, col2) \
3344 gsMoveWd(G_MW_LIGHTCOL, ((((n) - 1) * 0x10) + 0), col1), \
3345 gsMoveWd(G_MW_LIGHTCOL, ((((n) - 1) * 0x10) + 4), col2)
3346
3347
3372#define gSPSetLights(pkt, n, name) \
3373_DW({ \
3374 gSPNumLights(pkt, n); \
3375 gDma2p((pkt), G_MOVEMEM, &(name), (n) * 0x10 + 8, G_MV_LIGHT, 0x10); \
3376})
3380#define gsSPSetLights(n, name) \
3381 gsSPNumLights(n), \
3382 gsDma2p(G_MOVEMEM, &(name), (n) * 0x10 + 8, G_MV_LIGHT, 0x10)
3383
3384#define gSPSetLights0(pkt, name) gSPSetLights(pkt, 0, name)
3385#define gsSPSetLights0(name) gsSPSetLights( 0, name)
3386#define gSPSetLights1(pkt, name) gSPSetLights(pkt, 1, name)
3387#ifdef KAZE_GBI_HACKS
3388#define gsSPSetLights1(name) gsSPNoOp()
3389#else
3390#define gsSPSetLights1(name) gsSPSetLights( 1, name)
3391#endif
3392#define gSPSetLights2(pkt, name) gSPSetLights(pkt, 2, name)
3393#define gsSPSetLights2(name) gsSPSetLights( 2, name)
3394#define gSPSetLights3(pkt, name) gSPSetLights(pkt, 3, name)
3395#define gsSPSetLights3(name) gsSPSetLights( 3, name)
3396#define gSPSetLights4(pkt, name) gSPSetLights(pkt, 4, name)
3397#define gsSPSetLights4(name) gsSPSetLights( 4, name)
3398#define gSPSetLights5(pkt, name) gSPSetLights(pkt, 5, name)
3399#define gsSPSetLights5(name) gsSPSetLights( 5, name)
3400#define gSPSetLights6(pkt, name) gSPSetLights(pkt, 6, name)
3401#define gsSPSetLights6(name) gsSPSetLights( 6, name)
3402#define gSPSetLights7(pkt, name) gSPSetLights(pkt, 7, name)
3403#define gsSPSetLights7(name) gsSPSetLights( 7, name)
3404#define gSPSetLights8(pkt, name) gSPSetLights(pkt, 8, name)
3405#define gsSPSetLights8(name) gsSPSetLights( 8, name)
3406#define gSPSetLights9(pkt, name) gSPSetLights(pkt, 9, name)
3407#define gsSPSetLights9(name) gsSPSetLights( 9, name)
3408
3409
3414#define gSPCameraWorld(pkt, cam) \
3415 gDma2p((pkt), G_MOVEMEM, (cam), sizeof(PlainVtx), G_MV_LIGHT, 0)
3419#define gsSPCameraWorld(cam) \
3420 gsDma2p( G_MOVEMEM, (cam), sizeof(PlainVtx), G_MV_LIGHT, 0)
3421
3422
3427#define gSPLookAt(pkt, la) \
3428 gDma2p((pkt), G_MOVEMEM, (la), sizeof(LookAt), G_MV_LIGHT, 8)
3432#define gsSPLookAt(la) \
3433 gsDma2p( G_MOVEMEM, (la), sizeof(LookAt), G_MV_LIGHT, 8)
3434
3444#define gSPLookAtX(pkt, l) gSPLookAt(pkt, l)
3448#define gsSPLookAtX(l) gsSPLookAt(l)
3452#define gSPLookAtY(pkt, l) gSPNoOp(pkt)
3456#define gsSPLookAtY(l) gsSPNoOp()
3457
3458
3459#define gDPSetHilite1Tile(pkt, tile, hilite, width, height) \
3460 gDPSetTileSize(pkt, tile, \
3461 (hilite)->h.x1 & 0xFFF, \
3462 (hilite)->h.y1 & 0xFFF, \
3463 ((((width) - 1) * 4) + (hilite)->h.x1) & 0xFFF, \
3464 ((((height) - 1) * 4) + (hilite)->h.y1) & 0xFFF)
3465#define gsDPSetHilite1Tile(tile, hilite, width, height) \
3466 gsDPSetTileSize(tile, \
3467 (hilite)->h.x1 & 0xFFF, \
3468 (hilite)->h.y1 & 0xFFF, \
3469 ((((width) - 1) * 4) + (hilite)->h.x1) & 0xFFF, \
3470 ((((height) - 1) * 4) + (hilite)->h.y1) & 0xFFF)
3471
3472#define gDPSetHilite2Tile(pkt, tile, hilite, width, height) \
3473 gDPSetTileSize(pkt, tile, \
3474 (hilite)->h.x2 & 0xFFF, \
3475 (hilite)->h.y2 & 0xFFF, \
3476 ((((width) - 1) * 4) + (hilite)->h.x2) & 0xFFF, \
3477 ((((height) - 1) * 4) + (hilite)->h.y2) & 0xFFF)
3478#define gsDPSetHilite2Tile(tile, hilite, width, height) \
3479 gsDPSetTileSize(tile, \
3480 (hilite)->h.x2 & 0xFFF, \
3481 (hilite)->h.y2 & 0xFFF, \
3482 ((((width) - 1) * 4) + (hilite)->h.x2) & 0xFFF, \
3483 ((((height) - 1) * 4) + (hilite)->h.y2) & 0xFFF)
3484
3485
3498#define gSPOcclusionPlane(pkt, o) \
3499 gDma2p((pkt), G_MOVEMEM, (o), sizeof(OcclusionPlane), G_MV_LIGHT, \
3500 (G_MAX_LIGHTS * 0x10) + 0x18)
3504#define gsSPOcclusionPlane(o) \
3505 gsDma2p( G_MOVEMEM, (o), sizeof(OcclusionPlane), G_MV_LIGHT, \
3506 (G_MAX_LIGHTS * 0x10) + 0x18)
3507
3508
3522#define gSPFogFactor(pkt, fm, fo) \
3523 gMoveWd(pkt, G_MW_FOG, G_MWO_FOG, \
3524 (_SHIFTL(fm, 16, 16) | _SHIFTL(fo, 0, 16)))
3525
3529#define gsSPFogFactor(fm, fo) \
3530 gsMoveWd(G_MW_FOG, G_MWO_FOG, \
3531 (_SHIFTL(fm, 16, 16) | _SHIFTL(fo, 0, 16)))
3532
3533#define gSPFogPosition(pkt, min, max) \
3534 gMoveWd(pkt, G_MW_FOG, G_MWO_FOG, \
3535 (_SHIFTL((128000 / ((max) - (min))), 16, 16) | \
3536 _SHIFTL(((500 - (min)) * 256 / ((max) - (min))), 0, 16)))
3537
3538#define gsSPFogPosition(min, max) \
3539 gsMoveWd(G_MW_FOG, G_MWO_FOG, \
3540 (_SHIFTL((128000 / ((max) - (min))), 16, 16) | \
3541 _SHIFTL(((500 - (min)) * 256 / ((max) - (min))), 0, 16)))
3542
3543
3547#define gSPTexture(pkt, s, t, level, tile, on) \
3548_DW({ \
3549 Gfx *_g = (Gfx *)(pkt); \
3550 \
3551 _g->words.w0 = (_SHIFTL(G_TEXTURE, 24, 8) | \
3552 _SHIFTL((level), 11, 3) | \
3553 _SHIFTL((tile), 8, 3) | \
3554 _SHIFTL((on), 1, 7)); \
3555 _g->words.w1 = (_SHIFTL((s), 16, 16) | \
3556 _SHIFTL((t), 0, 16)); \
3557})
3561#define gsSPTexture(s, t, level, tile, on) \
3562{ \
3563 (_SHIFTL(G_TEXTURE, 24, 8) | \
3564 _SHIFTL((level), 11, 3) | \
3565 _SHIFTL((tile), 8, 3) | \
3566 _SHIFTL((on), 1, 7)), \
3567 (_SHIFTL((s), 16, 16) | \
3568 _SHIFTL((t), 0, 16)) \
3569}
3570
3575#define gSPTextureL(pkt, s, t, level, bowtie, tile, on) \
3576 gSPTexture(pkt, s, t, level, tile, on)
3580#define gsSPTextureL(s, t, level, bowtie, tile, on) \
3581 gsSPTexture(s, t, level, tile, on)
3582
3591#define gSPGeometryMode(pkt, c, s) \
3592_DW({ \
3593 Gfx *_g = (Gfx *)(pkt); \
3594 \
3595 _g->words.w0 = (_SHIFTL(G_GEOMETRYMODE, 24, 8) | \
3596 _SHIFTL(~(u32)(c), 0, 24)); \
3597 _g->words.w1 = (u32)(s); \
3598})
3599
3603#define gsSPGeometryMode(c, s) \
3604{ \
3605 (_SHIFTL(G_GEOMETRYMODE, 24, 8) | \
3606 _SHIFTL(~(u32)(c), 0, 24)), \
3607 (u32)(s) \
3608}
3609
3610#define gSPSetGeometryMode(pkt, word) gSPGeometryMode((pkt), 0, (word))
3611#define gsSPSetGeometryMode(word) gsSPGeometryMode( 0, (word))
3612#define gSPClearGeometryMode(pkt, word) gSPGeometryMode((pkt), (word), 0)
3613#define gsSPClearGeometryMode(word) gsSPGeometryMode( (word), 0)
3614#define gSPLoadGeometryMode(pkt, word) gSPGeometryMode((pkt), -1, (word))
3615#define gsSPLoadGeometryMode(word) gsSPGeometryMode( -1, (word))
3616
3617#define gsSPGeometryModeSetFirst(c, s) gsSPGeometryMode(c, s)
3618
3619#define gSPSetOtherMode(pkt, cmd, sft, len, data) \
3620_DW({ \
3621 Gfx *_g = (Gfx *)(pkt); \
3622 \
3623 _g->words.w0 = (_SHIFTL(cmd, 24, 8) | \
3624 _SHIFTL(32 - (sft) - (len), 8, 8) | \
3625 _SHIFTL((len) - 1, 0, 8)); \
3626 _g->words.w1 = (unsigned int)(data); \
3627})
3628
3629#define gsSPSetOtherMode(cmd, sft, len, data) \
3630{ \
3631 (_SHIFTL(cmd, 24, 8) | \
3632 _SHIFTL(32 - (sft) - (len), 8, 8) | \
3633 _SHIFTL((len) - 1, 0, 8)), \
3634 (unsigned int)(data) \
3635}
3636
3640#define gDPPipelineMode(pkt, mode) \
3641 gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_PIPELINE, 1, mode)
3645#define gsDPPipelineMode(mode) \
3646 gsSPSetOtherMode( G_SETOTHERMODE_H, G_MDSFT_PIPELINE, 1, mode)
3647
3648#define gDPSetCycleType(pkt, type) \
3649 gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_CYCLETYPE, 2, type)
3650#define gsDPSetCycleType(type) \
3651 gsSPSetOtherMode( G_SETOTHERMODE_H, G_MDSFT_CYCLETYPE, 2, type)
3652
3653#define gDPSetTexturePersp(pkt, type) \
3654 gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTPERSP, 1, type)
3655#define gsDPSetTexturePersp(type) \
3656 gsSPSetOtherMode( G_SETOTHERMODE_H, G_MDSFT_TEXTPERSP, 1, type)
3657
3658#define gDPSetTextureDetail(pkt, type) \
3659 gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTDETAIL, 2, type)
3660#define gsDPSetTextureDetail(type) \
3661 gsSPSetOtherMode( G_SETOTHERMODE_H, G_MDSFT_TEXTDETAIL, 2, type)
3662
3663#define gDPSetTextureLOD(pkt, type) \
3664 gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTLOD, 1, type)
3665#define gsDPSetTextureLOD(type) \
3666 gsSPSetOtherMode( G_SETOTHERMODE_H, G_MDSFT_TEXTLOD, 1, type)
3667
3668#define gDPSetTextureLUT(pkt, type) \
3669 gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTLUT, 2, type)
3670#define gsDPSetTextureLUT(type) \
3671 gsSPSetOtherMode( G_SETOTHERMODE_H, G_MDSFT_TEXTLUT, 2, type)
3672
3673#define gDPSetTextureFilter(pkt, type) \
3674 gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTFILT, 2, type)
3675#define gsDPSetTextureFilter(type) \
3676 gsSPSetOtherMode( G_SETOTHERMODE_H, G_MDSFT_TEXTFILT, 2, type)
3677
3678#define gDPSetTextureConvert(pkt, type) \
3679 gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTCONV, 3, type)
3680#define gsDPSetTextureConvert(type) \
3681 gsSPSetOtherMode( G_SETOTHERMODE_H, G_MDSFT_TEXTCONV, 3, type)
3682
3683#define gDPSetCombineKey(pkt, type) \
3684 gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_COMBKEY, 1, type)
3685#define gsDPSetCombineKey(type) \
3686 gsSPSetOtherMode( G_SETOTHERMODE_H, G_MDSFT_COMBKEY, 1, type)
3687
3688#define gDPSetColorDither(pkt, mode) \
3689 gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_RGBDITHER, 2, mode)
3690#define gsDPSetColorDither(mode) \
3691 gsSPSetOtherMode( G_SETOTHERMODE_H, G_MDSFT_RGBDITHER, 2, mode)
3692
3693#define gDPSetAlphaDither(pkt, mode) \
3694 gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_ALPHADITHER, 2, mode)
3695#define gsDPSetAlphaDither(mode) \
3696 gsSPSetOtherMode( G_SETOTHERMODE_H, G_MDSFT_ALPHADITHER, 2, mode)
3697
3704#define gDPSetBlendMask(pkt, mask) gSPNoOp(pkt)
3708#define gsDPSetBlendMask(mask) gsSPNoOp()
3709
3710#define gDPSetAlphaCompare(pkt, type) \
3711 gSPSetOtherMode(pkt, G_SETOTHERMODE_L, G_MDSFT_ALPHACOMPARE, 2, type)
3712#define gsDPSetAlphaCompare(type) \
3713 gsSPSetOtherMode( G_SETOTHERMODE_L, G_MDSFT_ALPHACOMPARE, 2, type)
3714
3715#define gDPSetDepthSource(pkt, src) \
3716 gSPSetOtherMode(pkt, G_SETOTHERMODE_L, G_MDSFT_ZSRCSEL, 1, src)
3717#define gsDPSetDepthSource(src) \
3718 gsSPSetOtherMode( G_SETOTHERMODE_L, G_MDSFT_ZSRCSEL, 1, src)
3719
3720#define gDPSetRenderMode(pkt, c0, c1) \
3721 gSPSetOtherMode(pkt, G_SETOTHERMODE_L, G_MDSFT_RENDERMODE, 29, (c0) | (c1))
3722#define gsDPSetRenderMode(c0, c1) \
3723 gsSPSetOtherMode( G_SETOTHERMODE_L, G_MDSFT_RENDERMODE, 29, (c0) | (c1))
3724
3725#define gSetImage(pkt, cmd, fmt, siz, width, i) \
3726_DW({ \
3727 Gfx *_g = (Gfx *)(pkt); \
3728 \
3729 _g->words.w0 = (_SHIFTL(cmd, 24, 8) | \
3730 _SHIFTL(fmt, 21, 3) | \
3731 _SHIFTL(siz, 19, 2) | \
3732 _SHIFTL((width) - 1, 0, 12)); \
3733 _g->words.w1 = (unsigned int)(i); \
3734})
3735
3736#define gsSetImage(cmd, fmt, siz, width, i) \
3737{ \
3738 (_SHIFTL(cmd, 24, 8) | \
3739 _SHIFTL(fmt, 21, 3) | \
3740 _SHIFTL(siz, 19, 2) | \
3741 _SHIFTL((width) - 1, 0, 12)), \
3742 (unsigned int)(i) \
3743}
3744
3745#define gDPSetColorImage(pkt, f, s, w, i) gSetImage(pkt, G_SETCIMG, f, s, w, i)
3746#define gsDPSetColorImage(f, s, w, i) gsSetImage( G_SETCIMG, f, s, w, i)
3747
3748
3749/* use these for new code */
3750#define gDPSetDepthImage(pkt, i) gSetImage(pkt, G_SETZIMG, 0, 0, 1, i)
3751#define gsDPSetDepthImage(i) gsSetImage( G_SETZIMG, 0, 0, 1, i)
3752/* kept for compatibility */
3753#define gDPSetMaskImage(pkt, i) gDPSetDepthImage(pkt, i)
3754#define gsDPSetMaskImage(i) gsDPSetDepthImage( i)
3755
3756#define gDPSetTextureImage(pkt, f, s, w, i) gSetImage(pkt, G_SETTIMG, f, s, w, i)
3757#define gsDPSetTextureImage(f, s, w, i) gsSetImage( G_SETTIMG, f, s, w, i)
3758
3759/*
3760 * RDP macros
3761 */
3762
3763#define gDPSetCombine(pkt, muxs0, muxs1) \
3764_DW({ \
3765 Gfx *_g = (Gfx *)(pkt); \
3766 \
3767 _g->words.w0 = (_SHIFTL(G_SETCOMBINE, 24, 8) | \
3768 _SHIFTL(muxs0, 0, 24)); \
3769 _g->words.w1 = (unsigned int)(muxs1); \
3770})
3771
3772#define gsDPSetCombine(muxs0, muxs1) \
3773{ \
3774 (_SHIFTL(G_SETCOMBINE, 24, 8) | \
3775 _SHIFTL(muxs0, 0, 24)), \
3776 (unsigned int)(muxs1) \
3777}
3778
3779#define GCCc0w0(saRGB0, mRGB0, saA0, mA0) \
3780 (_SHIFTL((saRGB0), 20, 4) | \
3781 _SHIFTL((mRGB0), 15, 5) | \
3782 _SHIFTL((saA0), 12, 3) | \
3783 _SHIFTL((mA0), 9, 3))
3784
3785#define GCCc1w0(saRGB1, mRGB1) \
3786 (_SHIFTL((saRGB1), 5, 4) | \
3787 _SHIFTL((mRGB1), 0, 5))
3788
3789#define GCCc0w1(sbRGB0, aRGB0, sbA0, aA0) \
3790 (_SHIFTL((sbRGB0), 28, 4) | \
3791 _SHIFTL((aRGB0), 15, 3) | \
3792 _SHIFTL((sbA0), 12, 3) | \
3793 _SHIFTL((aA0), 9, 3))
3794
3795#define GCCc1w1(sbRGB1, saA1, mA1, aRGB1, sbA1, aA1) \
3796 (_SHIFTL((sbRGB1), 24, 4) | \
3797 _SHIFTL((saA1), 21, 3) | \
3798 _SHIFTL((mA1), 18, 3) | \
3799 _SHIFTL((aRGB1), 6, 3) | \
3800 _SHIFTL((sbA1), 3, 3) | \
3801 _SHIFTL((aA1), 0, 3))
3802
3803#define gDPSetCombineLERP(pkt, a0, b0, c0, d0, Aa0, Ab0, Ac0, Ad0, \
3804 a1, b1, c1, d1, Aa1, Ab1, Ac1, Ad1) \
3805_DW({ \
3806 Gfx *_g = (Gfx *)(pkt); \
3807 \
3808 _g->words.w0 = (_SHIFTL(G_SETCOMBINE, 24, 8) | \
3809 _SHIFTL(GCCc0w0(G_CCMUX_##a0, G_CCMUX_##c0, \
3810 G_ACMUX_##Aa0, G_ACMUX_##Ac0) | \
3811 GCCc1w0(G_CCMUX_##a1, G_CCMUX_##c1), \
3812 0, 24)); \
3813 _g->words.w1 = (unsigned int)(GCCc0w1(G_CCMUX_##b0, G_CCMUX_##d0, \
3814 G_ACMUX_##Ab0, G_ACMUX_##Ad0) | \
3815 GCCc1w1(G_CCMUX_##b1, G_ACMUX_##Aa1, \
3816 G_ACMUX_##Ac1, G_CCMUX_##d1, \
3817 G_ACMUX_##Ab1, G_ACMUX_##Ad1)); \
3818})
3819
3820#define gsDPSetCombineLERP(a0, b0, c0, d0, Aa0, Ab0, Ac0, Ad0, \
3821 a1, b1, c1, d1, Aa1, Ab1, Ac1, Ad1) \
3822{ \
3823 (_SHIFTL(G_SETCOMBINE, 24, 8) | \
3824 _SHIFTL(GCCc0w0(G_CCMUX_##a0, G_CCMUX_##c0, \
3825 G_ACMUX_##Aa0, G_ACMUX_##Ac0) | \
3826 GCCc1w0(G_CCMUX_##a1, G_CCMUX_##c1), \
3827 0, 24)), \
3828 (unsigned int)(GCCc0w1(G_CCMUX_##b0, G_CCMUX_##d0, \
3829 G_ACMUX_##Ab0, G_ACMUX_##Ad0) | \
3830 GCCc1w1(G_CCMUX_##b1, G_ACMUX_##Aa1, \
3831 G_ACMUX_##Ac1, G_CCMUX_##d1, \
3832 G_ACMUX_##Ab1, G_ACMUX_##Ad1)) \
3833}
3834
3844#define gDPSetCombineMode(pkt, a, b) gDPSetCombineLERP(pkt, a, b)
3848#define gsDPSetCombineMode(a, b) gsDPSetCombineLERP( a, b)
3849
3850#define gDPSetColor(pkt, c, d) \
3851_DW({ \
3852 Gfx *_g = (Gfx *)(pkt); \
3853 \
3854 _g->words.w0 = _SHIFTL(c, 24, 8); \
3855 _g->words.w1 = (unsigned int)(d); \
3856})
3857
3858#define gsDPSetColor(c, d) \
3859{ \
3860 _SHIFTL(c, 24, 8), \
3861 (unsigned int)(d) \
3862}
3863
3864#define DPRGBColor(pkt, cmd, r, g, b, a) \
3865 gDPSetColor(pkt, cmd, \
3866 (_SHIFTL(r, 24, 8) | \
3867 _SHIFTL(g, 16, 8) | \
3868 _SHIFTL(b, 8, 8) | \
3869 _SHIFTL(a, 0, 8)))
3870
3871#define sDPRGBColor(cmd, r, g, b, a) \
3872 gsDPSetColor(cmd, \
3873 (_SHIFTL(r, 24, 8) | \
3874 _SHIFTL(g, 16, 8) | \
3875 _SHIFTL(b, 8, 8) | \
3876 _SHIFTL(a, 0, 8)))
3877
3878#define gDPSetEnvColor(pkt, r, g, b, a) \
3879 DPRGBColor(pkt, G_SETENVCOLOR, r, g, b, a)
3880
3881#ifdef KAZE_GBI_HACKS
3882#define gsDPSetEnvColor(r, g, b, a) \
3883 gsSPNoOp()
3884#else
3885#define gsDPSetEnvColor(r, g, b, a) \
3886 sDPRGBColor( G_SETENVCOLOR, r, g, b, a)
3887#endif
3888
3889#define gDPSetBlendColor(pkt, r, g, b, a) \
3890 DPRGBColor(pkt, G_SETBLENDCOLOR, r, g, b, a)
3891
3892#define gsDPSetBlendColor(r, g, b, a) \
3893 sDPRGBColor( G_SETBLENDCOLOR, r, g, b, a)
3894
3895#define gDPSetFogColor(pkt, r, g, b, a) \
3896 DPRGBColor(pkt, G_SETFOGCOLOR, r, g, b, a)
3897
3898#define gsDPSetFogColor(r, g, b, a) \
3899 sDPRGBColor( G_SETFOGCOLOR, r, g, b, a)
3900
3901#define gDPSetFillColor(pkt, d) \
3902 gDPSetColor(pkt, G_SETFILLCOLOR, (d))
3903
3904#define gsDPSetFillColor(d) \
3905 gsDPSetColor( G_SETFILLCOLOR, (d))
3906
3907#define gDPSetPrimDepth(pkt, z, dz) \
3908 gDPSetColor(pkt, G_SETPRIMDEPTH, \
3909 _SHIFTL(z, 16, 16) | _SHIFTL(dz, 0, 16))
3910
3911#define gsDPSetPrimDepth(z, dz) \
3912 gsDPSetColor(G_SETPRIMDEPTH, \
3913 _SHIFTL(z, 16, 16) | _SHIFTL(dz, 0, 16))
3914
3915#define gDPSetPrimColor(pkt, m, l, r, g, b, a) \
3916_DW({ \
3917 Gfx *_g = (Gfx *)(pkt); \
3918 \
3919 _g->words.w0 = (_SHIFTL(G_SETPRIMCOLOR, 24, 8) | \
3920 _SHIFTL(m, 8, 8) | \
3921 _SHIFTL(l, 0, 8)); \
3922 _g->words.w1 = (_SHIFTL(r, 24, 8) | \
3923 _SHIFTL(g, 16, 8) | \
3924 _SHIFTL(b, 8, 8) | \
3925 _SHIFTL(a, 0, 8)); \
3926})
3927
3928#define gsDPSetPrimColor(m, l, r, g, b, a) \
3929{ \
3930 (_SHIFTL(G_SETPRIMCOLOR, 24, 8) | \
3931 _SHIFTL(m, 8, 8) | \
3932 _SHIFTL(l, 0, 8)), \
3933 (_SHIFTL(r, 24, 8) | \
3934 _SHIFTL(g, 16, 8) | \
3935 _SHIFTL(b, 8, 8) | \
3936 _SHIFTL(a, 0, 8)) \
3937}
3938
3949#define gSPLightToRDP(pkt, light, alpha, word0) \
3950_DW({ \
3951 Gfx *_g = (Gfx *)(pkt); \
3952 _g->words.w0 = (_SHIFTL(G_LIGHTTORDP, 24, 8) | \
3953 _SHIFTL(light * 0x10, 8, 8) | \
3954 _SHIFTL(alpha, 0, 8)); \
3955 _g->words.w1 = (word0); \
3956})
3960#define gsSPLightToRDP(light, alpha, word0) \
3961{ \
3962 (_SHIFTL(G_LIGHTTORDP, 24, 8) | \
3963 _SHIFTL(light * 0x10, 8, 8) | \
3964 _SHIFTL(alpha, 0, 8)), \
3965 (word0) \
3966}
3967#define gSPLightToPrimColor(pkt, light, alpha, m, l) \
3968 gSPLightToRDP(pkt, light, alpha, \
3969 (_SHIFTL(G_SETPRIMCOLOR, 24, 8) | _SHIFTL(m, 8, 8) | _SHIFTL(l, 0, 8)))
3970#define gsSPLightToPrimColor(light, alpha, m, l) \
3971 gsSPLightToRDP(light, alpha, \
3972 (_SHIFTL(G_SETPRIMCOLOR, 24, 8) | _SHIFTL(m, 8, 8) | _SHIFTL(l, 0, 8)))
3973#define gSPLightToFogColor(pkt, light, alpha) \
3974 gSPLightToRDP(pkt, light, alpha, _SHIFTL(G_SETFOGCOLOR, 24, 8))
3975#define gsSPLightToFogColor(light, alpha) \
3976 gsSPLightToRDP(light, alpha, _SHIFTL(G_SETFOGCOLOR, 24, 8))
3977
4006#define gDPSetOtherMode(pkt, mode0, mode1) \
4007_DW({ \
4008 Gfx *_g = (Gfx *)(pkt); \
4009 \
4010 _g->words.w0 = (_SHIFTL(G_RDPSETOTHERMODE, 24, 8) | \
4011 _SHIFTL(mode0, 0, 24)); \
4012 _g->words.w1 = (unsigned int)(mode1); \
4013})
4014
4018#define gsDPSetOtherMode(mode0, mode1) \
4019{ \
4020 (_SHIFTL(G_RDPSETOTHERMODE, 24, 8) | \
4021 _SHIFTL(mode0, 0, 24)), \
4022 (unsigned int)(mode1) \
4023}
4024
4025/*
4026 * Texturing macros
4027 */
4028
4029#define G_TX_LOADTILE 7
4030#define G_TX_RENDERTILE 0
4031
4032/*
4033 * Define this to remove syncs from texture loading multi-command macros.
4034 *
4035 * You should convert your romhack codebase to F3DEX3 without this defined
4036 * first, then once everything is stable, define it and fix any crashes or
4037 * graphical issues that arise.
4038 *
4039 * How the syncs work: load, tile, and pipe sync all delay the RDP by fixed
4040 * numbers of cycles. It is the smallest number for load, a medium number for
4041 * tile, and the largest number for pipe. These syncs do NOT wait until
4042 * something is finished being used; they just stall for a fixed time.
4043 * (DPFullSync is different and DOES wait for writebacks to memory to be done;
4044 * that is not considered in this explanation.)
4045 *
4046 * Syncs always happen after rendering something and before changing some
4047 * settings. In other words:
4048 * - gsSP2Triangles(), gsSPTextureRectangle(), etc.
4049 * - gsDPSomeSync(),
4050 * - gsDPSetSomething()
4051 * You never need the opposite, i.e. you never need a sync after changing
4052 * settings but before rendering.
4053 *
4054 * Which sync you use depends on which settings you are changing. If you are
4055 * doing a texture load (DPLoadBlock or DPLoadTile), you need a load sync (or
4056 * either of the other syncs which wait for even longer). If you are changing
4057 * tile settings, you need a tile sync (or pipe sync which is longer). If you
4058 * are changing CC, othermode, env color, or other things like that, you need
4059 * a pipe sync.
4060 *
4061 * Display lists overall should be structured like:
4062 *
4063 * - ...
4064 * - previous draw tris
4065 * - pipe sync
4066 * - texture load, CC settings, othermode, etc. (no syncs within these)
4067 * - (no sync here)
4068 * - draw tris
4069 * - pipe sync
4070 * - next material setup
4071 * - ...
4072 *
4073 * In SM64, the pipe sync is at the end of each object or sub-object; in OoT
4074 * it is at the start of each display list. This ends up being the same thing
4075 * when the display lists are effectively concatenated: you have a pipe sync
4076 * after each set of rendering things, and before each new set of changing
4077 * settings.
4078 *
4079 * If you are doing multitexture and/or CI texture loads, use a different tile
4080 * for each load, and then you don't need any syncs in the loads. As an extreme
4081 * example with two CI textures:
4082 * - previous pipe sync, either at the start of this DL or the end of the last
4083 * - set tile 7 to load texture 0 CIs (no syncs)
4084 * - load block on tile 7 (no syncs)
4085 * - set tile 5 to load texture 0 palette (no syncs)
4086 * - load block on tile 5 (no syncs)
4087 * - set tile 6 to load texture 1 CIs (no syncs)
4088 * - load block on tile 6 (no syncs)
4089 * - set tile 4 to load texture 1 palette (no syncs)
4090 * - load block on tile 4 (no syncs)
4091 * - set tile 0 for render texture 0 (no syncs)
4092 * - set tile 1 for render texture 0 (no syncs)
4093 * - set othermode, CC, etc. (no syncs)
4094 * - draw tris (no syncs)
4095 * - next pipe sync, either at the end of this DL or the start of the next
4096 * Both fast64 and the multi-command macros in this GBI if
4097 * NO_SYNCS_IN_TEXTURE_LOADS is enabled do this, but if you wrote the DLs by
4098 * hand or they were vanilla DLs not using the multi-command macros, they may
4099 * need to be updated. (Then again, in that case the syncs are also written by
4100 * hand, so these syncs changes do not affect them.)
4101 *
4102 * If you are writing GUI display lists with texture rectangle which look like
4103 * - load tex
4104 * - tex rect
4105 * - load tex
4106 * - tex rect
4107 * you need a load sync before each load tex, and you don't need any other
4108 * syncs.
4109 */
4110#ifdef NO_SYNCS_IN_TEXTURE_LOADS
4111#define gDPLoadSyncInTexLoad(pkt) (void)0
4112#define gDPTileSyncInTexLoad(pkt) (void)0
4113#define gDPPipeSyncInTexLoad(pkt) (void)0
4114#define gsDPLoadSyncInTexLoad
4115#define gsDPTileSyncInTexLoad
4116#define gsDPPipeSyncInTexLoad
4117#define gsDPPipeSyncEndOfTexLoad
4118#define _G_TEXLOADTILE(rtile) (G_TX_LOADTILE - (rtile))
4119#define _G_PALLOADTILE(rtile) (G_TX_LOADTILE - 2 - (rtile))
4120#else
4121#define gDPLoadSyncInTexLoad(pkt) gDPLoadSync(pkt)
4122#define gDPTileSyncInTexLoad(pkt) gDPTileSync(pkt)
4123#define gDPPipeSyncInTexLoad(pkt) gDPPipeSync(pkt)
4124#define gsDPLoadSyncInTexLoad gsDPLoadSync(),
4125#define gsDPTileSyncInTexLoad gsDPTileSync(),
4126#define gsDPPipeSyncInTexLoad gsDPPipeSync(),
4127#define gsDPPipeSyncEndOfTexLoad , gsDPPipeSync()
4128#define _G_TEXLOADTILE(rtile) G_TX_LOADTILE
4129#define _G_PALLOADTILE(rtile) G_TX_LOADTILE
4130#endif
4131
4132
4133#define G_TX_NOMIRROR (0 << 0)
4134#define G_TX_WRAP (0 << 1)
4135#define G_TX_MIRROR (1 << 0)
4136#define G_TX_CLAMP (1 << 1)
4137#define G_TX_NOMASK 0
4138#define G_TX_NOLOD 0
4139
4140#ifndef MAX
4141#define MAX(a, b) ((a) > (b) ? (a) : (b))
4142#endif
4143
4144#ifndef MIN
4145#define MIN(a, b) ((a) < (b) ? (a) : (b))
4146#endif
4147
4148/*
4149 * Dxt is the inverse of the number of 64-bit words in a line of
4150 * the texture being loaded using the load_block command. If
4151 * there are any 1's to the right of the 11th fractional bit,
4152 * dxt should be rounded up. The following macros accomplish
4153 * this. The 4b macros are a special case since 4-bit textures
4154 * are loaded as 8-bit textures. Dxt is fixed point 1.11. RJM
4155 */
4156#define G_TX_DXT_FRAC 11
4157
4158/*
4159 * For RCP 2.0, the maximum number of texels that can be loaded
4160 * using a load_block command is 2048. In order to load the total
4161 * 4kB of Tmem, change the texel size when loading to be G_IM_SIZ_16b,
4162 * then change the tile to the proper texel size after the load.
4163 * The g*DPLoadTextureBlock macros already do this, so this change
4164 * will be transparent if you use these macros. If you use
4165 * the g*DPLoadBlock macros directly, you will need to handle this
4166 * tile manipulation yourself. RJM.
4167 */
4168#define G_TX_LDBLK_MAX_TXL 2047
4169
4170#define TXL2WORDS(txls, b_txl) \
4171 MAX(1, ((txls) * (b_txl) / 8))
4172
4173#define CALC_DXT(width, b_txl) \
4174 (((1 << G_TX_DXT_FRAC) + TXL2WORDS(width, b_txl) - 1) / TXL2WORDS(width, b_txl))
4175
4176#define TXL2WORDS_4b(txls) \
4177 MAX(1, ((txls) / 16))
4178
4179#define CALC_DXT_4b(width) \
4180 (((1 << G_TX_DXT_FRAC) + TXL2WORDS_4b(width) - 1) / TXL2WORDS_4b(width))
4181
4182#define gDPLoadTileGeneric(pkt, c, tile, uls, ult, lrs, lrt) \
4183_DW({ \
4184 Gfx *_g = (Gfx *)(pkt); \
4185 \
4186 _g->words.w0 = (_SHIFTL(c, 24, 8) | \
4187 _SHIFTL(uls, 12, 12) | \
4188 _SHIFTL(ult, 0, 12)); \
4189 _g->words.w1 = (_SHIFTL(tile, 24, 3) | \
4190 _SHIFTL(lrs, 12, 12) | \
4191 _SHIFTL(lrt, 0, 12)); \
4192})
4193
4194#define gsDPLoadTileGeneric(c, tile, uls, ult, lrs, lrt) \
4195{ \
4196 (_SHIFTL(c, 24, 8) | \
4197 _SHIFTL(uls, 12, 12) | \
4198 _SHIFTL(ult, 0, 12)), \
4199 (_SHIFTL(tile, 24, 3) | \
4200 _SHIFTL(lrs, 12, 12) | \
4201 _SHIFTL(lrt, 0, 12)) \
4202}
4203
4204#define gDPSetTileSize(pkt, t, uls, ult, lrs, lrt) \
4205 gDPLoadTileGeneric(pkt, G_SETTILESIZE, t, uls, ult, lrs, lrt)
4206#define gsDPSetTileSize(t, uls, ult, lrs, lrt) \
4207 gsDPLoadTileGeneric( G_SETTILESIZE, t, uls, ult, lrs, lrt)
4208#define gDPLoadTile(pkt, t, uls, ult, lrs, lrt) \
4209 gDPLoadTileGeneric(pkt, G_LOADTILE, t, uls, ult, lrs, lrt)
4210#define gsDPLoadTile(t, uls, ult, lrs, lrt) \
4211 gsDPLoadTileGeneric( G_LOADTILE, t, uls, ult, lrs, lrt)
4212
4213#define gDPSetTile(pkt, fmt, siz, line, tmem, tile, palette, cmt, \
4214 maskt, shiftt, cms, masks, shifts) \
4215_DW({ \
4216 Gfx *_g = (Gfx *)(pkt); \
4217 \
4218 _g->words.w0 = (_SHIFTL(G_SETTILE, 24, 8) | \
4219 _SHIFTL(fmt, 21, 3) | \
4220 _SHIFTL(siz, 19, 2) | \
4221 _SHIFTL(line, 9, 9) | \
4222 _SHIFTL(tmem, 0, 9)); \
4223 _g->words.w1 = (_SHIFTL(tile, 24, 3) | \
4224 _SHIFTL(palette, 20, 4) | \
4225 _SHIFTL(cmt, 18, 2) | \
4226 _SHIFTL(maskt, 14, 4) | \
4227 _SHIFTL(shiftt, 10, 4) | \
4228 _SHIFTL(cms, 8, 2) | \
4229 _SHIFTL(masks, 4, 4) | \
4230 _SHIFTL(shifts, 0, 4)); \
4231})
4232
4233#define gsDPSetTile(fmt, siz, line, tmem, tile, palette, cmt, \
4234 maskt, shiftt, cms, masks, shifts) \
4235{ \
4236 (_SHIFTL(G_SETTILE, 24, 8) | \
4237 _SHIFTL(fmt, 21, 3) | \
4238 _SHIFTL(siz, 19, 2) | \
4239 _SHIFTL(line, 9, 9) | \
4240 _SHIFTL(tmem, 0, 9)), \
4241 (_SHIFTL(tile, 24, 3) | \
4242 _SHIFTL(palette, 20, 4) | \
4243 _SHIFTL(cmt, 18, 2) | \
4244 _SHIFTL(maskt, 14, 4) | \
4245 _SHIFTL(shiftt, 10, 4) | \
4246 _SHIFTL(cms, 8, 2) | \
4247 _SHIFTL(masks, 4, 4) | \
4248 _SHIFTL(shifts, 0, 4)) \
4249}
4250
4251#define gDPLoadBlock(pkt, tile, uls, ult, lrs, dxt) \
4252_DW({ \
4253 Gfx *_g = (Gfx *)(pkt); \
4254 _g->words.w0 = (_SHIFTL(G_LOADBLOCK, 24, 8) | \
4255 _SHIFTL(uls, 12, 12) | \
4256 _SHIFTL(ult, 0, 12)); \
4257 _g->words.w1 = (_SHIFTL(tile, 24, 3) | \
4258 _SHIFTL(MIN(lrs, G_TX_LDBLK_MAX_TXL), 12, 12) | \
4259 _SHIFTL(dxt, 0, 12)); \
4260})
4261
4262#define gsDPLoadBlock(tile, uls, ult, lrs, dxt) \
4263{ \
4264 (_SHIFTL(G_LOADBLOCK, 24, 8) | \
4265 _SHIFTL(uls, 12, 12) | \
4266 _SHIFTL(ult, 0, 12)), \
4267 (_SHIFTL(tile, 24, 3) | \
4268 _SHIFTL((MIN(lrs, G_TX_LDBLK_MAX_TXL)), 12, 12) | \
4269 _SHIFTL(dxt, 0, 12)) \
4270}
4271
4272#define gDPLoadTLUTCmd(pkt, tile, count) \
4273_DW({ \
4274 Gfx *_g = (Gfx *)pkt; \
4275 \
4276 _g->words.w0 = _SHIFTL(G_LOADTLUT, 24, 8); \
4277 _g->words.w1 = (_SHIFTL((tile), 24, 3) | \
4278 _SHIFTL((count), 14, 10)); \
4279})
4280
4281#define gsDPLoadTLUTCmd(tile, count) \
4282{ \
4283 _SHIFTL(G_LOADTLUT, 24, 8), \
4284 (_SHIFTL((tile), 24, 3) | \
4285 _SHIFTL((count), 14, 10)) \
4286}
4287
4288#define gDPLoadTextureBlock(pkt, timg, fmt, siz, width, height, pal, \
4289 cms, cmt, masks, maskt, shifts, shiftt) \
4290_DW({ \
4291 gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \
4292 gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, 0, G_TX_LOADTILE, \
4293 0, cmt, maskt, shiftt, cms, masks, shifts); \
4294 gDPLoadSyncInTexLoad(pkt); \
4295 gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
4296 (((width) * (height) + siz##_INCR) >> siz##_SHIFT) -1, \
4297 CALC_DXT(width, siz##_BYTES)); \
4298 gDPPipeSyncInTexLoad(pkt); \
4299 gDPSetTile(pkt, fmt, siz, \
4300 (((width) * siz##_LINE_BYTES) + 7) >> 3, 0, \
4301 G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, shifts); \
4302 gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \
4303 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4304 ((height) - 1) << G_TEXTURE_IMAGE_FRAC); \
4305})
4306
4307#define gDPLoadTextureBlockYuv(pkt, timg, fmt, siz, width, height, pal, \
4308 cms, cmt, masks, maskt, shifts, shiftt) \
4309_DW({ \
4310 gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \
4311 gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, 0, G_TX_LOADTILE, \
4312 0, cmt, maskt, shiftt, cms, masks, shifts); \
4313 gDPLoadSyncInTexLoad(pkt); \
4314 gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
4315 (((width) * (height) + siz##_INCR) >> siz##_SHIFT) -1, \
4316 CALC_DXT(width, siz##_BYTES)); \
4317 gDPPipeSyncInTexLoad(pkt); \
4318 gDPSetTile(pkt, fmt, siz, \
4319 (((width) * 1) + 7) >> 3, 0, \
4320 G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, shifts); \
4321 gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \
4322 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4323 ((height) - 1) << G_TEXTURE_IMAGE_FRAC); \
4324})
4325
4326/* Load fix rww 27jun95 */
4327/* The S at the end means odd lines are already word Swapped */
4328
4329#define gDPLoadTextureBlockS(pkt, timg, fmt, siz, width, height, pal, \
4330 cms, cmt, masks, maskt, shifts, shiftt) \
4331_DW({ \
4332 gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \
4333 gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, 0, G_TX_LOADTILE, \
4334 0, cmt, maskt, shiftt, cms, masks, shifts); \
4335 gDPLoadSyncInTexLoad(pkt); \
4336 gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
4337 (((width) * (height) + siz##_INCR) >> siz##_SHIFT) - 1, 0); \
4338 gDPPipeSyncInTexLoad(pkt); \
4339 gDPSetTile(pkt, fmt, siz, \
4340 (((width) * siz##_LINE_BYTES) + 7) >> 3, 0, \
4341 G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, shifts); \
4342 gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \
4343 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4344 ((height) - 1) << G_TEXTURE_IMAGE_FRAC); \
4345})
4346
4351#define gDPLoadMultiBlockS(pkt, timg, tmem, rtile, fmt, siz, width, height, pal, \
4352 cms, cmt, masks, maskt, shifts, shiftt) \
4353_DW({ \
4354 gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \
4355 gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, tmem, _G_TEXLOADTILE(rtile), \
4356 0, cmt, maskt, shiftt, cms, masks, shifts); \
4357 gDPLoadSyncInTexLoad(pkt); \
4358 gDPLoadBlock(pkt, _G_TEXLOADTILE(rtile), 0, 0, \
4359 (((width) * (height) + siz##_INCR) >> siz##_SHIFT) - 1,0); \
4360 gDPPipeSyncInTexLoad(pkt); \
4361 gDPSetTile(pkt, fmt, siz, \
4362 (((width) * siz##_LINE_BYTES) + 7) >> 3, tmem, \
4363 rtile, pal, cmt, maskt, shiftt, cms, masks, \
4364 shifts); \
4365 gDPSetTileSize(pkt, rtile, 0, 0, \
4366 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4367 ((height) - 1) << G_TEXTURE_IMAGE_FRAC); \
4368})
4369
4370
4371#define gDPLoadTextureBlockYuvS(pkt, timg, fmt, siz, width, height, pal, \
4372 cms, cmt, masks, maskt, shifts, shiftt) \
4373_DW({ \
4374 gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \
4375 gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, 0, G_TX_LOADTILE, \
4376 0, cmt, maskt, shiftt, cms, masks, shifts); \
4377 gDPLoadSyncInTexLoad(pkt); \
4378 gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
4379 (((width) * (height) + siz##_INCR) >> siz##_SHIFT) - 1,0); \
4380 gDPPipeSyncInTexLoad(pkt); \
4381 gDPSetTile(pkt, fmt, siz, \
4382 (((width) * 1) + 7) >> 3, 0, \
4383 G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, shifts); \
4384 gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \
4385 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4386 ((height) - 1) << G_TEXTURE_IMAGE_FRAC); \
4387})
4388
4389/*
4390 * allows tmem address to be specified
4391 */
4392#define _gDPLoadTextureBlock(pkt, timg, tmem, fmt, siz, width, height, pal, \
4393 cms, cmt, masks, maskt, shifts, shiftt) \
4394_DW({ \
4395 gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \
4396 gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, tmem, G_TX_LOADTILE, \
4397 0, cmt, maskt, shiftt, cms, masks, shifts); \
4398 gDPLoadSyncInTexLoad(pkt); \
4399 gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
4400 (((width) * (height) + siz##_INCR) >> siz##_SHIFT) - 1, \
4401 CALC_DXT(width, siz##_BYTES)); \
4402 gDPPipeSyncInTexLoad(pkt); \
4403 gDPSetTile(pkt, fmt, siz, \
4404 (((width) * siz##_LINE_BYTES) + 7) >> 3, tmem, \
4405 G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, shifts); \
4406 gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \
4407 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4408 ((height) - 1) << G_TEXTURE_IMAGE_FRAC); \
4409})
4410
4411/*
4412 * allows tmem address and render tile to be specified
4413 */
4414#define _gDPLoadTextureBlockTile(pkt, timg, tmem, rtile, fmt, siz, width, height, pal, \
4415 cms, cmt, masks, maskt, shifts, shiftt) \
4416_DW({ \
4417 gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \
4418 gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, tmem, _G_TEXLOADTILE(rtile), \
4419 0, cmt, maskt, shiftt, cms, masks, shifts); \
4420 gDPLoadSyncInTexLoad(pkt); \
4421 gDPLoadBlock(pkt, _G_TEXLOADTILE(rtile), 0, 0, \
4422 (((width) * (height) + siz##_INCR) >> siz##_SHIFT) - 1, \
4423 CALC_DXT(width, siz##_BYTES)); \
4424 gDPPipeSyncInTexLoad(pkt); \
4425 gDPSetTile(pkt, fmt, siz, \
4426 (((width) * siz##_LINE_BYTES) + 7) >> 3, tmem, \
4427 rtile, pal, cmt, maskt, shiftt, cms, masks, shifts); \
4428 gDPSetTileSize(pkt, rtile, 0, 0, \
4429 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4430 ((height) - 1) << G_TEXTURE_IMAGE_FRAC); \
4431})
4432
4436#define gDPLoadMultiBlock(pkt, timg, tmem, rtile, fmt, siz, width, height, pal, \
4437 cms, cmt, masks, maskt, shifts, shiftt) \
4438_DW({ \
4439 gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \
4440 gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, tmem, _G_TEXLOADTILE(rtile), \
4441 0, cmt, maskt, shiftt, cms, masks, shifts); \
4442 gDPLoadSyncInTexLoad(pkt); \
4443 gDPLoadBlock(pkt, _G_TEXLOADTILE(rtile), 0, 0, \
4444 (((width) * (height) + siz##_INCR) >> siz##_SHIFT) - 1, \
4445 CALC_DXT(width, siz##_BYTES)); \
4446 gDPPipeSyncInTexLoad(pkt); \
4447 gDPSetTile(pkt, fmt, siz, \
4448 (((width) * siz##_LINE_BYTES) + 7) >> 3, tmem, \
4449 rtile, pal, cmt, maskt, shiftt, cms, masks, shifts); \
4450 gDPSetTileSize(pkt, rtile, 0, 0, \
4451 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4452 ((height) - 1) << G_TEXTURE_IMAGE_FRAC); \
4453})
4454
4455#define gsDPLoadTextureBlock(timg, fmt, siz, width, height, pal, \
4456 cms, cmt, masks, maskt, shifts, shiftt) \
4457 gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \
4458 gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, 0, G_TX_LOADTILE, \
4459 0, cmt, maskt, shiftt, cms, masks, shifts), \
4460 gsDPLoadSyncInTexLoad \
4461 gsDPLoadBlock(G_TX_LOADTILE, 0, 0, \
4462 (((width)*(height) + siz##_INCR) >> siz##_SHIFT) - 1, \
4463 CALC_DXT(width, siz##_BYTES)), \
4464 gsDPPipeSyncInTexLoad \
4465 gsDPSetTile(fmt, siz, \
4466 ((((width) * siz##_LINE_BYTES) + 7) >> 3), 0, \
4467 G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, shifts), \
4468 gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, \
4469 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4470 ((height) - 1) << G_TEXTURE_IMAGE_FRAC)
4471
4472/* Here is the static form of the pre-swapped texture block loading */
4473/* See gDPLoadTextureBlockS() for reference. Basically, just don't
4474 calculate DxT, use 0 */
4475
4476#define gsDPLoadTextureBlockS(timg, fmt, siz, width, height, pal, \
4477 cms, cmt, masks, maskt, shifts, shiftt) \
4478 gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \
4479 gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, 0, G_TX_LOADTILE, \
4480 0, cmt, maskt,shiftt, cms, masks, shifts), \
4481 gsDPLoadSyncInTexLoad \
4482 gsDPLoadBlock(G_TX_LOADTILE, 0, 0, \
4483 (((width) * (height) + siz##_INCR) >> siz##_SHIFT) - 1, 0), \
4484 gsDPPipeSyncInTexLoad \
4485 gsDPSetTile(fmt, siz, \
4486 ((((width) * siz##_LINE_BYTES) + 7) >> 3), 0, \
4487 G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \
4488 shifts), \
4489 gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, \
4490 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4491 ((height) - 1) << G_TEXTURE_IMAGE_FRAC)
4492
4493/*
4494 * Allow tmem address to be specified
4495 */
4496#define _gsDPLoadTextureBlock(timg, tmem, fmt, siz, width, height, pal, \
4497 cms, cmt, masks, maskt, shifts, shiftt) \
4498 gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \
4499 gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, tmem, G_TX_LOADTILE, \
4500 0, cmt, maskt, shiftt, cms, masks, shifts), \
4501 gsDPLoadSyncInTexLoad \
4502 gsDPLoadBlock(G_TX_LOADTILE, 0, 0, \
4503 (((width) * (height) + siz##_INCR) >> siz##_SHIFT) - 1, \
4504 CALC_DXT(width, siz##_BYTES)), \
4505 gsDPPipeSyncInTexLoad \
4506 gsDPSetTile(fmt, siz, \
4507 ((((width) * siz##_LINE_BYTES) + 7) >> 3), tmem, \
4508 G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \
4509 shifts), \
4510 gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, \
4511 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4512 ((height) - 1) << G_TEXTURE_IMAGE_FRAC)
4513
4514
4515/*
4516 * Allow tmem address and render_tile to be specified
4517 */
4518#define _gsDPLoadTextureBlockTile(timg, tmem, rtile, fmt, siz, width, height, pal, \
4519 cms, cmt, masks, maskt, shifts, shiftt) \
4520 gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \
4521 gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, tmem, _G_TEXLOADTILE(rtile), \
4522 0, cmt, maskt, shiftt, cms, masks, shifts), \
4523 gsDPLoadSyncInTexLoad \
4524 gsDPLoadBlock(_G_TEXLOADTILE(rtile), 0, 0, \
4525 (((width) * (height) + siz##_INCR) >> siz##_SHIFT) - 1, \
4526 CALC_DXT(width, siz##_BYTES)), \
4527 gsDPPipeSyncInTexLoad \
4528 gsDPSetTile(fmt, siz, \
4529 ((((width) * siz##_LINE_BYTES) + 7) >> 3), tmem, \
4530 rtile, pal, cmt, maskt, shiftt, cms, masks, \
4531 shifts), \
4532 gsDPSetTileSize(rtile, 0, 0, \
4533 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4534 ((height) - 1) << G_TEXTURE_IMAGE_FRAC)
4535
4536
4541#define gsDPLoadMultiBlock(timg, tmem, rtile, fmt, siz, width, height, pal, \
4542 cms, cmt, masks, maskt, shifts, shiftt) \
4543 gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \
4544 gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, tmem, _G_TEXLOADTILE(rtile), \
4545 0, cmt, maskt, shiftt, cms, masks, shifts), \
4546 gsDPLoadSyncInTexLoad \
4547 gsDPLoadBlock(_G_TEXLOADTILE(rtile), 0, 0, \
4548 (((width) * (height) + siz##_INCR) >> siz##_SHIFT) - 1, \
4549 CALC_DXT(width, siz##_BYTES)), \
4550 gsDPPipeSyncInTexLoad \
4551 gsDPSetTile(fmt, siz, \
4552 ((((width) * siz##_LINE_BYTES) + 7) >> 3), tmem, \
4553 rtile, pal, cmt, maskt, shiftt, cms, masks, shifts), \
4554 gsDPSetTileSize(rtile, 0, 0, \
4555 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4556 ((height) - 1) << G_TEXTURE_IMAGE_FRAC)
4557
4566#define gsDPLoadMultiBlockS(timg, tmem, rtile, fmt, siz, width, height, pal, \
4567 cms, cmt, masks, maskt, shifts, shiftt) \
4568 gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \
4569 gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, tmem, _G_TEXLOADTILE(rtile), \
4570 0, cmt, maskt,shiftt, cms, masks, shifts), \
4571 gsDPLoadSyncInTexLoad \
4572 gsDPLoadBlock(_G_TEXLOADTILE(rtile), 0, 0, \
4573 (((width) * (height) + siz##_INCR) >> siz##_SHIFT) - 1, 0), \
4574 gsDPPipeSyncInTexLoad \
4575 gsDPSetTile(fmt, siz, \
4576 ((((width) * siz##_LINE_BYTES) + 7) >> 3), tmem, \
4577 rtile, pal, cmt, maskt, shiftt, cms, masks, shifts), \
4578 gsDPSetTileSize(rtile, 0, 0, \
4579 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4580 ((height) - 1) << G_TEXTURE_IMAGE_FRAC)
4581
4582
4583#define gDPLoadTextureBlock_4b(pkt, timg, fmt, width, height, pal, \
4584 cms, cmt, masks, maskt, shifts, shiftt) \
4585_DW({ \
4586 gDPSetTextureImage(pkt, fmt, G_IM_SIZ_16b, 1, timg); \
4587 gDPSetTile(pkt, fmt, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, \
4588 0, cmt, maskt, shiftt, cms, masks, shifts); \
4589 gDPLoadSyncInTexLoad(pkt); \
4590 gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
4591 (((width) * (height) + 3) >> 2) - 1, \
4592 CALC_DXT_4b(width)); \
4593 gDPPipeSyncInTexLoad(pkt); \
4594 gDPSetTile(pkt, fmt, G_IM_SIZ_4b, \
4595 ((((width) >> 1) + 7) >> 3), 0, \
4596 G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, shifts); \
4597 gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \
4598 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4599 ((height) - 1) << G_TEXTURE_IMAGE_FRAC); \
4600})
4601
4602/* Load fix rww 27jun95 */
4603/* The S at the end means odd lines are already word Swapped */
4604
4605#define gDPLoadTextureBlock_4bS(pkt, timg, fmt, width, height, pal, \
4606 cms, cmt, masks, maskt, shifts, shiftt) \
4607_DW({ \
4608 gDPSetTextureImage(pkt, fmt, G_IM_SIZ_16b, 1, timg); \
4609 gDPSetTile(pkt, fmt, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, \
4610 0, cmt, maskt, shiftt, cms, masks, shifts); \
4611 gDPLoadSyncInTexLoad(pkt); \
4612 gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
4613 (((width) * (height) + 3) >> 2) - 1, \
4614 0); \
4615 gDPPipeSyncInTexLoad(pkt); \
4616 gDPSetTile(pkt, fmt, G_IM_SIZ_4b, \
4617 ((((width) >> 1) + 7) >> 3), 0, \
4618 G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, shifts); \
4619 gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \
4620 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4621 ((height) - 1) << G_TEXTURE_IMAGE_FRAC); \
4622})
4623
4627#define gDPLoadMultiBlock_4b(pkt, timg, tmem, rtile, fmt, width, height, pal, \
4628 cms, cmt, masks, maskt, shifts, shiftt) \
4629_DW({ \
4630 gDPSetTextureImage(pkt, fmt, G_IM_SIZ_16b, 1, timg); \
4631 gDPSetTile(pkt, fmt, G_IM_SIZ_16b, 0, tmem, _G_TEXLOADTILE(rtile), \
4632 0, cmt, maskt, shiftt, cms, masks, shifts); \
4633 gDPLoadSyncInTexLoad(pkt); \
4634 gDPLoadBlock(pkt, _G_TEXLOADTILE(rtile), 0, 0, \
4635 (((width) * (height) + 3) >> 2) - 1, \
4636 CALC_DXT_4b(width)); \
4637 gDPPipeSyncInTexLoad(pkt); \
4638 gDPSetTile(pkt, fmt, G_IM_SIZ_4b, \
4639 ((((width) >> 1) + 7) >> 3), tmem, \
4640 rtile, pal, cmt, maskt, shiftt, cms, masks, shifts); \
4641 gDPSetTileSize(pkt, rtile, 0, 0, \
4642 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4643 ((height) - 1) << G_TEXTURE_IMAGE_FRAC); \
4644})
4645
4650#define gDPLoadMultiBlock_4bS(pkt, timg, tmem, rtile, fmt, width, height, pal, \
4651 cms, cmt, masks, maskt, shifts, shiftt) \
4652_DW({ \
4653 gDPSetTextureImage(pkt, fmt, G_IM_SIZ_16b, 1, timg); \
4654 gDPSetTile(pkt, fmt, G_IM_SIZ_16b, 0, tmem, _G_TEXLOADTILE(rtile), \
4655 0, cmt, maskt, shiftt, cms, masks, shifts); \
4656 gDPLoadSyncInTexLoad(pkt); \
4657 gDPLoadBlock(pkt, _G_TEXLOADTILE(rtile), 0, 0, \
4658 (((width) * (height) + 3) >> 2) - 1, \
4659 0); \
4660 gDPPipeSyncInTexLoad(pkt); \
4661 gDPSetTile(pkt, fmt, G_IM_SIZ_4b, \
4662 ((((width) >> 1) + 7) >> 3), tmem, \
4663 rtile, pal, cmt, maskt, shiftt, cms, masks, shifts); \
4664 gDPSetTileSize(pkt, rtile, 0, 0, \
4665 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4666 ((height) - 1) << G_TEXTURE_IMAGE_FRAC); \
4667})
4668
4669
4670#define _gDPLoadTextureBlock_4b(pkt, timg, tmem, fmt, width, height, pal, \
4671 cms, cmt, masks, maskt, shifts, shiftt) \
4672_DW({ \
4673 gDPSetTextureImage(pkt, fmt, G_IM_SIZ_16b, 1, timg); \
4674 gDPSetTile(pkt, fmt, G_IM_SIZ_16b, 0, tmem, G_TX_LOADTILE, \
4675 0, cmt, maskt, shiftt, cms, masks, shifts); \
4676 gDPLoadSyncInTexLoad(pkt); \
4677 gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \
4678 (((width) * (height) + 3) >> 2) - 1, \
4679 CALC_DXT_4b(width)); \
4680 gDPPipeSyncInTexLoad(pkt); \
4681 gDPSetTile(pkt, fmt, G_IM_SIZ_4b, \
4682 ((((width) >> 1) + 7) >> 3), tmem, \
4683 G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, shifts); \
4684 gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \
4685 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4686 ((height) - 1) << G_TEXTURE_IMAGE_FRAC); \
4687})
4688
4689#define gsDPLoadTextureBlock_4b(timg, fmt, width, height, pal, \
4690 cms, cmt, masks, maskt, shifts, shiftt) \
4691 gsDPSetTextureImage(fmt, G_IM_SIZ_16b, 1, timg), \
4692 gsDPSetTile(fmt, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, \
4693 0, cmt, maskt, shiftt, cms, masks, shifts), \
4694 gsDPLoadSyncInTexLoad \
4695 gsDPLoadBlock(G_TX_LOADTILE, 0, 0, \
4696 (((width) * (height) + 3) >> 2) - 1, \
4697 CALC_DXT_4b(width)), \
4698 gsDPPipeSyncInTexLoad \
4699 gsDPSetTile(fmt, G_IM_SIZ_4b, \
4700 ((((width) >> 1) + 7) >> 3), 0, \
4701 G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, shifts), \
4702 gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, \
4703 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4704 ((height) - 1) << G_TEXTURE_IMAGE_FRAC)
4705
4706#define gsDPLoadTextureBlock_4bS(timg, fmt, width, height, pal, \
4707 cms, cmt, masks, maskt, shifts, shiftt) \
4708 gsDPSetTextureImage(fmt, G_IM_SIZ_16b, 1, timg), \
4709 gsDPSetTile(fmt, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, \
4710 0, cmt, maskt, shiftt, cms, masks, shifts), \
4711 gsDPLoadSyncInTexLoad \
4712 gsDPLoadBlock(G_TX_LOADTILE, 0, 0, \
4713 (((width) * (height) + 3) >> 2) - 1, \
4714 0), \
4715 gsDPPipeSyncInTexLoad \
4716 gsDPSetTile(fmt, G_IM_SIZ_4b, \
4717 ((((width) >> 1) + 7) >> 3), 0, \
4718 G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, shifts), \
4719 gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, \
4720 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4721 ((height) - 1) << G_TEXTURE_IMAGE_FRAC)
4722
4727#define gsDPLoadMultiBlock_4b(timg, tmem, rtile, fmt, width, height, pal, \
4728 cms, cmt, masks, maskt, shifts, shiftt) \
4729 gsDPSetTextureImage(fmt, G_IM_SIZ_16b, 1, timg), \
4730 gsDPSetTile(fmt, G_IM_SIZ_16b, 0, tmem, _G_TEXLOADTILE(rtile), \
4731 0, cmt, maskt, shiftt, cms, masks, shifts), \
4732 gsDPLoadSyncInTexLoad \
4733 gsDPLoadBlock(_G_TEXLOADTILE(rtile), 0, 0, \
4734 (((width) * (height) + 3) >> 2) - 1, \
4735 CALC_DXT_4b(width)), \
4736 gsDPPipeSyncInTexLoad \
4737 gsDPSetTile(fmt, G_IM_SIZ_4b, \
4738 ((((width) >> 1) + 7) >> 3), tmem, \
4739 rtile, pal, cmt, maskt, shiftt, cms, masks, shifts), \
4740 gsDPSetTileSize(rtile, 0, 0, \
4741 ((width)-1) << G_TEXTURE_IMAGE_FRAC, \
4742 ((height)-1) << G_TEXTURE_IMAGE_FRAC)
4743
4744
4749#define gsDPLoadMultiBlock_4bS(timg, tmem, rtile, fmt, width, height, pal, \
4750 cms, cmt, masks, maskt, shifts, shiftt) \
4751 gsDPSetTextureImage(fmt, G_IM_SIZ_16b, 1, timg), \
4752 gsDPSetTile(fmt, G_IM_SIZ_16b, 0, tmem, _G_TEXLOADTILE(rtile), \
4753 0, cmt, maskt, shiftt, cms, masks, shifts), \
4754 gsDPLoadSyncInTexLoad \
4755 gsDPLoadBlock(_G_TEXLOADTILE(rtile), 0, 0, \
4756 (((width) * (height) + 3) >> 2) - 1, \
4757 0), \
4758 gsDPPipeSyncInTexLoad \
4759 gsDPSetTile(fmt, G_IM_SIZ_4b, \
4760 ((((width) >> 1) + 7) >> 3), tmem, \
4761 rtile, pal, cmt, maskt, shiftt, cms, masks, shifts), \
4762 gsDPSetTileSize(rtile, 0, 0, \
4763 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4764 ((height) - 1) << G_TEXTURE_IMAGE_FRAC)
4765
4766
4767/*
4768 * Allows tmem address to be specified
4769 */
4770#define _gsDPLoadTextureBlock_4b(timg, tmem, fmt, width, height, pal, \
4771 cms, cmt, masks, maskt, shifts, shiftt) \
4772 gsDPSetTextureImage(fmt, G_IM_SIZ_16b, 1, timg), \
4773 gsDPSetTile(fmt, G_IM_SIZ_16b, 0, tmem, G_TX_LOADTILE, \
4774 0, cmt, maskt, shiftt, cms, masks, shifts), \
4775 gsDPLoadSyncInTexLoad \
4776 gsDPLoadBlock(G_TX_LOADTILE, 0, 0, \
4777 (((width) * (height) + 3) >> 2) - 1, \
4778 CALC_DXT_4b(width)), \
4779 gsDPPipeSyncInTexLoad \
4780 gsDPSetTile(fmt, G_IM_SIZ_4b, \
4781 ((((width) >> 1) + 7) >> 3), tmem, \
4782 G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, shifts), \
4783 gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, \
4784 ((width) - 1) << G_TEXTURE_IMAGE_FRAC, \
4785 ((height) - 1) << G_TEXTURE_IMAGE_FRAC)
4786
4787#define gDPLoadTextureTile(pkt, timg, fmt, siz, width, height, \
4788 uls, ult, lrs, lrt, pal, \
4789 cms, cmt, masks, maskt, shifts, shiftt) \
4790_DW({ \
4791 gDPSetTextureImage(pkt, fmt, siz, width, timg); \
4792 gDPSetTile(pkt, fmt, siz, \
4793 (((((lrs) - (uls) + 1) * siz##_TILE_BYTES) + 7) >> 3), 0, \
4794 G_TX_LOADTILE, 0, cmt, maskt, shiftt, cms, masks, \
4795 shifts); \
4796 gDPLoadSyncInTexLoad(pkt); \
4797 gDPLoadTile(pkt, G_TX_LOADTILE, \
4798 (uls) << G_TEXTURE_IMAGE_FRAC, \
4799 (ult) << G_TEXTURE_IMAGE_FRAC, \
4800 (lrs) << G_TEXTURE_IMAGE_FRAC, \
4801 (lrt) << G_TEXTURE_IMAGE_FRAC); \
4802 gDPPipeSyncInTexLoad(pkt); \
4803 gDPSetTile(pkt, fmt, siz, \
4804 (((((lrs) - (uls) + 1) * siz##_LINE_BYTES) + 7) >> 3), 0, \
4805 G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, shifts); \
4806 gDPSetTileSize(pkt, G_TX_RENDERTILE, \
4807 (uls) << G_TEXTURE_IMAGE_FRAC, \
4808 (ult) << G_TEXTURE_IMAGE_FRAC, \
4809 (lrs) << G_TEXTURE_IMAGE_FRAC, \
4810 (lrt) << G_TEXTURE_IMAGE_FRAC); \
4811})
4812
4817#define gDPLoadMultiTile(pkt, timg, tmem, rtile, fmt, siz, width, height, \
4818 uls, ult, lrs, lrt, pal, \
4819 cms, cmt, masks, maskt, shifts, shiftt) \
4820_DW({ \
4821 gDPSetTextureImage(pkt, fmt, siz, width, timg); \
4822 gDPSetTile(pkt, fmt, siz, \
4823 (((((lrs) - (uls) + 1) * siz##_TILE_BYTES) + 7) >> 3), tmem, \
4824 _G_TEXLOADTILE(rtile), 0, cmt, maskt, shiftt, cms, masks, shifts); \
4825 gDPLoadSyncInTexLoad(pkt); \
4826 gDPLoadTile(pkt, _G_TEXLOADTILE(rtile), \
4827 (uls) << G_TEXTURE_IMAGE_FRAC, \
4828 (ult) << G_TEXTURE_IMAGE_FRAC, \
4829 (lrs) << G_TEXTURE_IMAGE_FRAC, \
4830 (lrt) << G_TEXTURE_IMAGE_FRAC); \
4831 gDPPipeSyncInTexLoad(pkt); \
4832 gDPSetTile(pkt, fmt, siz, \
4833 (((((lrs) - (uls) + 1) * siz##_LINE_BYTES) + 7) >> 3), tmem, \
4834 rtile, pal, cmt, maskt, shiftt, cms, masks, shifts); \
4835 gDPSetTileSize(pkt, rtile, \
4836 (uls) << G_TEXTURE_IMAGE_FRAC, \
4837 (ult) << G_TEXTURE_IMAGE_FRAC, \
4838 (lrs) << G_TEXTURE_IMAGE_FRAC, \
4839 (lrt) << G_TEXTURE_IMAGE_FRAC); \
4840})
4841
4842
4843#define gsDPLoadTextureTile(timg, fmt, siz, width, height, \
4844 uls, ult, lrs, lrt, pal, \
4845 cms, cmt, masks, maskt, shifts, shiftt) \
4846 gsDPSetTextureImage(fmt, siz, width, timg), \
4847 gsDPSetTile(fmt, siz, \
4848 (((((lrs) - (uls) + 1) * siz##_TILE_BYTES) + 7) >> 3), 0, \
4849 G_TX_LOADTILE, 0, cmt, maskt, shiftt, cms, masks, shifts), \
4850 gsDPLoadSyncInTexLoad \
4851 gsDPLoadTile(G_TX_LOADTILE, \
4852 (uls) << G_TEXTURE_IMAGE_FRAC, \
4853 (ult) << G_TEXTURE_IMAGE_FRAC, \
4854 (lrs) << G_TEXTURE_IMAGE_FRAC, \
4855 (lrt) << G_TEXTURE_IMAGE_FRAC), \
4856 gsDPPipeSyncInTexLoad \
4857 gsDPSetTile(fmt, siz, \
4858 (((((lrs) - (uls) + 1) * siz##_LINE_BYTES) + 7) >> 3), 0, \
4859 G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, shifts), \
4860 gsDPSetTileSize(G_TX_RENDERTILE, \
4861 (uls) << G_TEXTURE_IMAGE_FRAC, \
4862 (ult) << G_TEXTURE_IMAGE_FRAC, \
4863 (lrs) << G_TEXTURE_IMAGE_FRAC, \
4864 (lrt) << G_TEXTURE_IMAGE_FRAC)
4865
4870#define gsDPLoadMultiTile(timg, tmem, rtile, fmt, siz, width, height, \
4871 uls, ult, lrs, lrt, pal, \
4872 cms, cmt, masks, maskt, shifts, shiftt) \
4873 gsDPSetTextureImage(fmt, siz, width, timg), \
4874 gsDPSetTile(fmt, siz, \
4875 (((((lrs) - (uls) + 1) * siz##_TILE_BYTES) + 7) >> 3), tmem, \
4876 _G_TEXLOADTILE(rtile), 0, cmt, maskt, shiftt, cms, masks, shifts), \
4877 gsDPLoadSyncInTexLoad \
4878 gsDPLoadTile(_G_TEXLOADTILE(rtile), \
4879 (uls) << G_TEXTURE_IMAGE_FRAC, \
4880 (ult) << G_TEXTURE_IMAGE_FRAC, \
4881 (lrs) << G_TEXTURE_IMAGE_FRAC, \
4882 (lrt) << G_TEXTURE_IMAGE_FRAC), \
4883 gsDPPipeSyncInTexLoad \
4884 gsDPSetTile(fmt, siz, \
4885 (((((lrs) - (uls) + 1) * siz##_LINE_BYTES) + 7) >> 3), \
4886 tmem, rtile, pal, cmt, maskt, shiftt, cms, masks, shifts), \
4887 gsDPSetTileSize(rtile, \
4888 (uls) << G_TEXTURE_IMAGE_FRAC, \
4889 (ult) << G_TEXTURE_IMAGE_FRAC, \
4890 (lrs) << G_TEXTURE_IMAGE_FRAC, \
4891 (lrt) << G_TEXTURE_IMAGE_FRAC)
4892
4893#define gDPLoadTextureTile_4b(pkt, timg, fmt, width, height, \
4894 uls, ult, lrs, lrt, pal, \
4895 cms, cmt, masks, maskt, shifts, shiftt) \
4896_DW({ \
4897 gDPSetTextureImage(pkt, fmt, G_IM_SIZ_8b, ((width) >> 1), timg); \
4898 gDPSetTile(pkt, fmt, G_IM_SIZ_8b, \
4899 (((((lrs) - (uls) + 1) >> 1) + 7) >> 3), 0, \
4900 G_TX_LOADTILE, 0, cmt, maskt, shiftt, cms, masks, shifts); \
4901 gDPLoadSyncInTexLoad(pkt); \
4902 gDPLoadTile(pkt, G_TX_LOADTILE, \
4903 (uls) << (G_TEXTURE_IMAGE_FRAC - 1), \
4904 (ult) << (G_TEXTURE_IMAGE_FRAC), \
4905 (lrs) << (G_TEXTURE_IMAGE_FRAC - 1), \
4906 (lrt) << (G_TEXTURE_IMAGE_FRAC)); \
4907 gDPPipeSyncInTexLoad(pkt); \
4908 gDPSetTile(pkt, fmt, G_IM_SIZ_4b, \
4909 (((((lrs) - (uls) + 1) >> 1) + 7) >> 3), 0, \
4910 G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, shifts); \
4911 gDPSetTileSize(pkt, G_TX_RENDERTILE, \
4912 (uls) << G_TEXTURE_IMAGE_FRAC, \
4913 (ult) << G_TEXTURE_IMAGE_FRAC, \
4914 (lrs) << G_TEXTURE_IMAGE_FRAC, \
4915 (lrt) << G_TEXTURE_IMAGE_FRAC); \
4916})
4917
4922#define gDPLoadMultiTile_4b(pkt, timg, tmem, rtile, fmt, width, height, \
4923 uls, ult, lrs, lrt, pal, \
4924 cms, cmt, masks, maskt, shifts, shiftt) \
4925_DW({ \
4926 gDPSetTextureImage(pkt, fmt, G_IM_SIZ_8b, ((width) >> 1), timg); \
4927 gDPSetTile(pkt, fmt, G_IM_SIZ_8b, \
4928 (((((lrs) - (uls) + 1) >> 1) + 7) >> 3), tmem, \
4929 _G_TEXLOADTILE(rtile), 0, cmt, maskt, shiftt, cms, masks, shifts); \
4930 gDPLoadSyncInTexLoad(pkt); \
4931 gDPLoadTile(pkt, _G_TEXLOADTILE(rtile), \
4932 (uls) << (G_TEXTURE_IMAGE_FRAC - 1), \
4933 (ult) << (G_TEXTURE_IMAGE_FRAC), \
4934 (lrs) << (G_TEXTURE_IMAGE_FRAC - 1), \
4935 (lrt) << (G_TEXTURE_IMAGE_FRAC)); \
4936 gDPPipeSyncInTexLoad(pkt); \
4937 gDPSetTile(pkt, fmt, G_IM_SIZ_4b, \
4938 (((((lrs) - (uls) + 1) >> 1) + 7) >> 3), tmem, \
4939 rtile, pal, cmt, maskt, shiftt, cms, masks, shifts); \
4940 gDPSetTileSize(pkt, rtile, \
4941 (uls) << G_TEXTURE_IMAGE_FRAC, \
4942 (ult) << G_TEXTURE_IMAGE_FRAC, \
4943 (lrs) << G_TEXTURE_IMAGE_FRAC, \
4944 (lrt) << G_TEXTURE_IMAGE_FRAC); \
4945})
4946
4947#define gsDPLoadTextureTile_4b(timg, fmt, width, height, \
4948 uls, ult, lrs, lrt, pal, \
4949 cms, cmt, masks, maskt, shifts, shiftt) \
4950 gsDPSetTextureImage(fmt, G_IM_SIZ_8b, ((width) >> 1), timg), \
4951 gsDPSetTile(fmt, G_IM_SIZ_8b, \
4952 (((((lrs) - (uls) + 1) >> 1) + 7) >> 3), 0, \
4953 G_TX_LOADTILE, 0, cmt, maskt, shiftt, cms, masks, shifts), \
4954 gsDPLoadSyncInTexLoad \
4955 gsDPLoadTile(G_TX_LOADTILE, \
4956 (uls) << (G_TEXTURE_IMAGE_FRAC - 1), \
4957 (ult) << (G_TEXTURE_IMAGE_FRAC), \
4958 (lrs) << (G_TEXTURE_IMAGE_FRAC - 1), \
4959 (lrt) << (G_TEXTURE_IMAGE_FRAC)), \
4960 gsDPPipeSyncInTexLoad \
4961 gsDPSetTile(fmt, G_IM_SIZ_4b, \
4962 (((((lrs) - (uls) + 1) >> 1) + 7) >> 3), 0, \
4963 G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, shifts), \
4964 gsDPSetTileSize(G_TX_RENDERTILE, \
4965 (uls) << G_TEXTURE_IMAGE_FRAC, \
4966 (ult) << G_TEXTURE_IMAGE_FRAC, \
4967 (lrs) << G_TEXTURE_IMAGE_FRAC, \
4968 (lrt) << G_TEXTURE_IMAGE_FRAC)
4969
4973#define gsDPLoadMultiTile_4b(timg, tmem, rtile, fmt, width, height, \
4974 uls, ult, lrs, lrt, pal, \
4975 cms, cmt, masks, maskt, shifts, shiftt) \
4976 \
4977 gsDPSetTextureImage(fmt, G_IM_SIZ_8b, ((width) >> 1), timg), \
4978 gsDPSetTile(fmt, G_IM_SIZ_8b, \
4979 (((((lrs) - (uls) + 1) >> 1) + 7) >> 3), tmem, \
4980 _G_TEXLOADTILE(rtile), 0, cmt, maskt, shiftt, cms, masks, shifts), \
4981 gsDPLoadSyncInTexLoad \
4982 gsDPLoadTile(_G_TEXLOADTILE(rtile), \
4983 (uls) << (G_TEXTURE_IMAGE_FRAC - 1), \
4984 (ult) << (G_TEXTURE_IMAGE_FRAC), \
4985 (lrs) << (G_TEXTURE_IMAGE_FRAC - 1), \
4986 (lrt) << (G_TEXTURE_IMAGE_FRAC)), \
4987 gsDPPipeSyncInTexLoad \
4988 gsDPSetTile(fmt, G_IM_SIZ_4b, \
4989 (((((lrs) - (uls) + 1) >> 1) + 7) >> 3), tmem, \
4990 rtile, pal, cmt, maskt, shiftt, cms, masks, shifts), \
4991 gsDPSetTileSize(rtile, \
4992 (uls) << G_TEXTURE_IMAGE_FRAC, \
4993 (ult) << G_TEXTURE_IMAGE_FRAC, \
4994 (lrs) << G_TEXTURE_IMAGE_FRAC, \
4995 (lrt) << G_TEXTURE_IMAGE_FRAC)
4996
5003#define gDPLoadTLUT_pal16(pkt, pal, dram) \
5004_DW({ \
5005 gDPSetTextureImage(pkt, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dram); \
5006 gDPTileSyncInTexLoad(pkt); \
5007 gDPSetTile(pkt, 0, 0, 0, (256 + (((pal) & 0xF) * 16)), \
5008 _G_PALLOADTILE((pal) & 1), 0, 0, 0, 0, 0, 0, 0); \
5009 gDPLoadSyncInTexLoad(pkt); \
5010 gDPLoadTLUTCmd(pkt, _G_PALLOADTILE((pal) & 1), 15); \
5011 gDPPipeSyncInTexLoad(pkt); \
5012})
5016#define gsDPLoadTLUT_pal16(pal, dram) \
5017 gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dram), \
5018 gsDPTileSyncInTexLoad \
5019 gsDPSetTile(0, 0, 0, (256 + (((pal) & 0xF) * 16)), \
5020 _G_PALLOADTILE((pal) & 1), 0, 0, 0, 0, 0, 0, 0), \
5021 gsDPLoadSyncInTexLoad \
5022 gsDPLoadTLUTCmd(_G_PALLOADTILE((pal) & 1), 15) \
5023 gsDPPipeSyncEndOfTexLoad
5024
5029#define gDPLoadTLUT_pal256(pkt, dram) \
5030_DW({ \
5031 gDPSetTextureImage(pkt, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dram); \
5032 gDPTileSyncInTexLoad(pkt); \
5033 gDPSetTile(pkt, 0, 0, 0, 256, \
5034 _G_PALLOADTILE(0), 0, 0, 0, 0, 0, 0, 0); \
5035 gDPLoadSyncInTexLoad(pkt); \
5036 gDPLoadTLUTCmd(pkt, _G_PALLOADTILE(0), 255); \
5037 gDPPipeSyncInTexLoad(pkt); \
5038})
5039
5043#define gsDPLoadTLUT_pal256(dram) \
5044 gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dram), \
5045 gsDPTileSyncInTexLoad \
5046 gsDPSetTile(0, 0, 0, 256, \
5047 _G_PALLOADTILE(0), 0, 0, 0, 0, 0, 0, 0), \
5048 gsDPLoadSyncInTexLoad \
5049 gsDPLoadTLUTCmd(_G_PALLOADTILE(0), 255) \
5050 gsDPPipeSyncEndOfTexLoad
5051
5052/*
5053 * Assumes that the starting TMEM address is calculated like in DPLoadTLUT_pal16
5054 * (which is the only sane way to do it if you are loading two palettes for
5055 * multitexture)
5056 */
5057#define _G_PALTMEMTOTILE(tmemaddr) _G_PALLOADTILE(((tmemaddr) >> 4) & 1)
5058
5059#define gDPLoadTLUT(pkt, count, tmemaddr, dram) \
5060_DW({ \
5061 gDPSetTextureImage(pkt, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dram); \
5062 gDPTileSyncInTexLoad(pkt); \
5063 gDPSetTile(pkt, 0, 0, 0, tmemaddr, \
5064 _G_PALTMEMTOTILE(tmemaddr), 0, 0, 0, 0, 0, 0, 0); \
5065 gDPLoadSyncInTexLoad(pkt); \
5066 gDPLoadTLUTCmd(pkt, _G_PALTMEMTOTILE(tmemaddr), ((count) - 1)); \
5067 gDPPipeSyncInTexLoad(pkt); \
5068})
5069
5070#define gsDPLoadTLUT(count, tmemaddr, dram) \
5071 gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dram), \
5072 gsDPTileSyncInTexLoad \
5073 gsDPSetTile(0, 0, 0, tmemaddr, \
5074 _G_PALTMEMTOTILE(tmemaddr), 0, 0, 0, 0, 0, 0, 0), \
5075 gsDPLoadSyncInTexLoad \
5076 gsDPLoadTLUTCmd(_G_PALTMEMTOTILE(tmemaddr), ((count) - 1)) \
5077 gsDPPipeSyncEndOfTexLoad
5078
5079
5080
5081#define gDPSetScissor(pkt, mode, ulx, uly, lrx, lry) \
5082_DW({ \
5083 Gfx *_g = (Gfx *)pkt; \
5084 \
5085 _g->words.w0 = (_SHIFTL(G_SETSCISSOR, 24, 8) | \
5086 _SHIFTL((int)((float)(ulx) * 4.0f), 12, 12) | \
5087 _SHIFTL((int)((float)(uly) * 4.0f), 0, 12)); \
5088 _g->words.w1 = (_SHIFTL(mode, 24, 2) | \
5089 _SHIFTL((int)((float)(lrx) * 4.0f), 12, 12) | \
5090 _SHIFTL((int)((float)(lry) * 4.0f), 0, 12)); \
5091})
5092
5093
5094#define gDPSetScissorFrac(pkt, mode, ulx, uly, lrx, lry) \
5095_DW({ \
5096 Gfx *_g = (Gfx *)pkt; \
5097 \
5098 _g->words.w0 = (_SHIFTL(G_SETSCISSOR, 24, 8) | \
5099 _SHIFTL((int)((ulx)), 12, 12) | \
5100 _SHIFTL((int)((uly)), 0, 12)); \
5101 _g->words.w1 = (_SHIFTL(mode, 24, 2) | \
5102 _SHIFTL((int)((lrx)), 12, 12) | \
5103 _SHIFTL((int)((lry)), 0, 12)); \
5104})
5105
5106#define gsDPSetScissor(mode, ulx, uly, lrx, lry) \
5107{ \
5108 (_SHIFTL(G_SETSCISSOR, 24, 8) | \
5109 _SHIFTL((int)((float)(ulx) * 4.0f), 12, 12) | \
5110 _SHIFTL((int)((float)(uly) * 4.0f), 0, 12)), \
5111 (_SHIFTL(mode, 24, 2) | \
5112 _SHIFTL((int)((float)(lrx) * 4.0f), 12, 12) | \
5113 _SHIFTL((int)((float)(lry) * 4.0f), 0, 12)) \
5114}
5115
5116#define gsDPSetScissorFrac(mode, ulx, uly, lrx, lry) \
5117{ \
5118 (_SHIFTL(G_SETSCISSOR, 24, 8) | \
5119 _SHIFTL((int)((ulx)), 12, 12) | \
5120 _SHIFTL((int)((uly)), 0, 12)), \
5121 (_SHIFTL(mode, 24, 2) | \
5122 _SHIFTL((int)(lrx), 12, 12) | \
5123 _SHIFTL((int)(lry), 0, 12)) \
5124}
5125
5126/* Fraction never used in fill */
5127#define gDPFillRectangle(pkt, ulx, uly, lrx, lry) \
5128_DW({ \
5129 Gfx *_g = (Gfx *)(pkt); \
5130 \
5131 _g->words.w0 = (_SHIFTL(G_FILLRECT, 24, 8) | \
5132 _SHIFTL((lrx), 14, 10) | \
5133 _SHIFTL((lry), 2, 10)); \
5134 _g->words.w1 = (_SHIFTL((ulx), 14, 10) | \
5135 _SHIFTL((uly), 2, 10)); \
5136})
5137
5138#define gsDPFillRectangle(ulx, uly, lrx, lry) \
5139{ \
5140 (_SHIFTL(G_FILLRECT, 24, 8) | \
5141 _SHIFTL((lrx), 14, 10) | \
5142 _SHIFTL((lry), 2, 10)), \
5143 (_SHIFTL((ulx), 14, 10) | \
5144 _SHIFTL((uly), 2, 10)) \
5145}
5146
5147/* like gDPFillRectangle but accepts negative arguments */
5148#define gDPScisFillRectangle(pkt, ulx, uly, lrx, lry) \
5149_DW({ \
5150 Gfx *_g = (Gfx *)(pkt); \
5151 \
5152 _g->words.w0 = (_SHIFTL(G_FILLRECT, 24, 8) | \
5153 _SHIFTL(MAX((lrx), 0), 14, 10) | \
5154 _SHIFTL(MAX((lry), 0), 2, 10)); \
5155 _g->words.w1 = (_SHIFTL(MAX((ulx), 0), 14, 10) | \
5156 _SHIFTL(MAX((uly), 0), 2, 10)); \
5157})
5158
5159#define gDPSetConvert(pkt, k0, k1, k2, k3, k4, k5) \
5160_DW({ \
5161 Gfx *_g = (Gfx *)(pkt); \
5162 \
5163 _g->words.w0 = (_SHIFTL(G_SETCONVERT, 24, 8) | \
5164 _SHIFTL(k0, 13, 9) | \
5165 _SHIFTL(k1, 4, 9) | \
5166 _SHIFTR(k2, 5, 4)); \
5167 _g->words.w1 = (_SHIFTL(k2, 27, 5) | \
5168 _SHIFTL(k3, 18, 9) | \
5169 _SHIFTL(k4, 9, 9) | \
5170 _SHIFTL(k5, 0, 9)); \
5171})
5172
5173#define gsDPSetConvert(k0, k1, k2, k3, k4, k5) \
5174{ \
5175 (_SHIFTL(G_SETCONVERT, 24, 8) | \
5176 _SHIFTL(k0, 13, 9) | \
5177 _SHIFTL(k1, 4, 9) | \
5178 _SHIFTL(k2, 5, 4)), \
5179 (_SHIFTL(k2, 27, 5) | \
5180 _SHIFTL(k3, 18, 9) | \
5181 _SHIFTL(k4, 9, 9) | \
5182 _SHIFTL(k5, 0, 9)) \
5183}
5184
5185#define gDPSetKeyR(pkt, cR, sR, wR) \
5186_DW({ \
5187 Gfx *_g = (Gfx *)(pkt); \
5188 \
5189 _g->words.w0 = _SHIFTL(G_SETKEYR, 24, 8); \
5190 _g->words.w1 = (_SHIFTL(wR, 16, 12) | \
5191 _SHIFTL(cR, 8, 8) | \
5192 _SHIFTL(sR, 0, 8)); \
5193})
5194
5195#define gsDPSetKeyR(cR, sR, wR) \
5196{ \
5197 _SHIFTL(G_SETKEYR, 24, 8), \
5198 (_SHIFTL(wR, 16, 12) | \
5199 _SHIFTL(cR, 8, 8) | \
5200 _SHIFTL(sR, 0, 8)) \
5201}
5202
5203#define gDPSetKeyGB(pkt, cG, sG, wG, cB, sB, wB) \
5204_DW({ \
5205 Gfx *_g = (Gfx *)(pkt); \
5206 \
5207 _g->words.w0 = (_SHIFTL(G_SETKEYGB, 24, 8) | \
5208 _SHIFTL(wG, 12, 12) | \
5209 _SHIFTL(wB, 0, 12)); \
5210 _g->words.w1 = (_SHIFTL(cG, 24, 8) | \
5211 _SHIFTL(sG, 16, 8) | \
5212 _SHIFTL(cB, 8, 8) | \
5213 _SHIFTL(sB, 0, 8)); \
5214})
5215
5216#define gsDPSetKeyGB(cG, sG, wG, cB, sB, wB) \
5217{ \
5218 (_SHIFTL(G_SETKEYGB, 24, 8) | \
5219 _SHIFTL(wG, 12, 12) | \
5220 _SHIFTL(wB, 0, 12)), \
5221 (_SHIFTL(cG, 24, 8) | \
5222 _SHIFTL(sG, 16, 8) | \
5223 _SHIFTL(cB, 8, 8) | \
5224 _SHIFTL(sB, 0, 8)) \
5225}
5226
5227#define gDPNoParam(pkt, cmd) \
5228_DW({ \
5229 Gfx *_g = (Gfx *)(pkt); \
5230 \
5231 _g->words.w0 = _SHIFTL(cmd, 24, 8); \
5232 _g->words.w1 = 0; \
5233})
5234
5235#define gsDPNoParam(cmd) \
5236{ \
5237 _SHIFTL(cmd, 24, 8), \
5238 0 \
5239}
5240
5241#define gDPParam(pkt, cmd, param) \
5242_DW({ \
5243 Gfx *_g = (Gfx *)(pkt); \
5244 \
5245 _g->words.w0 = _SHIFTL(cmd, 24, 8); \
5246 _g->words.w1 = (param); \
5247})
5248
5249#define gsDPParam(cmd, param) \
5250{ \
5251 _SHIFTL(cmd, 24, 8), \
5252 (param) \
5253}
5254
5261#define gsDPTextureRectangle(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
5262{ \
5263 (_SHIFTL(G_TEXRECT, 24, 8) | \
5264 _SHIFTL(xh, 12, 12) | \
5265 _SHIFTL(yh, 0, 12)), \
5266 (_SHIFTL(tile, 24, 3) | \
5267 _SHIFTL(xl, 12, 12) | \
5268 _SHIFTL(yl, 0, 12)), \
5269}, \
5270{ \
5271 (_SHIFTL(s, 16, 16) | \
5272 _SHIFTL(t, 0, 16)), \
5273 (_SHIFTL(dsdx, 16, 16) | \
5274 _SHIFTL(dtdy, 0, 16)) \
5275}
5276
5280#define gDPTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
5281_DW({ \
5282 Gfx *_g = (Gfx *)(pkt); \
5283 if (pkt); \
5284 _g->words.w0 = (_SHIFTL(G_TEXRECT, 24, 8) | \
5285 _SHIFTL(xh, 12, 12) | \
5286 _SHIFTL(yh, 0, 12)); \
5287 _g->words.w1 = (_SHIFTL(tile, 24, 3) | \
5288 _SHIFTL(xl, 12, 12) | \
5289 _SHIFTL(yl, 0, 12)); \
5290 _g ++; \
5291 _g->words.w0 = (_SHIFTL(s, 16, 16) | \
5292 _SHIFTL(t, 0, 16)); \
5293 _g->words.w1 = (_SHIFTL(dsdx, 16, 16) | \
5294 _SHIFTL(dtdy, 0, 16)); \
5295})
5296
5297#define gsDPTextureRectangleFlip(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
5298{ \
5299 (_SHIFTL(G_TEXRECTFLIP, 24, 8) | \
5300 _SHIFTL(xh, 12, 12) | \
5301 _SHIFTL(yh, 0, 12)), \
5302 (_SHIFTL(tile, 24, 3) | \
5303 _SHIFTL(xl, 12, 12) | \
5304 _SHIFTL(yl, 0, 12)), \
5305}, \
5306{ \
5307 (_SHIFTL(s, 16, 16) | \
5308 _SHIFTL(t, 0, 16)), \
5309 (_SHIFTL(dsdx, 16, 16) | \
5310 _SHIFTL(dtdy, 0, 16)) \
5311}
5312
5313#define gDPTextureRectangleFlip(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
5314_DW({ \
5315 Gfx *_g = (Gfx *)(pkt); \
5316 if (pkt); \
5317 _g->words.w0 = (_SHIFTL(G_TEXRECTFLIP, 24, 8) | \
5318 _SHIFTL(xh, 12, 12) | \
5319 _SHIFTL(yh, 0, 12)); \
5320 _g->words.w1 = (_SHIFTL(tile, 24, 3) | \
5321 _SHIFTL(xl, 12, 12) | \
5322 _SHIFTL(yl, 0, 12)); \
5323 _g ++; \
5324 _g->words.w0 = (_SHIFTL(s, 16, 16) | \
5325 _SHIFTL(t, 0, 16)); \
5326 _g->words.w1 = (_SHIFTL(dsdx, 16, 16) | \
5327 _SHIFTL(dtdy, 0, 16)); \
5328})
5329
5330#define gsSPTextureRectangle(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
5331 (_SHIFTL(G_TEXRECT, 24, 8) | \
5332 _SHIFTL(xh, 12, 12) | \
5333 _SHIFTL(yh, 0, 12)), \
5334 (_SHIFTL(tile, 24, 3) | \
5335 _SHIFTL(xl, 12, 12) | \
5336 _SHIFTL(yl, 0, 12)), \
5337 gsImmp1(G_RDPHALF_1, \
5338 (_SHIFTL(s, 16, 16) | \
5339 _SHIFTL(t, 0, 16))), \
5340 gsImmp1(G_RDPHALF_2, \
5341 (_SHIFTL(dsdx, 16, 16) | \
5342 _SHIFTL(dtdy, 0, 16)))
5343
5344#define gSPTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
5345_DW({ \
5346 Gfx *_g = (Gfx *)(pkt); \
5347 \
5348 _g->words.w0 = (_SHIFTL(G_TEXRECT, 24, 8) | \
5349 _SHIFTL(xh, 12, 12) | \
5350 _SHIFTL(yh, 0, 12)); \
5351 _g->words.w1 = (_SHIFTL(tile, 24, 3) | \
5352 _SHIFTL(xl, 12, 12) | \
5353 _SHIFTL(yl, 0, 12)); \
5354 gImmp1(pkt, G_RDPHALF_1, \
5355 (_SHIFTL(s, 16, 16) | \
5356 _SHIFTL(t, 0, 16))); \
5357 gImmp1(pkt, G_RDPHALF_2, \
5358 (_SHIFTL(dsdx, 16, 16) | \
5359 _SHIFTL(dtdy, 0, 16))); \
5360})
5361
5362/* like gSPTextureRectangle but accepts negative position arguments */
5363#define gSPScisTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
5364_DW({ \
5365 Gfx *_g = (Gfx *)(pkt); \
5366 \
5367 _g->words.w0 = (_SHIFTL(G_TEXRECT, 24, 8) | \
5368 _SHIFTL(MAX((s16)(xh),0), 12, 12) | \
5369 _SHIFTL(MAX((s16)(yh),0), 0, 12)); \
5370 _g->words.w1 = (_SHIFTL((tile), 24, 3) | \
5371 _SHIFTL(MAX((s16)(xl),0), 12, 12) | \
5372 _SHIFTL(MAX((s16)(yl),0), 0, 12)); \
5373 gImmp1(pkt, G_RDPHALF_1, \
5374 (_SHIFTL(((s) - \
5375 (((s16)(xl) < 0) ? \
5376 (((s16)(dsdx) < 0) ? \
5377 (MAX((((s16)(xl) * (s16)(dsdx)) >> 7), 0)) : \
5378 (MIN((((s16)(xl) * (s16)(dsdx)) >> 7), 0))) : 0)), 16, 16) | \
5379 _SHIFTL(((t) - \
5380 (( (yl) < 0) ? \
5381 (((s16)(dtdy) < 0) ? \
5382 (MAX((((s16)(yl) * (s16)(dtdy)) >> 7), 0)) : \
5383 (MIN((((s16)(yl) * (s16)(dtdy)) >> 7), 0))) : 0)), 0, 16))); \
5384 gImmp1(pkt, G_RDPHALF_2, \
5385 (_SHIFTL((dsdx), 16, 16) | \
5386 _SHIFTL((dtdy), 0, 16))); \
5387})
5388
5389#define gsSPTextureRectangleFlip(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
5390 (_SHIFTL(G_TEXRECTFLIP, 24, 8) | \
5391 _SHIFTL(xh, 12, 12) | \
5392 _SHIFTL(yh, 0, 12)), \
5393 (_SHIFTL(tile, 24, 3) | \
5394 _SHIFTL(xl, 12, 12) | \
5395 _SHIFTL(yl, 0, 12)), \
5396 gsImmp1(G_RDPHALF_1, \
5397 (_SHIFTL(s, 16, 16) | \
5398 _SHIFTL(t, 0, 16))), \
5399 gsImmp1(G_RDPHALF_2, \
5400 (_SHIFTL(dsdx, 16, 16) | \
5401 _SHIFTL(dtdy, 0, 16)))
5402
5403#define gSPTextureRectangleFlip(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
5404_DW({ \
5405 Gfx *_g = (Gfx *)(pkt); \
5406 \
5407 _g->words.w0 = (_SHIFTL(G_TEXRECTFLIP, 24, 8) | \
5408 _SHIFTL(xh, 12, 12) | \
5409 _SHIFTL(yh, 0, 12)); \
5410 _g->words.w1 = (_SHIFTL(tile, 24, 3) | \
5411 _SHIFTL(xl, 12, 12) | \
5412 _SHIFTL(yl, 0, 12)); \
5413 gImmp1(pkt, G_RDPHALF_1, \
5414 (_SHIFTL(s, 16, 16) | \
5415 _SHIFTL(t, 0, 16))); \
5416 gImmp1(pkt, G_RDPHALF_2, \
5417 (_SHIFTL(dsdx, 16, 16) | \
5418 _SHIFTL(dtdy, 0, 16))); \
5419})
5420
5421#define gsDPWord(wordhi, wordlo) \
5422 gsImmp1(G_RDPHALF_1, (unsigned int)(wordhi)), \
5423 gsImmp1(G_RDPHALF_2, (unsigned int)(wordlo))
5424
5425#define gDPWord(pkt, wordhi, wordlo) \
5426_DW({ \
5427 Gfx *_g = (Gfx *)(pkt); \
5428 gImmp1(pkt, G_RDPHALF_1, (unsigned int)(wordhi)); \
5429 gImmp1(pkt, G_RDPHALF_2, (unsigned int)(wordlo)); \
5430})
5431
5432#ifdef RISKY_RDP_SYNCS
5433/*
5434 * The community has found that in nearly all instances, a tile sync is
5435 * sufficient where a pipe sync is normally used--between rendering something
5436 * and changing critical RDP settings. However, we are not 100% sure this is
5437 * true for all obscure settings, so it is risky.
5438*/
5439#define G_USEASPIPESYNC G_RDPTILESYNC
5440#else
5441#define G_USEASPIPESYNC G_RDPPIPESYNC
5442#endif
5443
5444#define gDPFullSync(pkt) gDPNoParam(pkt, G_RDPFULLSYNC)
5445#define gsDPFullSync() gsDPNoParam( G_RDPFULLSYNC)
5446#define gDPTileSync(pkt) gDPNoParam(pkt, G_RDPTILESYNC)
5447#define gsDPTileSync() gsDPNoParam( G_RDPTILESYNC)
5448#define gDPPipeSync(pkt) gDPNoParam(pkt, G_USEASPIPESYNC)
5449#define gsDPPipeSync() gsDPNoParam( G_USEASPIPESYNC)
5450#define gDPLoadSync(pkt) gDPNoParam(pkt, G_RDPLOADSYNC)
5451#define gsDPLoadSync() gsDPNoParam( G_RDPLOADSYNC)
5452#define gDPNoOp(pkt) gDPNoParam(pkt, G_NOOP)
5453#define gsDPNoOp() gsDPNoParam( G_NOOP)
5454#define gDPNoOpTag(pkt, tag) gDPParam(pkt, G_NOOP, tag)
5455#define gsDPNoOpTag(tag) gsDPParam( G_NOOP, tag)
5456
5457#define gDPNoOpHere(pkt, file, line) gDma1p(pkt, G_NOOP, file, line, 1)
5458#define gDPNoOpString(pkt, data, n) gDma1p(pkt, G_NOOP, data, n, 2)
5459#define gDPNoOpWord(pkt, data, n) gDma1p(pkt, G_NOOP, data, n, 3)
5460#define gDPNoOpFloat(pkt, data, n) gDma1p(pkt, G_NOOP, data, n, 4)
5461#define gDPNoOpQuiet(pkt) gDma1p(pkt, G_NOOP, 0, 0, 5)
5462#define gDPNoOpVerbose(pkt, n) gDma1p(pkt, G_NOOP, 0, n, 5)
5463#define gDPNoOpCallBack(pkt, callback, arg) gDma1p(pkt, G_NOOP, callback, arg, 6)
5464#define gDPNoOpOpenDisp(pkt, file, line) gDma1p(pkt, G_NOOP, file, line, 7)
5465#define gDPNoOpCloseDisp(pkt, file, line) gDma1p(pkt, G_NOOP, file, line, 8)
5466#define gDPNoOpTag3(pkt, type, data, n) gDma1p(pkt, G_NOOP, data, n, type)
5467
5468#endif /* F3DEX3_H */
long int Mtx_t[4][4]
Definition gbi.h:1085
Definition gbi.h:1225
char pad1
Definition gbi.h:1227
char pad2
Definition gbi.h:1229
Definition gbi.h:1728
Definition gbi.h:1718
Definition gbi.h:1749
Definition gbi.h:1739
Definition gbi.h:1844
Definition gbi.h:1760
Definition gbi.h:1979
Definition gbi.h:1195
char pad3
Definition gbi.h:1201
unsigned char type
Definition gbi.h:1197
char pad2
Definition gbi.h:1199
Definition gbi.h:1212
unsigned char kq
Definition gbi.h:1218
unsigned char size
Definition gbi.h:1219
unsigned char kc
Definition gbi.h:1214
unsigned char kl
Definition gbi.h:1216
Definition gbi.h:1960
Definition gbi.h:1075
Definition gbi.h:1178
Definition gbi.h:1035
unsigned short flag
Definition gbi.h:1037
Definition gbi.h:1045
unsigned char a
Definition gbi.h:1050
unsigned short flag
Definition gbi.h:1047
Definition gbi.h:1988
Definition gbi.h:1056
long long int force_structure_alignment
Definition gbi.h:1059
Vtx_tn n
Definition gbi.h:1058