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