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