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