1 /*---------------------------------------------------------------------------*
2   Project:     WPAD demo program
3   File:        sampling.c
4   Programmers: HIRATSU Daisuke
5                TOKUNAGA, Yasuhiro
6 
7   Copyright (C) 2005-2006 Nintendo.  All rights reserved.
8 
9   These coded instructions, statements, and computer programs contain
10   proprietary information of Nintendo of America Inc. and/or Nintendo
11   Company Ltd., and are protected by Federal copyright law.  They may
12   not be disclosed to third parties or copied or duplicated in any form,
13   in whole or in part, without the prior written consent of Nintendo.
14 
15   $Log: sampling.c,v $
16   Revision 1.11  06/16/2006 08:37:31  tojo
17   (none)
18 
19   Revision 1.10  06/13/2006 04:55:21  tojo
20   (none)
21 
22   Revision 1.9  06/13/2006 01:57:26  ekwon
23   Minor cleanup.
24 
25   Revision 1.8  06/12/2006 12:03:28  ekwon
26   Fixes for querying DPD status before enabling DPD.
27 
28   Revision 1.7  06/12/2006 08:48:16  ekwon
29   Must re-establish sampling buffer AND DPD/ACC init upon reconnect.
30 
31   Revision 1.6  06/12/2006 08:22:53  ekwon
32   Sampling demo for WPADSetAutoSamplingBuf().
33 
34   Revision 1.1  06/01/2006 00:40:11  hiratsu
35   Moved from $(SDK)/build/demos/wpaddemo
36 
37   Revision 1.4  2006/03/13 02:10:46  yasuh-to
38   Modified copyright.
39 
40  *---------------------------------------------------------------------------*/
41 #include <stdlib.h>
42 #include <string.h>
43 #include <stddef.h>
44 #include <stdarg.h>
45 #include <stdio.h>
46 #include <ctype.h>
47 
48 #include <revolution.h>
49 #include <revolution/wpad.h>
50 
51 #define DEMO_USE_MEMLIB=1 // This turns on the DEMO library's MEM heaps.
52 #include <demo.h>
53 
54 
55 
56 #define SCREEN_WIDTH  320
57 #define SCREEN_HEIGHT 240
58 
59 #define SMPBUF_SIZE   100   // Size of WPADStatus array for auto sampling.
60 
61 
62 // ring buffer to store data from auto-sampling feature
63 static WPADStatus s_ringBuf[SMPBUF_SIZE];
64 
65 /*---------------------------------------------------------------------------*
66  * Function prototypes
67  *---------------------------------------------------------------------------*/
68 
69 
70 // MEM2 memory allocation routines. The application must provide these to
71 // WPAD, so it can setup the data transfer buffer. This buffer must reside
72 // in MEM2.
73 static void *myAlloc        (u32 size);
74 static u8    myFree         (void *ptr);
75 
76 
77 static void initialize      (void);
78 static void renderStatus    (WPADStatus *stat);
79 static void renderAimings   (void);
80 
81 
82 /*===========================================================================*
83  *                   F U N C T I O N    D E F I N I T I O N S
84  *===========================================================================*/
85 
86 /*---------------------------------------------------------------------------*
87  * Name        : main()
88  * Description :
89  * Arguments   : None.
90  * Returns     : None.
91  *---------------------------------------------------------------------------*/
main(void)92 int main( void )
93 {
94     WPADStatus wpad;
95 
96     s32 wpad_state;
97     s32 status;
98     u32 type;
99     u32 index;
100 
101         initialize();
102 
103 
104         // we should clear the WPADStatus block returned by
105         // WPADRead(), because if no channel is connected, nothing
106         // is copied. So we would be staring at garbage data.
107         memset( (void *)(&wpad), 0, sizeof(WPADStatus));
108 
109         // must register MEM2 allocation functions before invoking WPADInit()
110         WPADRegisterAllocator(myAlloc, myFree);
111         WPADInit();
112 
113 
114         // The WPAD initialization process is asynchronous.
115         // So we should wait until it's completed.
116         do
117         {
118 
119             wpad_state = WPADGetStatus();
120 
121         } while (WPAD_STATE_SETUP != wpad_state);
122 
123 
124         // Main loop
125         while( 1 )
126         {
127             status = WPADProbe(WPAD_CHAN0, &type);
128 
129             if (WPAD_ERR_NONE == status)
130             {
131 
132                 // Note: If the controller has disconnected and re-connected,
133                 // we need to reset and re-enable DPD and the auto-sampling buffer.
134                 // But we have to ensure that the device type is correct, because
135                 // it's possible a different type of device has connected on channel 0.
136                 if ((WPAD_DEV_CORE == type) || (WPAD_DEV_FREESTYLE == type))
137                 {
138 
139                     // Are the DPD and Accelerometers enabled?
140                     if (FALSE == WPADIsDpdEnabled(WPAD_CHAN0))
141                     {
142                         // if not, then set the format and turn on DPD and accelerometer
143                         WPADControlDpd(WPAD_CHAN0, WPAD_DPD_EXP, NULL);
144                         WPADSetDataFormat(WPAD_CHAN0, WPAD_FMT_CORE_ACC_DPD);
145 
146                         // ...and re-establish the sampling buffer here
147                         WPADSetAutoSamplingBuf( WPAD_CHAN0, s_ringBuf, SMPBUF_SIZE );
148 
149                     } // if DPD/ACC enabled?
150 
151                 } // if device type
152 
153             } // if no error
154 
155             index = WPADGetLatestIndexInBuf(WPAD_CHAN0);
156 
157             DEMOBeforeRender();
158             renderStatus(&s_ringBuf[index]);
159             renderAimings();
160             DEMODoneRender();
161 
162         } // while
163 
164         return 0;
165 
166 
167 } // end
168 
169 /*---------------------------------------------------------------------------*
170  * Name        : initialize()
171  * Description :
172  * Arguments   : None.
173  * Returns     : None.
174  *---------------------------------------------------------------------------*/
175 
initialize(void)176 static void initialize(void)
177 {
178 
179     const GXColor DARKBLUE = { 0, 0, 40, 255 };
180 
181         OSInit();
182 
183         DEMOInit( &GXNtsc480IntDf );
184         GXSetCopyClear( DARKBLUE, GX_MAX_Z24 );
185         GXCopyDisp( DEMOGetCurrentBuffer(), GX_TRUE );
186         DEMOInitCaption( DM_FT_XLU, SCREEN_WIDTH, SCREEN_HEIGHT );
187         GXSetZMode( GX_ENABLE, GX_ALWAYS, GX_ENABLE );                       // Set pixel processing mode
188         GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR );    // Translucent mode
189 
190 } // end
191 
192 /*---------------------------------------------------------------------------*
193  * Name        : renderStatus()
194  * Description :
195  * Arguments   : None.
196  * Returns     : None.
197  *---------------------------------------------------------------------------*/
renderStatus(WPADStatus * stat)198 static void renderStatus(WPADStatus *stat)
199 {
200     const int FONT_HEIGHT = 8;
201     char buf[] = "___________";
202     s16 x = FONT_HEIGHT;
203     s16 y = FONT_HEIGHT;
204     int i = 0;
205 
206         // just print accelerometer data
207         DEMOPrintf( x, y+=FONT_HEIGHT, 0, "accX   :  %d", stat->accX );
208         DEMOPrintf( x, y+=FONT_HEIGHT, 0, "accY   :  %d", stat->accY );
209         DEMOPrintf( x, y+=FONT_HEIGHT, 0, "accZ   :  %d", stat->accZ );
210 
211         if( stat->button & WPAD_BUTTON_RIGHT  ) buf[0] = '>';
212         if( stat->button & WPAD_BUTTON_DOWN   ) buf[1] = 'v';
213         if( stat->button & WPAD_BUTTON_UP     ) buf[2] = '^';
214         if( stat->button & WPAD_BUTTON_LEFT   ) buf[3] = '<';
215         if( stat->button & WPAD_BUTTON_START  ) buf[4] = 'S';
216         if( stat->button & WPAD_BUTTON_SELECT ) buf[5] = 'T';
217         if( stat->button & WPAD_BUTTON_A      ) buf[7] = 'A';
218         if( stat->button & WPAD_BUTTON_B      ) buf[6] = 'B';
219         if( stat->button & WPAD_BUTTON_SMALL_A) buf[8] = 'a';
220         if( stat->button & WPAD_BUTTON_SMALL_B) buf[9] = 'b';
221         if( stat->button & WPAD_BUTTON_HOME   ) buf[10]= 'H';
222 
223         DEMOPrintf( x, y+=FONT_HEIGHT, 0, "Buttons: [%s]",buf);
224         y+=FONT_HEIGHT;
225         DEMOPrintf( x, y+=FONT_HEIGHT, 0, "DPD-ID     X    Y SIZE");
226 
227         for( i=0; i<WPAD_DPD_MAX_OBJECTS; ++i )
228         {
229             const DPDObject *p = &( stat->obj[i] );
230 
231 
232                 DEMOPrintf( x, y+=FONT_HEIGHT, 0, "%1d       %4d %4d  %3d", p->traceId, p->x, p->y, p->size );
233 
234         }
235 
236 
237         y+=FONT_HEIGHT;
238         DEMOPrintf( x, y+=FONT_HEIGHT, 0, "Controller Type: %d", stat->dev );
239         DEMOPrintf( x, y+=FONT_HEIGHT, 0, "ERROR Info     : %d", stat->err );
240 
241         if (WPAD_ERR_NO_CONTROLLER == stat->err)
242         {
243             y+=FONT_HEIGHT;
244             y+=FONT_HEIGHT;
245             DEMOPrintf(x, y+=FONT_HEIGHT, 0, ">> No controller is connected!");
246             DEMOPrintf(x, y+=FONT_HEIGHT, 0, ">> Please press a button on a paired");
247             DEMOPrintf(x, y+=FONT_HEIGHT, 0, ">> controller to connect.");
248         }
249 
250 
251 } // end
252 
253 
254 /*---------------------------------------------------------------------------*
255  * Name        : renderAimings()
256  * Description :
257  * Arguments   : None.
258  * Returns     : None.
259  *---------------------------------------------------------------------------*/
renderAimings(void)260 static void renderAimings(void)
261 {
262     u32 latest;
263     int i;
264     int index;
265 
266         latest = WPADGetLatestIndexInBuf(WPAD_CHAN0);
267 
268 
269         for (i=0; i<SMPBUF_SIZE-1; ++i)
270         {
271             index = (int)(latest - i);
272 
273             if (index < 0)
274             {
275                 index += SMPBUF_SIZE;
276             }
277 
278             if(s_ringBuf[index].err == WPAD_ERR_NONE)
279             {
280 		        s16 x=(s16)(SCREEN_WIDTH -(s_ringBuf[index].obj[0].x+s_ringBuf[index].obj[1].x)/2*SCREEN_WIDTH /WPAD_DPD_IMG_RESO_WX);
281 		        s16 y=(s16)(SCREEN_HEIGHT-(s_ringBuf[index].obj[0].y+s_ringBuf[index].obj[1].y)/2*SCREEN_HEIGHT/WPAD_DPD_IMG_RESO_WY);
282                 DEMOPrintf(x, y, 0, ".");
283 		    }
284         }
285 
286 } // end
287 
288 /*---------------------------------------------------------------------------*
289  * Name        : myAlloc()
290  * Description : Callback needed by WPAD to allocate mem from MEM2 heap
291  * Arguments   : size of block, in bytes.
292  * Returns     : pointer to allocated block.
293  *---------------------------------------------------------------------------*/
myAlloc(u32 size)294 static void *myAlloc(u32 size)
295 {
296     void *ptr;
297 
298     ptr = MEMAllocFromAllocator(&DemoAllocator2, size);
299     ASSERTMSG(ptr, "Memory allocation failed\n");
300 
301     return(ptr);
302 
303 } // myAlloc()
304 
305 /*---------------------------------------------------------------------------*
306  * Name        : myFree()
307  * Description : Callback needed by WPAD to free mem from MEM2 heap
308  * Arguments   : None.
309  * Returns     : Always 1.
310  *---------------------------------------------------------------------------*/
myFree(void * ptr)311 static u8 myFree(void *ptr)
312 {
313 
314     MEMFreeToAllocator(&DemoAllocator2, ptr);
315 
316     // we should ensure that memory is free'd properly, but oh well
317     return(1);
318 
319 } // myFree()
320 
321