1 /*---------------------------------------------------------------------------*
2 Project: WPAD demo program
3 File: distance.c
4 Programmer: HIRATSU Daisuke
5
6 Copyright (C) 2005-2006 Nintendo. All rights reserved.
7
8 These coded instructions, statements, and computer programs contain
9 proprietary information of Nintendo of America Inc. and/or Nintendo
10 Company Ltd., and are protected by Federal copyright law. They may
11 not be disclosed to third parties or copied or duplicated in any form,
12 in whole or in part, without the prior written consent of Nintendo.
13 *---------------------------------------------------------------------------*/
14
15 #include <stdlib.h>
16 #include <string.h>
17 #include <stddef.h>
18 #include <stdarg.h>
19 #include <stdio.h>
20 #include <ctype.h>
21 #include <math.h>
22
23 #include <revolution.h>
24 #include <revolution/wpad.h>
25
26 #define DEMO_USE_MEMLIB=1 // This turns on the DEMO library's MEM heaps.
27 #include <demo.h>
28
29 /*---------------------------------------------------------------------------*
30 * Local definitions
31 *---------------------------------------------------------------------------*/
32
33 #define SCREEN_WIDTH 320
34 #define SCREEN_HEIGHT 240
35 #define SEPARATION 0.20f // Meter unit. You must modify this value according to your environment.
36
37 /*---------------------------------------------------------------------------*
38 * Function prototypes
39 *---------------------------------------------------------------------------*/
40
41 // MEM2 memory allocation routines. The application must provide these to
42 // WPAD, so it can setup the data transfer buffer. This buffer must reside
43 // in MEM2.
44 static void *myAlloc (u32 size);
45 static u8 myFree (void *ptr);
46
47
48 static void initialize (void);
49 static void renderStatus (const WPADStatus *stat);
50 static void renderDistance (const WPADStatus *stat);
51 static f32 getDistance (const WPADStatus *stat);
52
53 /*===========================================================================*
54 * F U N C T I O N D E F I N I T I O N S
55 *===========================================================================*/
56
57 /*---------------------------------------------------------------------------*
58 * Name : main()
59 * Description :
60 * Arguments : None.
61 * Returns : None.
62 *---------------------------------------------------------------------------*/
main(void)63 int main(void)
64 {
65
66 WPADStatus wpad;
67
68 s32 wpad_state;
69 s32 status;
70 u32 type;
71
72 initialize();
73
74 // we should clear the WPADStatus block returned by
75 // WPADRead(), because if no channel is connected, nothing
76 // is copied. So we would be staring at garbage data.
77 memset( (void *)(&wpad), 0, sizeof(WPADStatus));
78
79 // must register MEM2 allocation functions before invoking WPADInit()
80 WPADRegisterAllocator(myAlloc, myFree);
81 WPADInit();
82
83
84 // The WPAD initialization process is asynchronous.
85 // So we should wait until it's completed.
86 do
87 {
88
89 wpad_state = WPADGetStatus();
90
91 } while (WPAD_STATE_SETUP != wpad_state);
92
93
94 // Main loop
95 while(1)
96 {
97
98 status = WPADProbe(WPAD_CHAN0, &type);
99 WPADRead(WPAD_CHAN0, &wpad);
100
101 if (WPAD_ERR_NONE == status)
102 {
103
104 // Note: If the controller has disconnected and re-connected,
105 // we need to reset and re-enable the DPD and accelerometers.
106 // But we have to ensure that the device type is correct, because
107 // it's possible a different type of device has connected on channel 0.
108 if ((WPAD_DEV_CORE == type) || (WPAD_DEV_FREESTYLE == type))
109 {
110
111 // Are the DPD and Accelerometers enabled?
112 if (FALSE == WPADIsDpdEnabled(WPAD_CHAN0))
113 {
114 // if not, then set the format and turn on DPD and accelerometer
115 WPADSetDataFormat(WPAD_CHAN0, WPAD_FMT_CORE_ACC_DPD); // should be called before WPADControlDPD()
116 WPADControlDpd(WPAD_CHAN0, WPAD_DPD_EXP, NULL);
117 }
118
119 } // if device type is correct
120
121 } // if no error...
122
123
124 DEMOBeforeRender();
125 renderStatus( &wpad );
126 renderDistance( &wpad );
127 DEMODoneRender();
128
129 } // while
130
131 return 0;
132
133 } // end
134
135 /*---------------------------------------------------------------------------*
136 * Name : initialize
137 * Description :
138 * Arguments : None.
139 * Returns : None.
140 *---------------------------------------------------------------------------*/
initialize(void)141 static void initialize( void )
142 {
143
144 const GXColor DARKBLUE = { 0, 0, 40, 255 };
145
146 OSInit();
147
148 DEMOInit( &GXNtsc480IntDf );
149 GXSetCopyClear( DARKBLUE, GX_MAX_Z24 );
150 GXCopyDisp( DEMOGetCurrentBuffer(), GX_TRUE );
151 DEMOInitCaption( DM_FT_XLU, SCREEN_WIDTH, SCREEN_HEIGHT );
152 GXSetZMode( GX_ENABLE, GX_ALWAYS, GX_ENABLE ); // Set pixel processing mode
153 GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR ); // Translucent mode
154
155 } // end
156
157
158 /*---------------------------------------------------------------------------*
159 * Name : renderStatus
160 * Description :
161 * Arguments : None.
162 * Returns : None.
163 *---------------------------------------------------------------------------*/
renderStatus(const WPADStatus * stat)164 static void renderStatus(const WPADStatus *stat)
165 {
166
167 const int FONT_HEIGHT = 8;
168 s16 x = FONT_HEIGHT;
169 s16 y = FONT_HEIGHT;
170 int i = 0;
171
172 y+=FONT_HEIGHT;
173 DEMOPrintf( x, y+=FONT_HEIGHT, 0, "DPD-ID X Y SIZE");
174
175 for( i=0; i<WPAD_DPD_MAX_OBJECTS; ++i )
176 {
177 const DPDObject *p = &( stat->obj[i] );
178 DEMOPrintf( x, y+=FONT_HEIGHT, 0, "%1d %4d %4d %3d", p->traceId, p->x, p->y, p->size );
179
180 }
181
182 y+=FONT_HEIGHT;
183 y+=FONT_HEIGHT;
184 DEMOPrintf( x, y+=FONT_HEIGHT, 0, "Controller Type: %d", stat->dev );
185 DEMOPrintf( x, y+=FONT_HEIGHT, 0, "ERROR Info : %d", stat->err );
186
187 if (WPAD_ERR_NO_CONTROLLER == stat->err)
188 {
189 y+=FONT_HEIGHT;
190 y+=FONT_HEIGHT;
191 y+=FONT_HEIGHT;
192 y+=FONT_HEIGHT;
193 y+=FONT_HEIGHT;
194 y+=FONT_HEIGHT;
195 DEMOPrintf(x, y+=FONT_HEIGHT, 0, ">> No controller is connected!");
196 DEMOPrintf(x, y+=FONT_HEIGHT, 0, ">> Please press a button on a paired");
197 DEMOPrintf(x, y+=FONT_HEIGHT, 0, ">> controller to connect.");
198 }
199
200 } // end
201
202 /*---------------------------------------------------------------------------*
203 * Name : renderDistance
204 * Description :
205 * Arguments : None.
206 * Returns : None.
207 *---------------------------------------------------------------------------*/
renderDistance(const WPADStatus * stat)208 static void renderDistance(const WPADStatus *stat)
209 {
210 char buf[256];
211 f32 dist;
212
213 dist = getDistance(stat);
214
215 if(dist > 0.0f)
216 {
217 sprintf(buf, "Distance: %.02f m", dist);
218 }
219 else
220 {
221 sprintf(buf, "Distance: Unknown");
222 }
223 DEMOPrintf(100, 120, 0, buf);
224
225 } // end
226
227 /*---------------------------------------------------------------------------*
228 * Name : getDistance
229 * Description :
230 * Arguments : None.
231 * Returns : None.
232 *---------------------------------------------------------------------------*/
getDistance(const WPADStatus * stat)233 static f32 getDistance(const WPADStatus *stat)
234 {
235
236 const f32 PI=3.141592f;
237 const f32 TH=WPAD_DPD_ANGLE/2*PI/180;
238 f32 xDiff;
239 f32 yDiff;
240 f32 dpdDist;
241
242 xDiff = stat->obj[0].x - stat->obj[1].x;
243 yDiff = stat->obj[0].y - stat->obj[1].y;
244 dpdDist = (f32)sqrt(xDiff*xDiff+yDiff*yDiff);
245
246 if ((stat->obj[0].size > 0) && (stat->obj[1].size > 0))
247 {
248 return (f32)(SEPARATION/2/tan(TH)*WPAD_DPD_IMG_RESO_WX/dpdDist);
249 }
250 else
251 {
252 return -1.0f;
253 }
254
255 } // end
256
257
258 /*---------------------------------------------------------------------------*
259 * Name : myAlloc()
260 * Description : Callback needed by WPAD to allocate mem from MEM2 heap
261 * Arguments : size of block, in bytes.
262 * Returns : pointer to allocated block.
263 *---------------------------------------------------------------------------*/
myAlloc(u32 size)264 static void *myAlloc(u32 size)
265 {
266 void *ptr;
267
268 ptr = MEMAllocFromAllocator(&DemoAllocator2, size);
269 ASSERTMSG(ptr, "Memory allocation failed\n");
270
271 return(ptr);
272
273 } // myAlloc()
274
275 /*---------------------------------------------------------------------------*
276 * Name : myFree()
277 * Description : Callback needed by WPAD to free mem from MEM2 heap
278 * Arguments : None.
279 * Returns : Always 1.
280 *---------------------------------------------------------------------------*/
myFree(void * ptr)281 static u8 myFree(void *ptr)
282 {
283
284 MEMFreeToAllocator(&DemoAllocator2, ptr);
285
286 // we should ensure that memory is free'd properly, but oh well
287 return(1);
288
289 } // myFree()
290
291