1 /*---------------------------------------------------------------------------*
2 Project: WPAD health demo program
3 File: wbc_simple.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: balance.c,v $
14 Revision 1.4.30.1 2009/12/08 06:23:06 miyamoto_satoshi
15 Modified cast and avoid warning.
16
17 Revision 1.4 2008/06/17 08:03:33 tojo
18 Removed unused headers.
19
20 Revision 1.3 2008/04/24 00:20:47 tojo
21 Updated WBCGetTGCWeight to latest spec.
22
23 Revision 1.2 2008/04/17 05:25:33 tojo
24 Changed API for WBCSetupCalibration.
25
26 Revision 1.1 2008/04/17 02:55:42 tojo
27 initial check-in.
28
29 *---------------------------------------------------------------------------*/
30 #include <math.h>
31
32 #include <revolution.h>
33 #include <revolution/wpad.h>
34 #include <revolution/wpadBalance.h>
35 #include <revolution/sc.h>
36 #include <revolution/wbc.h>
37
38 #define DEMO_USE_MEMLIB=1 // This turns on the DEMO library's MEM heaps.
39 #include <demo.h>
40
41
42 /*---------------------------------------------------------------------------*
43 * Local Definitions
44 *---------------------------------------------------------------------------*/
45 static u8 workarea[WPAD_BLCINT_WORK_LEN] ATTRIBUTE_ALIGN(32);
46 static WPADBLStatus status;
47 static double zero[WPAD_PRESS_UNITS];
48
49 /*---------------------------------------------------------------------------*
50 * Function prototypes
51 *---------------------------------------------------------------------------*/
52 // MEM2 memory allocation routines. The application must provide these to
53 // WPAD, so it can setup the data transfer buffer. This buffer must reside
54 // in MEM2.
55 static void *myAlloc ( u32 size );
56 static u8 myFree ( void *ptr );
57
58
59 // callbacks for CONNECT and EXTENSION events
60 static void connectCallback ( s32 chan, s32 reason );
61 static void extensionCallback ( s32 chan, s32 result );
62
63 /*===========================================================================*
64 * F U N C T I O N D E F I N I T I O N S
65 *===========================================================================*/
WaitMilliTime(s32 msec)66 static void WaitMilliTime(s32 msec)
67 {
68 OSTime t=OSGetTime();
69 while(OSTicksToMilliseconds(OSGetTime()-t) < msec)
70 ;
71 }
72
73
ZeroSetStart2(s32 chan,s32 result)74 static void ZeroSetStart2( s32 chan, s32 result )
75 {
76 #pragma unused(chan, result)
77
78 // Wait about 200[ms] so that Board's press value rarely becomes unstable
79 // after updating Balance Wii Board's temperature.
80 WaitMilliTime(200);
81
82 // Set Zero point.
83 zero[0] = (f64)status.press[0]; //Normally, set the average for 2 seconds.
84 zero[1] = (f64)status.press[1]; //Normally, set the average for 2 seconds.
85 zero[2] = (f64)status.press[2]; //Normally, set the average for 2 seconds.
86 zero[3] = (f64)status.press[3]; //Normally, set the average for 2 seconds.
87 WBCSetZEROPoint( zero,(u32)(sizeof(zero) / sizeof(zero[0])));
88 }
89
90
ZeroSetStart(s32 chan,s32 result)91 static void ZeroSetStart( s32 chan, s32 result )
92 {
93 #pragma unused(chan, result)
94
95 // Check Board's temperature.
96 WPADRead(WPAD_CHAN3, &status);
97
98
99 if((status.temp == 127) || (status.temp == -128))
100 {
101 // Update Board's temperature again if you can not get correct Board's temperature.
102 WPADControlBLC(WPAD_CHAN3, WPAD_BLCMD_UPDATE_TEMP, ZeroSetStart2);
103 }
104 else
105 {
106 // Wait about 200[ms] so that Board's press value rarely becomes unstable
107 // after updating Balance Wii Board's temperature.
108 WaitMilliTime(200);
109
110 // Set Zero point.
111 zero[0] = (f64)status.press[0]; //Normally, set the average for 2 seconds.
112 zero[1] = (f64)status.press[1]; //Normally, set the average for 2 seconds.
113 zero[2] = (f64)status.press[2]; //Normally, set the average for 2 seconds.
114 zero[3] = (f64)status.press[3]; //Normally, set the average for 2 seconds.
115 WBCSetZEROPoint( zero,(u32)(sizeof(zero) / sizeof(zero[0])));
116 }
117 }
118
119
120 /*---------------------------------------------------------------------------*
121 * Name : main()
122 * Description :
123 * Arguments : None.
124 * Returns : None.
125 *---------------------------------------------------------------------------*/
main(void)126 int main( void )
127 {
128 double weight[WPAD_PRESS_UNITS];
129 u32 type;
130
131 DEMOInit( NULL );
132 DEMOPadInit();
133
134 // If Japan, need to call WPADRegisterBLCWorkarea to set a work buffer.
135 // If not Japan, WPADRegisterBLCWorkarea does nothing.
136 WPADRegisterBLCWorkarea( workarea );
137
138 WPADRegisterAllocator(myAlloc, myFree);
139 WPADInit();
140 WPADSetConnectCallback(WPAD_CHAN3, connectCallback);
141
142 while (WPAD_STATE_SETUP != WPADGetStatus())
143 {
144 ;
145 }
146
147 // You can release the work buffer so initialize of WPAD library has finished.
148 // This sample program does nothing it uses static buffer.
149
150
151 if (DEMOInitROMFont() == 0)
152 {
153 OSHalt("FONT ERROR\n");
154 // NOT REACHED HERE
155 }
156
157 while(1)
158 {
159 GXRenderModeObj *rmp = DEMOGetRenderModeObj();
160 s16 x,y;
161 double w1,w2,w3,w4;
162 double left,right,front,back;
163
164 w1 = weight[0]; // front right
165 w2 = weight[1]; // back right
166 w3 = weight[2]; // front left
167 w4 = weight[3]; // back left
168
169 if(fabs(w1) < 1) w1 = 1;
170 if(fabs(w2) < 1) w2 = 1;
171 if(fabs(w3) < 1) w3 = 1;
172 if(fabs(w4) < 1) w4 = 1;
173
174 left = (double)(w3 + w4);
175 right = (double)(w1 + w2);
176 front = (double)(w1 + w3);
177 back = (double)(w4 + w2);
178
179 // Calculate a balance point.
180 x = (s16)((right / (left + right)) * rmp->fbWidth);
181 y = (s16)((back / (front + back)) * rmp->viHeight);
182
183 DEMOBeforeRender();
184 DEMOInitCaption(DM_FT_XLU, (s16) rmp->fbWidth, (s16) rmp->efbHeight);
185 DEMOSetROMFontSize(16, -1);
186 DEMORFPrintf(x, y, 0, "X"); //Draw the center of gravity.
187 DEMODoneRender();
188
189
190 DEMOPadRead();
191
192 if (DEMOPadGetButtonDown(0) & PAD_BUTTON_A)
193 {
194 // Update Board's temperature the eve of zero point correction.
195 WPADControlBLC(WPAD_CHAN3, WPAD_BLCMD_UPDATE_TEMP, ZeroSetStart);
196 }
197
198 if (WPADProbe(WPAD_CHAN3, &type) == WPAD_ERR_NO_CONTROLLER)
199 {
200 if (WPADIsRegisteredBLC())
201 {
202 OSReport("Balance Wii board is not connected.\n");
203 }
204 else
205 {
206 OSReport("Balance Wii board is not registered. Please regist Balance Wii board with SYNC button.\n");
207 }
208 }
209 else
210 {
211 if (type == WPAD_DEV_BALANCE_CHECKER)
212 {
213 WPADRead(WPAD_CHAN3, &status);
214
215 if(WBCGetCalibrationStatus() == TRUE)
216 {
217 double total;
218 double tgc_weight;
219
220 WBCRead(&status, weight, (u32)(sizeof(weight) / sizeof(weight[0])));
221 total = (double)(weight[0]+weight[1]+weight[2]+weight[3]);
222
223 // Show the total weight. Normally, "total" value is the average for 2 seconds.
224 if (WBCGetTGCWeight(total, &tgc_weight, &status) == WBC_ERR_NONE)
225 {
226 OSReport("%3.1f[kg]\n", tgc_weight);
227 }
228 }
229 else
230 {
231 OSReport("Calibration data read error. Please reconnect Balance Wii board.\n");
232 }
233 }
234 else
235 {
236 OSReport("No Balance Wii board is attached.\n");
237 }
238 }
239 }
240 } // end main()
241
242
243 /*---------------------------------------------------------------------------*
244 * Name : connectCallback()
245 *
246 * Description : This callback is invoked when a controller is connected or
247 * disconnected.
248 *
249 * Arguments : The channel (chan) for which the event has occurred.
250 * The channel status (reason):
251 * WPAD_ERR_NONE means a controller has been connected.
252 * WPAD_ERR_NO_CONTROLLER means a controller disconnected.
253 *
254 * Returns : None.
255 *---------------------------------------------------------------------------*/
connectCallback(s32 chan,s32 reason)256 static void connectCallback(s32 chan, s32 reason)
257 {
258 u32 type;
259
260 if (reason == WPAD_ERR_NONE)
261 {
262 // Disconnect 4P if 4P is not Balance Wii board.
263 // Because 4P is reserved for Balance Wii board.
264 WPADProbe(chan, &type);
265 if (chan == WPAD_CHAN0 && type != WPAD_DEV_BALANCE_CHECKER)
266 {
267 OSReport("Channel%d is reserved for Balance Wii board.\n", chan);
268 WPADDisconnect(chan);
269 }
270 else
271 {
272 // Read the calibration value for calculating a weight.
273 if(!WBCSetupCalibration())
274 {
275 OSHalt("Balance Wii board FATAL ERROR!!\n");
276 }
277 OSReport("Channel%d is connected.\n", chan);
278 WPADSetExtensionCallback(chan, extensionCallback);
279 }
280 }
281 else
282 {
283 OSReport("Channel%d is disconnected.\n", chan);
284 }
285 } // end connectCallback()
286
287 /*---------------------------------------------------------------------------*
288 * Name : extensionCallback()
289 *
290 * Description : This callback is invoked when an Extension has been attached.
291 *
292 * Arguments : The channel (chan) for which the extension event occurred.
293 * The device type (result):
294 *
295 * WPAD_DEV_UNKNOWN means that something has been attached, but
296 * it's being initialized, and we won't know what it is until
297 * initialization is complete.
298 *
299 * WPAD_DEV_CORE means that an extension has been removed and
300 * we're back to just the core device.
301 *
302 * WPAD_DEV_FREESTYLE means that the "NUNCHAK" extension has
303 * been attached and initialized.
304 *
305 * WPAD_DEV_CLASSIC means that the "CLASSIC" extension has been
306 * attached and initialized.
307 *
308 * Returns : None.
309 *---------------------------------------------------------------------------*/
extensionCallback(s32 chan,s32 result)310 static void extensionCallback(s32 chan, s32 result)
311 {
312 switch(result)
313 {
314 case WPAD_DEV_UNKNOWN:
315 OSReport("Initializing extension on channel%d...\n", chan);
316 break;
317
318 case WPAD_DEV_CORE:
319 WPADControlDpd(chan, WPAD_DPD_EXP, NULL);
320 WPADSetDataFormat(chan, WPAD_FMT_CORE_ACC_DPD);
321
322 OSReport("Extension removed on channel%d.\n", chan);
323 break;
324
325 case WPAD_DEV_NOT_SUPPORTED:
326 case WPAD_DEV_FUTURE:
327 WPADControlDpd(chan, WPAD_DPD_EXP, NULL);
328 WPADSetDataFormat(chan, WPAD_FMT_CORE_ACC_DPD);
329
330 OSReport("Extension is not useful on channel%d.\n", chan);
331 break;
332
333 case WPAD_DEV_FREESTYLE:
334 WPADControlDpd(chan, WPAD_DPD_STD, NULL);
335 WPADSetDataFormat(chan, WPAD_FMT_FREESTYLE_ACC_DPD);
336
337 OSReport("Freestyle initialized on channel%d.\n", chan);
338 break;
339
340 case WPAD_DEV_CLASSIC:
341 WPADControlDpd(chan, WPAD_DPD_STD, NULL);
342 WPADSetDataFormat(chan, WPAD_FMT_CLASSIC_ACC_DPD);
343
344 OSReport("Classicstyle initialized on channel%d.\n", chan);
345 break;
346
347 case WPAD_DEV_BALANCE_CHECKER:
348 WPADControlDpd(chan, WPAD_DPD_OFF, NULL);
349 WPADSetDataFormat(chan, WPAD_FMT_BALANCE_CHECKER);
350 WPADControlBLC(chan, WPAD_BLCMD_ON, NULL);
351
352 OSReport("Balance Wii board initialized on channel%d.\n", chan);
353 break;
354
355 default:
356 // Here is WPAD_DEV_NOT_FOUND.
357 // If the controller is disconnected while the extension is initializing
358 // it reaches here. There is nothing to do.
359 break;
360
361 } // end
362 } // end extensionCallback()
363
364 /*---------------------------------------------------------------------------*
365 * Name : myAlloc()
366 * Description : Callback needed by WPAD to allocate mem from MEM2 heap
367 * Arguments : size of block, in bytes.
368 * Returns : pointer to allocated block.
369 *---------------------------------------------------------------------------*/
myAlloc(u32 size)370 static void *myAlloc(u32 size)
371 {
372 void *ptr;
373
374 ptr = MEMAllocFromAllocator(&DemoAllocator2, size);
375 ASSERTMSG(ptr, "Memory allocation failed\n");
376
377 return(ptr);
378
379 } // myAlloc()
380
381 /*---------------------------------------------------------------------------*
382 * Name : myFree()
383 * Description : Callback needed by WPAD to free mem from MEM2 heap
384 * Arguments : None.
385 * Returns : Always 1.
386 *---------------------------------------------------------------------------*/
myFree(void * ptr)387 static u8 myFree(void *ptr)
388 {
389
390 MEMFreeToAllocator(&DemoAllocator2, ptr);
391
392 // we should ensure that memory is free'd properly, but oh well
393 return(1);
394
395 } // myFree()
396