1 /*---------------------------------------------------------------------------*
2   Project:    WPAD demo program
3   File:       full_mode.c
4 
5   Copyright (C) 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   $Log: full_mode.c,v $
14   Revision 1.6.4.1  2007/12/11 01:15:27  tojo
15   Modified to handle the error code of WPADStatus.
16 
17   Revision 1.6  2007/04/23 08:48:46  tojo
18   (none)
19 
20   Revision 1.5  2007/04/10 10:15:01  tojo
21   (none)
22 
23   Revision 1.4  2007/03/19 11:14:38  tojo
24   (none)
25 
26   Revision 1.3  2006/10/23 01:05:09  tojo
27   Called WPADSetConnectCallback before initialization complete.
28 
29   Revision 1.2  2006/09/08 07:59:30  tojo
30   (none)
31 
32   Revision 1.1  2006/09/05 12:22:31  tojo
33   (none)
34 
35 
36  *---------------------------------------------------------------------------*/
37 
38 #define DEMO_USE_MEMLIB = 1
39 #include <demo.h>
40 #include <revolution/wpad.h>
41 #include <math.h>
42 #include <string.h>
43 
44 #define SCREEN_WIDTH  1024
45 #define SCREEN_HEIGHT 768
46 
47 /*---------------------------------------------------------------------------*
48  * Private function prototypes
49  *---------------------------------------------------------------------------*/
50 void *myAlloc( u32 size  );
51 u8    myFree ( void *ptr );
52 
53 /*---------------------------------------------------------------------------*
54  * Globals
55  *---------------------------------------------------------------------------*/
56 s32 status;
57 u32 type;
58 
59 const GXColor LIME     = {   0, 255,   0, 255 };
60 const GXColor AQUA     = {   0, 255, 255, 255 };
61 const GXColor MAGENTA  = { 255,   0, 255, 255 };
62 const GXColor GRAY     = { 128, 128, 128, 255 };
63 const GXColor WHITE    = { 255, 255, 255, 255 };
64 const GXColor TEAL     = {   0, 128, 128, 255 };
65 const GXColor ORANGE   = { 255, 165,   0, 255 };
66 const GXColor PINK     = { 255, 192, 203, 255 };
67 const GXColor GREEN    = {   0, 128,   0, 255 };
68 
69 const f32 PI=3.141592f;
70 
71 static GXColor circle[4];
72 static GXColor box[4];
73 
74 
75 /*---------------------------------------------------------------------------*
76  * Name        : myAlloc()
77  * Description : Callback needed by WPAD to allocate mem from MEM2 heap
78  * Arguments   : size of block, in bytes.
79  * Returns     : pointer to allocated block.
80  *---------------------------------------------------------------------------*/
myAlloc(u32 size)81 void *myAlloc( u32 size )
82 {
83     void *ptr;
84 
85     ptr = MEMAllocFromAllocator(&DemoAllocator2, size);
86     ASSERTMSG(ptr, "Memory allocation failed\n");
87 
88     return(ptr);
89 }
90 
91 /*---------------------------------------------------------------------------*
92  * Name        : myFree()
93  * Description : Callback needed by WPAD to free mem from MEM2 heap
94  * Arguments   : point to the block that should be freed.
95  * Returns     : Always 1.
96  *---------------------------------------------------------------------------*/
myFree(void * ptr)97 u8 myFree( void *ptr )
98 {
99     MEMFreeToAllocator(&DemoAllocator2, ptr);
100 
101     return(1);
102 }
103 
104 /*---------------------------------------------------------------------------*
105  * Name        : initialize()
106  * Description : Performs basic system initialization.
107  * Arguments   : None.
108  * Returns     : None.
109  *---------------------------------------------------------------------------*/
initialize(void)110 static void initialize( void )
111 {
112     OSInit();
113 
114     DEMOInit( &GXNtsc480IntDf );
115     GXSetCopyClear( GRAY, GX_MAX_Z24 );
116     GXCopyDisp( DEMOGetCurrentBuffer(), GX_TRUE );
117     DEMOInitCaption( DM_FT_XLU, SCREEN_WIDTH, SCREEN_HEIGHT );
118     GXSetZMode( GX_ENABLE, GX_ALWAYS, GX_ENABLE );                       // Set pixel processing mode
119     GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR );    // Translucent mode
120 
121     DEMOPadInit();
122 
123     circle[0] = WHITE;
124     circle[1] = AQUA;
125     circle[2] = LIME;
126     circle[3] = PINK;
127 
128     box[0] = ORANGE;
129     box[1] = TEAL;
130     box[2] = GREEN;
131     box[3] = MAGENTA;
132 
133 } /* end initialize() */
134 
135 /*---------------------------------------------------------------------------*
136  * Name        : RenderLine()
137  * Description : Draw line
138  * Arguments   : x1 and y1 are the coordinate of start point
139                  x2 and y2 are the coordinate of end point
140                  clr is line color
141  * Returns     : None.
142  *---------------------------------------------------------------------------*/
RenderLine(s16 x1,s16 y1,s16 x2,s16 y2,GXColor clr)143 static void RenderLine( s16 x1, s16 y1, s16 x2, s16 y2, GXColor clr )
144 {
145     Mtx mv;
146     MTXIdentity(mv);
147     GXLoadPosMtxImm(mv, GX_PNMTX0);
148     GXSetCurrentMtx(GX_PNMTX0);
149 
150     GXSetNumChans(1);
151     GXSetNumTevStages(1);
152     GXSetNumTexGens(0);
153     GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
154     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
155 
156     GXClearVtxDesc();
157     GXSetVtxDesc(GX_VA_POS,  GX_DIRECT);
158     GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
159     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS,  GX_POS_XY,   GX_S16,   0);
160     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
161 
162     GXBegin(GX_LINES, GX_VTXFMT0, 2);
163         GXPosition2s16(x1, y1);
164         GXColor4u8(clr.r, clr.g, clr.b, clr.a);
165         GXPosition2s16(x2, y2);
166         GXColor4u8(clr.r, clr.g, clr.b, clr.a);
167     GXEnd();
168 }
169 
170 /*---------------------------------------------------------------------------*
171  * Name        : RenderCircle()
172  * Description : Draw a circle
173  * Arguments   : x and y are the coordinate of center point.
174                  div is roundish
175                  clr is color
176  * Returns     : None.
177  *---------------------------------------------------------------------------*/
RenderCircle(s16 x,s16 y,s16 r,s16 div,GXColor clr)178 static void RenderCircle( s16 x, s16 y, s16 r, s16 div, GXColor clr )
179 {
180     f32 th;
181     f32 phi;
182     s16 i;
183 
184     for(i=0; i<div; ++i)
185     {
186         th=2*PI/div*i;
187         phi=2*PI/div*(i+1);
188 
189         RenderLine((s16)(x+r*cos(th)),
190                    (s16)(y+r*sin(th)),
191                    (s16)(x+r*cos(phi)),
192                    (s16)(y+r*sin(phi)),
193                    clr);
194     }
195 }
196 
197 
198 /*---------------------------------------------------------------------------*
199  * Name        : RenderObjects()
200  * Description : Draw the objects dpd catches
201  * Arguments   : type       device type.
202                  status     controller data.
203  * Returns     : None.
204  *---------------------------------------------------------------------------*/
RenderObjects(WPADStatusEx * status)205 static void RenderObjects( WPADStatusEx *status )
206 {
207     int i;
208     s16 l;
209     s32 chan;
210 
211     for(chan=0; chan<WPAD_MAX_CONTROLLERS; chan++)
212     {
213         if (WPADIsDpdEnabled(chan))
214         {
215             WPADStatusEx *ep = &status[chan];
216 
217             if (ep->err == WPAD_ERR_NONE)
218             {
219                 for(i=0; i<WPAD_DPD_MAX_OBJECTS; i++)
220                 {
221                     l = (s16)((sqrt(ep->exp[i].pixel * 2))/2);
222 
223                     RenderCircle(ep->obj[i].x, ep->obj[i].y, (s16)(sqrt((f32)ep->obj[i].size/PI)*8), 16, circle[chan]);
224                     RenderLine(ep->exp[i].range_x1, ep->exp[i].range_y1, ep->exp[i].range_x1, ep->exp[i].range_y2, box[chan]);
225                     RenderLine(ep->exp[i].range_x1, ep->exp[i].range_y2, ep->exp[i].range_x2, ep->exp[i].range_y2, box[chan]);
226                     RenderLine(ep->exp[i].range_x2, ep->exp[i].range_y2, ep->exp[i].range_x2, ep->exp[i].range_y1, box[chan]);
227                     RenderLine(ep->exp[i].range_x2, ep->exp[i].range_y1, ep->exp[i].range_x1, ep->exp[i].range_y1, box[chan]);
228                 }
229             }
230         }
231     }
232 }
233 
234 /*---------------------------------------------------------------------------*
235  * Name        : dpdCallback()
236  * Description : Callback called when dpd is turned off. Turn on dpd as full mode.
237  * Arguments   : chan       controller channel
238                  result     result code
239  * Returns     : None.
240  *---------------------------------------------------------------------------*/
dpdCallback(s32 chan,s32 result)241 static void dpdCallback( s32 chan, s32 result )
242 {
243 #pragma unused(chan, result)
244 
245     if (result == WPAD_ERR_NONE)
246     {
247         WPADControlDpd(chan, WPAD_DPD_FULL, NULL);
248         WPADSetDataFormat(chan, WPAD_FMT_CORE_ACC_DPD_FULL);
249     }
250 }
251 
252 /*---------------------------------------------------------------------------*
253  * Name        : ExtensionCallback()
254  * Description : Callback called when an extension is installed/detached.
255  * Arguments   : chan       controller channel
256                  result     result code
257  * Returns     : None.
258  *---------------------------------------------------------------------------*/
ExtensionCallback(s32 chan,s32 result)259 static void ExtensionCallback( s32 chan, s32 result )
260 {
261 
262     switch(result)
263     {
264         case WPAD_DEV_CORE:
265             WPADControlDpd(chan, WPAD_DPD_FULL, NULL);
266             WPADSetDataFormat(chan, WPAD_FMT_CORE_ACC_DPD_FULL);
267             break;
268 
269         case WPAD_DEV_FREESTYLE:
270             WPADControlDpd(chan, WPAD_DPD_STD, NULL);
271             WPADSetDataFormat(chan, WPAD_FMT_FREESTYLE_ACC_DPD);
272             break;
273 
274         case WPAD_DEV_CLASSIC:
275             WPADControlDpd(chan, WPAD_DPD_STD, NULL);
276             WPADSetDataFormat(chan, WPAD_FMT_CLASSIC_ACC_DPD);
277             break;
278 
279         default:
280             break;
281     }
282 }
283 
284 /*---------------------------------------------------------------------------*
285  * Name        : ConnectCallback()
286  * Description : Callback called when a controller connects/disconnects.
287  * Arguments   : chan       controller channel
288                  result     result code
289  * Returns     : None.
290  *---------------------------------------------------------------------------*/
ConnectCallback(s32 chan,s32 reason)291 static void ConnectCallback( s32 chan, s32 reason )
292 {
293     if (reason == WPAD_ERR_NONE)
294     {
295         WPADSetExtensionCallback( chan, ExtensionCallback );
296         WPADControlDpd(chan, WPAD_DPD_FULL, dpdCallback);
297         WPADSetDataFormat(chan, WPAD_FMT_CORE_ACC_DPD_FULL);
298     }
299 }
300 
301 
302 /*---------------------------------------------------------------------------*
303  * Name        : PrintIntro()
304  * Description :
305  * Arguments   : None.
306  * Returns     : None.
307  *---------------------------------------------------------------------------*/
PrintIntro(void)308 static void PrintIntro( void )
309 {
310     OSReport("* -------------------------------------------- *\n");
311     OSReport("* WPAD SAMPLE DEMO:                            *\n");
312     OSReport("*                                              *\n");
313     OSReport("* DPD Full mode and Change DPD sensitivity     *\n");
314     OSReport("* DPD sensitivity range (low) 1 <--> 5 (high)  *\n");
315     OSReport("* -------------------------------------------- *\n");
316     OSReport("* MENU: Only Controller1 can change            *\n");
317     OSReport("* -------------------------------------------- *\n");
318     OSReport("* press + button: increase the dpd sensitivity.*\n");
319     OSReport("* press - button: decrease the dpd sensitivity.*\n");
320     OSReport("* -------------------------------------------- *\n");
321 }
322 
changeSensitivity(u8 level)323 static void changeSensitivity( u8 level )
324 {
325     s32 chan;
326     u32 type;
327 
328     WPADSetDpdSensitivity(level);
329 
330     for(chan=0; chan<WPAD_MAX_CONTROLLERS; chan++)
331     {
332         if (WPADProbe(chan, &type) != WPAD_ERR_NO_CONTROLLER)
333         {
334             WPADSetDataFormat(chan, WPAD_FMT_CORE);
335             WPADControlDpd(chan, WPAD_DPD_OFF, dpdCallback);
336         }
337     }
338 }
339 
340 /*---------------------------------------------------------------------------*
341  * Name        : main()
342  * Description :
343  * Arguments   : None.
344  * Returns     : None.
345  *---------------------------------------------------------------------------*/
main(void)346 void main( void )
347 {
348     s32 bb_stat;
349     s32 chan;
350     WPADStatusEx full[WPAD_MAX_CONTROLLERS];
351     u16 curr = 0;
352     u16 prev = 0;
353     int i;
354     u8 level;
355 
356     initialize();
357 
358     // register allocator for stack before WPADInit().
359     WPADRegisterAllocator(myAlloc, myFree);
360 
361     // Initialize WPAD.
362     WPADInit();
363 
364     for(i=0;i<WPAD_MAX_CONTROLLERS; i++)
365     {
366         WPADSetConnectCallback  (i, ConnectCallback);
367         WPADSetExtensionCallback(i, ExtensionCallback);
368     }
369 
370     // wait that BT stack is enabled
371     do {
372         bb_stat = WPADGetStatus();
373     } while (bb_stat != WPAD_STATE_SETUP);
374 
375     PrintIntro();
376 
377     // get dpd sensitivity.
378     level = WPADGetDpdSensitivity();
379 
380     // Main loop
381     while( 1 )
382     {
383         for(chan=0; chan<WPAD_MAX_CONTROLLERS; chan++)
384         {
385             status = WPADProbe( chan, &type );
386             if (status != WPAD_ERR_NO_CONTROLLER)
387             {
388                 WPADRead( chan, &full[chan] );
389             }
390         }
391         // button is available if err is not invalid.
392         if (full[0].err != WPAD_ERR_INVALID)
393         {
394             curr = full[0].button;
395         }
396 
397         if (WPADButtonDown(prev, curr) & WPAD_BUTTON_PLUS)
398         {
399             if (level != 5)
400             {
401                 level++;
402                 changeSensitivity(level);
403             }
404         }
405         if (WPADButtonDown(prev, curr) & WPAD_BUTTON_MINUS)
406         {
407             if (level != 1)
408             {
409                 level--;
410                 changeSensitivity(level);
411             }
412         }
413         prev = curr;
414 
415         DEMOBeforeRender();
416         RenderObjects(full);
417         DEMODoneRender();
418 
419     }
420 }
421 
422