1 /*---------------------------------------------------------------------------*
2 Project: WPAD demo program
3 File: sync.c
4 Programmer: Eugene Kwon
5
6 Copyright (C) 2005-2006 Nintendo. All rights reserved.
7
8 These coded instructions, statements, and computer programs contain
9 proprietary information of Nintendo of America Inc. and/or Nintendo
10 Company Ltd., and are protected by Federal copyright law. They may
11 not be disclosed to third parties or copied or duplicated in any form,
12 in whole or in part, without the prior written consent of Nintendo.
13
14 $Log: sync-callback.c,v $
15 Revision 1.4 08/15/2006 08:55:56 tojo
16 (none)
17
18 Revision 1.3 06/16/2006 14:10:56 ekwon
19 Ensured that WPADProbe() is used to check channel status and to update device type.
20
21 Revision 1.2 06/15/2006 13:50:00 tojo
22 Removed DOLPHIN.
23 Added WPAD_CLEAR_EVT_BUSY.
24
25 Revision 1.1 06/14/2006 11:39:45 ekwon
26 Demonstrates use of the SYNC and CLEAR callbacks. Also demonstrates how to retrieve number of registered devicesl
27
28
29 *---------------------------------------------------------------------------*/
30
31 #include <stdlib.h>
32 #include <string.h>
33 #include <stddef.h>
34 #include <stdarg.h>
35 #include <stdio.h>
36 #include <ctype.h>
37
38 #include <revolution.h>
39 #include <revolution/wpad.h>
40
41 #define DEMO_USE_MEMLIB=1 // This turns on the DEMO library's MEM heaps.
42 #include <demo.h>
43
44
45 #define SCREEN_WIDTH 320
46 #define SCREEN_HEIGHT 240
47 #define FONT_HEIGHT 9
48
49
50 /*---------------------------------------------------------------------------*
51 * Function prototypes
52 *---------------------------------------------------------------------------*/
53
54
55 // MEM2 memory allocation routines. The application must provide these to
56 // WPAD, so it can setup the data transfer buffer. This buffer must reside
57 // in MEM2.
58 static void *myAlloc (u32 size);
59 static u8 myFree (void *ptr);
60
61 // The sync and clear callbacks are optional; applications can register
62 // callbacks to receive notifications for sync/clear events.
63 static void syncCallback (s32 result, s32 num);
64 static void clearCallback (s32 result);
65
66 // internal functions
67 static void initialize (void);
68 static void renderStatus (void);
69 static void printBuffer (char *string, ...);
70
71
72 /*---------------------------------------------------------------------------*
73 * Local Data
74 *---------------------------------------------------------------------------*/
75
76 #define BUFFER_SIZE_BYTES 128
77 static char __buffer[BUFFER_SIZE_BYTES];
78
79
80 /*===========================================================================*
81 * F U N C T I O N D E F I N I T I O N S
82 *===========================================================================*/
83
84
85 /*---------------------------------------------------------------------------*
86 * Name : main()
87 * Description :
88 * Arguments : None.
89 * Returns : None.
90 *---------------------------------------------------------------------------*/
91
main(void)92 int main( void )
93 {
94
95 s32 wpad_state;
96
97 initialize();
98
99 // - We must now register memory allocation/free functions
100 // for MEM2.
101 // - WPAD requires some memory in MEM2 for data transfers
102 // between the controller and WPAD driver stack.
103 // - Memory allocation only occurs once, at the initialization.
104 // - Memory usage is on the order of 1KB.
105 // - NOTE: We are using the MEM library allocators defined by
106 // the DEMO library.
107 //
108 WPADRegisterAllocator(myAlloc, myFree);
109
110 // Initialize WPAD!
111 WPADInit();
112
113 // The WPAD initialization process is asynchronous.
114 // So we should wait until it's completed.
115 do
116 {
117 wpad_state = WPADGetStatus();
118
119 } while (WPAD_STATE_SETUP != wpad_state);
120
121
122 // Register our callback. The callback will be invoked when
123 // the user presses the "Sync" button on the console/dev kit.
124 WPADSetSyncDeviceCallback(syncCallback);
125
126 // Register our callback. The callback will be invoked when
127 // the user presses AND HOLDS the "Sync" button for longer
128 // than 10 seconds or so.
129 WPADSetClearDeviceCallback(clearCallback);
130
131
132 while(1)
133 {
134 DEMOBeforeRender();
135 renderStatus();
136 DEMODoneRender();
137 }
138
139
140 } // end main()
141
142 /*---------------------------------------------------------------------------*
143 * Name : myAlloc()
144 * Description : Callback needed by WPAD to allocate mem from MEM2 heap
145 * Arguments : size of block, in bytes.
146 * Returns : pointer to allocated block.
147 *---------------------------------------------------------------------------*/
myAlloc(u32 size)148 static void *myAlloc(u32 size)
149 {
150 void *ptr;
151
152 ptr = MEMAllocFromAllocator(&DemoAllocator2, size);
153 ASSERTMSG(ptr, "Memory allocation failed\n");
154
155 return(ptr);
156
157 } // myAlloc()
158
159 /*---------------------------------------------------------------------------*
160 * Name : myFree()
161 * Description : Callback needed by WPAD to free mem from MEM2 heap
162 * Arguments : None.
163 * Returns : Always 1.
164 *---------------------------------------------------------------------------*/
myFree(void * ptr)165 static u8 myFree(void *ptr)
166 {
167
168 MEMFreeToAllocator(&DemoAllocator2, ptr);
169
170 // we should ensure that memory is free'd properly, but oh well
171 return(1);
172
173 } // myFree()
174
175 /*---------------------------------------------------------------------------*
176 * Name : syncCallback()
177 * Description :
178 * Arguments : None.
179 * Returns : None.
180 *---------------------------------------------------------------------------*/
syncCallback(s32 result,s32 num)181 static void syncCallback(s32 result, s32 num)
182 {
183 #pragma unused(num)
184
185 switch (result)
186 {
187 case WPAD_SYNC_EVT_BUSY:
188 printBuffer(">> SYNC already in progress.");
189 break;
190
191 case WPAD_SYNC_EVT_START:
192
193 printBuffer(">> SYNC process starting...");
194
195 // Because we registered a callback for the SYNC button-press
196 // event, we are responsible for invoking the SYNC process.
197 // If we do not register a callback, WPAD will start the process
198 // automatically.
199 if (FALSE == WPADStartSyncDevice())
200 {
201 printBuffer(">> SYNC Request Failed!");
202 }
203 break;
204
205 case WPAD_SYNC_EVT_DONE:
206
207 // When complete, this callback will be invoked with the number
208 // of devices that were paired during the SYNC process.
209 printBuffer(">> SYNC complete.");
210
211 break;
212
213 default:
214 printBuffer(">> SYNC ERROR: 0x%08X", result);
215
216 break;
217
218 } // end switch
219
220
221 } // end syncCallback()
222
223
224 /*---------------------------------------------------------------------------*
225 * Name : clearCallback()
226 * Description :
227 * Arguments : None.
228 * Returns : None.
229 *---------------------------------------------------------------------------*/
clearCallback(s32 result)230 static void clearCallback(s32 result)
231 {
232 switch (result)
233 {
234 case WPAD_CLEAR_EVT_BUSY:
235 printBuffer(">> CLEAR already in progress.");
236 break;
237
238 case WPAD_CLEAR_EVT_START:
239
240 printBuffer(">> CLEAR process starting...");
241
242 // Again, because we have registered a callback, we are
243 // responsible for invoking the clearing process.
244 // If no callback is registered, WPAD will do this
245 // automatically.
246 WPADStartClearDevice();
247
248 break;
249
250 case WPAD_CLEAR_EVT_DONE:
251 printBuffer(">> All devices cleared.");
252 break;
253 default:
254 printBuffer(">> CLEAR ERROR: Unknown result 0x%08X", result);
255 break;
256
257 } // end switch
258
259 } // end clearCallback()
260
261
262 /*---------------------------------------------------------------------------*
263 * Name : renderStatus()
264 * Description : Prints interesting data from WPADStatus.
265 * Arguments : Pointer to current WPADStatus.
266 * Returns : None.
267 *---------------------------------------------------------------------------*/
renderStatus(void)268 static void renderStatus(void)
269 {
270
271 s32 i;
272 s16 y;
273
274 u8 num_paired;
275
276 s32 status;
277 u32 type;
278
279
280 // Retrieve the number of devices currently paired to
281 // to this host
282
283 num_paired = WPADGetRegisteredDevNum();
284
285
286 y = FONT_HEIGHT;
287 DEMOPrintf(5, y, 0, "SYNC/CLEAR Demo");
288
289 y += FONT_HEIGHT;
290 y += FONT_HEIGHT;
291
292 DEMOPrintf(5, y, 0, "Connect Status");
293
294 y += FONT_HEIGHT;
295 DEMOPrintf(5, y, 0, "--------------");
296
297
298 for (i=0; i<WPAD_MAX_CONTROLLERS; i++)
299 {
300
301 // Probe the channel
302 status = WPADProbe(i, &type);
303
304 y += FONT_HEIGHT;
305 DEMOPrintf(5, y, 0, "Channel %2d:", i);
306
307 switch(status)
308 {
309 case WPAD_ERR_NONE:
310 DEMOPrintf(105, y, 0, "[Connected]");
311 break;
312 case WPAD_ERR_NO_CONTROLLER:
313 DEMOPrintf(105, y, 0, "[None ]");
314 break;
315 case WPAD_ERR_BUSY:
316 DEMOPrintf(105, y, 0, "[Busy ]");
317 break;
318 case WPAD_ERR_TRANSFER:
319 DEMOPrintf(105, y, 0, "[Transfer ]");
320 break;
321 case WPAD_ERR_INVALID:
322 DEMOPrintf(105, y, 0, "[Invalid ]");
323 break;
324 default:
325 DEMOPrintf(105, y, 0, "[Undefined]");
326 break;
327
328 }// end switch
329
330 switch(type)
331 {
332 case WPAD_DEV_CORE:
333 DEMOPrintf(200, y, 0, "[Core ]");
334 break;
335 case WPAD_DEV_FREESTYLE:
336 DEMOPrintf(200, y, 0, "[Nunchak ]");
337 break;
338 case WPAD_DEV_UNKNOWN:
339 DEMOPrintf(200, y, 0, "[Unknown ]");
340 break;
341 default:
342 DEMOPrintf(200, y, 0, "[Undefined]");
343 break;
344
345 }// end switch
346
347 }
348
349 y += FONT_HEIGHT;
350 y += FONT_HEIGHT;
351 DEMOPrintf(5, y, 0, ">> There are %2d devices currently <<", num_paired);
352 y += FONT_HEIGHT;
353 DEMOPrintf(5, y, 0, ">> paired to this host. <<");
354
355 y += FONT_HEIGHT;
356 y += FONT_HEIGHT;
357 DEMOPrintf(5, y, 0, "- Press SYNC to start pairing. Then");
358 y += FONT_HEIGHT;
359 DEMOPrintf(5, y, 0, " press the SYNC button on the back");
360 y += FONT_HEIGHT;
361 DEMOPrintf(5, y, 0, " of the controller.");
362
363 y += FONT_HEIGHT;
364 DEMOPrintf(5, y, 0, "- Hold SYNC for 10 seconds to CLEAR");
365 y += FONT_HEIGHT;
366 DEMOPrintf(5, y, 0, " all devices.");
367
368
369
370 y += FONT_HEIGHT;
371 y += FONT_HEIGHT;
372
373 DEMOPrintf(5, y, 0, __buffer);
374
375 } // end renderStatus()
376
printBuffer(char * string,...)377 static void printBuffer(char *string, ...)
378 {
379
380 va_list vlist;
381
382
383 memset(__buffer, 0, BUFFER_SIZE_BYTES);
384
385 va_start(vlist, string);
386 vsprintf((char *)__buffer, string, vlist);
387 va_end(vlist);
388
389
390 } // clear and dump string to buffer
391
392
393 /*---------------------------------------------------------------------------*
394 * Name : initialize()
395 * Description : Performs basic system initialization.
396 * Arguments : None.
397 * Returns : None.
398 *---------------------------------------------------------------------------*/
399
initialize(void)400 static void initialize( void )
401 {
402 const GXColor DARKBLUE = { 0, 0, 40, 255 };
403
404 OSInit();
405
406 DEMOInit( &GXNtsc480IntDf );
407
408 GXSetCopyClear( DARKBLUE, GX_MAX_Z24 );
409 GXCopyDisp( DEMOGetCurrentBuffer(), GX_TRUE );
410 DEMOInitCaption( DM_FT_XLU, SCREEN_WIDTH, SCREEN_HEIGHT );
411 GXSetZMode( GX_ENABLE, GX_ALWAYS, GX_ENABLE ); // Set pixel processing mode
412 GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR ); // Translucent mode
413
414
415 memset(__buffer, 0, BUFFER_SIZE_BYTES);
416
417 } // end
418