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