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