1 /*---------------------------------------------------------------------------*
2 Project: Dolphin
3 File: gd-init-create.c
4
5 Copyright 2001 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Log: gd-init-create.c,v $
14 Revision 1.2 02/20/2006 04:13:09 mitu
15 changed include path from dolphin/ to revolution/.
16
17 Revision 1.1 02/08/2006 11:19:43 mitu
18 1st version.
19
20
21 1 9/25/01 6:23p Carl
22 Sources for GD init demo.
23
24 $NoKeywords: $
25 *---------------------------------------------------------------------------*/
26
27 #include <revolution/gd.h>
28 #include <revolution/mtx/GeoTypes.h>
29
30 #ifdef WIN32
31 #include <assert.h>
32 #include <stdlib.h>
33 #else
34 #include <revolution/os.h>
35 #endif
36
37 /*---------------------------------------------------------------------------*/
38
39 #ifdef WIN32
40 #define ASSERT assert
41 #define OSRoundUp32B(x) (((u32)(x) + 31) & ~31)
42 #define OSAlloc(x) ((void*)OSRoundUp32B(malloc((x)+31)))
43 #define OSFree(x) free(x)
44 #endif
45
46 /*---------------------------------------------------------------------------*
47 Forward references
48 *---------------------------------------------------------------------------*/
49
50 void CreateDLs( void );
51
52 /*---------------------------------------------------------------------------*
53 Global variables
54 *---------------------------------------------------------------------------*/
55
56 // Display lists *************************************************************
57
58 // This DL is used with the "Draw" display list.
59 // It initializes state that will be used by the Draw DL.
60
61 extern GDLObj InitDLO;
62 #define INIT_STATE_SIZE 2048 // maximum (not actual) size
63
64 // This DL draws a cube.
65
66 extern GDLObj DrawDLO;
67 #define DRAW_SIZE 2048 // maximum (not actual) size
68
69 // This array indicates the offsets to patch memory addresses for the
70 // primitive data arrays (positions, colors) referred to in the Init DL.
71
72 extern u32 *setArrayOffsets;
73
74 /*---------------------------------------------------------------------------*
75 Functions
76 *---------------------------------------------------------------------------*/
77
78 /*---------------------------------------------------------------------------*
79 Name: CreateDLs
80
81 Description: Creates the display lists used by the program.
82
83 Arguments: none
84
85 Returns: none
86 *---------------------------------------------------------------------------*/
CreateDLs(void)87 void CreateDLs ( void )
88 {
89 u8 *InitStateList;
90 u8 *DrawList;
91
92 f32 identity_mtx[3][4];
93 GXColor black = {0, 0, 0, 0};
94 GXColor white = {255, 255, 255, 255};
95 u32 i;
96
97 //
98 // Create the init-state DL
99 //
100
101 // This display list (for the most part) follows the settings of GXInit.
102 // Whatever GXInit does (regarding GX API initialization), this DL also
103 // does (wherever possible).
104 //
105 // We also set up a few things in order to draw a cube in the draw DL.
106
107 InitStateList = OSAlloc( INIT_STATE_SIZE );
108 ASSERT(InitStateList);
109
110 setArrayOffsets = OSAlloc( 2 * sizeof(u32) );
111 ASSERT(setArrayOffsets);
112
113 GDInitGDLObj( &InitDLO, InitStateList, INIT_STATE_SIZE );
114 GDSetCurrent( &InitDLO );
115
116 // ----------------------------------------------------------------------
117
118 // Here we follow GXInit, section by section.
119 // The comments not in parenthesis are from the original GXInit code.
120
121 //
122 // Geometry and Vertex
123 //
124
125 GDSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0,
126 GX_FALSE, GX_PTIDENTITY);
127 GDSetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1,
128 GX_FALSE, GX_PTIDENTITY);
129 GDSetTexCoordGen(GX_TEXCOORD2, GX_TG_MTX2x4, GX_TG_TEX2,
130 GX_FALSE, GX_PTIDENTITY);
131 GDSetTexCoordGen(GX_TEXCOORD3, GX_TG_MTX2x4, GX_TG_TEX3,
132 GX_FALSE, GX_PTIDENTITY);
133 GDSetTexCoordGen(GX_TEXCOORD4, GX_TG_MTX2x4, GX_TG_TEX4,
134 GX_FALSE, GX_PTIDENTITY);
135 GDSetTexCoordGen(GX_TEXCOORD5, GX_TG_MTX2x4, GX_TG_TEX5,
136 GX_FALSE, GX_PTIDENTITY);
137 GDSetTexCoordGen(GX_TEXCOORD6, GX_TG_MTX2x4, GX_TG_TEX6,
138 GX_FALSE, GX_PTIDENTITY);
139 GDSetTexCoordGen(GX_TEXCOORD7, GX_TG_MTX2x4, GX_TG_TEX7,
140 GX_FALSE, GX_PTIDENTITY);
141 // (GDSetGenMode2: nTexgens, nChannels, nTevs, nIndirects, cullmode)
142 GDSetGenMode2(1, 0, 1, 0, GX_CULL_BACK);
143
144 // (GXInit just clears the VCD and does not touch the VATs.
145 // That is not so useful, so here as an example we set the
146 // VCD and VAT 0 as required by this demo.)
147 {
148 static GXVtxDescList vcd[] = {
149 { GX_VA_POS, GX_INDEX8 },
150 { GX_VA_CLR0, GX_INDEX8 },
151 { GX_VA_NULL, GX_NONE }, // NULL terminator is required
152 };
153 static GXVtxAttrFmtList vat[] = {
154 { GX_VA_POS, GX_POS_XYZ, GX_F32, 0 },
155 { GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0 },
156 { GX_VA_NULL, GX_POS_XY, GX_U8, 0 }, // NULL terminator is required
157 };
158
159 GDSetVtxDescv( vcd );
160 GDSetVtxAttrFmtv( GX_VTXFMT0, vat );
161 }
162
163 // (Vertex cache invalidation is not part of GD.)
164
165 // (For the line-aspect ratio, GXInit looks at the render mode in
166 // order to set this properly. We assume frame-rendering mode here.)
167 GDSetLPSize(6, 6, GX_TO_ZERO, GX_TO_ZERO, GX_DISABLE);
168
169 // (Line/point texture-offset enables are set with texcoord scaling.)
170 // (As an example, we show how to set one here; we do not set all 8.)
171 GDSetTexCoordScaleAndTOEs( GX_TEXCOORD0, // tcoord
172 128, GX_FALSE, GX_FALSE, // s size, bias, wrap
173 128, GX_FALSE, GX_FALSE, // t size, bias, wrap
174 GX_DISABLE, GX_DISABLE ); // tex-offset enables
175
176 //
177 // Transformation and Matrix
178 //
179
180 identity_mtx[0][0] = 1.0f; identity_mtx[0][1] = 0.0f;
181 identity_mtx[0][2] = 0.0f; identity_mtx[0][3] = 0.0f;
182 identity_mtx[1][0] = 0.0f; identity_mtx[1][1] = 1.0f;
183 identity_mtx[1][2] = 0.0f; identity_mtx[1][3] = 0.0f;
184 identity_mtx[2][0] = 0.0f; identity_mtx[2][1] = 0.0f;
185 identity_mtx[2][2] = 1.0f; identity_mtx[2][3] = 0.0f;
186
187 // (Setting projection matrix is not part of GXInit or GD.)
188 GDLoadPosMtxImm(identity_mtx, GX_PNMTX0);
189 GDLoadNrmMtxImm(identity_mtx, GX_PNMTX0);
190 GDSetCurrentMtx(GX_PNMTX0,
191 GX_IDENTITY, GX_IDENTITY, GX_IDENTITY, GX_IDENTITY,
192 GX_IDENTITY, GX_IDENTITY, GX_IDENTITY, GX_IDENTITY);
193 GDLoadTexMtxImm(identity_mtx, GX_IDENTITY, GX_MTX3x4);
194 GDLoadTexMtxImm(identity_mtx, GX_PTIDENTITY, GX_MTX3x4);
195 // (Setting viewport is not part of GD.)
196
197 //
198 // Clipping and Culling
199 //
200
201 GDSetCoPlanar(GX_DISABLE);
202 // (Setting clip mode is not part of GD.)
203 // (Setting scissoring is not part of GD.)
204
205 //
206 // Lighting - pass vertex color through
207 //
208
209 GDSetChanCtrl(
210 GX_COLOR0A0,
211 GX_DISABLE,
212 GX_SRC_REG,
213 GX_SRC_VTX,
214 GX_LIGHT_NULL,
215 GX_DF_NONE,
216 GX_AF_NONE );
217
218 GDSetChanAmbColor(GX_COLOR0A0, black);
219 GDSetChanMatColor(GX_COLOR0A0, white);
220
221 GDSetChanCtrl(
222 GX_COLOR1A1,
223 GX_DISABLE,
224 GX_SRC_REG,
225 GX_SRC_VTX,
226 GX_LIGHT_NULL,
227 GX_DF_NONE,
228 GX_AF_NONE );
229
230 GDSetChanAmbColor(GX_COLOR1A1, black);
231 GDSetChanMatColor(GX_COLOR1A1, white);
232
233 //
234 // Texture
235 //
236
237 // (Texture cache invalidation is not part of GD.)
238
239 // Allocate 8 32k caches for RGBA texture mipmaps.
240 // Equal size caches to support 32b RGBA textures.
241 //
242
243 // (This is the default TMEM configuration set in GXInit.
244 // Note that texmap ID's are bound to specific regions.)
245
246 GDSetTexCached( GX_TEXMAP0, 0x00000, GX_TEXCACHE_32K,
247 0x80000, GX_TEXCACHE_32K );
248 GDSetTexCached( GX_TEXMAP1, 0x08000, GX_TEXCACHE_32K,
249 0x88000, GX_TEXCACHE_32K );
250 GDSetTexCached( GX_TEXMAP2, 0x10000, GX_TEXCACHE_32K,
251 0x90000, GX_TEXCACHE_32K );
252 GDSetTexCached( GX_TEXMAP3, 0x18000, GX_TEXCACHE_32K,
253 0x98000, GX_TEXCACHE_32K );
254 GDSetTexCached( GX_TEXMAP4, 0x20000, GX_TEXCACHE_32K,
255 0xa0000, GX_TEXCACHE_32K );
256 GDSetTexCached( GX_TEXMAP5, 0x28000, GX_TEXCACHE_32K,
257 0xa8000, GX_TEXCACHE_32K );
258 GDSetTexCached( GX_TEXMAP6, 0x30000, GX_TEXCACHE_32K,
259 0xb0000, GX_TEXCACHE_32K );
260 GDSetTexCached( GX_TEXMAP7, 0x38000, GX_TEXCACHE_32K,
261 0xb8000, GX_TEXCACHE_32K );
262
263 // Allocate color index caches in low bank of TMEM.
264 // Each cache is 32kB.
265 // Even and odd regions should be allocated on different address.
266 //
267 #if 0
268 // (This is an example of how you would rebind 4 texmap ID's
269 // to map to the setup suggested above.)
270
271 GDSetTexCached( GX_TEXMAP0, 0x40000, GX_TEXCACHE_32K,
272 0x48000, GX_TEXCACHE_32K );
273 GDSetTexCached( GX_TEXMAP1, 0x50000, GX_TEXCACHE_32K,
274 0x58000, GX_TEXCACHE_32K );
275 GDSetTexCached( GX_TEXMAP2, 0x60000, GX_TEXCACHE_32K,
276 0x68000, GX_TEXCACHE_32K );
277 GDSetTexCached( GX_TEXMAP3, 0x70000, GX_TEXCACHE_32K,
278 0x78000, GX_TEXCACHE_32K );
279 #endif
280
281 // Allocate TLUTs, 16 256-entry TLUTs and 4 1K-entry TLUTs.
282 // 256-entry TLUTs are 8kB, 1k-entry TLUTs are 32kB.
283 //
284 #if 0
285 // (This is an example of how you would bind 4 texmap ID's
286 // to 4 256-entry RGB565 TLUT's and the other 4 texmap ID's
287 // to 4 1K-entry RGB565 TLUT's. The bindings are only relevant
288 // if the texmaps are color-index format, of course.)
289
290 GDSetTexTlut( GX_TEXMAP0, 0xc0000, GX_TL_RGB565 );
291 GDSetTexTlut( GX_TEXMAP1, 0xc2000, GX_TL_RGB565 );
292 GDSetTexTlut( GX_TEXMAP2, 0xc4000, GX_TL_RGB565 );
293 GDSetTexTlut( GX_TEXMAP3, 0xc6000, GX_TL_RGB565 );
294
295 GDSetTexTlut( GX_TEXMAP4, 0xe0000, GX_TL_RGB565 );
296 GDSetTexTlut( GX_TEXMAP5, 0xe8000, GX_TL_RGB565 );
297 GDSetTexTlut( GX_TEXMAP6, 0xf0000, GX_TL_RGB565 );
298 GDSetTexTlut( GX_TEXMAP7, 0xf8000, GX_TL_RGB565 );
299 #endif
300
301 //
302 // Set texture region and tlut region Callbacks
303 //
304
305 // (GD does not have any concept of region callbacks.
306 // Texmap ID's are bound to regions explicitly.)
307
308 //
309 // Texture Environment
310 //
311 GDSetTevOrder(GX_TEVSTAGE0,
312 GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0,
313 GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR0A0 );
314 GDSetTevOrder(GX_TEVSTAGE2,
315 GX_TEXCOORD2, GX_TEXMAP2, GX_COLOR0A0,
316 GX_TEXCOORD3, GX_TEXMAP3, GX_COLOR0A0 );
317 GDSetTevOrder(GX_TEVSTAGE4,
318 GX_TEXCOORD4, GX_TEXMAP4, GX_COLOR0A0,
319 GX_TEXCOORD5, GX_TEXMAP5, GX_COLOR0A0 );
320 GDSetTevOrder(GX_TEVSTAGE6,
321 GX_TEXCOORD6, GX_TEXMAP6, GX_COLOR0A0,
322 GX_TEXCOORD7, GX_TEXMAP7, GX_COLOR0A0 );
323
324 GDSetTevOrder(GX_TEVSTAGE8,
325 GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL,
326 GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL );
327 GDSetTevOrder(GX_TEVSTAGE10,
328 GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL,
329 GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL );
330 GDSetTevOrder(GX_TEVSTAGE12,
331 GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL,
332 GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL );
333 GDSetTevOrder(GX_TEVSTAGE14,
334 GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL,
335 GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL );
336
337 GDSetTevOp(GX_TEVSTAGE0, GX_REPLACE);
338 GDSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
339 GDSetZTexture(GX_ZT_DISABLE, GX_TF_Z8, 0);
340
341 for (i = GX_TEVSTAGE0; i < GX_MAX_TEVSTAGE; i+=2) {
342 GDSetTevKonstantSel((GXTevStageID) i,
343 GX_TEV_KCSEL_1_4, GX_TEV_KASEL_1,
344 GX_TEV_KCSEL_1_4, GX_TEV_KASEL_1 );
345 // (Swap mode is set with TevOp.)
346 }
347 GDSetTevSwapModeTable(GX_TEV_SWAP0,
348 GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA);
349 GDSetTevSwapModeTable(GX_TEV_SWAP1,
350 GX_CH_RED, GX_CH_RED, GX_CH_RED, GX_CH_ALPHA);
351 GDSetTevSwapModeTable(GX_TEV_SWAP2,
352 GX_CH_GREEN, GX_CH_GREEN, GX_CH_GREEN, GX_CH_ALPHA);
353 GDSetTevSwapModeTable(GX_TEV_SWAP3,
354 GX_CH_BLUE, GX_CH_BLUE, GX_CH_BLUE, GX_CH_ALPHA);
355
356 // Indirect Textures.
357
358 // (Indirect texturing is not yet part of GD.)
359
360 //
361 // Pixel Processing
362 //
363 GDSetFog(GX_FOG_NONE, 0.0F, 1.0F, 0.1F, 1.0F, black);
364 // (Fog range adjust in not part of GD.)
365 GDSetBlendModeEtc(GX_BM_NONE,
366 GX_BL_SRCALPHA, // src factor
367 GX_BL_INVSRCALPHA, // dst factor
368 GX_LO_CLEAR,
369 GX_ENABLE, // color update
370 GX_ENABLE, // alpha update
371 GX_ENABLE); // dither enable
372
373 GDSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
374 // (Z compare location is not part of GD.)
375 GDSetDstAlpha(GX_DISABLE, 0);
376 // (pixel format is not part of GD.)
377 // (field mask is not part of GD.)
378 // (field mode is not part of GD, except for line aspect ratio.)
379
380 //
381 // Framebuffer
382 //
383
384 // (Framebuffer operations are not part of GD.)
385
386 //
387 // CPU direct EFB access
388 //
389
390 // (This is not part of GD either.)
391
392 //
393 // Performance Counters
394 //
395
396 // (Nor is this.)
397
398 // ----------------------------------------------------------------------
399
400 // That is all of the GXInit-related code.
401 //
402 // The rest of this DL is for the demo.
403
404 // Set the vertex array pointers and strides. The actual array
405 // pointers will be patched in later, so we need to keep track of
406 // these patch points.
407 // We add a bit to skip over the command token and register ID bytes.
408
409 setArrayOffsets[0] = GDGetCurrOffset() + CP_DATA_OFFSET;
410 GDSetArrayRaw(GX_VA_POS, 0, 12);
411
412 setArrayOffsets[1] = GDGetCurrOffset() + CP_DATA_OFFSET;
413 GDSetArrayRaw(GX_VA_CLR0, 0, 4);
414
415 // The actual TEV/texture/color-channel configuration we need
416 // is different than what GXInit sets up, so we change it here:
417
418 GDSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
419 GDSetGenMode(0, 1, 1); // 0 texgens, 1 channel, 1 tevstage
420
421 // pad & flush
422 GDPadCurr32();
423 GDFlushCurrToMem(); // not strictly needed for PC-side, but not a bad idea
424
425 //
426 // Create the cube drawing DL
427 //
428
429 // Draw DL: commands to draw the actual geometry.
430 // Just draws a plain cube with color-indexed face colors.
431
432 DrawList = OSAlloc( DRAW_SIZE );
433 ASSERT(DrawList);
434
435 GDInitGDLObj( &DrawDLO, DrawList, DRAW_SIZE );
436 GDSetCurrent( &DrawDLO );
437
438 // face 1
439
440 GDBegin( GX_QUADS, GX_VTXFMT0, 4 );
441 GDPosition1x8( 0 ); GDColor1x8( 0 );
442 GDPosition1x8( 1 ); GDColor1x8( 0 );
443 GDPosition1x8( 2 ); GDColor1x8( 0 );
444 GDPosition1x8( 3 ); GDColor1x8( 0 );
445 GDEnd();
446
447 // face 2
448
449 GDBegin( GX_QUADS, GX_VTXFMT0, 4 );
450 GDPosition1x8( 4 ); GDColor1x8( 1 );
451 GDPosition1x8( 5 ); GDColor1x8( 1 );
452 GDPosition1x8( 6 ); GDColor1x8( 1 );
453 GDPosition1x8( 7 ); GDColor1x8( 1 );
454 GDEnd();
455
456 // face 3
457
458 GDBegin( GX_QUADS, GX_VTXFMT0, 4 );
459 GDPosition1x8( 2 ); GDColor1x8( 2 );
460 GDPosition1x8( 6 ); GDColor1x8( 2 );
461 GDPosition1x8( 5 ); GDColor1x8( 2 );
462 GDPosition1x8( 3 ); GDColor1x8( 2 );
463 GDEnd();
464
465 // face 4
466
467 GDBegin( GX_QUADS, GX_VTXFMT0, 4 );
468 GDPosition1x8( 1 ); GDColor1x8( 3 );
469 GDPosition1x8( 0 ); GDColor1x8( 3 );
470 GDPosition1x8( 4 ); GDColor1x8( 3 );
471 GDPosition1x8( 7 ); GDColor1x8( 3 );
472 GDEnd();
473
474 // face 5
475
476 GDBegin( GX_QUADS, GX_VTXFMT0, 4 );
477 GDPosition1x8( 5 ); GDColor1x8( 4 );
478 GDPosition1x8( 4 ); GDColor1x8( 4 );
479 GDPosition1x8( 0 ); GDColor1x8( 4 );
480 GDPosition1x8( 3 ); GDColor1x8( 4 );
481 GDEnd();
482
483 // face 6
484
485 GDBegin( GX_QUADS, GX_VTXFMT0, 4 );
486 GDPosition1x8( 6 ); GDColor1x8( 5 );
487 GDPosition1x8( 2 ); GDColor1x8( 5 );
488 GDPosition1x8( 1 ); GDColor1x8( 5 );
489 GDPosition1x8( 7 ); GDColor1x8( 5 );
490 GDEnd();
491
492 // pad & flush
493 GDPadCurr32();
494 GDFlushCurrToMem(); // not strictly needed for PC-side, but not a bad idea
495
496 GDSetCurrent(NULL); // bug-prevention
497 }
498