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