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