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