1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin/Revolution gx demo
3   File:     smp-onetri.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   Model Data
18  *---------------------------------------------------------------------------*/
19 #define STRUT_LN        130     // long side of strut
20 #define STRUT_SD        4       // short side of strut
21 #define JOINT_SD        10      // joint is a cube
22 
23 /*---------------------------------------------------------------------------*
24    The macro ATTRIBUTE_ALIGN provides a convenient way to align initialized
25    arrays.  Alignment of vertex arrays to 32B IS NOT required, but may result
26    in a slight performance improvement.
27  *---------------------------------------------------------------------------*/
28 s16 Verts_s16[] ATTRIBUTE_ALIGN(32) =
29 {
30 //      x             y             z
31     -STRUT_SD,     STRUT_SD,    -STRUT_SD,   // 0
32      STRUT_SD,     STRUT_SD,    -STRUT_SD,   // 1
33      STRUT_SD,     STRUT_SD,     STRUT_SD,   // 2
34     -STRUT_SD,     STRUT_SD,     STRUT_SD,   // 3
35      STRUT_SD,    -STRUT_SD,    -STRUT_SD,   // 4
36      STRUT_SD,    -STRUT_SD,     STRUT_SD,   // 5
37      STRUT_SD,     STRUT_LN,    -STRUT_SD,   // 6
38      STRUT_SD,     STRUT_LN,     STRUT_SD,   // 7
39     -STRUT_SD,     STRUT_LN,     STRUT_SD,   // 8
40     -STRUT_SD,     STRUT_SD,    -STRUT_LN,   // 9
41      STRUT_SD,     STRUT_SD,    -STRUT_LN,   // 10
42      STRUT_SD,    -STRUT_SD,    -STRUT_LN,   // 11
43      STRUT_LN,     STRUT_SD,    -STRUT_SD,   // 12
44      STRUT_LN,     STRUT_SD,     STRUT_SD,   // 13
45      STRUT_LN,    -STRUT_SD,     STRUT_SD,   // 14
46     -JOINT_SD,     JOINT_SD,    -JOINT_SD,   // 15
47      JOINT_SD,     JOINT_SD,    -JOINT_SD,   // 16
48      JOINT_SD,     JOINT_SD,     JOINT_SD,   // 17
49     -JOINT_SD,     JOINT_SD,     JOINT_SD,   // 18
50      JOINT_SD,    -JOINT_SD,    -JOINT_SD,   // 19
51      JOINT_SD,    -JOINT_SD,     JOINT_SD,   // 20
52     -JOINT_SD,    -JOINT_SD,     JOINT_SD    // 21
53 };
54 
55 u8 Colors_rgba8[] ATTRIBUTE_ALIGN(32) =
56 {
57 //   r,   g,   b,   a
58     42,  42,  50, 255,   // 0
59     80,  80,  80, 255,   // 1
60    114, 114, 110, 255    // 2
61 };
62 
63 /*---------------------------------------------------------------------------*
64    Forward references
65  *---------------------------------------------------------------------------*/
66 
67 void        main            ( void );
68 static void CameraInit      ( Mtx v );
69 static void DrawInit        ( void );
70 static void DrawTick        ( Mtx v );
71 static void AnimTick        ( Mtx v );
72 static void PrintIntro      ( void );
73 
74 /*---------------------------------------------------------------------------*
75    Application main loop
76  *---------------------------------------------------------------------------*/
77 
main(void)78 void main ( void )
79 {
80     Mtx         v;   // view matrix
81     PADStatus   pad[PAD_MAX_CONTROLLERS]; // game pad state
82 
83     pad[0].button = 0;
84 
85     DEMOInit(NULL);    // Init os, pad, gx, vi
86 
87     CameraInit(v); // Initialize the camera.
88     DrawInit();    // Define my vertex formats and set array pointers.
89 
90     PrintIntro(); // Print demo directions
91 
92     while(!(pad[0].button & PAD_BUTTON_MENU))
93     {
94         DEMOBeforeRender();
95         DrawTick(v);        // Draw the model.
96         DEMODoneRender();
97         AnimTick(v);        // Update animation.
98         PADRead(pad);
99     }
100 
101     OSHalt("End of demo");
102 }
103 
104 
105 /*---------------------------------------------------------------------------*
106    Functions
107  *---------------------------------------------------------------------------*/
108 
109 /*---------------------------------------------------------------------------*
110     Name:           CameraInit
111 
112     Description:    Initialize the projection matrix and load into hardware.
113                     Initialize the view matrix.
114 
115     Arguments:      v      view matrix
116 
117     Returns:        none
118  *---------------------------------------------------------------------------*/
CameraInit(Mtx v)119 static void CameraInit ( Mtx v )
120 {
121     Mtx44   p;      // projection matrix
122     Vec     up      = {0.20F, 0.97F, 0.0F};
123     Vec     camLoc  = {90.0F, 110.0F, 13.0F};
124     Vec     objPt   = {-110.0F, -70.0F, -190.0F};
125     f32     left    = 24.0F;
126     f32     top     = 32.0F;
127     f32     znear   = 50.0F;
128     f32     zfar    = 2000.0F;
129 
130     MTXFrustum(p, left, -left, -top, top, znear, zfar);
131     GXSetProjection(p, GX_PERSPECTIVE);
132 
133     MTXLookAt(v, &camLoc, &up, &objPt);
134 }
135 
136 /*---------------------------------------------------------------------------*
137     Name:           DrawInit
138 
139     Description:    Initializes the vertex attribute format 0, and sets
140                     the array pointers and strides for the indexed data.
141 
142     Arguments:      none
143 
144     Returns:        none
145  *---------------------------------------------------------------------------*/
DrawInit(void)146 static void DrawInit( void )
147 {
148     GXColor black = {0, 0, 0, 0};
149 
150     GXSetCopyClear(black, 0x00FFFFFF);
151 
152     // Set current vertex descriptor to enable position and color0.
153     // Both use 8b index to access their data arrays.
154     GXClearVtxDesc();
155     GXSetVtxDesc(GX_VA_POS, GX_INDEX8);
156     GXSetVtxDesc(GX_VA_CLR0, GX_INDEX8);
157 
158     // Position has 3 elements (x,y,z), each of type s16,
159     // no fractional bits (integers)
160     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
161 
162     // Color 0 has 4 components (r, g, b, a), each component is 8b.
163     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
164 
165     // stride = 3 elements (x,y,z) each of type s16
166     GXSetArray(GX_VA_POS, Verts_s16, 3*sizeof(s16));
167     // stride = 4 elements (r,g,b,a) each of type u8
168     GXSetArray(GX_VA_CLR0, Colors_rgba8, 4*sizeof(u8));
169 
170     // Initialize lighting, texgen, and tev parameters
171     GXSetNumChans(1); // default, color = vertex color
172     GXSetNumTexGens(0); // no texture in this demo
173     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
174     GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
175 }
176 
177 /*---------------------------------------------------------------------------*
178     Name:           Vertex
179 
180     Description:    Create my vertex format
181 
182     Arguments:      v        8-bit position index
183                     c        8-bit color index
184 
185     Returns:        none
186  *---------------------------------------------------------------------------*/
Vertex(u8 v,u8 c)187 static inline void Vertex( u8 v, u8 c )
188 {
189     GXPosition1x8(v);
190     GXColor1x8(c);
191 }
192 
193 /*---------------------------------------------------------------------------*
194     Name:           DrawFsQuad
195 
196     Description:    Draw a flat-shaded quad.
197 
198     Arguments:      v0    8-bit position index 0
199                     v1    8-bit position index 1
200                     v2    8-bit position index 2
201                     v3    8-bit position index 3
202                     c     8-bit color index
203 
204     Returns:        none
205  *---------------------------------------------------------------------------*/
DrawFsQuad(u8 v0,u8 v1,u8 v2,u8 v3,u8 c)206 static inline void DrawFsQuad(
207     u8 v0,
208     u8 v1,
209     u8 v2,
210     u8 v3,
211     u8 c )
212 {
213     Vertex(v0, c);
214     Vertex(v1, c);
215     Vertex(v2, c);
216     Vertex(v3, c);
217 }
218 
219 /*---------------------------------------------------------------------------*
220     Name:           DrawTick
221 
222     Description:    Draw the model once.  Replicates a simple strut model
223                     many times in the x, y, z directions to create a dense
224                     3D grid.  GXInit makes GX_PNMTX0 the default matrix.
225 
226     Arguments:      v        view matrix
227 
228     Returns:        none
229  *---------------------------------------------------------------------------*/
DrawTick(Mtx v)230 static void DrawTick( Mtx v )
231 {
232     f32  x;  // Translation in x.
233     f32  y;  // Translation in y.
234     f32  z;  // Translation in z.
235     Mtx  m;  // Model matrix.
236     Mtx  mv; // Modelview matrix.
237 
238     GXSetNumTexGens( 0 );
239     GXSetNumTevStages( 1 );
240     GXSetTevOp( GX_TEVSTAGE0, GX_PASSCLR );
241 
242     MTXIdentity(m);
243 
244     for(x = -10*STRUT_LN; x < 2*STRUT_LN; x += STRUT_LN)
245     {
246         for(y = -10*STRUT_LN; y < STRUT_LN; y += STRUT_LN)
247         {
248             for(z = STRUT_LN; z > -10*STRUT_LN; z -= STRUT_LN)
249             {
250                 MTXRowCol(m, 0, 3) = x;
251                 MTXRowCol(m, 1, 3) = y;
252                 MTXRowCol(m, 2, 3) = z;
253                 MTXConcat(v, m, mv);
254                 GXLoadPosMtxImm(mv, GX_PNMTX0);
255 
256                 GXBegin(GX_QUADS, GX_VTXFMT0, 36); //4 vtx/qd x 9 qd = 36 vtx
257                     DrawFsQuad(8, 7, 2, 3, 0);
258                     DrawFsQuad(1, 2, 7, 6, 1);
259                     DrawFsQuad(1, 0, 9, 10, 2);
260                     DrawFsQuad(4, 1, 10, 11, 1);
261                     DrawFsQuad(1, 12, 13, 2, 2);
262                     DrawFsQuad(2, 13, 14, 5, 0);
263                     DrawFsQuad(18, 15, 16, 17, 2);
264                     DrawFsQuad(20, 17, 16, 19, 1);
265                     DrawFsQuad(20, 21, 18, 17, 0);
266                 GXEnd();
267             }
268         }
269     }
270 }
271 
272 /*---------------------------------------------------------------------------*
273     Name:           AnimTick
274 
275     Description:    Moves viewpoint through the grid.  Loops animation so
276                     that it appears viewpoint is continuously moving forward.
277 
278     Arguments:      v       view matrix
279 
280     Returns:        none
281  *---------------------------------------------------------------------------*/
AnimTick(Mtx v)282 static void AnimTick( Mtx v )
283 {
284     static u32  ticks = 0; // Counter.
285     Mtx         fwd;       // Forward stepping translation matrix.
286     Mtx         back;      // Loop back translation matrix.
287 
288     u32    animSteps    = 100;
289     f32    animLoopBack = (f32)STRUT_LN;
290     f32    animStepFwd  = animLoopBack / animSteps;
291 
292     MTXTrans(fwd, 0, 0, animStepFwd);
293     MTXTrans(back, 0, 0, -animLoopBack);
294 
295     MTXConcat(v, fwd, v);
296     if((ticks % animSteps) == 0)
297         MTXConcat(v, back, v);
298 
299     ticks++;
300 }
301 
302 /*---------------------------------------------------------------------------*
303     Name:           PrintIntro
304 
305     Description:    Prints the directions on how to use this demo.
306 
307     Arguments:      none
308 
309     Returns:        none
310  *---------------------------------------------------------------------------*/
PrintIntro(void)311 static void PrintIntro( void )
312 {
313     OSReport("\n\n****************************************\n");
314     OSReport("to quit:\n");
315     OSReport("     hit the start button\n");
316     OSReport("****************************************\n");
317 }
318