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