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