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.17 2007/10/26 09:07:04 seiki_masashi
15 support for Shift_JIS and ISO-8859-1
16
17 Revision 1.16 2007/10/26 08:07:07 seiki_masashi
18 Support for REXDEMOGetAnyMixedPadTrigger.
19
20 Revision 1.15 2007/10/11 06:40:46 yosizaki
21 Support for custom-banner.
22
23 Revision 1.14 2007/08/01 09:36:29 kitase_hirotake
24 Changed TAB to SPACE.
25
26 Revision 1.13 2007/02/16 06:30:15 yosizaki
27 Changed type of the playerbits (from int to u32)
28
29 Revision 1.12 2006/11/21 09:43:21 yosizaki
30 Added an option.
31
32 Revision 1.11 2006/10/16 01:30:20 adachi_hiroaki
33 Deleted unnecessary header files.
34
35 Revision 1.10 2006/09/15 03:29:02 yosizaki
36 Changed main loop to retry new entry.
37
38 Revision 1.9 2006/09/05 10:56:58 yosizaki
39 Changed to use demos/share.
40
41 Revision 1.8 2006/08/30 09:03:16 yosizaki
42 Changed to use REXDEMO library.
43
44 Revision 1.7 2006/08/30 07:48:00 yosizaki
45 Changed font size.
46
47 Revision 1.6 2006/08/28 10:21:43 yosizaki
48 Moved from DEMO to sample.
49
50 Revision 1.5 2006/08/25 02:46:36 yosizaki
51 Revised displayed information.
52
53 Revision 1.4 2006/08/23 09:05:00 yosizaki
54 Added function for rendering.
55
56 Revision 1.3 2006/08/14 14:39:50 yasu
57 Suppressed return value ignored warnings
58
59 Revision 1.2 2006/07/05 07:51:50 yosizaki
60 Fixes specific to including headers.
61
62 Revision 1.1 2006/07/03 08:41:00 yosizaki
63 Initial upload.
64
65 $NoKeywords: $
66 *---------------------------------------------------------------------------*/
67
68
69 #include <revolution.h>
70 #include <revolution/mpdl.h>
71 #include <revolution/mem.h>
72 #include <revolution/enc.h>
73
74 #include "rexdemo/demokpad.h"
75 #include "rexdemo/graphic.h"
76
77
78
79 /*===========================================================================*/
80 /* variable */
81
82 /* NintendoDS program image on memory */
83 static const u32 program_buffer_max = (u32)(3 * 1024 * 1024);
84 static u8 program_buffer[program_buffer_max] ATTRIBUTE_ALIGN(32);
85 static const char *program_path = "ds_program.srl";
86
87 static const GXColor white = { 0xFF, 0xFF, 0xFF, };
88 static const GXColor yellow = { 0xFF, 0xFF, 0x00, };
89 static const GXColor gray = { 0x80, 0x80, 0x80, };
90 static const GXColor black = { 0x00, 0x00, 0x00, };
91
92 #define USERHEAP_SIZE ( 1024 * 1024 )
93 static MEMHeapHandle userHeap;
94
95 static ENCContext encContext;
96
97
98 /*===========================================================================*/
99 /* function */
100
MyAlloc(u32 size)101 static void* MyAlloc( u32 size )
102 {
103 return MEMAllocFromExpHeapEx( userHeap, size, 32 );
104 }
105
MyFree(void * ptr)106 static void MyFree( void* ptr )
107 {
108 MEMFreeToExpHeap( userHeap, ptr );
109 }
110
111 /* MPDL work structure */
112 static MPDLConfig mpdlConfig ATTRIBUTE_ALIGN(32) =
113 {
114 MyAlloc,
115 MyFree,
116 2, // threadPriority
117 0x003fff21, // ggid
118 MP_TGID_AUTO, // tgid
119 MP_CHANNEL_AUTO, // channel
120
121 0, // serverColor
122 L"Wii", // serverName
123 L"Wii��DS", // programTitle
124 L"Wii Will Widen Wifi World!", // programComment
125 3, // programMaxEntry
126 program_buffer, // programImage
127
128 };
129
main(void)130 void main(void)
131 {
132 /* Initialize OS and memory heap */
133 DVDInit();
134 OSReport( "startup mpdlsimple demo\n" );
135 REXDEMOKPadInit();
136 REXDEMOInitScreen( FALSE );
137 REXDEMOSetGroundColor( black );
138 REXDEMOSetFontSize( 10, 20 );
139 REXDEMOBeginRender();
140 REXDEMOWaitRetrace();
141
142 /* Initialize heap for MP library */
143 {
144 void* heapAddress;
145
146 heapAddress = OSGetMEM2ArenaLo();
147 OSSetMEM2ArenaLo( (void*)OSRoundUp32B( (u32)heapAddress + USERHEAP_SIZE ) );
148 userHeap = MEMCreateExpHeapEx( heapAddress, USERHEAP_SIZE, MEM_HEAP_OPT_THREAD_SAFE );
149 if( userHeap == NULL )
150 {
151 OSHalt( "Could not create heap.\n" );
152 }
153 }
154
155 /* Initialize ENCContext for ROM Font */
156 (void)ENCInitContext(&encContext);
157 (void)ENCSetExternalEncoding(&encContext,
158 ( OSGetFontEncode() == OS_FONT_ENCODE_SJIS )
159 ? (const u8*)"Shift_JIS" : (const u8*)"ISO-8859-1");
160 (void)ENCSetBreakType(&encContext, ENC_BR_KEEP);
161 (void)ENCSetAlternativeCharacter(&encContext, L'?', L'?');
162
163 /* Load NintendoDS program from DVD */
164 {
165 DVDFileInfo file[1];
166 if ( !DVDOpen(program_path, file) )
167 {
168 OSHalt( "failed to read NintendoDS program file from DVD.\n" );
169 }
170 else
171 {
172 const u32 file_len = ( (DVDGetLength(file) + 31) & ~31 );
173 if ( file_len > program_buffer_max )
174 {
175 OSHalt( "specified program file is too large.\n" );
176 }
177 else if ( DVDRead(file, program_buffer, (int)file_len, 0) <= 0 )
178 {
179 OSHalt( "failed to read NintendoDS program file from DVD.\n" );
180 }
181 (void)DVDClose(file);
182 }
183 }
184
185 /* if necessary, prepare custom banner image */
186 {
187 static const char *banner_character_path = "custom_banner.chr";
188 static const char *banner_palette_path = "custom_banner.plt";
189 static u8 banner_character_buffer[sizeof(u16) * 16 * 16];
190 static u8 banner_palette_buffer[sizeof(u16) * 16];
191 BOOL banner_character_loaded = FALSE;
192 BOOL banner_palette_loaded = FALSE;
193 DVDFileInfo file[1];
194 if ( DVDOpen(banner_character_path, file) )
195 {
196 if ( DVDRead(file, banner_character_buffer, (int)sizeof(banner_character_buffer), 0) == sizeof(banner_character_buffer) )
197 {
198 banner_character_loaded = TRUE;
199 }
200 (void)DVDClose(file);
201 }
202 if ( DVDOpen(banner_palette_path, file) )
203 {
204 if ( DVDRead(file, banner_palette_buffer, (int)sizeof(banner_palette_buffer), 0) == sizeof(banner_palette_buffer) )
205 {
206 banner_palette_loaded = TRUE;
207 }
208 (void)DVDClose(file);
209 }
210 if ( banner_character_loaded && banner_palette_loaded )
211 {
212 mpdlConfig.bannerCharacter = banner_character_buffer;
213 mpdlConfig.bannerPalette = banner_palette_buffer;
214 }
215 }
216
217 for (; ;)
218 {
219 enum
220 {
221 MODE_AUTODOWNLOAD,
222 MODE_MAX
223 };
224 int mode_cursor = 0;
225
226 BOOL is_entry_closed;
227 u32 fixed_entry;
228 static BOOL auto_download_mode = TRUE;
229
230 /* Initialize and startup MPDL */
231 if ( MPDLStartup( &mpdlConfig ) != MP_RESULT_OK )
232 {
233 OSHalt( "failed to startup MPDL!\n" );
234 }
235
236 is_entry_closed = FALSE;
237 fixed_entry = 0;
238 for (; ;)
239 {
240 int i;
241 u32 entry;
242 u32 booted;
243
244 REXDEMOKPadRead();
245
246 /* Update sequence */
247 entry = MPDLGetEntryBitmap();
248 booted = MPDLGetBootedBitmap();
249 if (!is_entry_closed)
250 {
251 const u32 full_entry = (u32)(((1 << mpdlConfig.programMaxEntry) - 1) & ~1);
252 /* Move cursor and select options */
253 if ((REXDEMOGetAnyMixedPadTrigger() & (KPAD_BUTTON_RIGHT | KPAD_BUTTON_LEFT | (PAD_BUTTON_RIGHT << 16) | (PAD_BUTTON_LEFT << 16))) != 0)
254 {
255 switch (mode_cursor)
256 {
257 case MODE_AUTODOWNLOAD:
258 auto_download_mode = !auto_download_mode;
259 break;
260 default:
261 break;
262 }
263 }
264 if (((REXDEMOGetAnyMixedPadTrigger() & (KPAD_BUTTON_UP | (PAD_BUTTON_UP << 16))) != 0) && (--mode_cursor < 0))
265 {
266 mode_cursor += MODE_MAX;
267 }
268 if (((REXDEMOGetAnyMixedPadTrigger() & (KPAD_BUTTON_DOWN | (PAD_BUTTON_DOWN << 16))) != 0) && (++mode_cursor >= MODE_MAX))
269 {
270 mode_cursor -= MODE_MAX;
271 }
272 /* Close entry and start download */
273 if (((entry == full_entry) && auto_download_mode) ||
274 ((REXDEMOGetAnyMixedPadTrigger() & (KPAD_BUTTON_A | (PAD_BUTTON_A << 16))) != 0))
275 {
276 is_entry_closed = TRUE;
277 fixed_entry = MPDLStartDownload();
278 }
279 }
280 else if (entry == 0)
281 {
282 if ((REXDEMOGetAnyMixedPadTrigger() & (KPAD_BUTTON_A | (PAD_BUTTON_A << 16))) != 0)
283 {
284 break;
285 }
286 }
287
288 /* DrawFrame */
289 REXDEMOBeginRender();
290 {
291 /* *INDENT-OFF* */
292 static const GXColor ds_ipl_color_table[16] =
293 {
294 { 0x63, 0x84, 0x9C, }, /* GRAY */
295 { 0xBD, 0x4A, 0x00, }, /* BROWN */
296 { 0xFF, 0x00, 0x18, }, /* RED */
297 { 0xFF, 0x8C, 0xFF, }, /* PINK */
298 { 0xFF, 0x94, 0x00, }, /* ORANGE */
299 { 0xF7, 0xE7, 0x00, }, /* YELLOW */
300 { 0xAD, 0xFF, 0x00, }, /* LIME_GREEN */
301 { 0x00, 0xFF, 0x00, }, /* GREEN */
302 { 0x00, 0xA5, 0x39, }, /* DARK_GREEN */
303 { 0x4A, 0xDE, 0x8C, }, /* SEA_GREEN */
304 { 0x31, 0xBD, 0xF7, }, /* TURQUOISE */
305 { 0x00, 0x5A, 0xF7, }, /* BLUE */
306 { 0x00, 0x00, 0x94, }, /* DARK_BLUE */
307 { 0x8C, 0x00, 0xD6, }, /* PURPLE */
308 { 0xD6, 0x00, 0xEF, }, /* VIOLET */
309 { 0xFF, 0x00, 0x94, }, /* MAGENTA */
310 };
311 /* *INDENT-ON* */
312 const s16 ox = 4, oy = 158;
313
314 /* header */
315 REXDEMOSetTextColor(white);
316 REXDEMOPrintf(4, 8, 0, "MPDL simple sample");
317 REXDEMOSetTextColor(yellow);
318 if (!is_entry_closed)
319 {
320 REXDEMOPrintf(4, 24, 0, "entry is opened.");
321 REXDEMOPrintf(200, 24, 0, "(press A to start download)");
322 }
323 else if (entry > 0)
324 {
325 REXDEMOPrintf(4, 24, 0, "entry is closed, now downloading...");
326 }
327 else
328 {
329 REXDEMOPrintf(4, 24, 0, "download has been completed.");
330 REXDEMOPrintf(320, 24, 0, "(press A to restart new entry)");
331 }
332
333 REXDEMOSetTextColor(white);
334 REXDEMOPrintf(30, 60, 0, "auto-download mode : ON OFF");
335 REXDEMOSetTextColor(yellow);
336 REXDEMOPrintf(10, 60 + mode_cursor * 10, 0, ">");
337 REXDEMOPrintf(30, 60, 0, " %s %s",
338 auto_download_mode ? "[ ]" : " ",
339 auto_download_mode ? " " : "[ ]");
340
341 /* entries */
342 REXDEMOSetTextColor(white);
343 REXDEMOPrintf(ox, oy, 0, "AID STATUS MAC-ADDR NAME");
344 for (i = 1; i < 16; ++i)
345 {
346 const s16 sy = (s16)(oy + i * 15);
347 MPDLPlayerInfo info[1];
348 BOOL valid_player = MPDLGetPlayerInfo(i, info);
349 REXDEMOSetTextColor(valid_player ? ds_ipl_color_table[info->color] : gray);
350
351 /* AID */
352 REXDEMOPrintf(ox + 5, sy, 0, "%2d", i);
353
354 /* STATUS */
355 if (!is_entry_closed)
356 {
357 if (valid_player)
358 {
359 REXDEMOPrintf(ox + 40, sy, 0, "ready");
360 }
361 else if (i < mpdlConfig.programMaxEntry)
362 {
363 REXDEMOPrintf(ox + 40, sy, 0, " none ");
364 }
365 }
366 else
367 {
368 if (valid_player)
369 {
370 if ((booted & (1 << i)) != 0)
371 {
372 REXDEMOPrintf(ox + 40, sy, 0, "booted");
373 }
374 else
375 {
376 REXDEMOPrintf(ox + 40, sy, 0, " %3d%% ", info->progress);
377 }
378 }
379 else if ((fixed_entry & (1 << i)) != 0)
380 {
381 REXDEMOPrintf(ox + 40, sy, 0, "failed");
382 }
383 }
384
385 /* MAC-ADDR & NAME */
386 if (valid_player)
387 {
388 char name[MPDL_PLAYER_NAME_MAX + 1];
389 {
390 ENCContext convCtx;
391 s32 dstlen, srclen;
392 u16 nameUTF16[MPDL_PLAYER_NAME_MAX + 1];
393
394 dstlen = MPDL_PLAYER_NAME_MAX;
395 srclen = (s32)(NETMinU32(info->name_length, MPDL_PLAYER_NAME_MAX)*sizeof(u16));
396 NETSwapAndCopyMemory16(nameUTF16, info->name, (u32)srclen);
397 (void)NETMemSet(name, 0, sizeof(name));
398 (void)ENCDuplicateContext(&convCtx, &encContext);
399 (void)ENCConvertFromInternalEncoding(&convCtx, (u8*)name, &dstlen, nameUTF16, &srclen);
400 }
401 REXDEMOPrintf(ox + 110, sy, 0,
402 "%02X%02X%02X:%02X%02X%02X %-10s",
403 info->mac[0], info->mac[1], info->mac[2],
404 info->mac[3], info->mac[4], info->mac[5], name);
405 }
406
407 }
408 }
409
410 REXDEMOWaitRetrace();
411 }
412 (void)MPDLCleanup();
413 }
414
415 }
416
417
418 /*===========================================================================*/
419