1 /*---------------------------------------------------------------------------*
2   Project:     KPAD sample program
3   File:        sample.c
4   Programmer:  Keizo Ohta
5                HIRATSU Daisuke
6 
7   Copyright 2005 -2006 Nintendo.  All rights reserved.
8 
9   These coded instructions, statements, and computer programs contain
10   proprietary information of Nintendo of America Inc. and/or Nintendo
11   Company Ltd., and are protected by Federal copyright law.  They may
12   not be disclosed to third parties or copied or duplicated in any form,
13   in whole or in part, without the prior written consent of Nintendo.
14  *---------------------------------------------------------------------------*/
15 
16 #include	<revolution.h>
17 #include	<math.h>
18 
19 #include	<revolution/kpad.h>
20 #include	"main.h"
21 #include	"kfont.h"
22 #include	"graphic.h"
23 #include	"sample.h"
24 
25 
26 /***************************************************************
27 	Definitions
28 ***************************************************************/
29 #define CMD_LEFT	( (kpads[0][0].trig & KPAD_BUTTON_LEFT ) != 0 )	// Move cursor
30 #define CMD_RIGHT	( (kpads[0][0].trig & KPAD_BUTTON_RIGHT) != 0 )
31 #define CMD_UP		( (kpads[0][0].trig & KPAD_BUTTON_UP   ) != 0 )
32 #define CMD_DOWN	( (kpads[0][0].trig & KPAD_BUTTON_DOWN ) != 0 )
33 
34 #define CMD_INC		( (kpads[0][0].trig & KPAD_BUTTON_A    ) != 0 )	// Increase/decrease values
35 #define CMD_DEC		( (kpads[0][0].trig & KPAD_BUTTON_B    ) != 0 )
36 
37 #define BTN_CALIBRATE	( KPAD_BUTTON_PLUS | KPAD_BUTTON_MINUS )	// Calibration operations
38 #define CMD_CALIBRATE	( (kpads[0][0].hold & BTN_CALIBRATE) == BTN_CALIBRATE && kpads[0][0].trig )
39 
40 
41 /***************************************************************
42 	Adjustable items
43 ***************************************************************/
44 static f32	pointing_scale = 200.0f ;	// On-screen pointing scale
45 
46 static f32	obj_interval     = 0.20f ;	// Interval between light-emitting points on the TV (in meters)
47 
48 static f32	pos_play_radius  = 0.00f ;	// Set pos sensitivity
49 static f32	pos_sensitivity  = 1.00f ;
50 static f32	hori_play_radius = 0.00f ;	// Set horizon sensitivity
51 static f32	hori_sensitivity = 1.00f ;
52 static f32	dist_play_radius = 0.00f ;	// Set dist sensitivity
53 static f32	dist_sensitivity = 1.00f ;
54 static f32	acc_play_radius  = 0.00f ;	// Set acc sensitivity
55 static f32	acc_sensitivity  = 1.00f ;
56 
57 static f32	repeat_delay_sec = 0.75f ;	// Set key repeat
58 static f32	repeat_pulse_sec = 0.25f ;
59 
60 #define EDIT_DATA_MAX	12	// Number of edited data items
61 
62 typedef struct {
63 	f32	*vp ;	// Pointer to variable
64 	f32	min ;	// Minimum value of variable
65 	f32	max ;	// Maximum value of variable
66 	u8	y ;	// Y cursor position
67 	u8	x[3] ;	// X cursor position of each of the digits
68 	f32	v[3] ;	// Amount of change in value of each of the digits
69 } EditData ;
70 
71 static EditData		edit_data[ EDIT_DATA_MAX ] = {
72 	{ &  pointing_scale, 0.0f,900.0f,  3, {12,13,14}, {100.0f, 10.0f, 1.0f} },
73 	{ &    obj_interval, 0.00f,9.00f,  5, {11,13,14}, {1.00f, 0.10f, 0.01f} },
74 	{ & pos_play_radius, 0.00f,9.00f,  8, { 6, 8, 9}, {1.00f, 0.10f, 0.01f} },
75 	{ & pos_sensitivity, 0.00f,1.00f,  8, {11,13,14}, {1.00f, 0.10f, 0.01f} },
76 	{ &hori_play_radius, 0.00f,9.00f,  9, { 6, 8, 9}, {1.00f, 0.10f, 0.01f} },
77 	{ &hori_sensitivity, 0.00f,1.00f,  9, {11,13,14}, {1.00f, 0.10f, 0.01f} },
78 	{ &dist_play_radius, 0.00f,9.00f, 10, { 6, 8, 9}, {1.00f, 0.10f, 0.01f} },
79 	{ &dist_sensitivity, 0.00f,1.00f, 10, {11,13,14}, {1.00f, 0.10f, 0.01f} },
80 	{ & acc_play_radius, 0.00f,9.00f, 11, { 6, 8, 9}, {1.00f, 0.10f, 0.01f} },
81 	{ & acc_sensitivity, 0.00f,1.00f, 11, {11,13,14}, {1.00f, 0.10f, 0.01f} },
82 	{ &repeat_delay_sec, 0.00f,9.00f, 14, { 6, 8, 9}, {1.00f, 0.10f, 0.01f} },
83 	{ &repeat_pulse_sec, 0.00f,9.00f, 14, {11,13,14}, {1.00f, 0.10f, 0.01f} },
84 } ;
85 
86 
87 /***************************************************************
88 	Variables
89 ***************************************************************/
90 static s32	csr_x, csr_y ;	// Cursor position for adjusting values
91 static s32	csr_i, csr_k ;	// Data instance being edited and digit position
92 static s32	calib_disp_ct ;	// Calibration message display count
93 
94 static f32	dpd_disp_scale = 140.0f ;	// DPD object display scale
95 static f32	dpd_disp_ox    = 165.0f ;	// DPD object display position
96 static f32	dpd_disp_oy    =  65.0f ;
97 
98 
99 /*******************************************************************************
100 	Initialization function
101 *******************************************************************************/
init_sample(void)102 void init_sample( void )
103 {
104 	//----- Initial settings for controller
105 	KPADReset() ;
106 	KPADSetPosParam ( 0,  pos_play_radius,  pos_sensitivity ) ;
107 	KPADSetHoriParam( 0, hori_play_radius, hori_sensitivity ) ;
108 	KPADSetDistParam( 0, dist_play_radius, dist_sensitivity ) ;
109 	KPADSetAccParam ( 0,  acc_play_radius,  acc_sensitivity ) ;
110 	KPADSetBtnRepeat( 0, repeat_delay_sec, repeat_pulse_sec ) ;
111 
112 	//----- Initialize cursor position
113 	csr_i = 0 ;		// Data instance being edited
114 	csr_k = 2 ;		// Position of digit being edited
115 	csr_x = edit_data[ csr_i ].x[ csr_k ] ;
116 	csr_y = edit_data[ csr_i ].y ;
117 
118 	//----- Initialize the calibration message count
119 	calib_disp_ct = 0 ;	// Minus: Failed display, 0: No display, Plus: Successful display
120 }
121 
122 
123 /*******************************************************************************
124 	Processing for moving the cursor
125 *******************************************************************************/
move_cursor(void)126 static void move_cursor( void )
127 {
128 	EditData	*ep ;
129 	s32		vx,vy, wx,wy, fy ;
130 	s32		i,w,k, im,wm,km ;
131 
132 
133 	/***********************************************************************
134 		Processing for moving the cursor
135 	***********************************************************************/
136 	//----- Temporary motion vector
137 	if ( CMD_LEFT ) vx = -1 ;
138 	else if ( CMD_RIGHT ) vx = 1 ;
139 	else vx = 0 ;
140 
141 	if ( CMD_UP ) vy = -1 ;
142 	else if ( CMD_DOWN ) vy = 1 ;
143 	else vy = 0 ;
144 
145 	//------ Move to the closest digit position in edit data
146 	wm = 1 << 30 ;		// Maximum distance value
147 	i = EDIT_DATA_MAX - 1 ;
148 	do {
149 		ep = &edit_data[i] ;
150 
151 		fy = ( wy = ep->y - csr_y ) * vy ;	// Prepare to calculate inner product
152 		wy *= wy ;				// Prepare to calculate distance
153 		k = 0 ;
154 		do {
155 			//----- Inner product must be positive
156 			wx = ep->x[k] - csr_x ;
157 			if ( wx * vx + fy <= 0 ) continue ;
158 
159 			//----- Distance must be closest possible
160 			w = wx * wx + wy ;
161 			if ( w >= wm ) continue ;
162 
163 			//----- Record candidates
164 			wm = w ;
165 			im = i ;
166 			km = k ;
167 		} while ( ++k < 3 ) ;
168 	} while ( --i >= 0 ) ;
169 
170 	//----- Move cursor if candidate has been recorded
171 	if ( wm != 1 << 30 ) {
172 		csr_i = im ;
173 		csr_k = km ;
174 		csr_x = edit_data[ csr_i ].x[ csr_k ] ;
175 		csr_y = edit_data[ csr_i ].y ;
176 	}
177 }
178 
179 
180 /*******************************************************************************
181 	Adjust values
182 *******************************************************************************/
push_cursor(void)183 static void push_cursor( void )
184 {
185 	EditData	*ep = &edit_data[ csr_i ] ;
186 
187 
188 	//----- Has a button been pushed?
189 	if ( CMD_INC ) {
190 		*(ep->vp) += ep->v[ csr_k ] ;
191 		if ( *(ep->vp) > ep->max ) *(ep->vp) = ep->max ;
192 	} else if ( CMD_DEC ) {
193 		*(ep->vp) -= ep->v[ csr_k ] ;
194 		if ( *(ep->vp) < ep->min ) *(ep->vp) = ep->min ;
195 	} else {
196 		return ;	// No change in numeric values
197 	}
198 
199 	//----- Reset because numeric values have changed
200 	if ( csr_i >= 10 ) {
201 		KPADSetBtnRepeat( 0, repeat_delay_sec, repeat_pulse_sec ) ;
202 	} else if ( csr_i >= 8 ) {
203 		KPADSetAccParam ( 0,  acc_play_radius,  acc_sensitivity ) ;
204 	} else if ( csr_i >= 6 ) {
205 		KPADSetDistParam( 0, dist_play_radius, dist_sensitivity ) ;
206 	} else if ( csr_i >= 4 ) {
207 		KPADSetHoriParam( 0, hori_play_radius, hori_sensitivity ) ;
208 	} else if ( csr_i >= 2 ) {
209 		KPADSetPosParam ( 0,  pos_play_radius,  pos_sensitivity ) ;
210 	} else if ( csr_i == 1 ) {
211 		KPADSetObjInterval( obj_interval ) ;
212 	}
213 }
214 
215 
216 /*******************************************************************************
217 	CPU processing function
218 *******************************************************************************/
work_sample(void)219 void work_sample( void )
220 {
221 	/***********************************************************************
222 		Calibrate
223 	***********************************************************************/
224 	if ( calib_disp_ct < 0 ) ++ calib_disp_ct ;
225 	else if ( calib_disp_ct ) -- calib_disp_ct ;
226 
227 	if ( CMD_CALIBRATE ) {
228 		if ( KPADCalibrateDPD( 0 ) == 2 ) {
229 			calib_disp_ct = 180 ;	// Succeeded
230 		} else {
231 			calib_disp_ct = -180 ;	// Failed
232 		}
233 	}
234 
235 	/***********************************************************************
236 		Processing for editing numeric values
237 	***********************************************************************/
238 	move_cursor() ;		// Processing for moving the cursor
239 	push_cursor() ;		// Adjust values
240 }
241 
242 
243 /*******************************************************************************
244 	Draw pointing scale frame
245 *******************************************************************************/
draw_pointing_frame(void)246 static void draw_pointing_frame( void )
247 {
248 	draw_line( -pointing_scale,-pointing_scale, pointing_scale,-pointing_scale, blue_clr, 2.5f ) ;
249 	draw_line(  pointing_scale,-pointing_scale, pointing_scale, pointing_scale, blue_clr, 2.5f ) ;
250 	draw_line(  pointing_scale, pointing_scale,-pointing_scale, pointing_scale, blue_clr, 2.5f ) ;
251 	draw_line( -pointing_scale, pointing_scale,-pointing_scale,-pointing_scale, blue_clr, 2.5f ) ;
252 }
253 
254 
255 /*******************************************************************************
256 	Draw pointing coordinate
257 *******************************************************************************/
draw_position(KPADStatus * sp)258 static void draw_position( KPADStatus *sp )
259 {
260 	Vec2		pos, vec ;
261 	f32		scale ;
262 
263 
264 	//------ Cross
265 	pos.x = pointing_scale * sp->pos.x ;	// Coordinate of center
266 	pos.y = pointing_scale * sp->pos.y ;
267 
268 	scale = 72.0f ;
269 	vec.x = scale * sp->horizon.x ;		// Right-facing vector
270 	vec.y = scale * sp->horizon.y ;
271 	draw_line( pos.x-vec.x,pos.y-vec.y, pos.x+vec.x,pos.y+vec.y, yellow_clr, 3 ) ;
272 
273 	scale = 28.0f ;
274 	vec.x = scale * -sp->horizon.y ;	// Downward-facing vector
275 	vec.y = scale *  sp->horizon.x ;
276 	draw_arrow( pos.x+vec.x,pos.y+vec.y, pos.x-vec.x,pos.y-vec.y, silver_clr, 3 ) ;
277 
278 	//------ Center point
279 	draw_point( pos.x,pos.y, black_clr, 11 ) ;
280 	draw_point( pos.x,pos.y,  cyan_clr,  9 ) ;
281 }
282 
283 
284 /*******************************************************************************
285 	Draw grid
286 *******************************************************************************/
draw_grid(f32 ox,f32 oy,f32 radius,GXColor clr)287 static void draw_grid( f32 ox, f32 oy, f32 radius, GXColor clr )
288 {
289 	f32		r = radius * 1.4f ;	// Cross length
290 
291 	draw_arrow( ox-r,oy, ox+r,oy, clr, 3 ) ;	// Horizontal line
292 	draw_arrow( ox,oy+r, ox,oy-r, clr, 3 ) ;	// Vertical line
293 	draw_circle( ox,oy, radius, clr, 3 ) ;		// Circle
294 }
295 
296 
297 /*******************************************************************************
298 	Draw acceleration
299 *******************************************************************************/
draw_acc(f32 ox,f32 oy,f32 radius,f32 ax,f32 ay)300 static void draw_acc( f32 ox, f32 oy, f32 radius, f32 ax, f32 ay )
301 {
302 	f32		px = ax * radius + ox ;
303 	f32		py = ay * radius + oy ;
304 
305 	draw_arrow( ox,oy, px,py, red_clr, 4 ) ;
306 	draw_point( px,py, white_clr, 4 ) ;
307 }
308 
309 
310 /*******************************************************************************
311 	Draw nunchaku unit acceleration
312 *******************************************************************************/
draw_acc2(f32 ox,f32 oy,f32 radius,f32 ax,f32 ay)313 static void draw_acc2( f32 ox, f32 oy, f32 radius, f32 ax, f32 ay )
314 {
315 	f32		px = ax * radius + ox ;
316 	f32		py = ay * radius + oy ;
317 
318 	draw_dashed_arrow( ox,oy, px,py, red_clr, 4 ) ;
319 	draw_point( px,py, white_clr, 4 ) ;
320 }
321 
322 
draw_stick(f32 ox,f32 oy,f32 radius,f32 sx,f32 sy,GXColor clr,BOOL dashed)323 static void draw_stick( f32 ox, f32 oy, f32 radius, f32 sx, f32 sy, GXColor clr, BOOL dashed )
324 {
325     f32 px = sx * radius + ox;
326     f32 py = sy * radius + oy;
327 
328     if ( dashed ) {
329         draw_dashed_arrow( ox,oy, px,py, clr, 4 ) ;
330     } else {
331         draw_arrow( ox,oy, px,py, clr, 4 ) ;
332     }
333     draw_point( sx,sy, white_clr, 4 ) ;
334 }
335 
336 
337 /*******************************************************************************
338 	Draw cursor for adjusting numeric values
339 *******************************************************************************/
draw_cursor(void)340 static void draw_cursor( void )
341 {
342 	f32		x1,y1, x2,y2 ;
343 
344 	x1 = calc_kfont_x1( csr_x ) ;
345 	y1 = calc_kfont_y1( csr_y ) ;
346 	x2 = calc_kfont_x2( csr_x ) - 1.0f ;
347 	y2 = calc_kfont_y2( csr_y ) - 1.0f ;
348 	draw_line( x1,y1, x2,y1, white_clr, 2 ) ;
349 	draw_line( x2,y1, x2,y2, white_clr, 2 ) ;
350 	draw_line( x2,y2, x1,y2, white_clr, 2 ) ;
351 	draw_line( x1,y2, x1,y1, white_clr, 2 ) ;
352 }
353 
354 
355 /*******************************************************************************
356 	Draw DPD sensor frame
357 *******************************************************************************/
draw_dpd_frame(void)358 static void draw_dpd_frame( void )
359 {
360 	f32		rx,ry, x1,y1, x2,y2 ;
361 
362 
363 	rx = dpd_disp_scale * 0.5f ;
364 	ry = rx * (f32)WPAD_DPD_IMG_RESO_WY / (f32)WPAD_DPD_IMG_RESO_WX ;
365 	x1 = dpd_disp_ox - rx ;
366 	y1 = dpd_disp_oy - ry ;
367 	x2 = dpd_disp_ox + rx ;
368 	y2 = dpd_disp_oy + ry ;
369 
370 	GXSetTevColor( GX_TEVREG0, smoke_clr ) ;
371 
372 	GXBegin( GX_QUADS, GX_VTXFMT0, 4 ) ;
373 	  GXPosition2f32( x1, y1 ) ;
374 	  GXPosition2f32( x2, y1 ) ;
375 	  GXPosition2f32( x2, y2 ) ;
376 	  GXPosition2f32( x1, y2 ) ;
377 	GXEnd() ;
378 }
379 
380 
381 /*******************************************************************************
382 	Draw DPD object
383 *******************************************************************************/
draw_object(void)384 static void draw_object( void )
385 {
386 	WPADStatus   *wp ;
387 	WPADFSStatus *fp ;
388 	WPADCLStatus *cp ;
389 	DPDObject    *op, *op1 ;
390 	f32          px,py, scale, ofx,ofy ;
391 	s32          n, i ;
392 
393 
394 	if ( kpads[0][0].dev_type != WPAD_DEV_CORE &&
395 	     kpads[0][0].dev_type != WPAD_DEV_FREESTYLE &&
396 	     kpads[0][0].dev_type != WPAD_DEV_CLASSIC) {
397 		return ;
398 	}
399 
400 	//----- Calculate display position
401 	scale = dpd_disp_scale / (f32)WPAD_DPD_IMG_RESO_WX ;
402 	ofx = dpd_disp_scale * -0.5f ;
403 	ofy = ofx * (f32)WPAD_DPD_IMG_RESO_WY / (f32)WPAD_DPD_IMG_RESO_WX ;
404 	ofx += dpd_disp_ox ;
405 	ofy += dpd_disp_oy ;
406 
407 	//----- Display all values sampled at 200 Hz
408 	switch ( kpads[0][0].dev_type ) {
409 	    case WPAD_DEV_CORE:
410             wp = KPADGetWPADRingBuffer( 0 ) ;   // WPAD ring buffer
411             break;
412         case WPAD_DEV_FREESTYLE:
413             fp = KPADGetWPADFSRingBuffer( 0 ) ; // WPAD ring buffer
414             break;
415         case WPAD_DEV_CLASSIC:
416             cp = KPADGetWPADCLRingBuffer( 0 ) ; // WPAD ring buffer
417             break;
418     }
419 	i = (s32)WPADGetLatestIndexInBuf( 0 ) ;	// Latest index
420 	n = kpad_reads ;			// Current sampling rate
421 
422 	i -= n - 1 ;				// Draw beginning from oldest data
423 	if ( i < 0 ) i += KPAD_RING_BUFS ;
424 
425 	while ( --n >= 0 ) {
426 	    switch( kpads[0][0].dev_type ) {
427 	        case WPAD_DEV_CORE:
428                 op = &wp[i].obj[ WPAD_DPD_MAX_OBJECTS - 1 ] ;
429                 op1 = wp[i].obj ;
430                 break;
431             case WPAD_DEV_FREESTYLE:
432                 op = &fp[i].obj[ WPAD_DPD_MAX_OBJECTS - 1 ] ;
433                 op1 = fp[i].obj ;
434                 break;
435             case WPAD_DEV_CLASSIC:
436                 op = &cp[i].obj[ WPAD_DPD_MAX_OBJECTS - 1 ] ;
437                 op1 = cp[i].obj ;
438 		}
439 		do {
440 			if ( op->size == 0 ) continue ;
441 
442 			//----- Convert to screen coordinates
443 			px = (f32)op->x * scale + ofx ;
444 			py = (f32)op->y * scale + ofy ;
445 
446 			//----- Draw object
447 			draw_point( px,py, white_clr, 5 ) ;
448 			draw_circle( px,py, 5, black_clr, 2 ) ;
449 			draw_circle( px,py, 4, smoke_clr, 2 ) ;
450 			draw_circle( px,py, 3,  gray_clr, 2 ) ;
451 		} while ( --op >= op1 ) ;
452 
453 		if ( ++i == KPAD_RING_BUFS ) i = 0 ;
454 	}
455 }
456 
457 
458 /*******************************************************************************
459 	Drawing function
460 *******************************************************************************/
draw_sample(void)461 void draw_sample( void )
462 {
463 	s32		cx,cy ;
464 	f32		x1,x2, y, r ;
465 	u32     hold, trig, release;
466 
467 
468 	/***********************************************************************
469 		Pointing scale frame
470 	***********************************************************************/
471 	init_draw_graphic( rmode_p->fbWidth, rmode_p->efbHeight ) ;
472 	draw_pointing_frame() ;
473 
474 	/***********************************************************************
475 		Adjustable items
476 	***********************************************************************/
477 	init_draw_kfont( rmode_p->fbWidth, rmode_p->efbHeight, 15.6f, 20.8f ) ;
478 	cx = 2 ;
479 	cy = 3 ;
480 	draw_kfont_letter( cx,cy, gray_clr, "POINTING") ;
481 	(void)draw_kfont_s32( cx+12,cy, blue_clr, (s32)pointing_scale ) ;
482 	cy += 2 ;
483 	draw_kfont_letter( cx,cy, gray_clr, "INTERVAL") ;
484 	(void)draw_kfont_f32( cx+9,cy, peagreen_clr, obj_interval, 2 ) ;
485 	cy += 2 ;
486 	draw_kfont_letter( cx,cy, gray_clr, "    PLAY SENS") ;
487 	++ cy ;
488 	draw_kfont_letter( cx,cy, gray_clr, "POS" ) ;
489 	(void)draw_kfont_f32( cx+4,cy,   cyan_clr,  pos_play_radius, 2 ) ;
490 	(void)draw_kfont_f32( cx+9,cy,   cyan_clr,  pos_sensitivity, 2 ) ;
491 	++ cy ;
492 	draw_kfont_letter( cx,cy, gray_clr, "HOR" ) ;
493 	(void)draw_kfont_f32( cx+4,cy, yellow_clr, hori_play_radius, 2 ) ;
494 	(void)draw_kfont_f32( cx+9,cy, yellow_clr, hori_sensitivity, 2 ) ;
495 	++ cy ;
496 	draw_kfont_letter( cx,cy, gray_clr, "DIS" ) ;
497 	(void)draw_kfont_f32( cx+4,cy,  green_clr, dist_play_radius, 2 ) ;
498 	(void)draw_kfont_f32( cx+9,cy,  green_clr, dist_sensitivity, 2 ) ;
499 	++ cy ;
500 	draw_kfont_letter( cx,cy, gray_clr, "ACC" ) ;
501 	(void)draw_kfont_f32( cx+4,cy,    red_clr,  acc_play_radius, 2 ) ;
502 	(void)draw_kfont_f32( cx+9,cy,    red_clr,  acc_sensitivity, 2 ) ;
503 	cy += 2 ;
504 	draw_kfont_letter( cx,cy, gray_clr, "    DLAY PULS") ;
505 	++ cy ;
506 	draw_kfont_letter( cx,cy, gray_clr, "RPT") ;
507 	(void)draw_kfont_f32( cx+4,cy, orange_clr, repeat_delay_sec, 2 ) ;
508 	(void)draw_kfont_f32( cx+9,cy, orange_clr, repeat_pulse_sec, 2 ) ;
509 
510 	//----- Various data titles
511 	draw_kfont_letter( 26.0f, 3.0f, gray_clr, "ACC"  ) ;	// Acceleration data
512 	draw_kfont_letter( 18.7f,10.3f, gray_clr, "VALID") ;	// DPD enable flag
513 	draw_kfont_letter( 19.2f,13.4f, gray_clr, "DIST" ) ;	// Distance data
514 	draw_kfont_letter( 30.8f,10.1f, gray_clr, "OBJ"  ) ;	// Object
515 
516 	/***********************************************************************
517 		Cursor for adjusting numeric values
518 	***********************************************************************/
519 	init_draw_graphic( rmode_p->fbWidth, rmode_p->efbHeight ) ;
520 	draw_cursor() ;
521 
522 	/***********************************************************************
523 		DPD enable flag & distance data
524 	***********************************************************************/
525 	init_draw_kfont( rmode_p->fbWidth, rmode_p->efbHeight, 30.0f, 40.0f ) ;
526 	(void)draw_kfont_s32( 10.4f,5.8f, violet_clr, kpads[0][0].dpd_valid_fg ) ;
527 	(void)draw_kfont_f32(  8.8f,7.4f,  green_clr, kpads[0][0].dist, 2 ) ;
528 
529 	/***********************************************************************
530 		Button bit data
531 	***********************************************************************/
532 	init_draw_kfont( rmode_p->fbWidth, rmode_p->efbHeight, 14.0f, 18.8f ) ;
533 	cx =  2 ;
534 	cy =  18 ;
535 
536     hold    = kpads[0][0].hold;
537     trig    = kpads[0][0].trig;
538     release = kpads[0][0].release;
539 
540 	draw_kfont_letter( cx,cy, gray_clr, "HLD") ;
541 	draw_kfont_bit( cx+38,cy, orange_clr, hold   , 32 ) ;
542 	++ cy ;
543 	draw_kfont_letter( cx,cy, gray_clr, "TRG") ;
544 	draw_kfont_bit( cx+38,cy, orange_clr, trig   , 32 ) ;
545 	++ cy ;
546 	draw_kfont_letter( cx,cy, gray_clr, "REL") ;
547 	draw_kfont_bit( cx+38,cy, orange_clr, release, 32 ) ;
548 
549 	if ( kpads[0][0].dev_type == WPAD_DEV_CLASSIC ) {
550 	    hold    = kpads[0][0].ex_status.cl.hold;
551 	    trig    = kpads[0][0].ex_status.cl.trig;
552 	    release = kpads[0][0].ex_status.cl.release;
553 
554     	++ cy ;
555     	draw_kfont_letter( cx,cy, gray_clr, "HLD") ;
556     	draw_kfont_bit( cx+38,cy, peagreen_clr, hold   , 32 ) ;
557     	++ cy ;
558     	draw_kfont_letter( cx,cy, gray_clr, "TRG") ;
559     	draw_kfont_bit( cx+38,cy, peagreen_clr, trig   , 32 ) ;
560     	++ cy ;
561     	draw_kfont_letter( cx,cy, gray_clr, "REL") ;
562     	draw_kfont_bit( cx+38,cy, peagreen_clr, release, 32 ) ;
563     }
564 
565 	/***********************************************************************
566 		Acceleration data
567 	***********************************************************************/
568 	init_draw_kfont( rmode_p->fbWidth, rmode_p->efbHeight, 15.0f, 20.0f ) ;
569 	draw_kfont_letter( 23.0f,2.5f, smoke_clr, "Y            Y") ;
570 	draw_kfont_letter( 27.0f,6.5f, smoke_clr, "X            Z") ;
571 
572 	x1 =   10.0f ;	// X coordinate of left grid
573 	x2 =  185.0f ;	// X coordinate of right grid
574 	y  = -100.0f ;	// Shared Y coordinate
575 	r  =   60.0f ;	// Shared radius
576 
577 	init_draw_graphic( rmode_p->fbWidth, rmode_p->efbHeight ) ;
578 	draw_grid( x1, y, r, smoke_clr ) ;
579 	draw_grid( x2, y, r, smoke_clr ) ;
580 
581 	cx = kpad_reads ;
582 	while ( --cx >= 0 ) {
583 		draw_acc( x1, y, r, kpads[0][cx].acc.x, -kpads[0][cx].acc.y ) ;
584 		draw_acc( x2, y, r, kpads[0][cx].acc.z, -kpads[0][cx].acc.y ) ;
585 		if(kpads[0][cx].dev_type == WPAD_DEV_FREESTYLE) {
586     		draw_acc2( x1, y, r, kpads[0][cx].ex_status.fs.acc.x, -kpads[0][cx].ex_status.fs.acc.y ) ;
587     		draw_acc2( x2, y, r, kpads[0][cx].ex_status.fs.acc.z, -kpads[0][cx].ex_status.fs.acc.y ) ;
588     	}
589 	}
590 
591 	init_draw_graphic( rmode_p->fbWidth, rmode_p->efbHeight ) ;
592 	cx = kpad_reads ;
593 	while ( --cx >= 0 ) {
594 		if(kpads[0][cx].dev_type == WPAD_DEV_FREESTYLE) {
595 		    draw_stick( x1, y, r, kpads[0][cx].ex_status.fs.stick.x, -kpads[0][cx].ex_status.fs.stick.y, yellow_clr, TRUE ) ;
596 		} else if (kpads[0][cx].dev_type == WPAD_DEV_CLASSIC) {
597 		    draw_stick( x1, y, r, kpads[0][cx].ex_status.cl.lstick.x, -kpads[0][cx].ex_status.cl.lstick.y, blue_clr,  FALSE ) ;
598 		    draw_stick( x1, y, r, kpads[0][cx].ex_status.cl.rstick.x, -kpads[0][cx].ex_status.cl.rstick.y, green_clr, FALSE ) ;
599 
600     	}
601 	}
602 
603 
604 	/***********************************************************************
605 		Display DPD object
606 	***********************************************************************/
607 	init_draw_graphic( rmode_p->fbWidth, rmode_p->efbHeight ) ;
608 	draw_dpd_frame() ;
609 	draw_object() ;
610 
611 	/***********************************************************************
612 		Pointing cursor
613 	***********************************************************************/
614 	init_draw_graphic( rmode_p->fbWidth, rmode_p->efbHeight ) ;
615 	cx = kpad_reads ;
616 	while ( --cx >= 0 ) {
617 		draw_position( &kpads[0][cx] ) ;
618 	}
619 
620 	/***********************************************************************
621 		Calibration messages
622 	***********************************************************************/
623 	init_draw_kfont( rmode_p->fbWidth, rmode_p->efbHeight, 60.0f, 80.0f ) ;
624 	if ( calib_disp_ct < 0 ) {
625 		draw_kfont_letter( 0.5f,1.4f, magenta_clr, "  ERROR  ") ;	// Message in case of failure
626 	} else if ( calib_disp_ct ) {
627 		draw_kfont_letter( 0.5f,1.4f, magenta_clr, "CALIBRATE") ;	// Message in case of success
628 	}
629 }
630 
631