1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin/Revolution gx demo
3   File:     mgt-single-buf.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     0, 0, 0, 255,   // 0:0
54     0, 0, 0, 255,   // 0:1
55     0, 0, 0, 255,   // 0:2
56     255, 255, 255, 255, // 1:0
57     255, 255, 255, 255, // 1:1
58     255, 255, 255, 255, // 1:2
59     0, 0, 0, 255,   // 2:0
60     0, 0, 0, 255,   // 2:1
61     0, 0, 0, 255,   // 2:2
62     255, 255, 255, 255, // 3:0
63     255, 255, 255, 255, // 3:1
64     255, 255, 255, 255, // 3:2
65     255, 255, 255, 255, // 4:0
66     255, 255, 255, 255, // 4:1
67     255, 255, 255, 255, // 4:2
68     0, 0, 0, 255,   // 5:0
69     0, 0, 0, 255,   // 5:1
70     0, 0, 0, 255,   // 5:2
71     255, 255, 255, 255, // 6:0
72     255, 255, 255, 255, // 6:1
73     255, 255, 255, 255, // 6:2
74     0, 0, 0, 255,   // 7:0
75     0, 0, 0, 255,   // 7:1
76     0, 0, 0, 255    // 7:2
77 };
78 
79 
80 u32 ticks = 0;  // time counter
81 
82 GXBool  do_copy = GX_FALSE;
83 
84 /*---------------------------------------------------------------------------*
85    Forward references
86  *---------------------------------------------------------------------------*/
87 
88 void        VIPostCallback  ( u32 retraceCount );
89 void        main            ( void );
90 static void CameraInit      ( Mtx v );
91 static void DrawInit        ( void );
92 static void DrawTick        ( Mtx v );
93 static void AnimTick        ( void );
94 static void PrintIntro      ( void );
95 
96 /*---------------------------------------------------------------------------*
97    VI Post Callback (VBlank interrupt)
98 
99    We use a post callback (instead of a pre) because we don't need to
100    change any VI registers during the VBlank period.
101 
102  *---------------------------------------------------------------------------*/
103 
VIPostCallback(u32 retraceCount)104 void VIPostCallback ( u32 retraceCount )
105 {
106     #pragma unused (retraceCount)
107 
108     if (do_copy) {
109         GXCopyDisp(DEMOGetCurrentBuffer(), GX_TRUE);
110         GXFlush();
111         do_copy = FALSE;
112     }
113 }
114 
115 /*---------------------------------------------------------------------------*
116    Application main loop
117  *---------------------------------------------------------------------------*/
118 
main(void)119 void main ( void )
120 {
121     Mtx         v;   // view matrix
122     PADStatus   pad[PAD_MAX_CONTROLLERS]; // game pad state
123 
124     pad[0].button = 0;
125 
126     DEMOInit(NULL);    // Init os, pad, gx, vi
127 
128     CameraInit(v); // Initialize the camera.
129     DrawInit();    // Define my vertex formats and set array pointers.
130 
131     PrintIntro(); // Print demo directions
132 
133     (void) VISetPostRetraceCallback(VIPostCallback);
134     VISetNextFrameBuffer(DEMOGetCurrentBuffer());
135     VISetBlack(FALSE);
136     VIFlush();
137 
138     while(!(pad[0].button & PAD_BUTTON_MENU))
139     {
140         DEMOBeforeRender();
141         DrawTick(v);        // Draw the model.
142 
143         GXDrawDone();
144         do_copy = GX_TRUE;
145         VIWaitForRetrace();
146 
147         AnimTick();        // Update animation.
148         PADRead(pad);
149     }
150 
151     OSHalt("End of demo");
152 }
153 
154 
155 /*---------------------------------------------------------------------------*
156    Functions
157  *---------------------------------------------------------------------------*/
158 
159 /*---------------------------------------------------------------------------*
160     Name:           CameraInit
161 
162     Description:    Initialize the projection matrix and load into hardware.
163                     Initialize the view matrix.
164 
165     Arguments:      v      view matrix
166 
167     Returns:        none
168  *---------------------------------------------------------------------------*/
CameraInit(Mtx v)169 static void CameraInit ( Mtx v )
170 {
171     Mtx44   p;      // projection matrix
172     Vec     up      = {0.0F, 0.0F, 1.0F};
173     Vec     camLoc  = {0.25F, 3.0F, 0.5F};
174     Vec     objPt   = {0.0F, 0.0F, 0.0F};
175     f32     left    = 0.0375F;
176     f32     top     = 0.050F;
177     f32     znear   = 0.1F;
178     f32     zfar    = 10.0F;
179 
180     MTXFrustum(p, left, -left, -top, top, znear, zfar);
181     GXSetProjection(p, GX_PERSPECTIVE);
182 
183     MTXLookAt(v, &camLoc, &up, &objPt);
184 }
185 
186 /*---------------------------------------------------------------------------*
187     Name:           DrawInit
188 
189     Description:    Initializes the vertex attribute format 0, and sets
190                     the array pointers and strides for the indexed data.
191 
192     Arguments:      none
193 
194     Returns:        none
195  *---------------------------------------------------------------------------*/
DrawInit(void)196 static void DrawInit( void )
197 {
198     GXColor blue = {0, 0, 255, 0};
199 
200     GXSetCopyClear(blue, 0x00ffffff);
201 
202     // Set current vertex descriptor to enable position and color0.
203     // Both use 8b index to access their data arrays.
204     GXClearVtxDesc();
205     GXSetVtxDesc(GX_VA_POS, GX_INDEX8);
206     GXSetVtxDesc(GX_VA_CLR0, GX_INDEX8);
207 
208     // Position has 3 elements (x,y,z), each of type f32
209     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
210 
211     // Color 0 has 4 components (r, g, b, a), each component is 8b.
212     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
213 
214     // stride = 3 elements (x,y,z) each of type s16
215     GXSetArray(GX_VA_POS, Verts_f32, 3*sizeof(f32));
216     // stride = 4 elements (r,g,b,a) each of type u8
217     GXSetArray(GX_VA_CLR0, Colors_rgba8, 4*sizeof(u8));
218 
219     // Initialize lighting, texgen, and tev parameters
220     GXSetNumChans(1); // default, color = vertex color
221     GXSetNumTexGens(0); // no texture in this demo
222     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
223     GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
224 }
225 
226 /*---------------------------------------------------------------------------*
227     Name:           Vertex
228 
229     Description:    Create my vertex format
230 
231     Arguments:      t        8-bit triangle index
232                     v        8-bit vertex index
233 
234     Returns:        none
235  *---------------------------------------------------------------------------*/
Vertex(u8 t,u8 v)236 static inline void Vertex( u8 t, u8 v )
237 {
238     u8 tv = (u8) (3 * t + v);
239     GXPosition1x8(tv);
240     GXColor1x8(tv);
241 }
242 
243 /*---------------------------------------------------------------------------*
244     Name:           DrawTick
245 
246     Description:    Draw the model once.
247 
248     Arguments:      v        view matrix
249 
250     Returns:        none
251  *---------------------------------------------------------------------------*/
DrawTick(Mtx v)252 static void DrawTick( Mtx v )
253 {
254     Mtx m;  // Model matrix.
255     Mtx mv; // Modelview matrix.
256     u8  iTri;   // index of triangle
257     u8  iVert;  // index of vertex
258 
259     GXSetNumTexGens( 0 );
260     GXSetNumTevStages( 1 );
261     GXSetTevOp( GX_TEVSTAGE0, GX_PASSCLR );
262 
263     // model has a rotation about z axis
264     MTXRotDeg(m, 'z', 8 * ticks);
265     MTXConcat(v, m, mv);
266     GXLoadPosMtxImm(mv, GX_PNMTX0);
267 
268     GXBegin(GX_TRIANGLES, GX_VTXFMT0, 24);
269 
270     // for all triangles of octahedron, ...
271     for (iTri = 0; iTri < 8; ++iTri)
272     {
273         // for all vertices of triangle, ...
274         for (iVert = 0; iVert < 3; ++iVert)
275         {
276             Vertex(iTri, iVert);
277         }
278     }
279 
280     GXEnd();
281 }
282 
283 /*---------------------------------------------------------------------------*
284     Name:           AnimTick
285 
286     Description:    Computes next time step.
287 
288     Arguments:      none
289 
290     Returns:        none
291  *---------------------------------------------------------------------------*/
AnimTick(void)292 static void AnimTick( void )
293 {
294     ticks++;
295 }
296 
297 /*---------------------------------------------------------------------------*
298     Name:            PrintIntro
299 
300     Description:    Prints the directions on how to use this demo.
301 
302     Arguments:        none
303 
304     Returns:        none
305  *---------------------------------------------------------------------------*/
PrintIntro(void)306 static void PrintIntro( void )
307 {
308     OSReport("\n\n******************************************\n");
309     OSReport("frb-single - double-buffer with only 1 XFB\n");
310     OSReport("******************************************\n");
311     OSReport("to quit:\n");
312     OSReport("     hit the start button\n");
313     OSReport("********************************\n");
314 }
315