1 /*---------------------------------------------------------------------------*
2   Project:    WPAD Health Demo Program
3   File:       handling.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: handling.c,v $
14   Revision 1.2.4.4  2008/02/01 08:22:32  tojo
15   Changed to call WPADRegisterBLCWorkarea when the application runs on the JPN console.
16 
17   Revision 1.2.4.3  2007/11/14 10:24:28  tojo
18   (none)
19 
20   Revision 1.2.4.2  2007/11/14 10:19:34  tojo
21   (none)
22 
23   Revision 1.2.4.1  2007/09/11 07:49:25  tojo
24   (none)
25 
26   Revision 1.2  2007/05/31 09:29:25  tojo
27   (none)
28 
29   Revision 1.1  2007/03/12 05:24:08  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 #include <revolution/wpadBalance.h>
45 #include <revolution/sc.h>
46 
47 #define DEMO_USE_MEMLIB=1 // This turns on the DEMO library's MEM heaps.
48 #include <demo.h>
49 
50 /*---------------------------------------------------------------------------*
51  * Local Definitions
52  *---------------------------------------------------------------------------*/
53 
54 #define SCREEN_WIDTH  320
55 #define SCREEN_HEIGHT 240
56 #define FONT_HEIGHT     8
57 
58 GXColor smoke_clr    = {  61, 61, 61, 255 } ;
59 GXColor red_clr      = { 237, 28, 36, 255 } ;
60 GXColor blue_clr     = {   0, 84,166, 255 } ;
61 GXColor yellow_clr   = { 255,242,  0, 255 } ;
62 GXColor peagreen_clr = { 141,198, 63, 255 } ;
63 
64 WPADBLStatus status;
65 
66 u8  rxCalib[16];
67 u8  rxBuf[128] ATTRIBUTE_ALIGN(32);
68 u8  txBuf[128] ATTRIBUTE_ALIGN(32);
69 
70 u8  workarea[WPAD_BLCINT_WORK_LEN] ATTRIBUTE_ALIGN(32);
71 
72 /*---------------------------------------------------------------------------*
73  * Function prototypes
74  *---------------------------------------------------------------------------*/
75 
76 
77 // MEM2 memory allocation routines. The application must provide these to
78 // WPAD, so it can setup the data transfer buffer. This buffer must reside
79 // in MEM2.
80 static void *myAlloc                 ( u32 size );
81 static u8    myFree                  ( void *ptr );
82 
83 
84 // Callbacks for CONNECT and EXTENSION events.
85 void         connectCallback         ( s32 chan, s32 reason );
86 void         extensionCallback       ( s32 chan, s32 result );
87 
88 // Internal functions
89 static void  initialize              ( void );
90 static void  renderStatus            ( void );
91 static void  init_draw_graphic       ( u16 fb_width, u16 fb_height );
92 static void  draw_line               ( f32 x1, f32 y1, f32 x2, f32 y2, GXColor clr, f32 width );
93 static void  draw_box                ( f32 x1, f32 y1, f32 x2, f32 y2, GXColor clr, f32 width );
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        : main()
100  * Description :
101  * Arguments   : None.
102  * Returns     : None.
103  *---------------------------------------------------------------------------*/
getCalibration(s32 chan,s32 result)104 static void getCalibration( s32 chan, s32 result )
105 {
106     OSReport("Get Calibration\n");
107     OSReport("chan = %d, result = %d\n\n", chan, result);
108     OSReport("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n\n",
109         rxCalib[0], rxCalib[1], rxCalib[2],  rxCalib[3],  rxCalib[4],  rxCalib[5],  rxCalib[6],  rxCalib[7],
110         rxCalib[8], rxCalib[9], rxCalib[10], rxCalib[11], rxCalib[12], rxCalib[13], rxCalib[14], rxCalib[15]);
111 }
112 
ctrlWbc(s32 chan,s32 result)113 static void ctrlWbc( s32 chan, s32 result )
114 {
115     OSReport("chan%d [%d]\n", chan, result);
116 }
117 
main(void)118 int main( void )
119 {
120     initialize();
121 
122     // Set the working buffer because it is required (for the Japanese version only) when the Wii Balance Board is initialized.
123     //
124     // It is possible to deallocate the working buffer because it will no longer be used after library initialization has completed.
125     //
126     //
127     // For regions outside of Japan, no problems will occur if this function is not called.
128     //
129     // Additionally, no problems will occur if it is called.
130     WPADRegisterBLCWorkarea( workarea );
131 
132     WPADRegisterAllocator(myAlloc, myFree);
133 
134     WPADInit();
135 
136     WPADSetConnectCallback(WPAD_CHAN3, connectCallback);
137 
138     while (WPAD_STATE_SETUP != WPADGetStatus())
139     {
140         ;
141     }
142 
143     // The working buffer can be released because library initialization has completed.
144     //
145     // Since a fixed buffer is given in this sample demo, nothing is done.
146     //
147 
148     while(1)
149     {
150         DEMOPadRead();
151 
152         if (DEMOPadGetButtonDown(0) & PAD_BUTTON_A)
153         {
154             // Turns on power to the Wii Balance Board.
155             WPADControlBLC(WPAD_CHAN3, WPAD_BLCMD_ON, ctrlWbc);
156         }
157         if (DEMOPadGetButtonDown(0) & PAD_BUTTON_B)
158         {
159             // Turns off power to the Wii Balance Board.
160             WPADControlBLC(WPAD_CHAN3, WPAD_BLCMD_OFF, ctrlWbc);
161         }
162         if (DEMOPadGetButtonDown(0) & PAD_TRIGGER_Z)
163         {
164             // Updates the temperature value for the Wii Balance Board
165             WPADControlBLC(WPAD_CHAN3, WPAD_BLCMD_UPDATE_TEMP, ctrlWbc);
166         }
167         if (DEMOPadGetButtonDown(0) & PAD_BUTTON_X)
168         {
169             // Gets calibration values for the Wii Balance Board
170             // The calibration values are divided into 5 blocks. The first block of values is obtained here.
171             //
172             WPADGetBLCalibration(WPAD_CHAN3, rxCalib, WPAD_BLCLB_BLK1_ADDR, WPAD_BLCLB_BLK1_LEN, getCalibration);
173         }
174         if (DEMOPadGetButtonDown(0) & PAD_BUTTON_Y)
175         {
176             // Gets calibration values for the Wii Balance Board
177             // The calibration values are divided into 5 blocks. The first block of values is obtained here.
178             //
179             WPADGetBLCalibration(WPAD_CHAN3, rxCalib, WPAD_BLCLB_BLK2_ADDR, WPAD_BLCLB_BLK2_LEN, getCalibration);
180         }
181 
182         // For character display.
183         DEMOInitCaption( DM_FT_XLU, SCREEN_WIDTH, SCREEN_HEIGHT );
184         GXSetZMode( GX_ENABLE, GX_ALWAYS, GX_ENABLE );
185         GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR );
186 
187         DEMOBeforeRender();
188         renderStatus();
189         DEMODoneRender();
190     }
191 
192 } // End main()
193 
194 /*---------------------------------------------------------------------------*
195  * Name        : connectCallback()
196  *
197  * Description : This callback is invoked when a controller is connected or
198  *               disconnected.
199  *
200  * Arguments   : The channel (chan) for which the event has occurred.
201  *               The channel status (reason):
202  *                 WPAD_ERR_NONE means a controller has been connected.
203  *                 WPAD_ERR_NO_CONTROLLER means a controller disconnected.
204  *
205  * Returns     : None.
206  *---------------------------------------------------------------------------*/
connectCallback(s32 chan,s32 reason)207 void connectCallback(s32 chan, s32 reason)
208 {
209     u32 type;
210 
211     if (reason == WPAD_ERR_NONE)
212     {
213         // 4P is reserved for the Wii Balance Board, so anything else is disconnected.
214         WPADProbe(chan, &type);
215         if (chan == WPAD_CHAN3 && type != WPAD_DEV_BALANCE_CHECKER)
216         {
217             OSReport("Channel%d is reserved for the balance checker.\n", chan);
218             WPADDisconnect(chan);
219         }
220         else
221         {
222             OSReport("Channel%d is connected.\n", chan);
223             WPADSetExtensionCallback(chan, extensionCallback);
224         }
225     }
226     else
227     {
228         OSReport("Channel%d is disconnected.\n", chan);
229     }
230 } // End connectCallback()
231 
232 /*---------------------------------------------------------------------------*
233  * Name        : extensionCallback()
234  *
235  * Description : This callback is invoked when an Extension has been attached.
236  *
237  * Arguments   : The channel (chan) for which the extension event occurred.
238  *               The device type (result):
239  *
240  *                 WPAD_DEV_UNKNOWN means that something has been attached, but
241  *                 it's being initialized, and we won't know what it is until
242  *                 initialization is complete.
243  *
244  *                 WPAD_DEV_CORE means that an extension has been removed and
245  *                 we're back to just the core device.
246  *
247  *                 WPAD_DEV_FREESTYLE means that the "NUNCHUK" extension has
248  *                 been attached and initialized.
249  *
250  *                 WPAD_DEV_CLASSIC means that the "CLASSIC" extension has been
251  *                 attached and initialized.
252  *
253  * Returns     : None.
254  *---------------------------------------------------------------------------*/
extensionCallback(s32 chan,s32 result)255 void extensionCallback(s32 chan, s32 result)
256 {
257     switch(result)
258     {
259         case WPAD_DEV_UNKNOWN:
260             OSReport("Initializing extension on channel%d...\n", chan);
261             break;
262 
263         case WPAD_DEV_CORE:
264             WPADControlDpd(chan, WPAD_DPD_EXP, NULL);
265             WPADSetDataFormat(chan, WPAD_FMT_CORE_ACC_DPD);
266 
267             OSReport("Extension removed on channel%d.\n", chan);
268             break;
269 
270         case WPAD_DEV_NOT_SUPPORTED:
271         case WPAD_DEV_FUTURE:
272             WPADControlDpd(chan, WPAD_DPD_EXP, NULL);
273             WPADSetDataFormat(chan, WPAD_FMT_CORE_ACC_DPD);
274 
275             OSReport("Extension is not useful on channel%d.\n", chan);
276             break;
277 
278         case WPAD_DEV_FREESTYLE:
279             WPADControlDpd(chan, WPAD_DPD_STD, NULL);
280             WPADSetDataFormat(chan, WPAD_FMT_FREESTYLE_ACC_DPD);
281 
282             OSReport("Freestyle initialized on channel%d.\n", chan);
283             break;
284 
285         case WPAD_DEV_CLASSIC:
286             WPADControlDpd(chan, WPAD_DPD_STD, NULL);
287             WPADSetDataFormat(chan, WPAD_FMT_CLASSIC_ACC_DPD);
288 
289             OSReport("Classicstyle initialized on channel%d.\n", chan);
290             break;
291 
292         case WPAD_DEV_BALANCE_CHECKER:
293             WPADControlDpd(chan, WPAD_DPD_OFF, NULL);
294             WPADSetDataFormat(chan, WPAD_FMT_BALANCE_CHECKER);
295             WPADControlBLC(chan, WPAD_BLCMD_ON, NULL);
296 
297             OSReport("Balance checker initialized on channel%d.\n", chan);
298             break;
299 
300         default:
301             // Here is WPAD_DEV_NOT_FOUND.
302             // If the controller is disconnected while the extension is initializing
303             // it reaches here. There is nothing to do.
304             break;
305 
306     } // End
307 
308 } // End extensionCallback()
309 
310 /*---------------------------------------------------------------------------*
311  * Name        : myAlloc()
312  * Description : Callback needed by WPAD to allocate mem from MEM2 heap.
313  * Arguments   : size of block, in bytes.
314  * Returns     : pointer to allocated block.
315  *---------------------------------------------------------------------------*/
myAlloc(u32 size)316 static void *myAlloc(u32 size)
317 {
318     void *ptr;
319 
320     ptr = MEMAllocFromAllocator(&DemoAllocator2, size);
321     ASSERTMSG(ptr, "Memory allocation failed\n");
322 
323     return(ptr);
324 
325 } // myAlloc()
326 
327 /*---------------------------------------------------------------------------*
328  * Name        : myFree()
329  * Description : Callback needed by WPAD to free mem from MEM2 heap.
330  * Arguments   : None.
331  * Returns     : Always 1.
332  *---------------------------------------------------------------------------*/
myFree(void * ptr)333 static u8 myFree(void *ptr)
334 {
335 
336     MEMFreeToAllocator(&DemoAllocator2, ptr);
337 
338     // we should ensure that memory is free'd properly, but oh well
339     return(1);
340 
341 } // myFree()
342 
renderStatus(void)343 static void renderStatus(void)
344 {
345     u32 type;
346 
347     if (WPADProbe(WPAD_CHAN3, &type) == WPAD_ERR_NO_CONTROLLER)
348     {
349         if (WPADIsRegisteredBLC())
350         {
351             DEMOPrintf( 50, 100, 0, "WBC is not connected.");
352         }
353         else
354         {
355             DEMOPrintf( 20, 100, 0, "WBC is not registered.");
356             DEMOPrintf( 20, 110, 0, "Please regist WBC with SYNC button.");
357         }
358     }
359     else
360     {
361         if (type == WPAD_DEV_BALANCE_CHECKER)
362         {
363             WPADRead(WPAD_CHAN3, &status);
364 
365             DEMOPrintf(100,  40, 0, "%04x", status.press[0]);
366             DEMOPrintf(100, 110, 0, "%04x", status.press[1]);
367             DEMOPrintf( 25,  40, 0, "%04x", status.press[2]);
368             DEMOPrintf( 25, 110, 0, "%04x", status.press[3]);
369 
370             DEMOPrintf(200,  20, 0, "Temp %d", status.temp);
371             DEMOPrintf(200,  30, 0, "Batt %d", status.battery);
372 
373             DEMOPrintf( 10, 160, 0, "A: Turn On  BLC");
374             DEMOPrintf( 10, 170, 0, "B: Turn Off BLC");
375             DEMOPrintf( 10, 180, 0, "X: Get the 1st block of calibration");
376             DEMOPrintf( 10, 190, 0, "Y: Get the 2nd block of calibration");
377             DEMOPrintf( 10, 200, 0, "Z: Update the current temperature");
378 
379             init_draw_graphic(SCREEN_WIDTH, SCREEN_HEIGHT);
380             draw_box(-130, -100, -80, -50, peagreen_clr, 2);
381             init_draw_graphic(SCREEN_WIDTH, SCREEN_HEIGHT);
382             draw_box(-130,  -30, -80,  20, yellow_clr, 2);
383             init_draw_graphic(SCREEN_WIDTH, SCREEN_HEIGHT);
384             draw_box(-60,  -100, -10, -50, blue_clr, 2);
385             init_draw_graphic(SCREEN_WIDTH, SCREEN_HEIGHT);
386             draw_box(-60,   -30, -10,  20, red_clr, 2);
387 
388         }
389         else
390         {
391             DEMOPrintf(50, 100, 0, "No balance checker is attached.");
392         }
393     }
394 
395 } // End renderStatus()
396 
initialize(void)397 static void initialize( void )
398 {
399     OSInit();
400 
401     DEMOInit( &GXNtsc480IntDf );
402 
403     GXSetCopyClear( smoke_clr, GX_MAX_Z24 );
404     GXCopyDisp( DEMOGetCurrentBuffer(), GX_TRUE );
405 
406     DEMOPadInit();
407 
408 } // End
409 
init_draw_graphic(u16 fb_width,u16 fb_height)410 static void init_draw_graphic( u16 fb_width, u16 fb_height )
411 {
412     Mtx44   proj_mtx ;
413     Mtx     view_mtx ;
414     f32     canvas_wd, canvas_ht ;
415 
416     //----- Virtual canvas size
417     canvas_wd = fb_width * 0.91346f ;
418     canvas_ht = fb_height ;
419 
420     //----- MTX
421     MTXOrtho( proj_mtx, canvas_ht * -0.5f,canvas_ht * 0.5f, canvas_wd * -0.5f,canvas_wd * 0.5f, -10.0f,10.0f ) ;
422     GXSetProjection( proj_mtx, GX_ORTHOGRAPHIC ) ;
423 
424     MTXIdentity( view_mtx ) ;
425     GXLoadPosMtxImm( view_mtx, GX_PNMTX0 ) ;
426     GXSetCurrentMtx( GX_PNMTX0 ) ;
427 
428     //----- VERTEX
429     GXClearVtxDesc() ;
430     GXSetVtxDesc( GX_VA_POS, GX_DIRECT ) ;
431     GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_F32, 0 ) ;
432 
433     //----- CHANNEL
434     GXSetNumChans( 1 ) ;
435     GXSetChanCtrl( GX_COLOR0A0, GX_DISABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE ) ;
436     GXSetChanCtrl( GX_COLOR1A1, GX_DISABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE ) ;
437 
438     //----- TEXTURE
439     GXSetNumTexGens( 0 ) ;
440 
441     //----- TEV
442     GXSetNumTevStages( 1 ) ;
443     GXSetTevOrder( GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL ) ;
444     GXSetTevColorIn( GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_C0 ) ;
445     GXSetTevColorOp( GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV ) ;
446     GXSetTevAlphaIn( GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0 ) ;
447     GXSetTevAlphaOp( GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV ) ;
448     GXSetAlphaCompare( GX_ALWAYS,0, GX_AOP_OR, GX_ALWAYS,0 ) ;
449 
450     //----- SCREEN
451     GXSetBlendMode( GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP ) ;
452     GXSetAlphaUpdate( GX_DISABLE ) ;
453 
454     GXSetZMode( GX_DISABLE, GX_ALWAYS, GX_DISABLE ) ;
455     GXSetCullMode( GX_CULL_BACK ) ;
456 }
457 
458 /*******************************************************************************
459 	Render a line segment
460 *******************************************************************************/
draw_line(f32 x1,f32 y1,f32 x2,f32 y2,GXColor clr,f32 width)461 static void draw_line( f32 x1, f32 y1, f32 x2, f32 y2, GXColor clr, f32 width )
462 {
463     GXSetTevColor( GX_TEVREG0, clr ) ;
464     GXSetLineWidth( (u8)(s32)(width * 6.0f + 0.5f), GX_TO_ZERO ) ;
465 
466     GXBegin( GX_LINES, GX_VTXFMT0, 2 ) ;
467       GXPosition2f32( x1, y1 ) ;
468       GXPosition2f32( x2, y2 ) ;
469     GXEnd() ;
470 }
471 
draw_box(f32 x1,f32 y1,f32 x2,f32 y2,GXColor clr,f32 width)472 static void draw_box( f32 x1, f32 y1, f32 x2, f32 y2, GXColor clr, f32 width )
473 {
474     draw_line(x1, y1, x2, y1, clr, width);
475     draw_line(x2, y1, x2, y2, clr, width);
476     draw_line(x2, y2, x1, y2, clr, width);
477     draw_line(x1, y2, x1, y1, clr, width);
478 }
479