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