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