1 /*---------------------------------------------------------------------------*
2 Project: WPAD demo program
3 File: full_mode.c
4
5 Copyright (C) 2006 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Log: full_mode.c,v $
14 Revision 1.6.4.1 2007/12/11 01:15:27 tojo
15 Modified to handle the error code of WPADStatus.
16
17 Revision 1.6 2007/04/23 08:48:46 tojo
18 (none)
19
20 Revision 1.5 2007/04/10 10:15:01 tojo
21 (none)
22
23 Revision 1.4 2007/03/19 11:14:38 tojo
24 (none)
25
26 Revision 1.3 2006/10/23 01:05:09 tojo
27 Called WPADSetConnectCallback before initialization complete.
28
29 Revision 1.2 2006/09/08 07:59:30 tojo
30 (none)
31
32 Revision 1.1 2006/09/05 12:22:31 tojo
33 (none)
34
35
36 *---------------------------------------------------------------------------*/
37
38 #define DEMO_USE_MEMLIB = 1
39 #include <demo.h>
40 #include <revolution/wpad.h>
41 #include <math.h>
42 #include <string.h>
43
44 #define SCREEN_WIDTH 1024
45 #define SCREEN_HEIGHT 768
46
47 /*---------------------------------------------------------------------------*
48 * Private function prototypes
49 *---------------------------------------------------------------------------*/
50 void *myAlloc( u32 size );
51 u8 myFree ( void *ptr );
52
53 /*---------------------------------------------------------------------------*
54 * Globals
55 *---------------------------------------------------------------------------*/
56 s32 status;
57 u32 type;
58
59 const GXColor LIME = { 0, 255, 0, 255 };
60 const GXColor AQUA = { 0, 255, 255, 255 };
61 const GXColor MAGENTA = { 255, 0, 255, 255 };
62 const GXColor GRAY = { 128, 128, 128, 255 };
63 const GXColor WHITE = { 255, 255, 255, 255 };
64 const GXColor TEAL = { 0, 128, 128, 255 };
65 const GXColor ORANGE = { 255, 165, 0, 255 };
66 const GXColor PINK = { 255, 192, 203, 255 };
67 const GXColor GREEN = { 0, 128, 0, 255 };
68
69 const f32 PI=3.141592f;
70
71 static GXColor circle[4];
72 static GXColor box[4];
73
74
75 /*---------------------------------------------------------------------------*
76 * Name : myAlloc()
77 * Description : Callback needed by WPAD to allocate mem from MEM2 heap
78 * Arguments : size of block, in bytes.
79 * Returns : pointer to allocated block.
80 *---------------------------------------------------------------------------*/
myAlloc(u32 size)81 void *myAlloc( u32 size )
82 {
83 void *ptr;
84
85 ptr = MEMAllocFromAllocator(&DemoAllocator2, size);
86 ASSERTMSG(ptr, "Memory allocation failed\n");
87
88 return(ptr);
89 }
90
91 /*---------------------------------------------------------------------------*
92 * Name : myFree()
93 * Description : Callback needed by WPAD to free mem from MEM2 heap
94 * Arguments : point to the block that should be freed.
95 * Returns : Always 1.
96 *---------------------------------------------------------------------------*/
myFree(void * ptr)97 u8 myFree( void *ptr )
98 {
99 MEMFreeToAllocator(&DemoAllocator2, ptr);
100
101 return(1);
102 }
103
104 /*---------------------------------------------------------------------------*
105 * Name : initialize()
106 * Description : Performs basic system initialization.
107 * Arguments : None.
108 * Returns : None.
109 *---------------------------------------------------------------------------*/
initialize(void)110 static void initialize( void )
111 {
112 OSInit();
113
114 DEMOInit( &GXNtsc480IntDf );
115 GXSetCopyClear( GRAY, GX_MAX_Z24 );
116 GXCopyDisp( DEMOGetCurrentBuffer(), GX_TRUE );
117 DEMOInitCaption( DM_FT_XLU, SCREEN_WIDTH, SCREEN_HEIGHT );
118 GXSetZMode( GX_ENABLE, GX_ALWAYS, GX_ENABLE ); // Set pixel processing mode
119 GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR ); // Translucent mode
120
121 DEMOPadInit();
122
123 circle[0] = WHITE;
124 circle[1] = AQUA;
125 circle[2] = LIME;
126 circle[3] = PINK;
127
128 box[0] = ORANGE;
129 box[1] = TEAL;
130 box[2] = GREEN;
131 box[3] = MAGENTA;
132
133 } /* end initialize() */
134
135 /*---------------------------------------------------------------------------*
136 * Name : RenderLine()
137 * Description : Draw line
138 * Arguments : x1 and y1 are the coordinate of start point
139 x2 and y2 are the coordinate of end point
140 clr is line color
141 * Returns : None.
142 *---------------------------------------------------------------------------*/
RenderLine(s16 x1,s16 y1,s16 x2,s16 y2,GXColor clr)143 static void RenderLine( s16 x1, s16 y1, s16 x2, s16 y2, GXColor clr )
144 {
145 Mtx mv;
146 MTXIdentity(mv);
147 GXLoadPosMtxImm(mv, GX_PNMTX0);
148 GXSetCurrentMtx(GX_PNMTX0);
149
150 GXSetNumChans(1);
151 GXSetNumTevStages(1);
152 GXSetNumTexGens(0);
153 GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
154 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
155
156 GXClearVtxDesc();
157 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
158 GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
159 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_S16, 0);
160 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
161
162 GXBegin(GX_LINES, GX_VTXFMT0, 2);
163 GXPosition2s16(x1, y1);
164 GXColor4u8(clr.r, clr.g, clr.b, clr.a);
165 GXPosition2s16(x2, y2);
166 GXColor4u8(clr.r, clr.g, clr.b, clr.a);
167 GXEnd();
168 }
169
170 /*---------------------------------------------------------------------------*
171 * Name : RenderCircle()
172 * Description : Draw a circle
173 * Arguments : x and y are the coordinate of center point.
174 div is roundish
175 clr is color
176 * Returns : None.
177 *---------------------------------------------------------------------------*/
RenderCircle(s16 x,s16 y,s16 r,s16 div,GXColor clr)178 static void RenderCircle( s16 x, s16 y, s16 r, s16 div, GXColor clr )
179 {
180 f32 th;
181 f32 phi;
182 s16 i;
183
184 for(i=0; i<div; ++i)
185 {
186 th=2*PI/div*i;
187 phi=2*PI/div*(i+1);
188
189 RenderLine((s16)(x+r*cos(th)),
190 (s16)(y+r*sin(th)),
191 (s16)(x+r*cos(phi)),
192 (s16)(y+r*sin(phi)),
193 clr);
194 }
195 }
196
197
198 /*---------------------------------------------------------------------------*
199 * Name : RenderObjects()
200 * Description : Draw the objects dpd catches
201 * Arguments : type device type.
202 status controller data.
203 * Returns : None.
204 *---------------------------------------------------------------------------*/
RenderObjects(WPADStatusEx * status)205 static void RenderObjects( WPADStatusEx *status )
206 {
207 int i;
208 s16 l;
209 s32 chan;
210
211 for(chan=0; chan<WPAD_MAX_CONTROLLERS; chan++)
212 {
213 if (WPADIsDpdEnabled(chan))
214 {
215 WPADStatusEx *ep = &status[chan];
216
217 if (ep->err == WPAD_ERR_NONE)
218 {
219 for(i=0; i<WPAD_DPD_MAX_OBJECTS; i++)
220 {
221 l = (s16)((sqrt(ep->exp[i].pixel * 2))/2);
222
223 RenderCircle(ep->obj[i].x, ep->obj[i].y, (s16)(sqrt((f32)ep->obj[i].size/PI)*8), 16, circle[chan]);
224 RenderLine(ep->exp[i].range_x1, ep->exp[i].range_y1, ep->exp[i].range_x1, ep->exp[i].range_y2, box[chan]);
225 RenderLine(ep->exp[i].range_x1, ep->exp[i].range_y2, ep->exp[i].range_x2, ep->exp[i].range_y2, box[chan]);
226 RenderLine(ep->exp[i].range_x2, ep->exp[i].range_y2, ep->exp[i].range_x2, ep->exp[i].range_y1, box[chan]);
227 RenderLine(ep->exp[i].range_x2, ep->exp[i].range_y1, ep->exp[i].range_x1, ep->exp[i].range_y1, box[chan]);
228 }
229 }
230 }
231 }
232 }
233
234 /*---------------------------------------------------------------------------*
235 * Name : dpdCallback()
236 * Description : Callback called when dpd is turned off. Turn on dpd as full mode.
237 * Arguments : chan controller channel
238 result result code
239 * Returns : None.
240 *---------------------------------------------------------------------------*/
dpdCallback(s32 chan,s32 result)241 static void dpdCallback( s32 chan, s32 result )
242 {
243 #pragma unused(chan, result)
244
245 if (result == WPAD_ERR_NONE)
246 {
247 WPADControlDpd(chan, WPAD_DPD_FULL, NULL);
248 WPADSetDataFormat(chan, WPAD_FMT_CORE_ACC_DPD_FULL);
249 }
250 }
251
252 /*---------------------------------------------------------------------------*
253 * Name : ExtensionCallback()
254 * Description : Callback called when an extension is installed/detached.
255 * Arguments : chan controller channel
256 result result code
257 * Returns : None.
258 *---------------------------------------------------------------------------*/
ExtensionCallback(s32 chan,s32 result)259 static void ExtensionCallback( s32 chan, s32 result )
260 {
261
262 switch(result)
263 {
264 case WPAD_DEV_CORE:
265 WPADControlDpd(chan, WPAD_DPD_FULL, NULL);
266 WPADSetDataFormat(chan, WPAD_FMT_CORE_ACC_DPD_FULL);
267 break;
268
269 case WPAD_DEV_FREESTYLE:
270 WPADControlDpd(chan, WPAD_DPD_STD, NULL);
271 WPADSetDataFormat(chan, WPAD_FMT_FREESTYLE_ACC_DPD);
272 break;
273
274 case WPAD_DEV_CLASSIC:
275 WPADControlDpd(chan, WPAD_DPD_STD, NULL);
276 WPADSetDataFormat(chan, WPAD_FMT_CLASSIC_ACC_DPD);
277 break;
278
279 default:
280 break;
281 }
282 }
283
284 /*---------------------------------------------------------------------------*
285 * Name : ConnectCallback()
286 * Description : Callback called when a controller connects/disconnects.
287 * Arguments : chan controller channel
288 result result code
289 * Returns : None.
290 *---------------------------------------------------------------------------*/
ConnectCallback(s32 chan,s32 reason)291 static void ConnectCallback( s32 chan, s32 reason )
292 {
293 if (reason == WPAD_ERR_NONE)
294 {
295 WPADSetExtensionCallback( chan, ExtensionCallback );
296 WPADControlDpd(chan, WPAD_DPD_FULL, dpdCallback);
297 WPADSetDataFormat(chan, WPAD_FMT_CORE_ACC_DPD_FULL);
298 }
299 }
300
301
302 /*---------------------------------------------------------------------------*
303 * Name : PrintIntro()
304 * Description :
305 * Arguments : None.
306 * Returns : None.
307 *---------------------------------------------------------------------------*/
PrintIntro(void)308 static void PrintIntro( void )
309 {
310 OSReport("* -------------------------------------------- *\n");
311 OSReport("* WPAD SAMPLE DEMO: *\n");
312 OSReport("* *\n");
313 OSReport("* DPD Full mode and Change DPD sensitivity *\n");
314 OSReport("* DPD sensitivity range (low) 1 <--> 5 (high) *\n");
315 OSReport("* -------------------------------------------- *\n");
316 OSReport("* MENU: Only Controller1 can change *\n");
317 OSReport("* -------------------------------------------- *\n");
318 OSReport("* press + button: increase the dpd sensitivity.*\n");
319 OSReport("* press - button: decrease the dpd sensitivity.*\n");
320 OSReport("* -------------------------------------------- *\n");
321 }
322
changeSensitivity(u8 level)323 static void changeSensitivity( u8 level )
324 {
325 s32 chan;
326 u32 type;
327
328 WPADSetDpdSensitivity(level);
329
330 for(chan=0; chan<WPAD_MAX_CONTROLLERS; chan++)
331 {
332 if (WPADProbe(chan, &type) != WPAD_ERR_NO_CONTROLLER)
333 {
334 WPADSetDataFormat(chan, WPAD_FMT_CORE);
335 WPADControlDpd(chan, WPAD_DPD_OFF, dpdCallback);
336 }
337 }
338 }
339
340 /*---------------------------------------------------------------------------*
341 * Name : main()
342 * Description :
343 * Arguments : None.
344 * Returns : None.
345 *---------------------------------------------------------------------------*/
main(void)346 void main( void )
347 {
348 s32 bb_stat;
349 s32 chan;
350 WPADStatusEx full[WPAD_MAX_CONTROLLERS];
351 u16 curr = 0;
352 u16 prev = 0;
353 int i;
354 u8 level;
355
356 initialize();
357
358 // register allocator for stack before WPADInit().
359 WPADRegisterAllocator(myAlloc, myFree);
360
361 // Initialize WPAD.
362 WPADInit();
363
364 for(i=0;i<WPAD_MAX_CONTROLLERS; i++)
365 {
366 WPADSetConnectCallback (i, ConnectCallback);
367 WPADSetExtensionCallback(i, ExtensionCallback);
368 }
369
370 // wait that BT stack is enabled
371 do {
372 bb_stat = WPADGetStatus();
373 } while (bb_stat != WPAD_STATE_SETUP);
374
375 PrintIntro();
376
377 // get dpd sensitivity.
378 level = WPADGetDpdSensitivity();
379
380 // Main loop
381 while( 1 )
382 {
383 for(chan=0; chan<WPAD_MAX_CONTROLLERS; chan++)
384 {
385 status = WPADProbe( chan, &type );
386 if (status != WPAD_ERR_NO_CONTROLLER)
387 {
388 WPADRead( chan, &full[chan] );
389 }
390 }
391 // button is available if err is not invalid.
392 if (full[0].err != WPAD_ERR_INVALID)
393 {
394 curr = full[0].button;
395 }
396
397 if (WPADButtonDown(prev, curr) & WPAD_BUTTON_PLUS)
398 {
399 if (level != 5)
400 {
401 level++;
402 changeSensitivity(level);
403 }
404 }
405 if (WPADButtonDown(prev, curr) & WPAD_BUTTON_MINUS)
406 {
407 if (level != 1)
408 {
409 level--;
410 changeSensitivity(level);
411 }
412 }
413 prev = curr;
414
415 DEMOBeforeRender();
416 RenderObjects(full);
417 DEMODoneRender();
418
419 }
420 }
421
422