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