1 /*---------------------------------------------------------------------------*
2 Project: Revolution SDK DS-download test
3 File: mpdlsimple.c
4
5 Copyright 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: mpdlsimple.c,v $
14 Revision 1.20 2008/12/19 02:25:58 okubata_ryoma
15 Made revisions to suppress warnings.
16
17 Revision 1.19 2008/10/31 07:55:50 yosizaki
18 2008/10/31 update.
19
20 Revision 1.18 2008/02/01 08:57:39 yosizaki
21 Added MPDLSetBootStopper.
22
23 Revision 1.17 2007/10/26 09:07:04 seiki_masashi
24 Added support for Shift_JIS and ISO-8859-1
25
26 Revision 1.16 2007/10/26 08:07:07 seiki_masashi
27 Added support for REXDEMOGetAnyMixedPadTrigger()
28
29 Revision 1.15 2007/10/11 06:40:46 yosizaki
30 Support for custom-banner.
31
32 Revision 1.14 2007/08/01 09:36:29 kitase_hirotake
33 Changed TAB to SPACE.
34
35 Revision 1.13 2007/02/16 06:30:15 yosizaki
36 Changed type of the playerbits (from int to u32).
37
38 Revision 1.12 2006/11/21 09:43:21 yosizaki
39 Added an option.
40
41 Revision 1.11 2006/10/16 01:30:20 adachi_hiroaki
42 Deleted unnecessary header files.
43
44 Revision 1.10 2006/09/15 03:29:02 yosizaki
45 Changed main loop to retry new entry.
46
47 Revision 1.9 2006/09/05 10:56:58 yosizaki
48 Changed to use demos/share.
49
50 Revision 1.8 2006/08/30 09:03:16 yosizaki
51 Changed to use REXDEMO library.
52
53 Revision 1.7 2006/08/30 07:48:00 yosizaki
54 Changed font size.
55
56 Revision 1.6 2006/08/28 10:21:43 yosizaki
57 Moved from DEMO to sample.
58
59 Revision 1.5 2006/08/25 02:46:36 yosizaki
60 Revised displayed information.
61
62 Revision 1.4 2006/08/23 09:05:00 yosizaki
63 Added function for rendering.
64
65 Revision 1.3 2006/08/14 14:39:50 yasu
66 Suppressed return value ignored warnings
67
68 Revision 1.2 2006/07/05 07:51:50 yosizaki
69 Fixes specific to including headers.
70
71 Revision 1.1 2006/07/03 08:41:00 yosizaki
72 Initial upload.
73
74 $NoKeywords: $
75 *---------------------------------------------------------------------------*/
76
77
78 #include <revolution.h>
79 #include <revolution/mpdl.h>
80 #include <revolution/mem.h>
81 #include <revolution/enc.h>
82
83 #include "rexdemo/demokpad.h"
84 #include "rexdemo/graphic.h"
85
86 // for sprintf()
87 #include <stdio.h>
88
89
90 /*===========================================================================*/
91 /* Variables */
92
93 /* Nintendo DS program image on memory */
94 static const u32 program_buffer_max = (u32)(3 * 1024 * 1024);
95 static u8 program_buffer[program_buffer_max] ATTRIBUTE_ALIGN(32);
96 static const char *program_path = "ds_program.srl";
97
98 static const GXColor white = { 0xFF, 0xFF, 0xFF, };
99 static const GXColor yellow = { 0xFF, 0xFF, 0x00, };
100 static const GXColor gray = { 0x80, 0x80, 0x80, };
101 static const GXColor black = { 0x00, 0x00, 0x00, };
102
103 #define USERHEAP_SIZE ( 1024 * 1024 )
104 static MEMHeapHandle userHeap;
105
106 static ENCContext encContext;
107
108
109 /*===========================================================================*/
110 /* Functions */
111
MyAlloc(u32 size)112 static void* MyAlloc( u32 size )
113 {
114 return MEMAllocFromExpHeapEx( userHeap, size, 32 );
115 }
116
MyFree(void * ptr)117 static void MyFree( void* ptr )
118 {
119 MEMFreeToExpHeap( userHeap, ptr );
120 }
121
122 /* MPDL work structure */
123 static MPDLConfig mpdlConfig ATTRIBUTE_ALIGN(32) =
124 {
125 MyAlloc,
126 MyFree,
127 2, // threadPriority
128 0x003fff21, // ggid
129 MP_TGID_AUTO, // tgid
130 MP_CHANNEL_AUTO, // channel
131
132 0, // serverColor
133 L"Wii", // serverName
134 L"Wii->DS", // programTitle
135 L"Wii Will Widen Wifi World!", // programComment
136 3, // programMaxEntry
137 program_buffer, // programImage
138
139 };
140
main(void)141 void main(void)
142 {
143 /* Initialize OS and memory heap */
144 DVDInit();
145 OSReport( "startup mpdlsimple demo\n" );
146 REXDEMOKPadInit();
147 REXDEMOInitScreen( FALSE );
148 REXDEMOSetGroundColor( black );
149 REXDEMOSetFontSize( 10, 20 );
150 REXDEMOBeginRender();
151 REXDEMOWaitRetrace();
152
153 /* Initialize heap for MP library */
154 {
155 void* heapAddress;
156
157 heapAddress = OSGetMEM2ArenaLo();
158 OSSetMEM2ArenaLo( (void*)OSRoundUp32B( (u32)heapAddress + USERHEAP_SIZE ) );
159 userHeap = MEMCreateExpHeapEx( heapAddress, USERHEAP_SIZE, MEM_HEAP_OPT_THREAD_SAFE );
160 if( userHeap == NULL )
161 {
162 OSHalt( "Could not create heap.\n" );
163 }
164 }
165
166 /* Initialize ENCContext for ROM Font */
167 (void)ENCInitContext(&encContext);
168 (void)ENCSetExternalEncoding(&encContext,
169 ( OSGetFontEncode() == OS_FONT_ENCODE_SJIS )
170 ? (const u8*)"Shift_JIS" : (const u8*)"ISO-8859-1");
171 (void)ENCSetBreakType(&encContext, ENC_BR_KEEP);
172 (void)ENCSetAlternativeCharacter(&encContext, L'?', L'?');
173
174 /* Load Nintendo DS program from DVD */
175 {
176 DVDFileInfo file[1];
177 if ( !DVDOpen(program_path, file) )
178 {
179 OSHalt( "failed to read NintendoDS program file from DVD.\n" );
180 }
181 else
182 {
183 const u32 file_len = ( (DVDGetLength(file) + 31) & ~31 );
184 if ( file_len > program_buffer_max )
185 {
186 OSHalt( "specified program file is too large.\n" );
187 }
188 else if ( DVDRead(file, program_buffer, (int)file_len, 0) <= 0 )
189 {
190 OSHalt( "failed to read NintendoDS program file from DVD.\n" );
191 }
192 (void)DVDClose(file);
193 }
194 }
195
196 /* If necessary, prepare custom banner image */
197 {
198 static const char *banner_character_path = "custom_banner.chr";
199 static const char *banner_palette_path = "custom_banner.plt";
200 static u8 banner_character_buffer[sizeof(u16) * 16 * 16] ATTRIBUTE_ALIGN(32);
201 static u8 banner_palette_buffer[sizeof(u16) * 16] ATTRIBUTE_ALIGN(32);
202 BOOL banner_character_loaded = FALSE;
203 BOOL banner_palette_loaded = FALSE;
204 DVDFileInfo file[1];
205 if ( DVDOpen(banner_character_path, file) )
206 {
207 if ( DVDRead(file, banner_character_buffer, (int)sizeof(banner_character_buffer), 0) == sizeof(banner_character_buffer) )
208 {
209 banner_character_loaded = TRUE;
210 }
211 (void)DVDClose(file);
212 }
213 if ( DVDOpen(banner_palette_path, file) )
214 {
215 if ( DVDRead(file, banner_palette_buffer, (int)sizeof(banner_palette_buffer), 0) == sizeof(banner_palette_buffer) )
216 {
217 banner_palette_loaded = TRUE;
218 }
219 (void)DVDClose(file);
220 }
221 if ( banner_character_loaded && banner_palette_loaded )
222 {
223 mpdlConfig.bannerCharacter = banner_character_buffer;
224 mpdlConfig.bannerPalette = banner_palette_buffer;
225 }
226 }
227
228 /* If necessary, set user-defined dynamic parameters for download clients */
229 {
230 OSCalendarTime td[1];
231 OSTicksToCalendarTime(OSGetTime(), td);
232 (void)sprintf((char*)mpdlConfig.userParam, "started...%04d%02d%02d %02d:%02d:%02d",
233 td->year, td->mon + 1, td->mday, td->hour, td->min, td->sec);
234 }
235
236 while (MPDLStartup(&mpdlConfig) == MP_RESULT_OK)
237 {
238 int i;
239 int total = 0;
240 int downloading = 0;
241 for (;;)
242 {
243 // (control entries)
244 {
245 int booted = ((int)MPDLGetBootedBitmap() & downloading);
246 int entry = ((int)MPDLGetEntryBitmap() & ~booted);
247 int newcomer = (entry & ~downloading);
248 int disconnected = (~entry & ~booted & downloading);
249 if (newcomer != 0)
250 {
251 downloading |= newcomer;
252 for (i = 1; i < 16; ++i)
253 {
254 if ((newcomer & (1 << i)) != 0)
255 {
256 MPDLPlayerInfo info[1];
257 (void)MPDLGetPlayerInfo(i, info);
258 OSReport(" AID%2d[%02X:%02X:%02X:%02X:%02X:%02X]: downloading\n",
259 i, info->mac[0], info->mac[1], info->mac[2], info->mac[3], info->mac[4], info->mac[5]);
260 }
261 }
262 }
263 if (booted != 0)
264 {
265 downloading &= ~booted;
266 for (i = 1; i < 16; ++i)
267 {
268 if ((booted & (1 << i)) != 0)
269 {
270 MPDLPlayerInfo info[1];
271 (void)MPDLGetPlayerInfo(i, info);
272 OSReport("%5d AID%2d[%02X:%02X:%02X:%02X:%02X:%02X]: booted\n",
273 ++total, i, info->mac[0], info->mac[1], info->mac[2], info->mac[3], info->mac[4], info->mac[5]);
274 }
275 }
276 }
277 if (disconnected != 0)
278 {
279 downloading &= ~disconnected;
280 for (i = 1; i < 16; ++i)
281 {
282 if ((disconnected & (1 << i)) != 0)
283 {
284 MPDLPlayerInfo info[1];
285 (void)MPDLGetPlayerInfo(i, info);
286 OSReport(" AID%2d[%02X:%02X:%02X:%02X:%02X:%02X]: disconnected\n",
287 i, info->mac[0], info->mac[1], info->mac[2], info->mac[3], info->mac[4], info->mac[5]);
288 }
289 }
290 }
291 (void)MPDLResetEntryBitmap((u32)~downloading);
292 (void)MPDLStartDownloadEx((u32)entry);
293 }
294 // (update input)
295 {
296 REXDEMOKPadRead();
297 if ((REXDEMOGetAnyMixedPadTrigger() & (KPAD_BUTTON_A | KPAD_BUTTON_B)) != 0)
298 {
299 break;
300 }
301 }
302 // (show status)
303 {
304 static const s16 ox = 4;
305 static const s16 oy = 158;
306 REXDEMOBeginRender();
307 REXDEMOSetTextColor(white);
308 REXDEMOPrintf(ox, oy - 15 * 2, 0, "total %d downloads.", total);
309 REXDEMOPrintf(ox, oy - 15 * 1, 0, "press A or B to reset");
310 REXDEMOSetTextColor(yellow);
311 REXDEMOPrintf(ox, oy, 0, "AID STATUS MAC-ADDR NAME");
312 REXDEMOSetTextColor(white);
313 for (i = 1; i < 16; ++i)
314 {
315 const s16 sy = (s16)(oy + i * 15);
316 MPDLPlayerInfo info[1];
317 BOOL valid_player = MPDLGetPlayerInfo(i, info);
318 char name[MPDL_PLAYER_NAME_MAX + 1];
319 ENCContext convCtx;
320 s32 dstlen, srclen;
321 u16 nameUTF16[MPDL_PLAYER_NAME_MAX + 1];
322 REXDEMOSetTextColor((i < mpdlConfig.programMaxEntry) ? white : gray);
323 REXDEMOPrintf(ox + 5, sy, 0, "%2d", i);
324 if (!valid_player)
325 {
326 REXDEMOPrintf(ox + 40, sy, 0, " none ");
327 }
328 else if ((MPDLGetBootedBitmap() & (1 << i)) != 0)
329 {
330 REXDEMOPrintf(ox + 40, sy, 0, "booted");
331 }
332 else if (info->progress != 0)
333 {
334 REXDEMOPrintf(ox + 40, sy, 0, " %3d%% ", info->progress);
335 }
336 else
337 {
338 REXDEMOPrintf(ox + 40, sy, 0, "ready");
339 }
340 if (valid_player)
341 {
342 dstlen = MPDL_PLAYER_NAME_MAX;
343 srclen = (s32)(NETMinU32(info->name_length, MPDL_PLAYER_NAME_MAX) * sizeof(u16));
344 NETSwapAndCopyMemory16(nameUTF16, info->name, (u32)srclen);
345 (void)NETMemSet(name, 0, sizeof(name));
346 (void)ENCDuplicateContext(&convCtx, &encContext);
347 (void)ENCConvertFromInternalEncoding(&convCtx, (u8*)name, &dstlen, nameUTF16, &srclen);
348 REXDEMOPrintf(ox + 110, sy, 0,
349 "%02X%02X%02X:%02X%02X%02X %-10s",
350 info->mac[0], info->mac[1], info->mac[2],
351 info->mac[3], info->mac[4], info->mac[5], name);
352 }
353 }
354 REXDEMOWaitRetrace();
355 }
356 }
357 (void)MPDLCleanup();
358 }
359
360 }
361
362
363 /*===========================================================================*/
364