1 /*---------------------------------------------------------------------------*
2   Project:    WPAD demo program
3   File:       dummy_checker.c
4 
5   Copyright (C) 2007 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: dummy_checker.c,v $
14   Revision 1.5.6.1  2008/08/27 04:50:20  tojo
15   Modified the error handling of controller data.
16 
17   Revision 1.5  2007/07/11 12:47:49  tojo
18   (none)
19 
20   Revision 1.4  2007/07/10 12:14:46  tojo
21   (none)
22 
23   Revision 1.3  2007/05/02 07:52:23  tojo
24   (none)
25 
26   Revision 1.2  2007/04/23 08:16:09  tojo
27   (none)
28 
29   Revision 1.1  2007/04/18 01:30:48  tojo
30   Initial check-in.
31 
32 
33  *---------------------------------------------------------------------------*/
34 
35 #include <stdlib.h>
36 #include <string.h>
37 #include <stddef.h>
38 #include <stdarg.h>
39 #include <stdio.h>
40 #include <ctype.h>
41 
42 #include <revolution.h>
43 #include <revolution/wpad.h>
44 
45 #define DEMO_USE_MEMLIB=1 // This turns on the DEMO library's MEM heaps.
46 #include <demo.h>
47 
48 /*---------------------------------------------------------------------------*
49  * Local Definitions
50  *---------------------------------------------------------------------------*/
51 
52 #define SCREEN_WIDTH  320
53 #define SCREEN_HEIGHT 240
54 #define FONT_HEIGHT     8
55 
56 /*---------------------------------------------------------------------------*
57  * Local Data
58  *---------------------------------------------------------------------------*/
59 
60 
61 #define SMPBUF_SIZE 100
62 
63 static WPADCLStatus cl_ringbuffer[SMPBUF_SIZE];
64 static WPADFSStatus fs_ringbuffer[SMPBUF_SIZE];
65 static WPADStatus   co_ringbuffer[SMPBUF_SIZE];
66 
67 
68 /*---------------------------------------------------------------------------*
69  * Function prototypes
70  *---------------------------------------------------------------------------*/
71 
72 
73 // MEM2 memory allocation routines. The application must provide these to
74 // WPAD, so it can setup the data transfer buffer. This buffer must reside
75 // in MEM2.
76 static void *myAlloc                 ( u32 size  );
77 static u8    myFree                  ( void *ptr );
78 
79 // callbacks
80 void         connectCallback         ( s32 chan, s32 reason );
81 void         extensionCallback       ( s32 chan, s32 result );
82 void         samplingCallback        ( s32 chan );
83 
84 // internal functions
85 static void  initialize              ( void );
86 static void  renderStatus            ( void );
87 static void  renderAimings           ( void );
88 static void  printIntro              ( void );
89 static void  printBuffer             ( char *string, ... );
90 static u8   *get_dev_name            ( u32 type   );
91 static u8   *get_status_name         ( s32 status );
92 
93 
94 
95 /*===========================================================================*
96  *                   F U N C T I O N    D E F I N I T I O N S
97  *===========================================================================*/
98 /*---------------------------------------------------------------------------*
99  * Name        : printIntro()
100  * Description :
101  * Arguments   : None.
102  * Returns     : None.
103  *---------------------------------------------------------------------------*/
printIntro(void)104 static void printIntro( void )
105 {
106 #ifdef _DEBUG
107     OSReport("-------------------------------------------------------\n");
108     OSReport(" Dummy Extension Demo:                                 \n");
109     OSReport("             Button A: Attach the future device.       \n");
110     OSReport("             Button X: Attach the unsupported device.  \n");
111     OSReport("             Button B: Detach the device.              \n");
112     OSReport("-------------------------------------------------------\n");
113 #else
114     OSReport("-------------------------------------------------------\n");
115     OSReport("                                                       \n");
116     OSReport(" Dummy Extension cannot be used in release build!!!    \n");
117     OSReport("                                                       \n");
118     OSReport("-------------------------------------------------------\n");
119 #endif
120 }
121 
122 /*---------------------------------------------------------------------------*
123  * Name        : main()
124  * Description :
125  * Arguments   : None.
126  * Returns     : None.
127  *---------------------------------------------------------------------------*/
main(void)128 int main( void )
129 {
130 
131     int  i;
132 
133     initialize();
134 
135     // - We must now register memory allocation/free functions
136     //   for MEM2.
137     // - WPAD requires some memory in MEM2 for data transfers
138     //   between the controller and WPAD driver stack.
139     // - Memory allocation only occurs once, at the initialization.
140     // - Memory usage is on the order of 1KB.
141     // - NOTE: We are using the MEM library allocators defined by
142     //   the DEMO library.
143     //
144     WPADRegisterAllocator(myAlloc, myFree);
145 
146     // Initialize WPAD!
147     WPADInit();
148 
149     for (i=0; i<WPAD_MAX_CONTROLLERS; i++)
150     {
151         // Register a callback for each channel, for
152         // connect and disconnect events.
153         WPADSetConnectCallback(i, connectCallback);
154     }
155 
156     // The WPAD initialization process is asynchronous.
157     // So we should wait until it's completed.
158     while(WPADGetStatus() != WPAD_STATE_SETUP)
159     {
160         ;
161     }
162 
163     printIntro();
164 
165     while(1)
166     {
167 #ifdef _DEBUG
168         DEMOPadRead();
169 
170         if (DEMOPadGetButtonDown(0) & PAD_BUTTON_A)
171         {
172             if (WPADAttachDummyExtension( WPAD_CHAN0, WPAD_DEV_FUTURE ))
173             {
174                 OSReport(" Attach dummy extension [WPAD_DEV_FUTURE]\n");
175             }
176             else
177             {
178                 OSReport(" Something is already attached\n");
179             }
180         }
181         if (DEMOPadGetButtonDown(0) & PAD_BUTTON_X)
182         {
183             if (WPADAttachDummyExtension( WPAD_CHAN0, WPAD_DEV_NOT_SUPPORTED ))
184             {
185                 OSReport(" Attach dummy extension [WPAD_DEV_NOT_SUPPORTED]\n");
186             }
187             else
188             {
189                 OSReport(" Something is already attached\n");
190             }
191         }
192         if (DEMOPadGetButtonDown(0) & PAD_BUTTON_B)
193         {
194             if (WPADDetachDummyExtension( WPAD_CHAN0 ))
195             {
196                 OSReport(" Detach dummy extension\n");
197             }
198             else
199             {
200                 OSReport(" Nothing is attached\n");
201             }
202         }
203 #endif // _DEBUG
204 
205         DEMOBeforeRender();
206         renderStatus();
207         renderAimings();
208         DEMODoneRender();
209     }
210 
211 } // end main()
212 
213 /*---------------------------------------------------------------------------*
214  * Name        : connectCallback()
215  *
216  * Description : This callback is invoked when a controller is connected or
217  *               disconnected.
218  *
219  * Arguments   : The channel (chan) for which the event has occurred.
220  *               The channel status (reason):
221  *                 WPAD_ERR_NONE means a controller has been connected.
222  *                 WPAD_ERR_NO_CONTROLLER means a controller disconnected.
223  *
224  * Returns     : None.
225  *---------------------------------------------------------------------------*/
connectCallback(s32 chan,s32 reason)226 void connectCallback( s32 chan, s32 reason )
227 {
228     switch(reason)
229     {
230         case WPAD_ERR_NONE:
231             // Accept a connection to be asigned to CHAN0.
232             if (chan != WPAD_CHAN0)
233             {
234                 WPADDisconnect(chan);
235                 break;
236             }
237 
238             // If we want to support dynamic attachment/detachment of an
239             // extension, we must register an extension callback.
240             WPADSetExtensionCallback(chan, extensionCallback);
241 
242             // If we want to use the sampling callback, we need to register
243             // the callback when a device is connected.
244             WPADSetSamplingCallback(chan, samplingCallback);
245 
246             // Turn on dpd and acc.
247             WPADControlDpd(chan, WPAD_DPD_EXP, NULL);
248             WPADSetDataFormat(chan, WPAD_FMT_CORE_ACC_DPD);
249 
250             // Note we must reset the auto-sampling buffer so that WPAD
251             // will write into the appropriate buffer
252             WPADSetAutoSamplingBuf(chan, (void *)(&co_ringbuffer[0]), SMPBUF_SIZE);
253 
254             break;
255 
256         case WPAD_ERR_NO_CONTROLLER:
257             // We don't have to do anything.
258             // Note that all callbacks and the autosampling buffer will be
259             // cleared on disconnect events.
260             //
261             // Of course, the connect callback will still be valid for this channel.
262 
263             break;
264 
265         default:
266             // unexpected result!
267             break;
268 
269     } // end switch
270 
271 } // end connectCallback()
272 
273 /*---------------------------------------------------------------------------*
274  * Name        : extensionCallback()
275  *
276  * Description : This callback is invoked when an Extension has been attached.
277  *
278  * Arguments   : The channel (chan) for which the extension event occurred.
279  *               The device type (result):
280  *
281  *                 WPAD_DEV_UNKNOWN means that something has been attached, but
282  *                 it's being initialized, and we won't know what it is until
283  *                 initialization is complete.
284  *
285  *                 WPAD_DEV_CORE means that an extension has been removed and
286  *                 we're back to just the core device.
287  *
288  *                 WPAD_DEV_FREESTYLE means that the "NUNCHAK" extension has
289  *                 been attached and initialized.
290  *
291  *                 WPAD_DEV_CLASSIC means that the "CLASSIC" extension has been
292  *                 attached and initialized.
293  *
294  * Returns     : None.
295  *---------------------------------------------------------------------------*/
extensionCallback(s32 chan,s32 result)296 void extensionCallback( s32 chan, s32 result )
297 {
298     switch(result)
299     {
300         case WPAD_DEV_UNKNOWN:
301             // in this case, the extension has been attached by the user
302             // but we don't know what type it is yet. Initialization of
303             // the attachment may take a few seconds, during which time
304             // button presses, the DPD, and accelerometers will be affected.
305             // This event is provided so applications can notify the
306             // user of the interruption and/or pause the game.
307             break;
308 
309         case WPAD_DEV_CORE:
310             // In this case, the user has disconnected an extension.
311             // So, the device type will revert to "core only".
312             WPADControlDpd(chan, WPAD_DPD_EXP, NULL);
313             WPADSetDataFormat(chan, WPAD_FMT_CORE_ACC_DPD);
314 
315             // Note we must reset the auto-sampling buffer so that WPAD
316             // will write into the appropriate buffer
317             WPADSetAutoSamplingBuf(chan, (void *)(&co_ringbuffer[0]), SMPBUF_SIZE);
318             break;
319 
320         case WPAD_DEV_FREESTYLE:
321             // Now that we know the extension type, we must revise
322             // the data format and control the DPD accordingly.
323             WPADControlDpd(chan, WPAD_DPD_STD, NULL);
324             WPADSetDataFormat(chan, WPAD_FMT_FREESTYLE_ACC_DPD);
325 
326             // Note we must reset the auto-sampling buffer so that WPAD
327             // will write into the appropriate buffer
328             WPADSetAutoSamplingBuf(chan, (void *)(&fs_ringbuffer[0]), SMPBUF_SIZE);
329             break;
330 
331         case WPAD_DEV_CLASSIC:
332 
333             // Now that we know the extension type, we must revise
334             // the data format and control the DPD accordingly.
335             WPADControlDpd(chan, WPAD_DPD_STD, NULL);
336             WPADSetDataFormat(chan, WPAD_FMT_CLASSIC_ACC_DPD);
337 
338             // Note we must reset the auto-sampling buffer so that WPAD
339             // will write into the appropriate buffer
340             WPADSetAutoSamplingBuf(chan, (void *)(&cl_ringbuffer[0]), SMPBUF_SIZE);
341             break;
342 
343         case WPAD_DEV_FUTURE:
344             // Now that we don't know the extension type, we should ignore the extension and
345             // we must revise the data format and control the DPD accordingly.
346             WPADControlDpd(chan, WPAD_DPD_EXP, NULL);
347             WPADSetDataFormat(chan, WPAD_FMT_CORE_ACC_DPD);
348 
349             // Note we must reset the auto-sampling buffer so that WPAD
350             // will write into the appropriate buffer
351             WPADSetAutoSamplingBuf(chan, (void *)(&co_ringbuffer[0]), SMPBUF_SIZE);
352             break;
353 
354         case WPAD_DEV_NOT_SUPPORTED:
355             // The user plugged in something weird.
356             // The safe thing to do is revert to Core-only operation.
357             WPADControlDpd(chan, WPAD_DPD_EXP, NULL);
358             WPADSetDataFormat(chan, WPAD_FMT_CORE_ACC_DPD);
359 
360             // Note we must reset the auto-sampling buffer so that WPAD
361             // will write into the appropriate buffer
362             WPADSetAutoSamplingBuf(chan, (void *)(&co_ringbuffer[0]), SMPBUF_SIZE);
363             break;
364 
365         default:
366             // Here is WPAD_DEV_NOT_FOUND.
367             // If the controller is disconnected while the extension is initializing
368             // it reaches here. There is nothing to do.
369             break;
370 
371     } // end
372 
373 } // end extensionCallback()
374 
375 /*---------------------------------------------------------------------------*
376  * Name        : samplingCallback()
377  * Description : Invoked by WPAD every time data is available for WPADRead().
378  * Arguments   : Channel for which data is available.
379  * Returns     : None.
380  *---------------------------------------------------------------------------*/
samplingCallback(s32 chan)381 void samplingCallback( s32 chan )
382 {
383 #pragma unused(chan)
384 
385     // for this demo, we're not actually doing anything here.
386     // Normally, you can call WPADProbe() and WPADRead() to retrieve
387     // the WPAD Status block for the indicated channel.
388     //
389     // However, since we're using the auto sampling buffer, we won't bother.
390     //
391     // We are using this empty function to demonstrate how to handle
392     // registration of sampling callback during connect/attach events.
393     //
394 
395 
396 } // end sampling Callback
397 
398 
399 
400 /*---------------------------------------------------------------------------*
401  * Name        : myAlloc()
402  * Description : Callback needed by WPAD to allocate mem from MEM2 heap
403  * Arguments   : size of block, in bytes.
404  * Returns     : pointer to allocated block.
405  *---------------------------------------------------------------------------*/
myAlloc(u32 size)406 static void *myAlloc( u32 size )
407 {
408     void *ptr;
409 
410     ptr = MEMAllocFromAllocator(&DemoAllocator2, size);
411     ASSERTMSG(ptr, "Memory allocation failed\n");
412 
413     return(ptr);
414 
415 } // myAlloc()
416 
417 /*---------------------------------------------------------------------------*
418  * Name        : myFree()
419  * Description : Callback needed by WPAD to free mem from MEM2 heap
420  * Arguments   : None.
421  * Returns     : Always 1.
422  *---------------------------------------------------------------------------*/
myFree(void * ptr)423 static u8 myFree( void *ptr )
424 {
425 
426     MEMFreeToAllocator(&DemoAllocator2, ptr);
427 
428     // we should ensure that memory is free'd properly, but oh well
429     return(1);
430 
431 } // myFree()
432 
433 
434 
435 /*===========================================================================*
436  *                     I N T E R N A L    F U N C T I O N S
437  *===========================================================================*/
438 /*---------------------------------------------------------------------------*
439  * The following functions handle the status display of this demo.
440  * They aren't really relevant to the demonstration of the CONNECT
441  * and EXTENSION callbacks.
442  *---------------------------------------------------------------------------*/
443 /*---------------------------------------------------------------------------*
444  * Local Data
445  *---------------------------------------------------------------------------*/
446 
447 #define COL_WIDTH  6*FONT_HEIGHT
448 #define X_START    10
449 #define Y_START    10
450 
renderStatus(void)451 static void renderStatus( void )
452 {
453     WPADCLStatus  status_block;
454     WPADStatus   *wpad_ptr;
455     WPADCLStatus *cl_ptr;
456     WPADFSStatus *fs_ptr;
457 
458     s32 status;
459     u32 type;
460 
461     s16 x;
462     s16 y;
463 
464     char buf[] = "___________";
465     char buf2[] = "__";
466     char buf3[] = "_______________";
467 
468 
469     // clear status block
470     memset((void *)(&status_block), 0, sizeof(WPADCLStatus));
471 
472     x = X_START;
473     y = Y_START;
474 
475     DEMOPrintf(x, y, 0, "WPAD Demo -- Dummy checker");
476     y+=FONT_HEIGHT;
477     y+=FONT_HEIGHT;
478     DEMOPrintf(x, y, 0, "Status :"); y+=FONT_HEIGHT;
479     DEMOPrintf(x, y, 0, "Type   :"); y+=FONT_HEIGHT;
480     DEMOPrintf(x, y, 0, "Buttons:"); y+=FONT_HEIGHT;
481     DEMOPrintf(x, y, 0, "DPD0-xy:"); y+=FONT_HEIGHT;
482     DEMOPrintf(x, y, 0, "DPD1-xy:"); y+=FONT_HEIGHT;
483     DEMOPrintf(x, y, 0, "ACC-XYZ:"); y+=FONT_HEIGHT;
484     DEMOPrintf(x, y, 0, "--------"); y+=FONT_HEIGHT;
485     DEMOPrintf(x, y, 0, "Buttons:"); y+=FONT_HEIGHT;
486     DEMOPrintf(x, y, 0, "StickXY:"); y+=FONT_HEIGHT;
487     DEMOPrintf(x, y, 0, "ACC-XYZ:"); y+=FONT_HEIGHT;
488     DEMOPrintf(x, y, 0, "--------"); y+=FONT_HEIGHT;
489     DEMOPrintf(x, y, 0, "Buttons:"); y+=FONT_HEIGHT;
490     DEMOPrintf(x, y, 0, "StickXY:"); y+=FONT_HEIGHT;
491     DEMOPrintf(x, y, 0, "StickXY:"); y+=FONT_HEIGHT;
492     DEMOPrintf(x, y, 0, "TrigLR :"); y+=FONT_HEIGHT;
493 
494     x = (s16)(X_START + COL_WIDTH);
495     y = (s16)(Y_START + FONT_HEIGHT*2);
496 
497     status = WPADProbe(WPAD_CHAN0, &type);
498 
499     DEMOPrintf(x, y, 0, "%s", get_status_name(status)); y+= FONT_HEIGHT;
500     DEMOPrintf(x, y, 0, "%s", get_dev_name(type));      y+= FONT_HEIGHT;
501 
502     if (WPAD_ERR_NO_CONTROLLER != status)
503     {
504         WPADRead(WPAD_CHAN0, &status_block);
505         wpad_ptr = (WPADStatus   *)(&status_block);
506         cl_ptr   = (WPADCLStatus *)(&status_block);
507         fs_ptr   = (WPADFSStatus *)(&status_block);
508 
509         if( wpad_ptr->button & WPAD_BUTTON_LEFT   ) buf[ 0] = '<';
510         if( wpad_ptr->button & WPAD_BUTTON_UP     ) buf[ 1] = '^';
511         if( wpad_ptr->button & WPAD_BUTTON_DOWN   ) buf[ 2] = 'v';
512         if( wpad_ptr->button & WPAD_BUTTON_RIGHT  ) buf[ 3] = '>';
513         if( wpad_ptr->button & WPAD_BUTTON_A      ) buf[ 4] = 'A';
514         if( wpad_ptr->button & WPAD_BUTTON_B      ) buf[ 5] = 'B';
515         if( wpad_ptr->button & WPAD_BUTTON_1      ) buf[ 6] = '1';
516         if( wpad_ptr->button & WPAD_BUTTON_2      ) buf[ 7] = '2';
517         if( wpad_ptr->button & WPAD_BUTTON_MINUS  ) buf[ 8] = '-';
518         if( wpad_ptr->button & WPAD_BUTTON_HOME   ) buf[ 9] = 'H';
519         if( wpad_ptr->button & WPAD_BUTTON_PLUS   ) buf[10] = '+';
520 
521         DEMOPrintf(x, y, 0, "   %s", buf); y+= FONT_HEIGHT;
522         DEMOPrintf(x, y, 0, "   %04X %04X", (u16)(wpad_ptr->obj[0].x), (u16)(wpad_ptr->obj[0].y)); y+= FONT_HEIGHT;
523         DEMOPrintf(x, y, 0, "   %04X %04X", (u16)(wpad_ptr->obj[1].x), (u16)(wpad_ptr->obj[1].y)); y+= FONT_HEIGHT;
524         DEMOPrintf(x, y, 0, "   %04X %04X %04X", (u16)(wpad_ptr->accX), (u16)(wpad_ptr->accY), (u16)(wpad_ptr->accZ)); y+= FONT_HEIGHT;
525 
526         y+= FONT_HEIGHT;
527 
528         if (WPAD_DEV_FREESTYLE == type)
529         {
530             if( fs_ptr->button & WPAD_BUTTON_C) buf2[ 0] = 'C';
531             if( fs_ptr->button & WPAD_BUTTON_Z) buf2[ 1] = 'Z';
532 
533             DEMOPrintf(x, y, 0, "   %s", buf2); y+= FONT_HEIGHT;
534             DEMOPrintf(x, y, 0, "   %04X %04X", (u16)(fs_ptr->fsStickX), (u16)(fs_ptr->fsStickY)); y+= FONT_HEIGHT;
535             DEMOPrintf(x, y, 0, "   %04X %04X %04X", (u16)(fs_ptr->fsAccX), (u16)(fs_ptr->fsAccY), (u16)(fs_ptr->fsAccZ)); y+= FONT_HEIGHT;
536         }
537         else
538         {
539             y+= FONT_HEIGHT * 3;
540         }
541 
542         y+= FONT_HEIGHT;
543 
544         if (WPAD_DEV_CLASSIC == type)
545         {
546             if( cl_ptr->clButton & WPAD_CL_BUTTON_LEFT   ) buf3[ 0] = '<';
547             if( cl_ptr->clButton & WPAD_CL_BUTTON_UP     ) buf3[ 1] = '^';
548             if( cl_ptr->clButton & WPAD_CL_BUTTON_DOWN   ) buf3[ 2] = 'v';
549             if( cl_ptr->clButton & WPAD_CL_BUTTON_RIGHT  ) buf3[ 3] = '>';
550             if( cl_ptr->clButton & WPAD_CL_BUTTON_A      ) buf3[ 4] = 'A';
551             if( cl_ptr->clButton & WPAD_CL_BUTTON_B      ) buf3[ 5] = 'B';
552             if( cl_ptr->clButton & WPAD_CL_BUTTON_X      ) buf3[ 6] = 'X';
553             if( cl_ptr->clButton & WPAD_CL_BUTTON_Y      ) buf3[ 7] = 'Y';
554             if( cl_ptr->clButton & WPAD_CL_TRIGGER_L     ) buf3[ 8] = 'L';
555             if( cl_ptr->clButton & WPAD_CL_TRIGGER_R     ) buf3[ 9] = 'R';
556             if( cl_ptr->clButton & WPAD_CL_TRIGGER_ZL    ) buf3[10] = 'z';
557             if( cl_ptr->clButton & WPAD_CL_TRIGGER_ZR    ) buf3[11] = 'Z';
558             if( cl_ptr->clButton & WPAD_CL_BUTTON_MINUS  ) buf3[12] = '-';
559             if( cl_ptr->clButton & WPAD_CL_BUTTON_HOME   ) buf3[13] = 'H';
560             if( cl_ptr->clButton & WPAD_CL_BUTTON_PLUS   ) buf3[14] = '+';
561 
562             DEMOPrintf(x, y, 0, "   %s", buf3); y+= FONT_HEIGHT;
563             DEMOPrintf(x, y, 0, "   %04X %04X", (u16)(cl_ptr->clLStickX), (u16)(cl_ptr->clLStickY)); y+= FONT_HEIGHT;
564             DEMOPrintf(x, y, 0, "   %04X %04X", (u16)(cl_ptr->clRStickX), (u16)(cl_ptr->clRStickY)); y+= FONT_HEIGHT;
565             DEMOPrintf(x, y, 0, "   %04X %04X", (u16)(cl_ptr->clTriggerL), (u16)(cl_ptr->clTriggerR)); y+= FONT_HEIGHT;
566 
567         } // if classic
568 
569     } // if no error
570 
571 } // end renderStatus()
572 
573 
get_dev_name(u32 type)574 static u8 *get_dev_name( u32 type )
575 {
576 
577     u8 str_dev_core   [] = "   Core   ";
578     u8 str_dev_extn   [] = "   Extn   ";
579     u8 str_dev_cl     [] = "  Classic ";
580     u8 str_dev_future [] = "   Future ";
581     u8 str_dev_notsup [] = "  Not sup ";
582     u8 str_dev_unknown[] = "  Unknwon ";
583 
584     u8 *ptr;
585 
586     switch(type)
587     {
588         case WPAD_DEV_CORE:             ptr = &str_dev_core[0];     break;
589         case WPAD_DEV_FREESTYLE:        ptr = &str_dev_extn[0];     break;
590         case WPAD_DEV_CLASSIC:          ptr = &str_dev_cl[0];       break;
591         case WPAD_DEV_FUTURE:           ptr = &str_dev_future[0];   break;
592         case WPAD_DEV_NOT_SUPPORTED:    ptr = &str_dev_notsup[0];   break;
593         case WPAD_DEV_UNKNOWN:
594         default:                        ptr = &str_dev_unknown[0];  break;
595 
596     } // end switch
597 
598     return(ptr);
599 
600 } // end
601 
602 
get_status_name(s32 status)603 static u8 *get_status_name( s32 status )
604 {
605 
606     u8 str_status_ok  [] = "    OK    ";
607     u8 str_status_none[] = "   NONE   ";
608     u8 str_status_busy[] = "   BUSY   ";
609     u8 str_status_xfer[] = " Transfer ";
610     u8 str_status_inv [] = "  INVALID ";
611     u8 str_status_unk [] = "  UNKNOWN ";
612 
613     u8 *ptr;
614 
615     switch(status)
616     {
617         case WPAD_ERR_NONE:             ptr = &str_status_ok[0];    break;
618         case WPAD_ERR_NO_CONTROLLER:    ptr = &str_status_none[0];  break;
619         case WPAD_ERR_BUSY:             ptr = &str_status_busy[0];  break;
620         case WPAD_ERR_TRANSFER:         ptr = &str_status_xfer[0];  break;
621         case WPAD_ERR_INVALID:          ptr = &str_status_inv[0];   break;
622         default:                        ptr = &str_status_unk[0];   break;
623 
624     } // end switch
625 
626     return(ptr);
627 
628 } // end
629 
630 
initialize(void)631 static void initialize( void )
632 {
633     const GXColor DARKBLUE = { 0, 0, 40, 255 };
634 
635     OSInit();
636 
637     DEMOInit( &GXNtsc480IntDf );
638 
639     GXSetCopyClear( DARKBLUE, GX_MAX_Z24 );
640     GXCopyDisp( DEMOGetCurrentBuffer(), GX_TRUE );
641     DEMOInitCaption( DM_FT_XLU, SCREEN_WIDTH, SCREEN_HEIGHT );
642     GXSetZMode( GX_ENABLE, GX_ALWAYS, GX_ENABLE );                       // Set pixel processing mode
643     GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR );    // Translucent mode
644 
645     DEMOPadInit();
646 
647 } // end
648 
649 
650 /*---------------------------------------------------------------------------*
651  * Name        : renderAimings()
652  * Description :
653  * Arguments   : None.
654  * Returns     : None.
655  *---------------------------------------------------------------------------*/
renderAimings(void)656 static void renderAimings( void )
657 {
658     u32 latest;
659     u32 index;
660 
661     int i;
662     u32 fmt;
663 
664     WPADStatus   *co_ptr;
665     WPADFSStatus *fs_ptr;
666     WPADCLStatus *cl_ptr;
667 
668     fmt = WPADGetDataFormat(WPAD_CHAN0);
669 
670     switch (fmt)
671     {
672         case WPAD_FMT_CORE:
673         case WPAD_FMT_CORE_ACC:
674         case WPAD_FMT_CORE_ACC_DPD:
675 
676             co_ptr = (WPADStatus *)(&co_ringbuffer[0]);
677 
678             latest = WPADGetLatestIndexInBuf(WPAD_CHAN0);
679             index  = ((latest - 1) + SMPBUF_SIZE) % SMPBUF_SIZE;
680 
681             for (i=0; i<SMPBUF_SIZE-1; i++)
682             {
683                 if (WPAD_ERR_NONE == co_ptr[index].err)
684                 {
685                     s16 x=(s16)(SCREEN_WIDTH -(co_ptr[index].obj[0].x+co_ptr[index].obj[1].x)/2*SCREEN_WIDTH /WPAD_DPD_IMG_RESO_WX);
686                     s16 y=(s16)(SCREEN_HEIGHT-(co_ptr[index].obj[0].y+co_ptr[index].obj[1].y)/2*SCREEN_HEIGHT/WPAD_DPD_IMG_RESO_WY);
687                     DEMOPrintf(x, y, 0, ".");
688                 }
689                 index  = ((index - 1) + SMPBUF_SIZE) % SMPBUF_SIZE;
690             }
691             break;
692 
693         case WPAD_FMT_FREESTYLE:
694         case WPAD_FMT_FREESTYLE_ACC:
695         case WPAD_FMT_FREESTYLE_ACC_DPD:
696 
697             fs_ptr = (WPADFSStatus *)(&fs_ringbuffer[0]);
698 
699             latest = WPADGetLatestIndexInBuf(WPAD_CHAN0);
700             index  = ((latest - 1) + SMPBUF_SIZE) % SMPBUF_SIZE;
701 
702             for (i=0; i<SMPBUF_SIZE-1; i++)
703             {
704                 if (WPAD_ERR_NONE == fs_ptr[index].err)
705                 {
706                     s16 x=(s16)(SCREEN_WIDTH -(fs_ptr[index].obj[0].x+fs_ptr[index].obj[1].x)/2*SCREEN_WIDTH /WPAD_DPD_IMG_RESO_WX);
707                     s16 y=(s16)(SCREEN_HEIGHT-(fs_ptr[index].obj[0].y+fs_ptr[index].obj[1].y)/2*SCREEN_HEIGHT/WPAD_DPD_IMG_RESO_WY);
708                     DEMOPrintf(x, y, 0, ".");
709                 }
710                 index  = ((index - 1) + SMPBUF_SIZE) % SMPBUF_SIZE;
711             }
712             break;
713 
714         case WPAD_FMT_CLASSIC:
715         case WPAD_FMT_CLASSIC_ACC:
716         case WPAD_FMT_CLASSIC_ACC_DPD:
717 
718             cl_ptr = (WPADCLStatus*)(&cl_ringbuffer[0]);
719 
720             latest = WPADGetLatestIndexInBuf(WPAD_CHAN0);
721             index  = ((latest - 1) + SMPBUF_SIZE) % SMPBUF_SIZE;
722 
723             for(i=0; i<SMPBUF_SIZE-1; i++)
724             {
725                 if (WPAD_ERR_NONE == cl_ptr[index].err)
726                 {
727                     s16 x=(s16)(SCREEN_WIDTH -(cl_ptr[index].obj[0].x+cl_ptr[index].obj[1].x)/2*SCREEN_WIDTH /WPAD_DPD_IMG_RESO_WX);
728                     s16 y=(s16)(SCREEN_HEIGHT-(cl_ptr[index].obj[0].y+cl_ptr[index].obj[1].y)/2*SCREEN_HEIGHT/WPAD_DPD_IMG_RESO_WY);
729                     DEMOPrintf(x, y, 0, ".");
730                 }
731                 index  = ((index - 1) + SMPBUF_SIZE) % SMPBUF_SIZE;
732             }
733             break;
734 
735     } // end switch
736 
737 } // end
738