1 /*---------------------------------------------------------------------------*
2 Project: WPAD demo program
3 File: simple.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 $Log: simple.c,v $
15 Revision 1.19 08/11/2006 09:33:13 tojo
16 (none)
17
18 Revision 1.18 08/03/2006 13:33:02 tojo
19 Removed old APIs.
20
21 Revision 1.17 07/20/2006 06:40:35 tojo
22 (none)
23
24 Revision 1.16 06/16/2006 14:10:56 ekwon
25 Ensured that WPADProbe() is used to check channel status and to update device type.
26
27 Revision 1.15 06/13/2006 04:54:59 tojo
28 (none)
29
30 Revision 1.14 06/13/2006 01:57:26 ekwon
31 Minor cleanup.
32
33 Revision 1.13 06/12/2006 12:03:28 ekwon
34 Fixes for querying DPD status before enabling DPD.
35
36 Revision 1.12 06/12/2006 08:22:11 ekwon
37 Added some comments.
38
39 Revision 1.11 06/12/2006 07:18:02 ekwon
40 Initial check-in for WPAD SIMPLE demo. Revised to support new WPAD driver.
41
42 Revision 1.1 06/01/2006 00:40:11 hiratsu
43 Moved from $(SDK)/build/demos/wpaddemo
44
45 Revision 1.9 2006/03/13 12:18:57 yasuh-to
46 Added comment for how to use demo.
47
48 Revision 1.8 2006/03/13 02:10:46 yasuh-to
49 Modified copyright.
50
51 *---------------------------------------------------------------------------*/
52
53 #include <stdlib.h>
54 #include <string.h>
55 #include <stddef.h>
56 #include <stdarg.h>
57 #include <stdio.h>
58 #include <ctype.h>
59
60 #include <revolution.h>
61 #include <revolution/wpad.h>
62
63 #define DEMO_USE_MEMLIB=1 // This turns on the DEMO library's MEM heaps.
64 #include <demo.h>
65
66
67
68 #define SCREEN_WIDTH 320
69 #define SCREEN_HEIGHT 240
70
71
72
73 // MEM2 memory allocation routines. The application must provide these to
74 // WPAD, so it can setup the data transfer buffer. This buffer must reside
75 // in MEM2.
76 static void *myAlloc (u32 size);
77 static u8 myFree (void *ptr);
78
79 static void initialize ( void );
80 static void renderLuminousSources ( WPADStatus *stat );
81 static void renderStatus ( WPADStatus *stat );
82
83
84 /*===========================================================================*
85 * F U N C T I O N D E F I N I T I O N S
86 *===========================================================================*/
87
88
89 /*---------------------------------------------------------------------------*
90 * Name : main()
91 * Description :
92 * Arguments : None.
93 * Returns : None.
94 *---------------------------------------------------------------------------*/
main(void)95 int main( void )
96 {
97 WPADStatus wpad;
98
99 s32 wpad_state;
100
101 s32 status;
102 u32 type;
103
104 initialize();
105
106 // we should clear the WPADStatus block returned by
107 // WPADRead(), because if no channel is connected, nothing
108 // is copied. So we would be staring at garbage data.
109 memset( (void *)(&wpad), 0, sizeof(WPADStatus));
110
111 // - We must now register memory allocation/free functions
112 // for MEM2.
113 // - WPAD requires some memory in MEM2 for data transfers
114 // between the controller and WPAD driver stack.
115 // - Memory allocation only occurs once, at the initialization.
116 // - Memory usage is on the order of 1KB.
117 // - NOTE: We are using the MEM library allocators defined by
118 // the DEMO library.
119 //
120 WPADRegisterAllocator(myAlloc, myFree);
121
122
123 // Initialize WPAD!
124 WPADInit();
125
126
127 // The WPAD initialization process is asynchronous.
128 // So we should wait until it's completed.
129 do
130 {
131 wpad_state = WPADGetStatus();
132
133 } while (WPAD_STATE_SETUP != wpad_state);
134
135
136 // Main loop
137 while(1)
138 {
139
140
141 // We should probe the channel first
142 status = WPADProbe(WPAD_CHAN0, &type);
143
144 // is a controller connected?
145 if(WPAD_ERR_NONE == status)
146 {
147
148 // Read data/status from channel 0.
149 WPADRead( WPAD_CHAN0, &wpad );
150
151
152 // Note: If the controller has disconnected and re-connected,
153 // we need to reset and re-enable the DPD and accelerometers.
154 // But we have to ensure that the device type is correct, because
155 // it's possible a different type of device has connected on channel 0.
156 if ((WPAD_DEV_CORE == type) || (WPAD_DEV_FREESTYLE == type))
157 {
158
159 // Are the DPD and Accelerometers enabled?
160 if (FALSE == WPADIsDpdEnabled(WPAD_CHAN0))
161 {
162 // if not, then set the format and turn on DPD and accelerometer
163 WPADControlDpd(WPAD_CHAN0, WPAD_DPD_EXP, NULL);
164 WPADSetDataFormat(WPAD_CHAN0, WPAD_FMT_CORE_ACC_DPD);
165 }
166
167 if( wpad.button & WPAD_BUTTON_A )
168 {
169 WPADStartMotor( WPAD_CHAN0 );
170 }
171 if( wpad.button & WPAD_BUTTON_B )
172 {
173 WPADStopMotor( WPAD_CHAN0 );
174 }
175
176 } // if device type is correct...
177
178 } // if no error...
179
180
181 DEMOBeforeRender();
182 renderLuminousSources( &wpad );
183 renderStatus( &wpad );
184
185 DEMOPrintf( 16, 184, 0, "press A: Start Motor\n");
186 DEMOPrintf( 16, 200, 0, "press B: Stop Motor\n");
187
188 DEMODoneRender();
189
190 } // while
191
192 return 0;
193
194 } // end main
195
196 /*---------------------------------------------------------------------------*
197 * Name : myAlloc()
198 * Description : Callback needed by WPAD to allocate mem from MEM2 heap
199 * Arguments : size of block, in bytes.
200 * Returns : pointer to allocated block.
201 *---------------------------------------------------------------------------*/
myAlloc(u32 size)202 static void *myAlloc(u32 size)
203 {
204 void *ptr;
205
206 ptr = MEMAllocFromAllocator(&DemoAllocator2, size);
207 ASSERTMSG(ptr, "Memory allocation failed\n");
208
209 return(ptr);
210
211 } // myAlloc()
212
213 /*---------------------------------------------------------------------------*
214 * Name : myFree()
215 * Description : Callback needed by WPAD to free mem from MEM2 heap
216 * Arguments : None.
217 * Returns : Always 1.
218 *---------------------------------------------------------------------------*/
myFree(void * ptr)219 static u8 myFree(void *ptr)
220 {
221
222 MEMFreeToAllocator(&DemoAllocator2, ptr);
223
224 // we should ensure that memory is free'd properly, but oh well
225 return(1);
226
227 } // myFree()
228
229 /*---------------------------------------------------------------------------*
230 * Name : initialize()
231 * Description : Performs basic system initialization.
232 * Arguments : None.
233 * Returns : None.
234 *---------------------------------------------------------------------------*/
235
initialize(void)236 static void initialize( void )
237 {
238 const GXColor DARKBLUE = { 0, 0, 40, 255 };
239
240 OSInit();
241
242 DEMOInit( &GXNtsc480IntDf );
243
244 GXSetCopyClear( DARKBLUE, GX_MAX_Z24 );
245 GXCopyDisp( DEMOGetCurrentBuffer(), GX_TRUE );
246 DEMOInitCaption( DM_FT_XLU, SCREEN_WIDTH, SCREEN_HEIGHT );
247 GXSetZMode( GX_ENABLE, GX_ALWAYS, GX_ENABLE ); // Set pixel processing mode
248 GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR ); // Translucent mode
249
250 } // end
251
252 /*---------------------------------------------------------------------------*
253 * Name : renderLuminousSources()
254 * Description : Draws sources as "seen" by controller.
255 * Arguments : Pointer to current WPADStatus.
256 * Returns : None.
257 *---------------------------------------------------------------------------*/
renderLuminousSources(WPADStatus * stat)258 static void renderLuminousSources( WPADStatus *stat )
259 {
260 int i = 0;
261
262 // we'll pay attention to the first 2 sources
263 for( i = 0; i < 2; ++i )
264 {
265 s16 x = (s16)( stat->obj[i].x*SCREEN_WIDTH/WPAD_DPD_IMG_RESO_WX );
266 s16 y = (s16)( stat->obj[i].y*SCREEN_HEIGHT/WPAD_DPD_IMG_RESO_WY );
267 DEMOPrintf( x, y, 0, "*" );
268 }
269
270 } // end
271
272 /*---------------------------------------------------------------------------*
273 * Name : renderStatus()
274 * Description : Prints interesting data from WPADStatus.
275 * Arguments : Pointer to current WPADStatus.
276 * Returns : None.
277 *---------------------------------------------------------------------------*/
278
renderStatus(WPADStatus * stat)279 static void renderStatus( WPADStatus *stat )
280 {
281 const int FONT_HEIGHT = 8;
282 char buf[] = "___________";
283 s16 x = FONT_HEIGHT;
284 s16 y = FONT_HEIGHT;
285 int i = 0;
286
287 // just print accelerometer data
288 DEMOPrintf( x, y+=FONT_HEIGHT, 0, "accX : %d", stat->accX );
289 DEMOPrintf( x, y+=FONT_HEIGHT, 0, "accY : %d", stat->accY );
290 DEMOPrintf( x, y+=FONT_HEIGHT, 0, "accZ : %d", stat->accZ );
291
292 if( stat->button & WPAD_BUTTON_RIGHT ) buf[0] = '>';
293 if( stat->button & WPAD_BUTTON_DOWN ) buf[1] = 'v';
294 if( stat->button & WPAD_BUTTON_UP ) buf[2] = '^';
295 if( stat->button & WPAD_BUTTON_LEFT ) buf[3] = '<';
296 if( stat->button & WPAD_BUTTON_START ) buf[4] = 'S';
297 if( stat->button & WPAD_BUTTON_SELECT ) buf[5] = 'T';
298 if( stat->button & WPAD_BUTTON_A ) buf[7] = 'A';
299 if( stat->button & WPAD_BUTTON_B ) buf[6] = 'B';
300 if( stat->button & WPAD_BUTTON_SMALL_A) buf[8] = 'a';
301 if( stat->button & WPAD_BUTTON_SMALL_B) buf[9] = 'b';
302 if( stat->button & WPAD_BUTTON_HOME ) buf[10]= 'H';
303
304 DEMOPrintf( x, y+=FONT_HEIGHT, 0, "Buttons: [%s]",buf);
305 y+=FONT_HEIGHT;
306 DEMOPrintf( x, y+=FONT_HEIGHT, 0, "DPD-ID X Y SIZE");
307
308 for( i=0; i<WPAD_DPD_MAX_OBJECTS; ++i )
309 {
310 const DPDObject *p = &( stat->obj[i] );
311
312
313 DEMOPrintf( x, y+=FONT_HEIGHT, 0, "%1d %4d %4d %3d", p->traceId, p->x, p->y, p->size );
314
315 }
316
317
318 y+=FONT_HEIGHT;
319 DEMOPrintf( x, y+=FONT_HEIGHT, 0, "Controller Type: %d", stat->dev );
320 DEMOPrintf( x, y+=FONT_HEIGHT, 0, "ERROR Info : %d", stat->err );
321
322 if (WPAD_ERR_NO_CONTROLLER == stat->err)
323 {
324 y+=FONT_HEIGHT;
325 y+=FONT_HEIGHT;
326 DEMOPrintf(x, y+=FONT_HEIGHT, 0, ">> No controller is connected!");
327 DEMOPrintf(x, y+=FONT_HEIGHT, 0, ">> Please press a button on a paired");
328 DEMOPrintf(x, y+=FONT_HEIGHT, 0, ">> controller to connect.");
329 }
330
331
332
333 } // end
334