1 /*---------------------------------------------------------------------------*
2 Project: KPAD weight demo program
3 File: weight.c
4
5 Copyright (C) 2008 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 *---------------------------------------------------------------------------*/
14 #include <revolution.h>
15 #include <revolution/kpad.h>
16 #include <revolution/sc.h>
17
18 #define DEMO_USE_MEMLIB=1 // This turns on the DEMO library's MEM heaps.
19 #include <demo.h>
20
21 /*---------------------------------------------------------------------------*
22 * Local Definitions
23 *---------------------------------------------------------------------------*/
24
25 #define SCREEN_WIDTH 320
26 #define SCREEN_HEIGHT 240
27 #define FONT_HEIGHT 8
28 #define BUFF_SIZE 16
29
30 GXColor smoke_clr = { 61, 61, 61, 255 } ;
31 GXColor red_clr = { 237, 28, 36, 255 } ;
32 GXColor blue_clr = { 0, 84,166, 255 } ;
33 GXColor yellow_clr = { 255,242, 0, 255 } ;
34 GXColor peagreen_clr = { 141,198, 63, 255 } ;
35
36 static KPADStatus kpads [ BUFF_SIZE + KPAD_RING_BUFS ] ;
37 static KPADUnifiedWpadStatus kpad_buf[ BUFF_SIZE * WPAD_MAX_CONTROLLERS ] ;
38 static s32 kpad_reads ;
39 static s32 kpad_err ;
40
41 static u8 myWorkarea[ WPAD_BLCINT_WORK_LEN ] ATTRIBUTE_ALIGN( 32 ) ;
42
43 /*---------------------------------------------------------------------------*
44 * Function prototypes
45 *---------------------------------------------------------------------------*/
46
47 // MEM2 memory allocation routines. The application must provide these to
48 // WPAD, so it can setup the data transfer buffer. This buffer must reside
49 // in MEM2.
50 static void *myAlloc ( u32 size ) ;
51 static u8 myFree ( void *ptr ) ;
52
53 // Callbacks for CONNECT and EXTENSION events.
54 void connectCallback ( s32 chan, s32 reason ) ;
55
56 // Internal functions
57 static void initialize ( void ) ;
58 static void renderStatus ( void ) ;
59 static void init_draw_graphic ( u16 fb_width, u16 fb_height ) ;
60 static void draw_line ( f32 x1, f32 y1, f32 x2, f32 y2, GXColor clr, f32 width ) ;
61 static void draw_box ( f32 x1, f32 y1, f32 x2, f32 y2, GXColor clr, f32 width ) ;
62
63 /*===========================================================================*
64 * F U N C T I O N D E F I N I T I O N S
65 *===========================================================================*/
66 /*---------------------------------------------------------------------------*
67 * Name : main()
68 * Description :
69 * Arguments : None.
70 * Returns : None.
71 *---------------------------------------------------------------------------*/
main(void)72 int main( void )
73 {
74
75 initialize() ;
76
77 while( 1 )
78 {
79 kpad_reads = KPADReadEx( WPAD_CHAN3, kpads, KPAD_RING_BUFS + BUFF_SIZE/4, &kpad_err ) ;
80
81 if ( kpad_reads > 0 && kpads[0].trig & KPAD_BUTTON_A )
82 {
83 KPADResetWbcZeroPoint() ;
84 }
85
86 // Caption
87 DEMOInitCaption( DM_FT_XLU, SCREEN_WIDTH, SCREEN_HEIGHT ) ;
88 GXSetZMode( GX_ENABLE, GX_ALWAYS, GX_ENABLE ) ;
89 GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR ) ;
90
91 DEMOBeforeRender() ;
92 renderStatus() ;
93 DEMODoneRender() ;
94 }
95
96 } // End main()
97
98 /*---------------------------------------------------------------------------*
99 * Name : connectCallback()
100 *
101 * Description : This callback is invoked when a controller is connected or
102 * disconnected.
103 *
104 * Arguments : The channel (chan) for which the event has occurred.
105 * The channel status (reason):
106 * WPAD_ERR_NONE means a controller has been connected.
107 * WPAD_ERR_NO_CONTROLLER means a controller disconnected.
108 *
109 * Returns : None.
110 *---------------------------------------------------------------------------*/
connectCallback(s32 chan,s32 reason)111 void connectCallback( s32 chan, s32 reason )
112 {
113 u32 type ;
114
115 if ( reason == WPAD_ERR_NONE )
116 {
117 // Disconnect 4P if 4P is not Wii Balance Board.
118 // Because 4P is reserved for Wii Balance Board.
119 WPADProbe( chan, &type ) ;
120 if ( chan == WPAD_CHAN3 && type != WPAD_DEV_BALANCE_CHECKER )
121 {
122 OSReport( "Channel%d is reserved for the balance checker.\n", chan ) ;
123 WPADDisconnect( chan ) ;
124 }
125 }
126 else
127 {
128 OSReport( "Channel%d is disconnected.\n", chan ) ;
129 }
130 } // End connectCallback()
131
132 /*---------------------------------------------------------------------------*
133 * Name : myAlloc()
134 * Description : Callback needed by WPAD to allocate mem from MEM2 heap.
135 * Arguments : size of block, in bytes.
136 * Returns : pointer to allocated block.
137 *---------------------------------------------------------------------------*/
myAlloc(u32 size)138 static void *myAlloc( u32 size )
139 {
140 void *ptr;
141
142 ptr = MEMAllocFromAllocator( &DemoAllocator2, size ) ;
143 ASSERTMSG( ptr, "Memory allocation failed\n" ) ;
144
145 return( ptr ) ;
146
147 } // myAlloc()
148
149 /*---------------------------------------------------------------------------*
150 * Name : myFree()
151 * Description : Callback needed by WPAD to free mem from MEM2 heap.
152 * Arguments : None.
153 * Returns : Always 1.
154 *---------------------------------------------------------------------------*/
myFree(void * ptr)155 static u8 myFree( void *ptr )
156 {
157
158 MEMFreeToAllocator( &DemoAllocator2, ptr ) ;
159
160 // we should ensure that memory is free'd properly, but oh well
161 return( 1 ) ;
162
163 } // myFree()
164
165
renderStatus(void)166 static void renderStatus( void )
167 {
168 if ( kpad_err == KPAD_READ_ERR_NO_CONTROLLER )
169 {
170 if ( WPADIsRegisteredBLC() )
171 {
172 DEMOPrintf( 50, 100, 0, "WBC is not connected." ) ;
173 }
174 else
175 {
176 DEMOPrintf( 20, 100, 0, "WBC is not registered." ) ;
177 DEMOPrintf( 20, 110, 0, "Please regist WBC with SYNC button." ) ;
178 }
179 }
180 else
181 {
182 if ( kpads[0].dev_type == WPAD_DEV_BALANCE_CHECKER )
183 {
184 if( kpads[0].ex_status.bl.weight_err < 0 )
185 {
186 DEMOPrintf( 95, 55, 0, "wait..." ) ;
187 DEMOPrintf( 95, 125, 0, "wait..." ) ;
188 DEMOPrintf( 10, 55, 0, "wait..." ) ;
189 DEMOPrintf( 10, 125, 0, "wait..." ) ;
190 DEMOPrintf( 175, 60, 0, "Wt :WAIT" ) ;
191 DEMOPrintf( 175, 70, 0, "Wt(TGC):WAIT" ) ;
192 }
193 else
194 {
195 DEMOPrintf( 95, 55, 0, "%3.1f", kpads[0].ex_status.bl.weight[0] ) ;
196 DEMOPrintf( 95, 125, 0, "%3.1f", kpads[0].ex_status.bl.weight[1] ) ;
197 DEMOPrintf( 10, 55, 0, "%3.1f", kpads[0].ex_status.bl.weight[2] ) ;
198 DEMOPrintf( 10, 125, 0, "%3.1f", kpads[0].ex_status.bl.weight[3] ) ;
199 DEMOPrintf( 175, 60, 0, "Wt :%3.1f[kg]", ( kpads[0].ex_status.bl.weight_ave[0] \
200 + kpads[0].ex_status.bl.weight_ave[1] \
201 + kpads[0].ex_status.bl.weight_ave[2] \
202 + kpads[0].ex_status.bl.weight_ave[3] ) ) ;
203 DEMOPrintf( 175, 70, 0, "Wt(TGC):%3.1f[kg]", kpads[0].ex_status.bl.tgc_weight ) ;
204 }
205 switch( kpads[0].ex_status.bl.weight_err ) {
206 case KPAD_WBC_ERR_NO_BATTERY :
207 DEMOPrintf( 175, 30, 0, "Err = NOBAT" ) ;
208 break ;
209 case KPAD_WBC_ERR_SETUP :
210 DEMOPrintf( 175, 30, 0, "Err = SETUP" ) ;
211 break ;
212 case KPAD_WBC_ERR_WRONG_TEMP :
213 DEMOPrintf( 175, 30, 0, "Err = TEMP" ) ;
214 break ;
215 case KPAD_WBC_ERR_WRONG_ZERO :
216 DEMOPrintf( 175, 30, 0, "Err = ZERO" ) ;
217 break ;
218 default :
219 DEMOPrintf( 175, 30, 0, "Err = %d", kpads[0].ex_status.bl.weight_err ) ;
220 break ;
221 }
222
223 DEMOPrintf( 175, 40, 0, "IsEXIST = %s", ( kpads[0].ex_status.bl.weight_err == 1 ) ? "EXIST" : "NONE" ) ;
224
225 DEMOPrintf( 10, 160, 0, "A: Reset ZERO Point" ) ;
226
227 init_draw_graphic( SCREEN_WIDTH, SCREEN_HEIGHT ) ;
228 draw_box( -143, -100, -68, -50, peagreen_clr, 2 ) ;
229 init_draw_graphic( SCREEN_WIDTH, SCREEN_HEIGHT ) ;
230 draw_box( -143, -30, -68, 20, yellow_clr, 2 ) ;
231 init_draw_graphic( SCREEN_WIDTH, SCREEN_HEIGHT ) ;
232 draw_box( -63, -100, 12, -50, blue_clr, 2 ) ;
233 init_draw_graphic( SCREEN_WIDTH, SCREEN_HEIGHT ) ;
234 draw_box( -63, -30, 12, 20, red_clr, 2 ) ;
235 }
236 else
237 {
238 DEMOPrintf( 50, 100, 0, "No balance checker is attached." ) ;
239 }
240 }
241
242 } // End renderStatus()
243
244
initialize(void)245 static void initialize( void )
246 {
247 DEMOInit( &GXNtsc480IntDf ) ;
248
249 GXSetCopyClear( smoke_clr, GX_MAX_Z24 ) ;
250 GXCopyDisp( DEMOGetCurrentBuffer(), GX_TRUE ) ;
251
252 WPADRegisterAllocator( myAlloc, myFree ) ;
253 if ( SCGetLanguage() == SC_LANG_JAPANESE )
254 {
255 WPADRegisterBLCWorkarea( myWorkarea ) ;
256 }
257
258 KPADInitEx( kpad_buf, BUFF_SIZE ) ;
259 KPADSetConnectCallback( WPAD_CHAN3, connectCallback ) ;
260
261 } // End
262
263
init_draw_graphic(u16 fb_width,u16 fb_height)264 static void init_draw_graphic( u16 fb_width, u16 fb_height )
265 {
266 Mtx44 proj_mtx ;
267 Mtx view_mtx ;
268 f32 canvas_wd, canvas_ht ;
269
270 // CANVAS
271 canvas_wd = fb_width * 0.91346f ;
272 canvas_ht = fb_height ;
273
274 // MTX
275 MTXOrtho( proj_mtx, canvas_ht * -0.5f,canvas_ht * 0.5f, canvas_wd * -0.5f,canvas_wd * 0.5f, -10.0f,10.0f ) ;
276 GXSetProjection( proj_mtx, GX_ORTHOGRAPHIC ) ;
277
278 MTXIdentity( view_mtx ) ;
279 GXLoadPosMtxImm( view_mtx, GX_PNMTX0 ) ;
280 GXSetCurrentMtx( GX_PNMTX0 ) ;
281
282 // VERTEX
283 GXClearVtxDesc() ;
284 GXSetVtxDesc( GX_VA_POS, GX_DIRECT ) ;
285 GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_F32, 0 ) ;
286
287 // CHANNEL
288 GXSetNumChans( 1 ) ;
289 GXSetChanCtrl( GX_COLOR0A0, GX_DISABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE ) ;
290 GXSetChanCtrl( GX_COLOR1A1, GX_DISABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE ) ;
291
292 // TEXTURE
293 GXSetNumTexGens( 0 ) ;
294
295 // TEV
296 GXSetNumTevStages( 1 ) ;
297 GXSetTevOrder( GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL ) ;
298 GXSetTevColorIn( GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_C0 ) ;
299 GXSetTevColorOp( GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV ) ;
300 GXSetTevAlphaIn( GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0 ) ;
301 GXSetTevAlphaOp( GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV ) ;
302 GXSetAlphaCompare( GX_ALWAYS,0, GX_AOP_OR, GX_ALWAYS,0 ) ;
303
304 // SCREEN
305 GXSetBlendMode( GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP ) ;
306 GXSetAlphaUpdate( GX_DISABLE ) ;
307
308 GXSetZMode( GX_DISABLE, GX_ALWAYS, GX_DISABLE ) ;
309 GXSetCullMode( GX_CULL_BACK ) ;
310 }
311
312 /*******************************************************************************
313 Draw object
314 *******************************************************************************/
draw_line(f32 x1,f32 y1,f32 x2,f32 y2,GXColor clr,f32 width)315 static void draw_line( f32 x1, f32 y1, f32 x2, f32 y2, GXColor clr, f32 width )
316 {
317 GXSetTevColor( GX_TEVREG0, clr ) ;
318 GXSetLineWidth( (u8)(s32)( width * 6.0f + 0.5f ), GX_TO_ZERO ) ;
319
320 GXBegin( GX_LINES, GX_VTXFMT0, 2 ) ;
321 GXPosition2f32( x1, y1 ) ;
322 GXPosition2f32( x2, y2 ) ;
323 GXEnd() ;
324 }
325
draw_box(f32 x1,f32 y1,f32 x2,f32 y2,GXColor clr,f32 width)326 static void draw_box( f32 x1, f32 y1, f32 x2, f32 y2, GXColor clr, f32 width )
327 {
328 draw_line( x1, y1, x2, y1, clr, width ) ;
329 draw_line( x2, y1, x2, y2, clr, width ) ;
330 draw_line( x2, y2, x1, y2, clr, width ) ;
331 draw_line( x1, y2, x1, y1, clr, width ) ;
332 }
333
334