1 /*---------------------------------------------------------------------------*
2   Project:    WPAD demo program
3   File:       memory.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: memory.c,v $
14   Revision 1.10  2007/04/23 09:02:52  tojo
15   (none)
16 
17   Revision 1.9  2006/10/23 01:06:36  tojo
18   Called WPADSetConnectCallback before initialization complete.
19 
20   Revision 1.8  2006/09/28 10:52:25  tojo
21   (none)
22 
23   Revision 1.7  2006/09/23 07:13:15  tojo
24   Changed api names
25 
26   Revision 1.6  2006/09/08 09:00:28  tojo
27   (none)
28 
29   Revision 1.5  2006/09/05 11:30:09  tojo
30   (none)
31 
32   Revision 1.4  2006/09/05 02:49:10  tojo
33   (none)
34 
35   Revision 1.3  2006/09/05 02:38:35  tojo
36   (none)
37 
38   Revision 1.2  2006/08/31 12:44:19  tojo
39   (none)
40 
41   Revision 1.1  2006/08/16 05:05:30  tojo
42   Initial check in.
43 
44 
45  *---------------------------------------------------------------------------*/
46 #define DEMO_USE_MEMLIB = 1
47 #include <revolution.h>
48 #include <revolution/wpad.h>
49 #include <revolution/enc.h>
50 #include <demo.h>
51 #include <string.h>
52 
53 #define WDATA       0
54 #define RDATA       1
55 
56 u8 txBuf[WPAD_MAX_CONTROLLERS][WPAD_MEM_GAMEDATA_LEN];
57 u8 rxBuf[WPAD_MAX_CONTROLLERS][WPAD_MEM_GAMEDATA_LEN];
58 
59 OSTime start[WPAD_MAX_CONTROLLERS];
60 OSTime end[WPAD_MAX_CONTROLLERS];
61 
62 static void memory( s32 chan, u32 cmd, void *p_buf, u16 len );
63 
64 /*---------------------------------------------------------------------------*
65  * For WPAD testing
66  *---------------------------------------------------------------------------*/
67 void *myAlloc( u32 size  );
68 u8    myFree ( void *ptr );
69 
70 /*---------------------------------------------------------------------------*
71  * Name        : myAlloc
72  * Description : Callback needed by WPAD to allocate mem from MEM2 heap
73  * Arguments   : size of block, in bytes.
74  * Returns     : pointer to allocated block.
75  *---------------------------------------------------------------------------*/
myAlloc(u32 size)76 void *myAlloc( u32 size )
77 {
78     void *ptr;
79 
80     ptr = MEMAllocFromAllocator(&DemoAllocator2, size);
81     ASSERTMSG(ptr, "Memory allocation failed\n");
82 
83     return(ptr);
84 }
85 
86 /*---------------------------------------------------------------------------*
87  * Name        : myFree
88  * Description : Callback needed by WPAD to free mem from MEM2 heap
89  * Arguments   : point to the block that should be freed.
90  * Returns     : Always 1.
91  *---------------------------------------------------------------------------*/
myFree(void * ptr)92 u8 myFree( void *ptr )
93 {
94     MEMFreeToAllocator(&DemoAllocator2, ptr);
95 
96     return(1);
97 }
98 
99 /*---------------------------------------------------------------------------*
100  * Name        : ExtensionCallback
101  * Description : Callback called when extension is installed/detached
102  * Arguments   : chan           controller channel
103                  result         device type
104  * Returns     : None.
105  *---------------------------------------------------------------------------*/
ExtensionCallback(s32 chan,s32 result)106 static void ExtensionCallback( s32 chan, s32 result )
107 {
108     const u32 dpd[] = {WPAD_DPD_EXP,          WPAD_DPD_STD,               WPAD_DPD_STD};
109     const u32 fmt[] = {WPAD_FMT_CORE_ACC_DPD, WPAD_FMT_FREESTYLE_ACC_DPD, WPAD_FMT_CLASSIC_ACC_DPD};
110 
111     if (result == WPAD_DEV_CORE || result == WPAD_DEV_FREESTYLE || result == WPAD_DEV_CLASSIC)
112     {
113         WPADControlDpd   (chan, dpd[result], NULL);
114         WPADSetDataFormat(chan, fmt[result]);
115     }
116 }
117 
118 /*---------------------------------------------------------------------------*
119  * Name        : ConnectCallback
120  * Description : Callback called when a controller connects/disconnects
121  * Arguments   : chan           controller channel
122                  reason         WPAD_ERR_NONE if open
123                                 WPAD_ERR_NO_CONTROLLER if close
124  * Returns     : None.
125  *---------------------------------------------------------------------------*/
ConnectCallback(s32 chan,s32 reason)126 static void ConnectCallback( s32 chan, s32 reason )
127 {
128     OSReport("ConnectCallback(%d) : %s\n", chan, (reason < 0) ? "disconnect" : "connect");
129 
130     if (reason == WPAD_ERR_NONE)
131     {
132         WPADSetExtensionCallback( chan, ExtensionCallback );
133         WPADControlDpd(chan, WPAD_DPD_EXP, NULL);
134         WPADSetDataFormat(chan, WPAD_FMT_CORE_ACC_DPD);
135     }
136 }
137 
138 
139 /*---------------------------------------------------------------------------*
140  * Name        : ReadCallback
141  * Description : Callback called when reading is done.
142  * Arguments   : chan           controller channel
143                  result         result code
144  * Returns     : None.
145  *---------------------------------------------------------------------------*/
ReadCallback(s32 chan,s32 result)146 static void ReadCallback( s32 chan, s32 result )
147 {
148     u32 ms;
149     OSTime t;
150     OSCalendarTime ct;
151     const u16 *p_name;
152     u8 title[16];
153     s32 len = 16;
154 
155     end[chan] = OSGetTime();
156     ms  = OSTicksToMilliseconds(OSDiffTick(end[chan], start[chan]));
157     OSReport("chan[%d] result ==> err = %d, bytes: %d, time(ms): %d\n", chan, result, WPAD_MEM_GAMEDATA_LEN, ms);
158 
159     WPADGetGameTitleUtf16(chan, &p_name);
160     WPADGetGameDataTimeStamp(chan, &t);
161     ENCConvertStringUtf16ToUtf8(title, &len, p_name, &len);
162 
163     OSTicksToCalendarTime(t, &ct);
164     OSReport("Title : %s, TimeStamp : %d/%d/%d %02d:%02d:%02d\n", title, ct.year, ct.mon+1, ct.mday, ct.hour, ct.min, ct.sec);
165 
166     if (!memcmp(txBuf[chan], rxBuf[chan], WPAD_MEM_GAMEDATA_LEN))
167     {
168         OSReport("\n == OK == \n\n");
169     }
170     else
171     {
172         OSReport("\n == NG == \n\n");
173     }
174 }
175 
176 /*---------------------------------------------------------------------------*
177  * Name        : WriteCallback
178  * Description : Callback called when writing is done.
179  * Arguments   : chan           controller channel
180                  result         result code
181  * Returns     : None.
182  *---------------------------------------------------------------------------*/
WriteCallback(s32 chan,s32 result)183 static void WriteCallback( s32 chan, s32 result )
184 {
185     u32 ms;
186 
187     end[chan] = OSGetTime();
188     ms  = OSTicksToMilliseconds(OSDiffTick(end[chan], start[chan]));
189     OSReport("chan[%d] result ==> err = %d, bytes: %d, time(ms): %d\n", chan, result, WPAD_MEM_GAMEDATA_LEN, ms);
190 
191     memory(chan, RDATA, rxBuf[chan], WPAD_MEM_GAMEDATA_LEN);
192 
193 }
194 
195 /*---------------------------------------------------------------------------*
196  * Name        : memory
197  * Description : Performs reading/writing user data
198  * Arguments   : chan           controller channel
199                  cmd            read or write
200                  p_buf          point to the data buffer
201                  len            data length
202  * Returns     : None.
203  *---------------------------------------------------------------------------*/
memory(s32 chan,u32 cmd,void * p_buf,u16 len)204 static void memory( s32 chan, u32 cmd, void *p_buf, u16 len )
205 {
206     s32 result;
207     const char *funcName[] = {
208         "WPADWriteGameData",
209         "WPADReadGameData",
210     };
211 
212     switch(cmd)
213     {
214         case WDATA: result = WPADWriteGameData(chan, p_buf, len, 0, WriteCallback);   break;
215         case RDATA: result = WPADReadGameData (chan, p_buf, len, 0, ReadCallback);    break;
216     }
217     if (result == WPAD_ERR_NONE)
218     {
219         start[chan] = OSGetTime();
220     }
221 
222     OSReport("chan[%d] %s : %d\n", chan, funcName[cmd], result);
223 }
224 
225 /*---------------------------------------------------------------------------*
226  * Name        : PrintIntro
227  * Description : Print introduction
228  * Arguments   : None.
229  * Returns     : None.
230  *---------------------------------------------------------------------------*/
PrintIntro(void)231 static void PrintIntro( void )
232 {
233     OSReport("+------------ WPADMEM Sample Demo Program ------------+\n");
234     OSReport(" This is a demo program to access embedded memory    \n");
235     OSReport(" of Wii remote controller assigned to WPAD_CHAN0.    \n");
236     OSReport("+-----------------------------------------------------+\n");
237     OSReport(" MENU:                                               \n");
238     OSReport(" A button: Write game data to   Wii remote controller\n");
239     OSReport(" B button: Read  game data from Wii remote controller\n");
240     OSReport("+-----------------------------------------------------+\n");
241 }
242 
243 
244 /*---------------------------------------------------------------------------*
245  * Name        : main
246  * Description :
247  * Arguments   : None.
248  * Returns     : None.
249  *---------------------------------------------------------------------------*/
main(void)250 void main( void )
251 {
252     s32 bb_stat;
253     u32 type;
254     s32 chan;
255     int i;
256     u16 curr[WPAD_MAX_CONTROLLERS] = {0, 0, 0, 0};
257     u16 prev[WPAD_MAX_CONTROLLERS] = {0, 0, 0, 0};
258     WPADStatus status[WPAD_MAX_CONTROLLERS];
259 
260     const char *utf8_title = { "Wii Sample Demo" };  // UTF-8
261     u16 utf16_title[16];
262     s32 len  = (s32)strlen(utf8_title);
263 
264     OSInit();
265     DEMOInit( NULL );
266 
267     // register allocator for stack before WPADInit().
268     WPADRegisterAllocator(myAlloc, myFree);
269     // Initialize WPAD.
270     WPADInit();
271 
272     for(i=0;i<WPAD_MAX_CONTROLLERS; i++)
273     {
274         WPADSetConnectCallback(i, ConnectCallback);
275     }
276 
277     // wait that BT stack is enabled
278     do {
279         bb_stat = WPADGetStatus();
280     } while (bb_stat != WPAD_STATE_SETUP);
281 
282     // create data
283     for(chan=0; chan<WPAD_MAX_CONTROLLERS; chan++)
284     {
285         for(i=0; i<WPAD_MEM_GAMEDATA_LEN; i++)
286         {
287             txBuf[chan][i] = (u8)(i+chan);
288         }
289     }
290 
291     // set game title
292     memset(utf16_title, 0, sizeof(utf16_title));
293     ENCConvertStringUtf8ToUtf16(utf16_title, &len, (const u8*)utf8_title, &len);
294     WPADSetGameTitleUtf16(utf16_title);
295 
296     // display menu
297     PrintIntro();
298 
299     // main loop
300     while( 1 )
301     {
302         for(chan=0; chan<WPAD_MAX_CONTROLLERS; chan++)
303         {
304             if (WPADProbe(chan, &type) != WPAD_ERR_NO_CONTROLLER)
305             {
306                 WPADRead(chan, &status[chan]);
307                 curr[chan] = status[chan].button;
308             }
309 
310             if (WPADButtonDown(prev[chan], curr[chan]) & WPAD_BUTTON_A)
311             {
312                 memory(chan, WDATA, txBuf[chan], WPAD_MEM_GAMEDATA_LEN);
313             }
314             if (WPADButtonDown(prev[chan], curr[chan]) & WPAD_BUTTON_B)
315             {
316                 memory(chan, RDATA, rxBuf[chan], WPAD_MEM_GAMEDATA_LEN);
317             }
318             prev[chan] = curr[chan];
319         }
320     }
321 
322 }
323 
324 
325