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