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 #include <stdio.h>
20 
21 #include <revolution/kpad.h>
22 #include "main.h"
23 #include "kfont.h"
24 #include "graphic.h"
25 #include "sample.h"
26 
27 
28 /***************************************************************
29     Definitions
30 ***************************************************************/
31 #define CMD_LEFT        ( (kpads[0][0].trig & KPAD_BUTTON_LEFT ) != 0 ) // Cursor movement
32 #define CMD_RIGHT       ( (kpads[0][0].trig & KPAD_BUTTON_RIGHT) != 0 )
33 #define CMD_UP          ( (kpads[0][0].trig & KPAD_BUTTON_UP   ) != 0 )
34 #define CMD_DOWN        ( (kpads[0][0].trig & KPAD_BUTTON_DOWN ) != 0 )
35 
36 #define CMD_INC         ( (kpads[0][0].trig & KPAD_BUTTON_A    ) != 0 ) // Increase/decrease value
37 #define CMD_DEC         ( (kpads[0][0].trig & KPAD_BUTTON_B    ) != 0 )
38 
39 #define CMD_ENABLE_DPD  ( (kpads[0][0].trig & KPAD_BUTTON_1    ) != 0 ) // DPD ON/OFF
40 #define CMD_DISABLE_DPD ( (kpads[0][0].trig & KPAD_BUTTON_2    ) != 0 )
41 
42 #define BTN_CALIBRATE   ( KPAD_BUTTON_PLUS | KPAD_BUTTON_MINUS )        // Calibration operation
43 #define CMD_CALIBRATE   ( (kpads[0][0].hold & BTN_CALIBRATE) == BTN_CALIBRATE && kpads[0][0].trig )
44 
45 #define CMD_AIMMODE     ( (kpads[0][0].trig & KPAD_BUTTON_HOME ) != 0 )
46 
47 #define CMD_STICK_CLAMP_HOLD1 ( kpads[0][0].dev_type == WPAD_DEV_FREESTYLE && (kpads[0][0].hold & KPAD_BUTTON_Z) != 0 )
48 #define CMD_STICK_CLAMP_HOLD2 ( ( ( kpads[0][0].dev_type == WPAD_DEV_CLASSIC ) \
49                                || ( kpads[0][0].dev_type == WPAD_DEV_GUITAR  ) ) \
50                              && ( kpads[0][0].ex_status.cl.hold & KPAD_CL_BUTTON_PLUS ) != 0 )
51 
52 #define CMD_STICK_CLAMP_TRIG1 ( kpads[0][0].dev_type == WPAD_DEV_FREESTYLE && (kpads[0][0].trig & KPAD_BUTTON_C) != 0 )
53 #define CMD_STICK_CLAMP_TRIG2 ( ( ( kpads[0][0].dev_type == WPAD_DEV_CLASSIC ) \
54                                || ( kpads[0][0].dev_type == WPAD_DEV_GUITAR  ) ) \
55                              && ( kpads[0][0].ex_status.cl.trig & KPAD_CL_BUTTON_MINUS ) != 0 )
56 
57 
58 /***************************************************************
59  Adjustment item
60 ***************************************************************/
61 static f32 pointing_scale = 200.0f ; // Screen pointing scale
62 
63 static f32 obj_interval     = 0.20f ; // TV side light emitting point placement interval (in meters)
64 
65 static f32 pos_play_radius  = 0.00f ; // 'pos' sensitivity setting
66 static f32 pos_sensitivity  = 1.00f ;
67 static f32 pos_play_mode    = (f32)KPAD_PLAY_MODE_LOOSE ;
68 static f32 hori_play_radius = 0.00f ; // 'horizon' sensitivity setting
69 static f32 hori_sensitivity = 1.00f ;
70 static f32 hori_play_mode   = (f32)KPAD_PLAY_MODE_LOOSE ;
71 static f32 dist_play_radius = 0.00f ; // 'dist' sensitivity setting
72 static f32 dist_sensitivity = 1.00f ;
73 static f32 dist_play_mode   = KPAD_PLAY_MODE_LOOSE ;
74 static f32 acc_play_radius  = 0.00f ; // 'acc' sensitivity setting
75 static f32 acc_sensitivity  = 1.00f ;
76 static f32 acc_play_mode    = KPAD_PLAY_MODE_LOOSE ;
77 
78 static f32 repeat_delay_sec = 0.75f ; // Key repeat settings
79 static f32 repeat_pulse_sec = 0.25f ;
80 
81 #define EDIT_DATA_MAX 16 // Edit data count
82 
83 typedef struct {
84     f32 *vp ;   // Pointer to the variable
85     f32 min ;   // Variable minimum value
86     f32 max ;   // Variable maximum value
87     u8  y ;     // y-cursor position
88     u8  x[3] ;  // x-cursor position for each digit
89     f32 v[3] ;  // Value change for each digit
90 } EditData ;
91 
92 static EditData  edit_data[ EDIT_DATA_MAX ] = {
93     { &  pointing_scale, 0.0f,900.0f,  3, {10,11,12}, {100.0f, 10.0f, 1.0f} },
94     { &    obj_interval, 0.00f,9.00f,  5, { 9,11,12}, {1.00f, 0.10f, 0.01f} },
95     { & pos_play_radius, 0.00f,9.00f,  8, { 4, 6, 7}, {1.00f, 0.10f, 0.01f} },
96     { & pos_sensitivity, 0.00f,1.00f,  8, { 9,11,12}, {1.00f, 0.10f, 0.01f} },
97     { & pos_play_mode,   0.00f,1.00f,  8, {14,14,14}, {1.00f, 1.00f, 1.00f} },
98     { &hori_play_radius, 0.00f,9.00f,  9, { 4, 6, 7}, {1.00f, 0.10f, 0.01f} },
99     { &hori_sensitivity, 0.00f,1.00f,  9, { 9,11,12}, {1.00f, 0.10f, 0.01f} },
100     { &hori_play_mode,   0.00f,1.00f,  9, {14,14,14}, {1.00f, 1.00f, 1.00f} },
101     { &dist_play_radius, 0.00f,9.00f, 10, { 4, 6, 7}, {1.00f, 0.10f, 0.01f} },
102     { &dist_sensitivity, 0.00f,1.00f, 10, { 9,11,12}, {1.00f, 0.10f, 0.01f} },
103     { &dist_play_mode,   0.00f,1.00f, 10, {14,14,14}, {1.00f, 1.00f, 1.00f} },
104     { & acc_play_radius, 0.00f,9.00f, 11, { 4, 6, 7}, {1.00f, 0.10f, 0.01f} },
105     { & acc_sensitivity, 0.00f,1.00f, 11, { 9,11,12}, {1.00f, 0.10f, 0.01f} },
106     { & acc_play_mode,   0.00f,1.00f, 11, {14,14,14}, {1.00f, 1.00f, 1.00f} },
107     { &repeat_delay_sec, 0.00f,9.00f, 14, { 4, 6, 7}, {1.00f, 0.10f, 0.01f} },
108     { &repeat_pulse_sec, 0.00f,9.00f, 14, { 9,11,12}, {1.00f, 0.10f, 0.01f} },
109 } ;
110 
111 
112 /***************************************************************
113  Variables
114 ***************************************************************/
115 static const f32 O1Y = -1.5f;
116 static const f32 O2Y = -0.5f;
117 static const f32 O3Y = -1.0f;
118 static const f32 O4Y = -20.8f;
119 static const f32 O5Y = -20.8f;
120 static const f32 O6Y = -1.0f;
121 
122 
123 static s32 csr_x, csr_y ;   // Value adjustment cursor position
124 static s32 csr_i, csr_k ;   // Position of edited data index and digit
125 static s32 calib_disp_ct ;  // Calibration message display count
126 
127 static f32 dpd_disp_scale = 140.0f ; // DPD object display scale
128 static f32 dpd_disp_ox    = 205.0f ; // DPD object display position
129 static f32 dpd_disp_oy    =  65.0f+O5Y ;
130 
131 static BOOL aim_mode ;
132 static BOOL stick_clamp_mode ;
133 static BOOL stick_clamp_mode_work ;
134 static BOOL reset_request ;
135 
136 static WPADInfo              wpad_info ;
137 static KPADUnifiedWpadStatus unified_status[ KPAD_BUF_SIZE * 2 ] ;
138 
139 s32                 MyDpdCallbackLatestIdx = -1 ;
140 MyDpdCallbackStatus MyDpdCallbackStatusBuf[ MY_DPD_START_COUNTS_MAX ] ;
141 vu32                MySamplingCount ;
142 
143 /*******************************************************************************
144  Initialization Functions
145 *******************************************************************************/
init_sample(void)146 void init_sample( void )
147 {
148     //----- Initial controller settings
149     KPADReset() ;
150     KPADSetPosParam ( 0,  pos_play_radius,  pos_sensitivity ) ;
151     KPADSetHoriParam( 0, hori_play_radius, hori_sensitivity ) ;
152     KPADSetDistParam( 0, dist_play_radius, dist_sensitivity ) ;
153     KPADSetAccParam ( 0,  acc_play_radius,  acc_sensitivity ) ;
154     KPADSetBtnRepeat( 0, repeat_delay_sec, repeat_pulse_sec ) ;
155 
156     //----- Cursor position initialization
157     csr_i = 0 ;  // Data index being edited
158     csr_k = 2 ;  // Digit being edited
159     csr_x = edit_data[ csr_i ].x[ csr_k ] ;
160     csr_y = edit_data[ csr_i ].y ;
161 
162     //----- Calibration message count initialization
163     calib_disp_ct = 0 ; // Negative: display failed, 0: not displayed, positive: successful display
164 
165     aim_mode = TRUE;
166     stick_clamp_mode = stick_clamp_mode_work = FALSE;
167 }
168 
169 
170 /*******************************************************************************
171  Cursor movement process
172 *******************************************************************************/
move_cursor(void)173 static void move_cursor( void )
174 {
175     EditData *ep ;
176     s32  vx,vy, wx,wy, fy ;
177     s32  i,w,k, im,wm,km ;
178 
179     /***********************************************************************
180     Cursor movement process
181     ***********************************************************************/
182     //------ Temporary movement vector
183     if ( CMD_LEFT ) vx = -1 ;
184     else if ( CMD_RIGHT ) vx = 1 ;
185     else vx = 0 ;
186 
187     if ( CMD_UP ) vy = -1 ;
188     else if ( CMD_DOWN ) vy = 1 ;
189     else vy = 0 ;
190 
191     //------ Move to the nearest digit location using edit data
192     wm = 1 << 30 ;  // Maximum distance
193     i = EDIT_DATA_MAX - 1 ;
194     do {
195         ep = &edit_data[i] ;
196 
197         fy = ( wy = ep->y - csr_y ) * vy ; // Preparation for inner product calculation
198         wy *= wy ;    // Preparation for distance calculation
199         k = 0 ;
200         do {
201             //----- Inner product must be positive
202             wx = ep->x[k] - csr_x ;
203             if ( wx * vx + fy <= 0 ) continue ;
204 
205             //----- Distance must be shortest
206             w = wx * wx + wy ;
207             if ( w >= wm ) continue ;
208 
209             //----- Candidate recording
210             wm = w ;
211             im = i ;
212             km = k ;
213         } while ( ++k < 3 ) ;
214     } while ( --i >= 0 ) ;
215 
216     //----- Move cursor if candidate is recorded
217     if ( wm != 1 << 30 ) {
218         csr_i = im ;
219         csr_k = km ;
220         csr_x = edit_data[ csr_i ].x[ csr_k ] ;
221         csr_y = edit_data[ csr_i ].y ;
222     }
223 }
224 
225 
226 /*******************************************************************************
227  Process for increasing/decreasing numerical values
228 *******************************************************************************/
push_cursor(void)229 static void push_cursor( void )
230 {
231     EditData *ep = &edit_data[ csr_i ] ;
232 
233     //----- Was a button pressed?
234     if ( CMD_INC ) {
235         *(ep->vp) += ep->v[ csr_k ] ;
236         if ( *(ep->vp) > ep->max ) *(ep->vp) = ep->max ;
237     } else if ( CMD_DEC ) {
238         *(ep->vp) -= ep->v[ csr_k ] ;
239         if ( *(ep->vp) < ep->min ) *(ep->vp) = ep->min ;
240     } else {
241         return ; // No value change
242     }
243 
244     //----- Reset because value has changed
245     if ( csr_i >= 14 ) {
246         KPADSetBtnRepeat( 0, repeat_delay_sec, repeat_pulse_sec ) ;
247     } else if ( csr_i >=11 ) {
248         KPADSetAccParam    ( 0, acc_play_radius,  acc_sensitivity ) ;
249         KPADSetAccPlayMode ( 0, (KPADPlayMode)acc_play_mode ) ;
250     } else if ( csr_i >= 8 ) {
251         KPADSetDistParam   ( 0, dist_play_radius, dist_sensitivity ) ;
252         KPADSetDistPlayMode( 0, (KPADPlayMode)dist_play_mode ) ;
253     } else if ( csr_i >= 5 ) {
254         KPADSetHoriParam   ( 0, hori_play_radius, hori_sensitivity ) ;
255         KPADSetHoriPlayMode( 0, (KPADPlayMode)hori_play_mode ) ;
256     } else if ( csr_i >= 2 ) {
257         KPADSetPosParam    ( 0, pos_play_radius,  pos_sensitivity ) ;
258         KPADSetPosPlayMode ( 0, (KPADPlayMode)pos_play_mode ) ;
259     } else if ( csr_i == 1 ) {
260         KPADSetObjInterval( obj_interval ) ;
261         reset_request = TRUE;
262     }
263 }
264 
265 
266 /*******************************************************************************
267  CPU process function
268 *******************************************************************************/
work_sample(void)269 void work_sample( void )
270 {
271     if (kpad_reads <= 0) {
272         return;
273     }
274 
275     if (kpads[0][0].hold == 0 && reset_request) {
276         reset_request = FALSE;
277         OSReport("KPADReset() from work_sample()\n");
278         KPADReset();
279         return;
280     }
281 
282     /***********************************************************************
283     Calibration process
284     ***********************************************************************/
285     if ( calib_disp_ct < 0 ) ++ calib_disp_ct ;
286     else if ( calib_disp_ct ) -- calib_disp_ct ;
287 
288     if ( CMD_CALIBRATE ) {
289         if ( KPADCalibrateDPD( 0 ) == 2 ) {
290             calib_disp_ct = 180 ; // Successful
291         } else {
292             calib_disp_ct = -180 ; // Failed
293         }
294     }
295 
296     /***********************************************************************
297     DPD ON/OFF
298     ***********************************************************************/
299     if ( CMD_ENABLE_DPD ) {
300         KPADEnableDPD( 0 );
301     }
302     if ( CMD_DISABLE_DPD ) {
303         KPADDisableDPD( 0 );
304     }
305 
306     /***********************************************************************
307     AIMMODE on/off
308     ***********************************************************************/
309     if ( CMD_AIMMODE ) {
310         aim_mode = (aim_mode) ? FALSE : TRUE;
311         if( aim_mode ) {
312             KPADEnableAimingMode( 0 );
313         }
314         else {
315             KPADDisableAimingMode( 0 );
316         }
317     }
318 
319     /***********************************************************************
320     Stick clamp mode ON/OFF
321     ***********************************************************************/
322     if ( CMD_STICK_CLAMP_TRIG1 || CMD_STICK_CLAMP_TRIG2 ) {
323         stick_clamp_mode_work = (stick_clamp_mode_work) ? FALSE : TRUE;
324     }
325     if ( CMD_STICK_CLAMP_HOLD1 || CMD_STICK_CLAMP_HOLD2 ) {
326         stick_clamp_mode = (stick_clamp_mode_work) ? FALSE : TRUE;
327     } else {
328         stick_clamp_mode = stick_clamp_mode_work;
329     }
330     if ( stick_clamp_mode ) {
331         KPADEnableStickCrossClamp();
332     } else {
333         KPADDisableStickCrossClamp();
334     }
335 
336     /***********************************************************************
337     Value edit process
338     ***********************************************************************/
339     move_cursor() ;  // Cursor movement process
340     push_cursor() ;  // Process for increasing/decreasing numerical values
341 }
342 
343 
344 /*******************************************************************************
345  Rendering pointing scale frame
346 *******************************************************************************/
draw_pointing_frame(void)347 static void draw_pointing_frame( void )
348 {
349     draw_line( -pointing_scale,-pointing_scale, pointing_scale,-pointing_scale, blue_clr, 2.5f ) ;
350     draw_line(  pointing_scale,-pointing_scale, pointing_scale, pointing_scale, blue_clr, 2.5f ) ;
351     draw_line(  pointing_scale, pointing_scale,-pointing_scale, pointing_scale, blue_clr, 2.5f ) ;
352     draw_line( -pointing_scale, pointing_scale,-pointing_scale,-pointing_scale, blue_clr, 2.5f ) ;
353 }
354 
355 
356 /*******************************************************************************
357  Rendering pointing coordinate
358 *******************************************************************************/
draw_position(KPADStatus * sp)359 static void draw_position( KPADStatus *sp )
360 {
361     Vec2  pos, vec ;
362     f32  scale ;
363 
364     if (sp->dpd_valid_fg <= 0) {
365         return;
366     }
367     switch (sp->data_format) {
368       case WPAD_FMT_CORE_ACC_DPD :
369       case WPAD_FMT_FREESTYLE_ACC_DPD :
370       case WPAD_FMT_CLASSIC_ACC_DPD :
371       case WPAD_FMT_GUITAR :
372         break;
373 
374       default:
375         return;
376     }
377 
378     //------ Crosshair
379     pos.x = pointing_scale * sp->pos.x ; // Center coordinate
380     pos.y = pointing_scale * sp->pos.y ;
381 
382     scale = 72.0f ;
383     vec.x = scale * sp->horizon.x ;  // Right direction vector
384     vec.y = scale * sp->horizon.y ;
385     draw_line( pos.x-vec.x,pos.y-vec.y, pos.x+vec.x,pos.y+vec.y, yellow_clr, 3 ) ;
386 
387     scale = 28.0f ;
388     vec.x = scale * -sp->horizon.y ; // Lower direction vector
389     vec.y = scale *  sp->horizon.x ;
390     draw_arrow( pos.x+vec.x,pos.y+vec.y, pos.x-vec.x,pos.y-vec.y, silver_clr, 3 ) ;
391 
392     //------ Center point
393     draw_point( pos.x,pos.y, black_clr, 11 ) ;
394     draw_point( pos.x,pos.y,  cyan_clr,  9 ) ;
395 }
396 
397 
398 /*******************************************************************************
399  Rendering grids
400 *******************************************************************************/
draw_grid(f32 ox,f32 oy,f32 radius,GXColor clr)401 static void draw_grid( f32 ox, f32 oy, f32 radius, GXColor clr )
402 {
403     f32  r = radius * 1.4f ; // Crosshair length
404 
405     draw_arrow( ox-r,oy, ox+r,oy, clr, 3 ) ; // Horizontal line
406     draw_arrow( ox,oy+r, ox,oy-r, clr, 3 ) ; // Vertical line
407     draw_circle( ox,oy, radius, clr, 3 ) ;  // Circle
408 }
409 
410 
411 /*******************************************************************************
412  Rendering acceleration
413 *******************************************************************************/
draw_acc(f32 ox,f32 oy,f32 radius,f32 ax,f32 ay)414 static void draw_acc( f32 ox, f32 oy, f32 radius, f32 ax, f32 ay )
415 {
416     f32  px = ax * radius + ox ;
417     f32  py = ay * radius + oy ;
418 
419     draw_arrow( ox,oy, px,py, red_clr, 4 ) ;
420     draw_point( px,py, white_clr, 4 ) ;
421 }
422 
423 
424 /*******************************************************************************
425  Rendering Nunchuk unit acceleration
426 *******************************************************************************/
draw_acc2(f32 ox,f32 oy,f32 radius,f32 ax,f32 ay)427 static void draw_acc2( f32 ox, f32 oy, f32 radius, f32 ax, f32 ay )
428 {
429     f32  px = ax * radius + ox ;
430     f32  py = ay * radius + oy ;
431 
432     draw_dashed_arrow( ox,oy, px,py, red_clr, 4 ) ;
433     draw_point( px,py, white_clr, 4 ) ;
434 }
435 
436 /*******************************************************************************
437  Analog Stick Rendering
438 *******************************************************************************/
draw_stick(f32 ox,f32 oy,f32 radius,f32 sx,f32 sy,GXColor clr,BOOL dashed)439 static void draw_stick( f32 ox, f32 oy, f32 radius, f32 sx, f32 sy, GXColor clr, BOOL dashed )
440 {
441     f32 px = sx * radius + ox;
442     f32 py = sy * radius + oy;
443 
444     if ( dashed ) {
445         draw_dashed_arrow( ox,oy, px,py, clr, 4 ) ;
446     } else {
447         draw_arrow( ox,oy, px,py, clr, 4 ) ;
448     }
449     draw_point( px,py, white_clr, 4 ) ;
450 }
451 
452 /*******************************************************************************
453  Analog Trigger Rendering
454 *******************************************************************************/
draw_box(f32 ox,f32 oy,f32 width,f32 height,GXColor clr)455 static void draw_box( f32 ox, f32 oy, f32 width, f32 height, GXColor clr )
456 {
457     f32  x1,y1, x2,y2 ;
458 
459     x1 = ox ;
460     x2 = ox - width ;
461     y1 = oy ;
462     y2 = oy - height ;
463 
464     GXSetTevColor( GX_TEVREG0, clr ) ;
465 
466     GXBegin( GX_QUADS, GX_VTXFMT0, 4 ) ;
467       GXPosition2f32( x1, y1 ) ;
468       GXPosition2f32( x2, y1 ) ;
469       GXPosition2f32( x2, y2 ) ;
470       GXPosition2f32( x1, y2 ) ;
471     GXEnd() ;
472 }
473 
474 /*******************************************************************************
475  Rendering value adjustment cursor
476 *******************************************************************************/
draw_cursor(void)477 static void draw_cursor( void )
478 {
479     f32  x1,y1, x2,y2 ;
480 
481     x1 = calc_kfont_x1( csr_x ) ;
482     y1 = calc_kfont_y1( csr_y+O1Y ) ;
483     y2 = calc_kfont_y2( csr_y+O1Y ) - 1.0f ;
484     if ( csr_x > 12 ) {
485         x2 = calc_kfont_x2( csr_x + 4.0f ) - 1.0f ;
486     } else {
487         x2 = calc_kfont_x2( csr_x ) - 1.0f ;
488     }
489     draw_line( x1,y1, x2,y1, white_clr, 2 ) ;
490     draw_line( x2,y1, x2,y2, white_clr, 2 ) ;
491     draw_line( x2,y2, x1,y2, white_clr, 2 ) ;
492     draw_line( x1,y2, x1,y1, white_clr, 2 ) ;
493 }
494 
495 
496 /*******************************************************************************
497  Rendering DPD sensor frame
498 *******************************************************************************/
draw_dpd_frame(void)499 static void draw_dpd_frame( void )
500 {
501     f32  rx,ry, x1,y1, x2,y2 ;
502 
503     rx = dpd_disp_scale * 0.5f ;
504     ry = rx * (f32)WPAD_DPD_IMG_RESO_WY / (f32)WPAD_DPD_IMG_RESO_WX ;
505     x1 = dpd_disp_ox - rx ;
506     y1 = dpd_disp_oy - ry ;
507     x2 = dpd_disp_ox + rx ;
508     y2 = dpd_disp_oy + ry ;
509 
510     GXSetTevColor( GX_TEVREG0, smoke_clr ) ;
511 
512     GXBegin( GX_QUADS, GX_VTXFMT0, 4 ) ;
513       GXPosition2f32( x1, y1 ) ;
514       GXPosition2f32( x2, y1 ) ;
515       GXPosition2f32( x2, y2 ) ;
516       GXPosition2f32( x1, y2 ) ;
517     GXEnd() ;
518 }
519 
520 
521 /*******************************************************************************
522  Rendering DPD object
523 *******************************************************************************/
draw_object(void)524 static void draw_object( void )
525 {
526     DPDObject              *op, *op1 ;
527     f32                     px,py, scale, ofx,ofy ;
528     s32                     n;
529     KPADUnifiedWpadStatus  *up;
530 
531     // Caution: The return value of KPADRead() (number of samples) is not the same as the number of valid samples in unified_status[].
532     //
533     //
534     // Also, KPADGetUnifiedWpadStatus() gets the latest data at this point.
535     // Accordingly, buffer contents are not the same as data retrieved inside KPADRead().
536     //
537     //
538     // In order to get exactly the same data as is obtained inside KPADRead(), call KPADRead() and KPADGetUnifiedWpadStatus() in succession while interrupts are disabled.
539     //
540     //  However, the period during which interrupts are disabled will become longer.
541 
542     // kpad_reads is used as the number of samples without strictly synchronizing data because DPD objects are rendered simply in this sample program.
543     //
544     n = kpad_reads ;   // Current sampling count
545     if (n <= 0) {
546         return;
547     }
548 
549     KPADGetUnifiedWpadStatus( 0, unified_status, (u32)n );
550 
551     //----- Display position calculation
552     scale = dpd_disp_scale / (f32)WPAD_DPD_IMG_RESO_WX ;
553     ofx = dpd_disp_scale * -0.5f ;
554     ofy = ofx * (f32)WPAD_DPD_IMG_RESO_WY / (f32)WPAD_DPD_IMG_RESO_WX ;
555     ofx += dpd_disp_ox ;
556     ofy += dpd_disp_oy ;
557 
558     //----- Display all values sampled at 200Hz
559         // Render starting from older items
560 
561     while ( --n >= 0 ) {
562         up = &unified_status[n];
563         if (up->u.core.err == WPAD_ERR_NONE) {
564             switch (up->fmt) {
565               case WPAD_FMT_CORE_ACC :
566               case WPAD_FMT_CORE_ACC_DPD :
567               case WPAD_FMT_FREESTYLE_ACC :
568               case WPAD_FMT_FREESTYLE_ACC_DPD :
569               case WPAD_FMT_CLASSIC_ACC :
570               case WPAD_FMT_CLASSIC_ACC_DPD :
571               case WPAD_FMT_GUITAR :
572                 op1 = up->u.core.obj ;
573                 break;
574 
575               default:
576                 op1 = NULL;
577                 break;
578             }
579             if (op1) {
580                 op = op1 + (WPAD_DPD_MAX_OBJECTS - 1);
581                 do {
582                     if ( op->size == 0 ) continue ;
583 
584                     //----- Change to display coordinates
585                     px = (f32)op->x * scale + ofx ;
586                     py = (f32)op->y * scale + ofy ;
587 
588                     //----- Render object
589                     draw_point( px,py, white_clr, 5 ) ;
590                     draw_circle( px,py, 5, black_clr, 2 ) ;
591                     draw_circle( px,py, 4, smoke_clr, 2 ) ;
592                     draw_circle( px,py, 3,  gray_clr, 2 ) ;
593                 } while ( --op >= op1 ) ;
594             }
595         }
596     }
597 }
598 /*
599 static void draw_object_by_kpad1_style( void )
600 {
601     WPADStatus   *wp ;
602     WPADFSStatus *fp ;
603     WPADCLStatus *cp ;
604     DPDObject    *op, *op1 ;
605     f32          px,py, scale, ofx,ofy ;
606     s32          n, i ;
607 
608 
609     if ( kpads[0][0].dev_type == WPAD_DEV_NOT_FOUND ) {
610         return;
611     }
612 
613     //----- Calculate the display position
614     scale = dpd_disp_scale / (f32)WPAD_DPD_IMG_RESO_WX ;
615     ofx = dpd_disp_scale * -0.5f ;
616     ofy = ofx * (f32)WPAD_DPD_IMG_RESO_WY / (f32)WPAD_DPD_IMG_RESO_WX ;
617     ofx += dpd_disp_ox ;
618     ofy += dpd_disp_oy ;
619 
620     //----- Display all values sampled at 200Hz
621     switch ( kpads[0][0].dev_type ) {
622       case WPAD_DEV_CORE:
623       case WPAD_DEV_FUTURE:
624       case WPAD_DEV_NOT_SUPPORTED:
625       case WPAD_DEV_UNKNOWN:
626         wp = KPADGetWPADRingBuffer( 0 ) ;   // WPAD ring buffer
627         break;
628       case WPAD_DEV_FREESTYLE:
629         fp = KPADGetWPADFSRingBuffer( 0 ) ; // WPAD ring buffer
630         break;
631       case WPAD_DEV_CLASSIC:
632         cp = KPADGetWPADCLRingBuffer( 0 ) ; // WPAD ring buffer
633         break;
634     }
635     i = (s32)WPADGetLatestIndexInBuf( 0 ) ; // Latest index
636     n = kpad_reads ;                        // Current sampling count
637 
638     i -= n - 1 ;    // Render the oldest items first
639     if ( i < 0 ) i += KPAD_BUF_SIZE ;
640 
641     while ( --n >= 0 ) {
642         switch ( kpads[0][0].dev_type ) {
643           case WPAD_DEV_CORE:
644           case WPAD_DEV_FUTURE:
645           case WPAD_DEV_NOT_SUPPORTED:
646           case WPAD_DEV_UNKNOWN:
647             op = &wp[i].obj[ WPAD_DPD_MAX_OBJECTS - 1 ] ;
648             op1 = wp[i].obj ;
649             break;
650           case WPAD_DEV_FREESTYLE:
651             op = &fp[i].obj[ WPAD_DPD_MAX_OBJECTS - 1 ] ;
652             op1 = fp[i].obj ;
653             break;
654           case WPAD_DEV_CLASSIC:
655             op = &cp[i].obj[ WPAD_DPD_MAX_OBJECTS - 1 ] ;
656             op1 = cp[i].obj ;
657         }
658         do {
659             if ( op->size == 0 ) continue ;
660 
661             //----- Convert to screen coordinates
662             px = (f32)op->x * scale + ofx ;
663             py = (f32)op->y * scale + ofy ;
664 
665             //----- Render objects
666             draw_point( px,py, white_clr, 5 ) ;
667             draw_circle( px,py, 5, black_clr, 2 ) ;
668             draw_circle( px,py, 4, smoke_clr, 2 ) ;
669             draw_circle( px,py, 3,  gray_clr, 2 ) ;
670         } while ( --op >= op1 ) ;
671 
672         if ( ++i == KPAD_BUF_SIZE ) i = 0 ;
673     }
674 }
675 */
draw_sampling_rate(void)676 static void draw_sampling_rate( void )
677 {
678     static OSTime time ;
679     static u32 countDisp ;
680     BOOL enabled ;
681     OSTime t ;
682 
683     t = OSGetTime() ;
684     if ( OSTicksToSeconds((OSTime)(t - time)) > 0 ) {
685         time = t ;
686         enabled = OSDisableInterrupts() ;
687         countDisp = MySamplingCount ;
688         MySamplingCount = 0 ;
689         (void)OSRestoreInterrupts( enabled ) ;
690     }
691 
692     draw_kfont_letter( 0,17+O6Y, gray_clr, "SMP.RATE" ) ;
693     (void)draw_kfont_s32( 14,17+O6Y, white_clr, (s32)countDisp ) ;
694 }
695 
draw_battery_level(void)696 static void draw_battery_level( void )
697 {
698     static OSTime time ;
699     static u8 level ;
700     OSTime t ;
701     int i ;
702     f32 x ;
703     f32 y ;
704 
705     t = OSGetTime() ;
706     if ( OSTicksToSeconds((OSTime)(t - time)) > 0 ) {
707         time = t ;
708         WPADGetInfoAsync( 0, &wpad_info, NULL ) ;
709     }
710 
711     draw_kfont_letter( 20.0f,17+O6Y, gray_clr, "BAT" ) ;
712 
713     x = 40.0f ;
714     y = 96.0f ;
715     init_draw_graphic( rmode_p->fbWidth, rmode_p->efbHeight ) ;
716     for ( i = 0 ; i < 4 ; i++ ) {
717         if ( i < wpad_info.battery ) {
718             draw_box( x + i * 20.0f, y, 15.0f, 15.0f, cyan_clr ) ;
719         } else {
720             draw_box( x + i * 20.0f, y, 15.0f, 15.0f, gray_clr ) ;
721         }
722     }
723 }
724 
draw_dpd_callback_status(void)725 static void draw_dpd_callback_status( void )
726 {
727     u32 i;
728     MyDpdCallbackStatus buf[MY_DPD_START_COUNTS_MAX];
729     BOOL enabled;
730     char str[32];
731     s32  latestIdx;
732 
733     enabled = OSDisableInterrupts();
734     for (i = 0; i < MY_DPD_START_COUNTS_MAX; i++) {
735         if (MyDpdCallbackStatusBuf[i].count) {
736             MyDpdCallbackStatusBuf[i].count--;
737         }
738         buf[i] = MyDpdCallbackStatusBuf[i];
739     }
740     latestIdx = MyDpdCallbackLatestIdx;
741     (void)OSRestoreInterrupts( enabled );
742 
743     for (i = 0; i < MY_DPD_START_COUNTS_MAX; i++) {
744         if ((s32)i == latestIdx ||
745             buf[i].count) {
746             sprintf(str, "DPDCB %d", buf[i].reason);
747             draw_kfont_letter( (f32)(buf[i].reason == KPAD_STATE_CTRL_DPD_START
748                                      ? 0.0f
749                                      : 8.0f),
750                                buf[i].count * 0.05f + 0.5f, white_clr, str );
751         }
752     }
753 }
754 
755 
756 /*******************************************************************************
757  Drawing function
758 *******************************************************************************/
draw_sample(void)759 void draw_sample( void )
760 {
761     s32     cx,cy ;
762     f32     x1,x2, y, r ;
763     u32     hold, trig, release ;
764     u32     flag ;
765     GXColor clr ;
766 
767     /***********************************************************************
768         Pointing scale frame
769     ***********************************************************************/
770     init_draw_graphic( rmode_p->fbWidth, rmode_p->efbHeight ) ;
771     draw_pointing_frame() ;
772 
773     /***********************************************************************
774         Adjustment item
775     ***********************************************************************/
776     init_draw_kfont( rmode_p->fbWidth, rmode_p->efbHeight, 15.6f, 20.8f ) ;
777     cx = 0 ;
778     cy = 3 ;
779     draw_kfont_letter( cx,cy+O1Y, gray_clr, "POINTING") ;
780     (void)draw_kfont_s32( cx+12,cy+O1Y, blue_clr, (s32)pointing_scale ) ;
781     cy += 2 ;
782     draw_kfont_letter( cx,cy+O1Y, gray_clr, "INTERVAL") ;
783     (void)draw_kfont_f32( cx+9,cy+O1Y, peagreen_clr, obj_interval, 2 ) ;
784     cy += 2 ;
785     draw_kfont_letter( cx,cy+O1Y, gray_clr, "    PLAY SENS MODE") ;
786     ++ cy ;
787     draw_kfont_letter( cx,cy+O1Y, gray_clr, "POS" ) ;
788     (void)draw_kfont_f32   ( cx+ 4,cy+O1Y,   cyan_clr,  pos_play_radius, 2 ) ;
789     (void)draw_kfont_f32   ( cx+ 9,cy+O1Y,   cyan_clr,  pos_sensitivity, 2 ) ;
790     (void)draw_kfont_letter( cx+14,cy+O1Y,   cyan_clr, (pos_play_mode) ? "TIGHT" : "LOOSE" ) ;
791     ++ cy ;
792     draw_kfont_letter( cx,cy+O1Y, gray_clr, "HOR" ) ;
793     (void)draw_kfont_f32   ( cx+ 4,cy+O1Y, yellow_clr, hori_play_radius, 2 ) ;
794     (void)draw_kfont_f32   ( cx+ 9,cy+O1Y, yellow_clr, hori_sensitivity, 2 ) ;
795     (void)draw_kfont_letter( cx+14,cy+O1Y, yellow_clr,(hori_play_mode) ? "TIGHT" : "LOOSE" ) ;
796     ++ cy ;
797     draw_kfont_letter( cx,cy+O1Y, gray_clr, "DIS" ) ;
798     (void)draw_kfont_f32   ( cx+ 4,cy+O1Y,  green_clr, dist_play_radius, 2 ) ;
799     (void)draw_kfont_f32   ( cx+ 9,cy+O1Y,  green_clr, dist_sensitivity, 2 ) ;
800     (void)draw_kfont_letter( cx+14,cy+O1Y,  green_clr,(dist_play_mode) ? "TIGHT" : "LOOSE" ) ;
801     ++ cy ;
802     draw_kfont_letter( cx,cy+O1Y, gray_clr, "ACC" ) ;
803     (void)draw_kfont_f32   ( cx+ 4,cy+O1Y,    red_clr,  acc_play_radius, 2 ) ;
804     (void)draw_kfont_f32   ( cx+ 9,cy+O1Y,    red_clr,  acc_sensitivity, 2 ) ;
805     (void)draw_kfont_letter( cx+14,cy+O1Y,    red_clr, (acc_play_mode) ? "TIGHT" : "LOOSE" ) ;
806     cy += 2 ;
807     draw_kfont_letter( cx,cy+O1Y, gray_clr, "    DLAY PULS") ;
808     ++ cy ;
809     draw_kfont_letter( cx,cy+O1Y, gray_clr, "RPT") ;
810     (void)draw_kfont_f32( cx+4,cy+O1Y, orange_clr, repeat_delay_sec, 2 ) ;
811     (void)draw_kfont_f32( cx+9,cy+O1Y, orange_clr, repeat_pulse_sec, 2 ) ;
812 
813     //----- Various data title
814     draw_kfont_letter( 27.0f, 2.5f+O6Y, gray_clr, "ACC" ) ; // Acceleration information
815     draw_kfont_letter( 27.0f, 3.5f+O6Y, gray_clr, "STICK") ; // Control Stick information
816     draw_kfont_letter( 15.2f,12.5f+O6Y, gray_clr, "VALID") ; // DPD enable flag
817     draw_kfont_letter( 23.0f,12.5f+O6Y, gray_clr, "DIST" ) ; // Distance information
818     draw_kfont_letter( 33.8f,10.1f+O6Y, gray_clr, "OBJ"  ) ; // Object
819 
820     /***********************************************************************
821         Value adjustment cursor
822     ***********************************************************************/
823     init_draw_graphic( rmode_p->fbWidth, rmode_p->efbHeight ) ;
824     draw_cursor() ;
825 
826     /***********************************************************************
827         DPD enable flag & distance information
828     ***********************************************************************/
829     init_draw_kfont( rmode_p->fbWidth, rmode_p->efbHeight, 28.5f, 38.0f ) ;
830     (void)draw_kfont_s32(  9.0f,7.5f+O2Y, violet_clr, kpads[0][0].dpd_valid_fg ) ;
831     (void)draw_kfont_f32( 11.5f,7.5f+O2Y,  green_clr, kpads[0][0].dist, 2 ) ;
832 
833     /***********************************************************************
834         Battery level
835     ***********************************************************************/
836     init_draw_kfont( rmode_p->fbWidth, rmode_p->efbHeight, 14.0f, 18.8f ) ;
837     draw_battery_level() ;
838 
839     /***********************************************************************
840         Sampling rate
841     ***********************************************************************/
842     init_draw_kfont( rmode_p->fbWidth, rmode_p->efbHeight, 14.0f, 18.8f ) ;
843     draw_sampling_rate() ;
844 
845     /***********************************************************************
846         Button bit information
847     ***********************************************************************/
848     init_draw_kfont( rmode_p->fbWidth, rmode_p->efbHeight, 14.0f, 18.8f ) ;
849     cx =  0 ;
850     cy =  18 ;
851 
852     hold    = kpads[0][0].hold;
853     trig    = kpads[0][0].trig;
854     release = kpads[0][0].release;
855 
856     draw_kfont_letter( cx,cy+O6Y, gray_clr, "HLD") ;
857     if (kpad_reads > 0) {
858         draw_kfont_bit( cx+39,cy+O6Y, orange_clr, hold   , 32 ) ;
859     }
860     ++ cy ;
861     draw_kfont_letter( cx,cy+O6Y, gray_clr, "TRG") ;
862     if (kpad_reads > 0) {
863         draw_kfont_bit( cx+39,cy+O6Y, orange_clr, trig   , 32 ) ;
864     }
865     ++ cy ;
866     draw_kfont_letter( cx,cy+O6Y, gray_clr, "REL") ;
867     if (kpad_reads > 0) {
868         draw_kfont_bit( cx+39,cy+O6Y, orange_clr, release, 32 ) ;
869     }
870 
871     if (kpad_reads > 0) {
872         if ( kpads[0][0].wpad_err == WPAD_ERR_NONE
873         &&   ( kpads[0][0].dev_type == WPAD_DEV_CLASSIC
874             || kpads[0][0].dev_type == WPAD_DEV_GUITAR
875             || kpads[0][0].dev_type == WPAD_DEV_TRAIN ) ) {
876             hold    = kpads[0][0].ex_status.cl.hold;
877             trig    = kpads[0][0].ex_status.cl.trig;
878             release = kpads[0][0].ex_status.cl.release;
879 
880             switch( kpads[0][0].dev_type ) {
881               case WPAD_DEV_CLASSIC : clr = peagreen_clr ;  break ;
882               case WPAD_DEV_GUITAR :  clr =     cyan_clr ;  break ;
883               case WPAD_DEV_TRAIN :   clr =   yellow_clr ;  break ;
884             }
885 
886             ++ cy ;
887             draw_kfont_letter( cx,cy+O6Y, gray_clr, "HLD") ;
888             draw_kfont_bit( cx+39,cy+O6Y, clr, hold   , 32 ) ;
889             ++ cy ;
890             draw_kfont_letter( cx,cy+O6Y, gray_clr, "TRG") ;
891             draw_kfont_bit( cx+39,cy+O6Y, clr, trig   , 32 ) ;
892             ++ cy ;
893             draw_kfont_letter( cx,cy+O6Y, gray_clr, "REL") ;
894             draw_kfont_bit( cx+39,cy+O6Y, clr, release, 32 ) ;
895         }
896     } else {
897         switch ( kpad_err ) {
898           case KPAD_READ_ERR_INIT :
899           case KPAD_READ_ERR_SETUP :
900             cy -= 2 ;
901             draw_kfont_letter( cx+8,cy+O6Y, white_clr, "WPAD OR KPAD IS NOT INITIALIZED.") ;
902             cy += 2 ;
903             // break through
904           case KPAD_READ_ERR_NO_CONTROLLER :
905             cy -= 1;
906             draw_kfont_letter( cx+8,cy+O6Y, white_clr, "  OTHER TESTS BY GC CONT. 1P") ;
907             ++ cy ;
908             draw_kfont_letter( cx+8,cy+O6Y, white_clr, "   A BUTTON - KPADRESET") ;
909             ++ cy ;
910             draw_kfont_letter( cx+8,cy+O6Y, white_clr, "   B BUTTON - SKIP KPADREAD") ;
911             ++ cy ;
912             draw_kfont_letter( cx+8,cy+O6Y, white_clr, "   X BUTTON - CHANGE REVISE MODE") ;
913             ++ cy ;
914             draw_kfont_letter( cx+8,cy+O6Y, white_clr, "   Y BUTTON - KPADINIT/KPADSHUTDOWN") ;
915             ++ cy ;
916             draw_kfont_letter( cx+8,cy+O6Y, white_clr, "   Z BUTTON - CHANGE BUTTON PROC MODE") ;
917             break ;
918         }
919     }
920 
921     /***********************************************************************
922         Acceleration information
923     ***********************************************************************/
924     init_draw_kfont( rmode_p->fbWidth, rmode_p->efbHeight, 15.0f, 20.0f ) ;
925     draw_kfont_letter( 25.0f,2.5f+O3Y, smoke_clr, "Y            Y") ;
926     draw_kfont_letter( 29.0f,6.5f+O3Y, smoke_clr, "X            Z") ;
927 
928     x1 =   35.0f ;      // x-coordinate of left grid
929     x2 =  210.0f ;      // x-coordinate of right grid
930     y  = -100.0f+O4Y ;  // Common y-coordinate
931     r  =   60.0f ;      // Common radius
932 
933     init_draw_graphic( rmode_p->fbWidth, rmode_p->efbHeight ) ;
934     draw_grid( x1, y, r, smoke_clr ) ;
935     draw_grid( x2, y, r, smoke_clr ) ;
936 
937     cx = kpad_reads ;
938     while ( --cx >= 0 ) {
939         if (kpads[0][cx].wpad_err == WPAD_ERR_NONE) {
940             switch (kpads[0][cx].data_format) {
941               case WPAD_FMT_CORE_ACC :
942               case WPAD_FMT_CORE_ACC_DPD :
943               case WPAD_FMT_CLASSIC_ACC :
944               case WPAD_FMT_CLASSIC_ACC_DPD :
945               case WPAD_FMT_GUITAR :
946                 flag = 0x01 ;
947                 break ;
948 
949               case WPAD_FMT_FREESTYLE_ACC :
950               case WPAD_FMT_FREESTYLE_ACC_DPD :
951                 flag = 0x03 ;
952                 break ;
953 
954               default :
955                 flag = 0x00 ;
956                 break ;
957             }
958 
959             if (flag & 0x01) {
960                 draw_acc( x1, y, r, kpads[0][cx].acc.x, -kpads[0][cx].acc.y ) ;
961                 draw_acc( x2, y, r, kpads[0][cx].acc.z, -kpads[0][cx].acc.y ) ;
962             }
963             if (flag & 0x02) {
964                 draw_acc2( x1, y, r, kpads[0][cx].ex_status.fs.acc.x, -kpads[0][cx].ex_status.fs.acc.y ) ;
965                 draw_acc2( x2, y, r, kpads[0][cx].ex_status.fs.acc.z, -kpads[0][cx].ex_status.fs.acc.y ) ;
966             }
967         }
968     }
969 
970     /***********************************************************************
971         Control Stick information
972     ***********************************************************************/
973     init_draw_graphic( rmode_p->fbWidth, rmode_p->efbHeight ) ;
974     cx = kpad_reads ;
975     while ( --cx >= 0 ) {
976         if ( kpads[0][cx].wpad_err == WPAD_ERR_NONE ) {
977             if( kpads[0][cx].dev_type == WPAD_DEV_FREESTYLE ) {
978                 draw_stick( x1, y, r, kpads[0][cx].ex_status.fs.stick.x, -kpads[0][cx].ex_status.fs.stick.y, yellow_clr, TRUE ) ;
979             } else if ( kpads[0][cx].dev_type == WPAD_DEV_CLASSIC
980                      || kpads[0][cx].dev_type == WPAD_DEV_GUITAR
981                      || kpads[0][cx].dev_type == WPAD_DEV_TRAIN ) {
982 
983                 switch ( kpads[0][cx].dev_type ) {
984                   case WPAD_DEV_CLASSIC :  clr =  green_clr ;  break ;
985                   case WPAD_DEV_GUITAR :   clr =   blue_clr ;  break ;
986                   case WPAD_DEV_TRAIN :    clr =   cyan_clr ;  break ;
987                 }
988                 draw_stick( x1, y, r, kpads[0][cx].ex_status.cl.lstick.x, -kpads[0][cx].ex_status.cl.lstick.y, clr, FALSE ) ;
989                 draw_stick( x2, y, r, kpads[0][cx].ex_status.cl.rstick.x, -kpads[0][cx].ex_status.cl.rstick.y, clr, FALSE ) ;
990             }
991         }
992     }
993 
994     /***********************************************************************
995         Trigger information
996     ***********************************************************************/
997     x1 = 245.0f ;
998     x2 = 275.0f ;
999     y  = 215.0f ;
1000 
1001     cx = kpad_reads ;
1002     while ( --cx >= 0 ) {
1003         if ( kpads[0][cx].dev_type == WPAD_DEV_CLASSIC
1004             || kpads[0][cx].dev_type == WPAD_DEV_GUITAR
1005             || kpads[0][cx].dev_type == WPAD_DEV_TRAIN ) {
1006 
1007             init_draw_graphic( rmode_p->fbWidth, rmode_p->efbHeight ) ;
1008 
1009             draw_box( x1, y, 20.0f, 55.0f, smoke_clr ) ;
1010             draw_box( x2, y, 20.0f, 55.0f, smoke_clr ) ;
1011 
1012             if ( kpads[0][cx].wpad_err == WPAD_ERR_NONE ) {
1013                 draw_box( x1, y, 20.0f, 55.0f * kpads[0][cx].ex_status.cl.ltrigger, yellow_clr ) ;
1014                 draw_box( x2, y, 20.0f, 55.0f * kpads[0][cx].ex_status.cl.rtrigger, yellow_clr ) ;
1015             }
1016 
1017             init_draw_kfont( rmode_p->fbWidth, rmode_p->efbHeight, 15.6f, 20.8f ) ;
1018             draw_kfont_letter( 36.2f,17.8f+O6Y, gray_clr, "TRIG"  ) ; // Trigger
1019         }
1020     }
1021 
1022     /***********************************************************************
1023         DPD object display
1024     ***********************************************************************/
1025     init_draw_graphic( rmode_p->fbWidth, rmode_p->efbHeight ) ;
1026     draw_dpd_frame() ;
1027     draw_object() ;
1028 //  draw_object_by_kpad1_style() ;
1029 
1030     /***********************************************************************
1031         Pointing cursor
1032     ***********************************************************************/
1033     init_draw_graphic( rmode_p->fbWidth, rmode_p->efbHeight ) ;
1034     cx = kpad_reads ;
1035     while ( --cx >= 0 ) {
1036         draw_position( &kpads[0][cx] ) ;
1037     }
1038 
1039     /***********************************************************************
1040         Calibration message
1041     ***********************************************************************/
1042     init_draw_kfont( rmode_p->fbWidth, rmode_p->efbHeight, 60.0f, 80.0f ) ;
1043     if ( calib_disp_ct < 0 ) {
1044         draw_kfont_letter( 0.5f,1.4f, magenta_clr, "  ERROR  ") ; // Fail message
1045     } else if ( calib_disp_ct ) {
1046         draw_kfont_letter( 0.5f,1.4f, magenta_clr, "CALIBRATE") ; // Success message
1047     }
1048 
1049     /***********************************************************************
1050         KPAD DPD callback
1051     ***********************************************************************/
1052     init_draw_kfont( rmode_p->fbWidth, rmode_p->efbHeight, 15.0f, 20.0f ) ;
1053     draw_dpd_callback_status() ;
1054 
1055     /***********************************************************************
1056         Display for clamp processing and sensor bar position correction
1057     ***********************************************************************/
1058     init_draw_kfont( rmode_p->fbWidth, rmode_p->efbHeight, 15.0f, 20.0f ) ;
1059     draw_kfont_letter( 20.0f,0.5f, white_clr, aim_mode ? "AIM ON" : "AIM OFF");
1060     draw_kfont_letter( 30.0f,0.5f, white_clr, stick_clamp_mode ? "CROSS CLAMP" : "CIRCLE CLAMP");
1061 }
1062 
1063