1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: frb-fld-int.c
4
5 Copyright 1998-2006 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
14 #include <demo.h>
15
16 /*---------------------------------------------------------------------------*
17 The macro ATTRIBUTE_ALIGN provides a convenient way to align initialized
18 arrays. Alignment of vertex arrays to 32B IS NOT required, but may result
19 in a slight performance improvement.
20 *---------------------------------------------------------------------------*/
21 f32 Verts_f32[] ATTRIBUTE_ALIGN(32) =
22 {
23 // x, y, z
24 0.0f, 0.0f, 1.0f, // 0:0
25 0.0f, 1.0f, 0.0f, // 0:1
26 1.0f, 0.0f, 0.0f, // 0:2
27 0.0f, 0.0f, 1.0f, // 1:0
28 -1.0f, 0.0f, 0.0f, // 1:1
29 0.0f, 1.0f, 0.0f, // 1:2
30 0.0f, 0.0f, 1.0f, // 2:0
31 0.0f, -1.0f, 0.0f, // 2:1
32 -1.0f, 0.0f, 0.0f, // 2:2
33 0.0f, 0.0f, 1.0f, // 3:0
34 1.0f, 0.0f, 0.0f, // 3:1
35 0.0f, -1.0f, 0.0f, // 3:2
36 0.0f, 0.0f, -1.0f, // 4:0
37 1.0f, 0.0f, 0.0f, // 4:1
38 0.0f, 1.0f, 0.0f, // 4:2
39 0.0f, 0.0f, -1.0f, // 5:0
40 0.0f, 1.0f, 0.0f, // 5:1
41 -1.0f, 0.0f, 0.0f, // 5:2
42 0.0f, 0.0f, -1.0f, // 6:0
43 -1.0f, 0.0f, 0.0f, // 6:1
44 0.0f, -1.0f, 0.0f, // 6:2
45 0.0f, 0.0f, -1.0f, // 7:0
46 0.0f, -1.0f, 0.0f, // 7:1
47 1.0f, 0.0f, 0.0f // 7:2
48 };
49
50 u8 Colors_rgba8[] ATTRIBUTE_ALIGN(32) =
51 {
52 // r, g, b, a
53 255, 0, 0, 255, // 0:0
54 255, 0, 0, 255, // 0:1
55 255, 0, 0, 255, // 0:2
56 0, 255, 0, 255, // 1:0
57 0, 255, 0, 255, // 1:1
58 0, 255, 0, 255, // 1:2
59 255, 0, 0, 255, // 2:0
60 255, 0, 0, 255, // 2:1
61 255, 0, 0, 255, // 2:2
62 0, 255, 0, 255, // 3:0
63 0, 255, 0, 255, // 3:1
64 0, 255, 0, 255, // 3:2
65 0, 255, 0, 255, // 4:0
66 0, 255, 0, 255, // 4:1
67 0, 255, 0, 255, // 4:2
68 255, 0, 0, 255, // 5:0
69 255, 0, 0, 255, // 5:1
70 255, 0, 0, 255, // 5:2
71 0, 255, 0, 255, // 6:0
72 0, 255, 0, 255, // 6:1
73 0, 255, 0, 255, // 6:2
74 255, 0, 0, 255, // 7:0
75 255, 0, 0, 255, // 7:1
76 255, 0, 0, 255, // 7:2
77 0, 255, 0, 255, // 24 extra: green
78 255, 255, 0, 255, // 25 extra: yellow
79 0, 255, 255, 255, // 26 extra: cyan
80 255, 0, 255, 255, // 27 extra: magenta
81 255, 255, 255, 255 // 28 extra: white
82 };
83
84 #define GREEN 24
85 #define YELLOW 25
86 #define CYAN 26
87 #define MAGENTA 27
88 #define WHITE 28
89
90 typedef struct
91 {
92 u32 ticks; // time counter
93 Mtx v; // view matrix
94 u16 width; // screen width
95 u16 height; // screen height
96 } MyState;
97
98 MyState mystate;
99
100 /*---------------------------------------------------------------------------*
101 Forward references
102 *---------------------------------------------------------------------------*/
103
104 void main ( void );
105 static void CameraInit ( MyState *ms );
106 static void DrawInit ( void );
107 static void DrawTick ( MyState *ms );
108 static void AnimTick ( MyState *ms );
109 static void PrintIntro ( void );
110
111 /*---------------------------------------------------------------------------*
112 Application main loop
113 *---------------------------------------------------------------------------*/
114
main(void)115 void main ( void )
116 {
117 GXRenderModeObj *rmode;
118
119 DEMOInit(&GXNtsc240Int); // Init os, pad, gx, vi
120 rmode = DEMOGetRenderModeObj();
121
122 mystate.ticks = 0;
123 mystate.width = rmode->fbWidth;
124 mystate.height = rmode->viHeight; // Note: VI Height, not fb height!!!
125
126 CameraInit(&mystate); // Initialize the camera.
127 DrawInit(); // Define my vertex formats and set array pointers.
128
129 PrintIntro(); // Print demo directions
130
131 while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
132 {
133 DEMOBeforeRender();
134 DrawTick(&mystate); // Draw the model.
135 DEMODoneRender();
136 DEMOPadRead();
137 if (!(DEMOPadGetButton(0) & PAD_BUTTON_A))
138 {
139 AnimTick(&mystate); // Update animation.
140 }
141 }
142
143 OSHalt("End of test");
144 }
145
146
147 /*---------------------------------------------------------------------------*
148 Functions
149 *---------------------------------------------------------------------------*/
150
151 /*---------------------------------------------------------------------------*
152 Name: CameraInit
153
154 Description: Initialize the projection matrix and load into hardware.
155 Initialize the view matrix.
156
157 Arguments: ms pointer to general scene state
158
159 Returns: none
160 *---------------------------------------------------------------------------*/
CameraInit(MyState * ms)161 static void CameraInit ( MyState *ms )
162 {
163 Mtx44 p; // projection matrix
164 Vec up = {0.0F, 1.0F, 0.0F};
165 Vec camLoc = {0.0F, 0.0F, 500.0F};
166 Vec objPt = {0.0F, 0.0F, 0.0F};
167 f32 left;
168 f32 top;
169 f32 znear = 100.0F;
170 f32 zmid;
171 f32 zfar = 1000.0F;
172
173 zmid = camLoc.z;
174 left = znear * (ms->width / 2.0F) / zmid;
175 top = znear * (ms->height / 2.0F) / zmid;
176
177 // Assuming camera at zmid, the projection maps:
178 // (-width/2, -height/2, 0) to (-1, -1, 0)
179 // ( width/2, height/2, 0) to ( 1, 1, 0)
180
181 MTXFrustum(p, top, -top, -left, left, znear, zfar);
182 GXSetProjection(p, GX_PERSPECTIVE);
183
184 MTXLookAt(ms->v, &camLoc, &up, &objPt);
185 }
186
187 /*---------------------------------------------------------------------------*
188 Name: DrawInit
189
190 Description: Initializes the vertex attribute format 0, and sets
191 the array pointers and strides for the indexed data.
192
193 Arguments: none
194
195 Returns: none
196 *---------------------------------------------------------------------------*/
DrawInit(void)197 static void DrawInit( void )
198 {
199 GXColor black = {0, 0, 0, 0};
200
201 GXSetCopyClear(black, 0x00ffffff);
202
203 // Position has 3 elements (x,y,z), each of type f32
204 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
205
206 // Color 0 has 4 components (r, g, b, a), each component is 8b.
207 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
208
209 // stride = 3 elements (x,y,z) each of type s16
210 GXSetArray(GX_VA_POS, Verts_f32, 3*sizeof(f32));
211 // stride = 4 elements (r,g,b,a) each of type u8
212 GXSetArray(GX_VA_CLR0, Colors_rgba8, 4*sizeof(u8));
213
214 // Initialize lighting, texgen, and tev parameters
215 GXSetNumChans(1); // default, color = vertex color
216 GXSetNumTexGens(0); // no texture in this demo
217 GXSetNumTevStages( 1 );
218 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
219 GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
220 }
221
222 /*---------------------------------------------------------------------------*
223 Name: Vertex
224
225 Description: Create my vertex format
226
227 Arguments: t 8-bit triangle index
228 v 8-bit vertex index
229
230 Returns: none
231 *---------------------------------------------------------------------------*/
Vertex(u8 t,u8 v)232 static inline void Vertex( u8 t, u8 v )
233 {
234 u8 tv = (u8) (3 * t + v);
235 GXPosition1x8(tv);
236 GXColor1x8(tv);
237 }
238
239 /*---------------------------------------------------------------------------*
240 Name: DrawTick
241
242 Description: Draw the model once.
243
244 Arguments: ms pointer to general scene state
245
246 Returns: none
247 *---------------------------------------------------------------------------*/
DrawTick(MyState * ms)248 static void DrawTick( MyState *ms )
249 {
250 Mtx m; // Model matrix.
251 Mtx mv; // Modelview matrix.
252 u8 iTri; // index of triangle
253 u8 iVert; // index of vertex
254
255 // Set current vertex descriptor to enable position and color0.
256 // Both use 8b index to access their data arrays.
257 GXClearVtxDesc();
258 GXSetVtxDesc(GX_VA_POS, GX_INDEX8);
259 GXSetVtxDesc(GX_VA_CLR0, GX_INDEX8);
260
261 // model has a rotation about x axis...
262 MTXRotDeg(m, 'x', 20.0F);
263 MTXConcat(ms->v, m, mv);
264
265 // and an animated rotation about y axis
266 MTXRotDeg(m, 'y', 8 * ms->ticks + 102.5F);
267 MTXConcat(mv, m, mv);
268
269 // model needs to be scaled to fill screen better
270 MTXScale(m, 200.0F, 200.0F, 200.0F);
271 MTXConcat(mv, m, mv);
272
273 GXLoadPosMtxImm(mv, GX_PNMTX0);
274
275 GXBegin(GX_TRIANGLES, GX_VTXFMT0, 24);
276
277 // for all triangles of octahedron, ...
278 for (iTri = 0; iTri < 8; ++iTri)
279 {
280 // for all vertices of triangle, ...
281 for (iVert = 0; iVert < 3; ++iVert)
282 {
283 Vertex(iTri, iVert);
284 }
285 }
286
287 GXEnd();
288
289 // Set current vertex descriptor to enable position and color0.
290 // Both use direct data.
291 GXClearVtxDesc();
292 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
293 GXSetVtxDesc(GX_VA_CLR0, GX_INDEX8);
294
295 // Translate, scale to map to screen space
296 MTXScale(m, 1.0F, -1.0F, 1.0F);
297 MTXConcat(ms->v, m, mv);
298 MTXTrans(m, -ms->width/2.0F, -ms->height/2.0F, 0.0F);
299 MTXConcat(mv, m, mv);
300 GXLoadPosMtxImm(mv, GX_PNMTX0);
301
302 // Field-specific rectangles:
303 // VI_FIELD_BELOW draws cyan rectangles
304 // VI_FIELD_ABOVE draws yellow rectangles
305
306 if (VIGetNextField() == VI_FIELD_BELOW)
307 {
308 GXBegin(GX_QUADS, GX_VTXFMT0, 8);
309 GXPosition3f32(50.0F, 50.0F, 0.0F);
310 GXColor1x8(CYAN);
311 GXPosition3f32(75.0F, 50.0F, 0.0F);
312 GXColor1x8(CYAN);
313 GXPosition3f32(75.0F, 75.0F, 0.0F);
314 GXColor1x8(CYAN);
315 GXPosition3f32(50.0F, 75.0F, 0.0F);
316 GXColor1x8(CYAN);
317
318 GXPosition3f32(175.0F, 50.0F, 0.0F);
319 GXColor1x8(CYAN);
320 GXPosition3f32(200.0F, 50.0F, 0.0F);
321 GXColor1x8(CYAN);
322 GXPosition3f32(200.0F, 75.0F, 0.0F);
323 GXColor1x8(CYAN);
324 GXPosition3f32(175.0F, 75.0F, 0.0F);
325 GXColor1x8(CYAN);
326 GXEnd();
327 }
328 else
329 {
330 GXBegin(GX_QUADS, GX_VTXFMT0, 8);
331 GXPosition3f32(150.0F, 50.0F, 0.0F);
332 GXColor1x8(YELLOW);
333 GXPosition3f32(175.0F, 50.0F, 0.0F);
334 GXColor1x8(YELLOW);
335 GXPosition3f32(175.0F, 75.0F, 0.0F);
336 GXColor1x8(YELLOW);
337 GXPosition3f32(150.0F, 75.0F, 0.0F);
338 GXColor1x8(YELLOW);
339
340 GXPosition3f32(75.0F, 50.0F, 0.0F);
341 GXColor1x8(YELLOW);
342 GXPosition3f32(100.0F, 50.0F, 0.0F);
343 GXColor1x8(YELLOW);
344 GXPosition3f32(100.0F, 75.0F, 0.0F);
345 GXColor1x8(YELLOW);
346 GXPosition3f32(75.0F, 75.0F, 0.0F);
347 GXColor1x8(YELLOW);
348 GXEnd();
349 }
350
351 // Diagonal lines
352
353 GXBegin(GX_LINES, GX_VTXFMT0, 12);
354
355 // Off by one lines
356 GXPosition3f32(100.0F, 44.0F, 0.0F);
357 GXColor1x8(MAGENTA);
358 GXPosition3f32(150.0F, 45.0F, 0.0F);
359 GXColor1x8(MAGENTA);
360
361 GXPosition3f32(100.0F, 80.0F, 0.0F);
362 GXColor1x8(MAGENTA);
363 GXPosition3f32(150.0F, 81.0F, 0.0F);
364 GXColor1x8(MAGENTA);
365
366 // Off by two lines
367 GXPosition3f32(100.0F, 38.0F, 0.0F);
368 GXColor1x8(GREEN);
369 GXPosition3f32(150.0F, 40.0F, 0.0F);
370 GXColor1x8(GREEN);
371
372 GXPosition3f32(100.0F, 85.0F, 0.0F);
373 GXColor1x8(GREEN);
374 GXPosition3f32(150.0F, 87.0F, 0.0F);
375 GXColor1x8(GREEN);
376
377 // Crossing lines
378 GXPosition3f32(100.0F, 50.0F, 0.0F);
379 GXColor1x8(WHITE);
380 GXPosition3f32(150.0F, 75.0F, 0.0F);
381 GXColor1x8(WHITE);
382
383 GXPosition3f32(150.0F, 50.0F, 0.0F);
384 GXColor1x8(WHITE);
385 GXPosition3f32(100.0F, 75.0F, 0.0F);
386 GXColor1x8(WHITE);
387
388 GXEnd();
389 }
390
391 /*---------------------------------------------------------------------------*
392 Name: AnimTick
393
394 Description: Computes next time step.
395
396 Arguments: ms pointer to general scene state
397
398 Returns: none
399 *---------------------------------------------------------------------------*/
AnimTick(MyState * ms)400 static void AnimTick( MyState *ms )
401 {
402 ms->ticks++;
403 }
404
405 /*---------------------------------------------------------------------------*
406 Name: PrintIntro
407
408 Description: Prints the directions on how to use this demo.
409
410 Arguments: none
411
412 Returns: none
413 *---------------------------------------------------------------------------*/
PrintIntro(void)414 static void PrintIntro( void )
415 {
416 OSReport("\n\n*************************************************\n");
417 OSReport("A Button : pause animation while pressed down\n");
418 OSReport("To quit:\n");
419 OSReport(" hit the start/pause button\n");
420 OSReport("***************************************************\n");
421 }
422