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