/*---------------------------------------------------------------------------* Project: Revolution SDK DS-download test File: mpdlsimple.c Copyright 2006 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Log: mpdlsimple.c,v $ Revision 1.17 2007/10/26 09:07:04 seiki_masashi support for Shift_JIS and ISO-8859-1 Revision 1.16 2007/10/26 08:07:07 seiki_masashi Support for REXDEMOGetAnyMixedPadTrigger. Revision 1.15 2007/10/11 06:40:46 yosizaki Support for custom-banner. Revision 1.14 2007/08/01 09:36:29 kitase_hirotake Changed TAB to SPACE. Revision 1.13 2007/02/16 06:30:15 yosizaki Changed type of the playerbits (from int to u32) Revision 1.12 2006/11/21 09:43:21 yosizaki Added an option. Revision 1.11 2006/10/16 01:30:20 adachi_hiroaki Deleted unnecessary header files. Revision 1.10 2006/09/15 03:29:02 yosizaki Changed main loop to retry new entry. Revision 1.9 2006/09/05 10:56:58 yosizaki Changed to use demos/share. Revision 1.8 2006/08/30 09:03:16 yosizaki Changed to use REXDEMO library. Revision 1.7 2006/08/30 07:48:00 yosizaki Changed font size. Revision 1.6 2006/08/28 10:21:43 yosizaki Moved from DEMO to sample. Revision 1.5 2006/08/25 02:46:36 yosizaki Revised displayed information. Revision 1.4 2006/08/23 09:05:00 yosizaki Added function for rendering. Revision 1.3 2006/08/14 14:39:50 yasu Suppressed return value ignored warnings Revision 1.2 2006/07/05 07:51:50 yosizaki Fixes specific to including headers. Revision 1.1 2006/07/03 08:41:00 yosizaki Initial upload. $NoKeywords: $ *---------------------------------------------------------------------------*/ #include #include #include #include #include "rexdemo/demokpad.h" #include "rexdemo/graphic.h" /*===========================================================================*/ /* variable */ /* NintendoDS program image on memory */ static const u32 program_buffer_max = (u32)(3 * 1024 * 1024); static u8 program_buffer[program_buffer_max] ATTRIBUTE_ALIGN(32); static const char *program_path = "ds_program.srl"; static const GXColor white = { 0xFF, 0xFF, 0xFF, }; static const GXColor yellow = { 0xFF, 0xFF, 0x00, }; static const GXColor gray = { 0x80, 0x80, 0x80, }; static const GXColor black = { 0x00, 0x00, 0x00, }; #define USERHEAP_SIZE ( 1024 * 1024 ) static MEMHeapHandle userHeap; static ENCContext encContext; /*===========================================================================*/ /* function */ static void* MyAlloc( u32 size ) { return MEMAllocFromExpHeapEx( userHeap, size, 32 ); } static void MyFree( void* ptr ) { MEMFreeToExpHeap( userHeap, ptr ); } /* MPDL work structure */ static MPDLConfig mpdlConfig ATTRIBUTE_ALIGN(32) = { MyAlloc, MyFree, 2, // threadPriority 0x003fff21, // ggid MP_TGID_AUTO, // tgid MP_CHANNEL_AUTO, // channel 0, // serverColor L"Wii", // serverName L"WiiDS", // programTitle L"Wii Will Widen Wifi World!", // programComment 3, // programMaxEntry program_buffer, // programImage }; void main(void) { /* Initialize OS and memory heap */ DVDInit(); OSReport( "startup mpdlsimple demo\n" ); REXDEMOKPadInit(); REXDEMOInitScreen( FALSE ); REXDEMOSetGroundColor( black ); REXDEMOSetFontSize( 10, 20 ); REXDEMOBeginRender(); REXDEMOWaitRetrace(); /* Initialize heap for MP library */ { void* heapAddress; heapAddress = OSGetMEM2ArenaLo(); OSSetMEM2ArenaLo( (void*)OSRoundUp32B( (u32)heapAddress + USERHEAP_SIZE ) ); userHeap = MEMCreateExpHeapEx( heapAddress, USERHEAP_SIZE, MEM_HEAP_OPT_THREAD_SAFE ); if( userHeap == NULL ) { OSHalt( "Could not create heap.\n" ); } } /* Initialize ENCContext for ROM Font */ (void)ENCInitContext(&encContext); (void)ENCSetExternalEncoding(&encContext, ( OSGetFontEncode() == OS_FONT_ENCODE_SJIS ) ? (const u8*)"Shift_JIS" : (const u8*)"ISO-8859-1"); (void)ENCSetBreakType(&encContext, ENC_BR_KEEP); (void)ENCSetAlternativeCharacter(&encContext, L'?', L'?'); /* Load NintendoDS program from DVD */ { DVDFileInfo file[1]; if ( !DVDOpen(program_path, file) ) { OSHalt( "failed to read NintendoDS program file from DVD.\n" ); } else { const u32 file_len = ( (DVDGetLength(file) + 31) & ~31 ); if ( file_len > program_buffer_max ) { OSHalt( "specified program file is too large.\n" ); } else if ( DVDRead(file, program_buffer, (int)file_len, 0) <= 0 ) { OSHalt( "failed to read NintendoDS program file from DVD.\n" ); } (void)DVDClose(file); } } /* if necessary, prepare custom banner image */ { static const char *banner_character_path = "custom_banner.chr"; static const char *banner_palette_path = "custom_banner.plt"; static u8 banner_character_buffer[sizeof(u16) * 16 * 16]; static u8 banner_palette_buffer[sizeof(u16) * 16]; BOOL banner_character_loaded = FALSE; BOOL banner_palette_loaded = FALSE; DVDFileInfo file[1]; if ( DVDOpen(banner_character_path, file) ) { if ( DVDRead(file, banner_character_buffer, (int)sizeof(banner_character_buffer), 0) == sizeof(banner_character_buffer) ) { banner_character_loaded = TRUE; } (void)DVDClose(file); } if ( DVDOpen(banner_palette_path, file) ) { if ( DVDRead(file, banner_palette_buffer, (int)sizeof(banner_palette_buffer), 0) == sizeof(banner_palette_buffer) ) { banner_palette_loaded = TRUE; } (void)DVDClose(file); } if ( banner_character_loaded && banner_palette_loaded ) { mpdlConfig.bannerCharacter = banner_character_buffer; mpdlConfig.bannerPalette = banner_palette_buffer; } } for (; ;) { enum { MODE_AUTODOWNLOAD, MODE_MAX }; int mode_cursor = 0; BOOL is_entry_closed; u32 fixed_entry; static BOOL auto_download_mode = TRUE; /* Initialize and startup MPDL */ if ( MPDLStartup( &mpdlConfig ) != MP_RESULT_OK ) { OSHalt( "failed to startup MPDL!\n" ); } is_entry_closed = FALSE; fixed_entry = 0; for (; ;) { int i; u32 entry; u32 booted; REXDEMOKPadRead(); /* Update sequence */ entry = MPDLGetEntryBitmap(); booted = MPDLGetBootedBitmap(); if (!is_entry_closed) { const u32 full_entry = (u32)(((1 << mpdlConfig.programMaxEntry) - 1) & ~1); /* Move cursor and select options */ if ((REXDEMOGetAnyMixedPadTrigger() & (KPAD_BUTTON_RIGHT | KPAD_BUTTON_LEFT | (PAD_BUTTON_RIGHT << 16) | (PAD_BUTTON_LEFT << 16))) != 0) { switch (mode_cursor) { case MODE_AUTODOWNLOAD: auto_download_mode = !auto_download_mode; break; default: break; } } if (((REXDEMOGetAnyMixedPadTrigger() & (KPAD_BUTTON_UP | (PAD_BUTTON_UP << 16))) != 0) && (--mode_cursor < 0)) { mode_cursor += MODE_MAX; } if (((REXDEMOGetAnyMixedPadTrigger() & (KPAD_BUTTON_DOWN | (PAD_BUTTON_DOWN << 16))) != 0) && (++mode_cursor >= MODE_MAX)) { mode_cursor -= MODE_MAX; } /* Close entry and start download */ if (((entry == full_entry) && auto_download_mode) || ((REXDEMOGetAnyMixedPadTrigger() & (KPAD_BUTTON_A | (PAD_BUTTON_A << 16))) != 0)) { is_entry_closed = TRUE; fixed_entry = MPDLStartDownload(); } } else if (entry == 0) { if ((REXDEMOGetAnyMixedPadTrigger() & (KPAD_BUTTON_A | (PAD_BUTTON_A << 16))) != 0) { break; } } /* DrawFrame */ REXDEMOBeginRender(); { /* *INDENT-OFF* */ static const GXColor ds_ipl_color_table[16] = { { 0x63, 0x84, 0x9C, }, /* GRAY */ { 0xBD, 0x4A, 0x00, }, /* BROWN */ { 0xFF, 0x00, 0x18, }, /* RED */ { 0xFF, 0x8C, 0xFF, }, /* PINK */ { 0xFF, 0x94, 0x00, }, /* ORANGE */ { 0xF7, 0xE7, 0x00, }, /* YELLOW */ { 0xAD, 0xFF, 0x00, }, /* LIME_GREEN */ { 0x00, 0xFF, 0x00, }, /* GREEN */ { 0x00, 0xA5, 0x39, }, /* DARK_GREEN */ { 0x4A, 0xDE, 0x8C, }, /* SEA_GREEN */ { 0x31, 0xBD, 0xF7, }, /* TURQUOISE */ { 0x00, 0x5A, 0xF7, }, /* BLUE */ { 0x00, 0x00, 0x94, }, /* DARK_BLUE */ { 0x8C, 0x00, 0xD6, }, /* PURPLE */ { 0xD6, 0x00, 0xEF, }, /* VIOLET */ { 0xFF, 0x00, 0x94, }, /* MAGENTA */ }; /* *INDENT-ON* */ const s16 ox = 4, oy = 158; /* header */ REXDEMOSetTextColor(white); REXDEMOPrintf(4, 8, 0, "MPDL simple sample"); REXDEMOSetTextColor(yellow); if (!is_entry_closed) { REXDEMOPrintf(4, 24, 0, "entry is opened."); REXDEMOPrintf(200, 24, 0, "(press A to start download)"); } else if (entry > 0) { REXDEMOPrintf(4, 24, 0, "entry is closed, now downloading..."); } else { REXDEMOPrintf(4, 24, 0, "download has been completed."); REXDEMOPrintf(320, 24, 0, "(press A to restart new entry)"); } REXDEMOSetTextColor(white); REXDEMOPrintf(30, 60, 0, "auto-download mode : ON OFF"); REXDEMOSetTextColor(yellow); REXDEMOPrintf(10, 60 + mode_cursor * 10, 0, ">"); REXDEMOPrintf(30, 60, 0, " %s %s", auto_download_mode ? "[ ]" : " ", auto_download_mode ? " " : "[ ]"); /* entries */ REXDEMOSetTextColor(white); REXDEMOPrintf(ox, oy, 0, "AID STATUS MAC-ADDR NAME"); for (i = 1; i < 16; ++i) { const s16 sy = (s16)(oy + i * 15); MPDLPlayerInfo info[1]; BOOL valid_player = MPDLGetPlayerInfo(i, info); REXDEMOSetTextColor(valid_player ? ds_ipl_color_table[info->color] : gray); /* AID */ REXDEMOPrintf(ox + 5, sy, 0, "%2d", i); /* STATUS */ if (!is_entry_closed) { if (valid_player) { REXDEMOPrintf(ox + 40, sy, 0, "ready"); } else if (i < mpdlConfig.programMaxEntry) { REXDEMOPrintf(ox + 40, sy, 0, " none "); } } else { if (valid_player) { if ((booted & (1 << i)) != 0) { REXDEMOPrintf(ox + 40, sy, 0, "booted"); } else { REXDEMOPrintf(ox + 40, sy, 0, " %3d%% ", info->progress); } } else if ((fixed_entry & (1 << i)) != 0) { REXDEMOPrintf(ox + 40, sy, 0, "failed"); } } /* MAC-ADDR & NAME */ if (valid_player) { char name[MPDL_PLAYER_NAME_MAX + 1]; { ENCContext convCtx; s32 dstlen, srclen; u16 nameUTF16[MPDL_PLAYER_NAME_MAX + 1]; dstlen = MPDL_PLAYER_NAME_MAX; srclen = (s32)(NETMinU32(info->name_length, MPDL_PLAYER_NAME_MAX)*sizeof(u16)); NETSwapAndCopyMemory16(nameUTF16, info->name, (u32)srclen); (void)NETMemSet(name, 0, sizeof(name)); (void)ENCDuplicateContext(&convCtx, &encContext); (void)ENCConvertFromInternalEncoding(&convCtx, (u8*)name, &dstlen, nameUTF16, &srclen); } REXDEMOPrintf(ox + 110, sy, 0, "%02X%02X%02X:%02X%02X%02X %-10s", info->mac[0], info->mac[1], info->mac[2], info->mac[3], info->mac[4], info->mac[5], name); } } } REXDEMOWaitRetrace(); } (void)MPDLCleanup(); } } /*===========================================================================*/