TwlIPL/build/libraries_sysmenu/util/ARM9/src/util_menuAppManager.c
yosiokat f559330864 WRAMクリアの領域確認。
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@1887 b08762b0-b915-fc4b-9d8c-17b2551a87ff
2008-07-15 01:44:36 +00:00

1295 lines
38 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*---------------------------------------------------------------------------*
Project: TwlIPL
File: util_menuAppManager.c
Copyright 2007 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.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#ifndef TWL_IPL_MENU_APP_MANAGER_FOR_STG
#include <sysmenu/util_menuAppManager.h>
#endif
#include <stddef.h>
#define MEASURE_BANNER_LOAD_TIME 0
void *(*AMNi_Alloc)( u32 size ) = NULL;
void (*AMNi_Free )( void *ptr ) = NULL;
/////////////////////////////////////////////////////////////////////////////////
// private:
static BOOL AMN_isTitleIdValidForLauncher(NAMTitleId id);
static void AMN_initFlags_();
static void AMN_initCardTitleList_();
static void AMN_initNandTitleList_();
static void AMN_lockSubBannerFileBuffer();
static void AMN_unlockSubBannerFileBuffer();
static u32 AMN_getBannerAnimeCRC(const BannerAnime* pAnime);
static BOOL AMN_checkAndReplaceBannerAnime(s32 index);
static vu8 sThreadStarted;
static vu8 sReadCancelFlag; // Æè ¦¸³Ž<C5BD>B
static vu8 sNandTitleListReady;
static vu8 sCardTitleListLength;
static s32 sNandAllTitleListLength; // error if <= 0
static s32 sNandTitleListLengthForLauncher;
static s32 sNandAppRomHeaderArrayLength;
static TitleProperty sAllTitlePropertyArray[cAllTitleArrayMax];
enum {
cEventMask_SubBannerFileBuffer = 0x1
};
static OSEvent sSubBannerFileBufferEvent;
enum {
cThreadPriority_Read = OS_THREAD_LAUNCHER_PRIORITY + 1,
cThreadPriority_Check = OS_THREAD_LAUNCHER_PRIORITY + 2
};
static OSThread sReadThread;
static OSThread sCheckThread;
static u64 sReadThreadStack[1024];
static u64 sCheckThreadStack[2048]; // 16KBytes FSÆNAMðŽg¤ÌÅ<E2809A>­µ½ßÉŽæé
static OSMessage sCheckMsgBuf[1];
static OSMessageQueue sCheckMsgQueue;
static void AMN_procRead();
static void AMN_procReadNandTitleOnly();
static void AMN_procReadNandTitleHeaderOnly();
static void AMN_procCheck();
static char sBootContentPath[FS_ENTRY_LONGNAME_MAX];
static TWLBannerFile* spNandBannerFileArray;
static TWLBannerFile* spEmptyBannerFileBuffer;
// ƒoƒi<C692>[ƒoƒbƒtƒ@<40>AƒTƒuƒoƒi<C692>[ƒoƒbƒtƒ@Í0x20 Bytes alignedɵ½¢<E2809A>B
// ƒ<>ƒƒŠªŒµµ¢ÌŃTƒuƒoƒi<C692>[ƒoƒbƒtƒ@Í1ŒÂÅŽg¢‰ñ·<E2809A>B
static TWLSubBannerFile* spSubBannerFileBuffer;
static AMNBannerCounter sBannerCounterArray[cAllTitleArrayMax];
static AMNFrameAnimeData sFrameAnimeDataArray[cAllTitleArrayMax];
static AMNFrameAnimeData sEmptyAnimeData;
static ROM_Header_Short sRomHeaderBuffer;
static ROM_Header_Short s_AllRomHeaderArray[OS_TITLEIDLIST_MAX];
// see also TwlIPL_RED/build/systemmenu_RED/Launcher/ARM9/src/bannerCounter.h
inline void AMN_BNC_resetCount( AMNBannerCounter *c )
{
c->count = 0;
c->control = 0;
}
inline void AMN_BNC_setBanner( AMNBannerCounter *c, const TWLBannerFile *b)
{
c->banner = b;
}
inline void AMN_BNC_initCounter( AMNBannerCounter *c, const TWLBannerFile *b)
{
AMN_BNC_setBanner( c, b );
AMN_BNC_resetCount( c );
}
inline const TWLBannerFile* AMN_BNC_getBanner( AMNBannerCounter *c )
{
return c->banner;
}
static void AMN_BNC_incrementCount( AMNBannerCounter *c );
static AMNFrameAnimeData AMN_BNC_getFAD( AMNBannerCounter *c );
static AMNFrameAnimeData AMN_BNC_getFADAndIncCount( AMNBannerCounter *c );
////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL AMN_isNandTitleListReady() { return sNandTitleListReady; }
s32 AMN_getNandTitleListLengthForLauncher() { return sNandTitleListLengthForLauncher; }
s32 AMN_getCardTitleListLength() { return sCardTitleListLength; }
s32 AMN_getRomHeaderListLength() { return sNandAppRomHeaderArrayLength + cNandTitleIndexStart;}
////////////////////////////////////////////////////////////////////////////////////////////////////
/*!
ƒRƒ“ƒXƒgƒ‰ƒNƒ^<5E>iC++Žžã̈╨<E280A2>j
AMN_Init()‚©‚çŒÄ‚΂ê‚邾‚¯
*/
static void AMN_Manager( )
{
sThreadStarted = FALSE;
spNandBannerFileArray = NULL;
spEmptyBannerFileBuffer = NULL;
spSubBannerFileBuffer = NULL;
// CARDƒAƒvƒŠÍ1ŒÂÜÅ<E2809A>B
SDK_ASSERT( cCardTitleArrayMax == 1 );
// NANDƒAƒvƒŠÍ39ŒÂÜÅ•\ަūé<E2809A>B
SDK_ASSERT( cNandTitleArrayMax == 39 );
#ifndef TWL_IPL_FINAL
// Œ¾ŒêenumÌŠÄŽ<C5BD>B
SDK_ASSERT( BANNER_PRIO_JAPANESE == OS_LANGUAGE_JAPANESE );
SDK_ASSERT( BANNER_PRIO_ENGLISH == OS_LANGUAGE_ENGLISH );
SDK_ASSERT( BANNER_PRIO_FRENCH == OS_LANGUAGE_FRENCH );
SDK_ASSERT( BANNER_PRIO_GERMAN == OS_LANGUAGE_GERMAN );
SDK_ASSERT( BANNER_PRIO_ITALIAN == OS_LANGUAGE_ITALIAN );
SDK_ASSERT( BANNER_PRIO_SPANISH == OS_LANGUAGE_SPANISH );
SDK_ASSERT( BANNER_PRIO_CHINESE == OS_LANGUAGE_CHINESE );
SDK_ASSERT( BANNER_PRIO_KOREAN == OS_LANGUAGE_HANGUL );
#endif
AMN_initFlags_();
}
/*!
N“®<E2809C>B
*/
void AMN_init( void *(*pAlloc)(u32), void (*pFree)(void*) )
{
// Œ³ƒRƒ“ƒXƒgƒ‰ƒNƒ^
AMN_Manager();
// ±ÌŽž“_ÅAMNi_AllocÆAMNi_FreeªNULLÅ é×µ
SDK_ASSERT( AMNi_Alloc == NULL && AMNi_Free == NULL );
AMNi_Alloc = pAlloc;
AMNi_Free = pFree;
spNandBannerFileArray = (TWLBannerFile*)AMNi_Alloc( sizeof(TWLBannerFile) * cNandTitleArrayMax );
SDK_ASSERT( spNandBannerFileArray );
spEmptyBannerFileBuffer = (TWLBannerFile*)AMNi_Alloc( sizeof(TWLBannerFile) );
SDK_ASSERT( spEmptyBannerFileBuffer );
spSubBannerFileBuffer = (TWLSubBannerFile*)AMNi_Alloc( sizeof(TWLSubBannerFile) );
SDK_ASSERT( spSubBannerFileBuffer );
MI_CpuClearFast(spEmptyBannerFileBuffer, sizeof(TWLBannerFile));
sEmptyAnimeData.image = spEmptyBannerFileBuffer->v1.image;
sEmptyAnimeData.pltt = spEmptyBannerFileBuffer->v1.pltt;
sEmptyAnimeData.hflip = FALSE;
sEmptyAnimeData.vflip = FALSE;
MI_CpuClearFast(sAllTitlePropertyArray, sizeof(sAllTitlePropertyArray));
#ifndef TWL_IPL_FINAL
// test
#if 0
if (0) {
BOOL ret;
ret = NAM_CheckTitleLaunchRights(
0x00030004534d504c // "SMPL" - nandAppSample
// 0x00030015344e4141 // "4NAA" - UIG launcher default
);
IPL_PRINT("NAM_CheckTitleLaunchRights()=%d\n", ret);
SDK_ASSERT( FALSE );
}
if (0) {
FSFile file[1];
BOOL ret;
FS_InitFile(file);
ret = FS_OpenFileEx(file, "sdmc:/dummy.bkp", FS_FILEMODE_R);
IPL_PRINT("FS_OpenFileEx()=%d\n", ret);
FS_CloseFile(file);
SDK_ASSERT( FALSE );
}
// test
if (0) {
s32 ret = NAM_ImportBkpSave("sdmc:/dummy.bkp");
IPL_PRINT("NAM_ImportBkpSave()=%d\n", ret);
SDK_ASSERT( FALSE );
}
if (0) {
// Èñ©<E2809A>A[ES] generate cert failed -2012
// ÉÈé<E2809A>B
s32 ret = NAM_ExportBkp(
// 0x0003001534303241, // "402A" - UIG launcher clone
// 0x00030015344e4141, // "4NAA" - UIG launcher default
0x00030004534d504c, // "SMPL" - nandAppSample
"sdmc:/test.bkp");
IPL_PRINT("NAM_ExportBkp()=%d\n", ret);
}
if (0) {
NAMBkpInfo info;
static TWLBannerFile banner;
info.fileSize = 0;
info.hardwareId = 0;
s32 ret = NAM_ReadBkpInfo(&info, &banner, sizeof(banner),
"sdmc:/test.bkp");
IPL_PRINT("NAM_ReadBkpInfo()=%d, fileSize=%d, HWID=%016llx\n",
ret, info.fileSize, (u64)info.hardwareId);
SDK_ASSERT( FALSE );
}
#endif
#endif
//AMN_restart(); // Ž©“®ƒ<C2AE><C692>[ƒhµÄµÜ¤ÌÍ<E2809A>ˆ<C5A0>ü}”²ƒ‰ƒCƒuƒ‰ƒŠÅCARD¾¯“Çݽ¢<E2809A>ê<EFBFBD>âNAND“ÇÝ<E2809A>žÝƒ^ƒCƒ~ƒ“ƒOðxç¹½¢<E2809A>ê<EFBFBD>É•s“s<E2809C>
}
/*!
<20>ÄN“®<E2809C>B
*/
void AMN_restart()
{
// AMNi_Alloc¨æÑAMNi_Free̓Zƒbƒg³êÄ¢é×µ
SDK_ASSERT( AMNi_Alloc != NULL && AMNi_Free != NULL );
AMN_initFlags_();
SDK_ASSERT( !sThreadStarted || OS_IsThreadTerminated(&sReadThread) );
sThreadStarted = TRUE;
OS_InitEvent(&sSubBannerFileBufferEvent);
AMN_unlockSubBannerFileBuffer();
OS_InitMessageQueue(&sCheckMsgQueue, sCheckMsgBuf, sizeof(sCheckMsgBuf) / sizeof(*sCheckMsgBuf));
OS_CreateThread(&sReadThread, AMN_procRead, NULL,
sReadThreadStack + (sizeof(sReadThreadStack) / sizeof(*sReadThreadStack)),
sizeof(sReadThreadStack),
cThreadPriority_Read);
OS_CreateThread(&sCheckThread, AMN_procCheck, NULL,
sCheckThreadStack + (sizeof(sCheckThreadStack) / sizeof(*sCheckThreadStack)),
sizeof(sCheckThreadStack),
cThreadPriority_Check);
// for safety, wakeup sCheckThread first
OS_WakeupThreadDirect(&sCheckThread);
OS_WakeupThreadDirect(&sReadThread);
}
/*!
NANDƒ^ƒCƒgƒ¾¯Žæ“¾µÈªçÌ<E2809A>ÄN“®<E2809C>B
*/
void AMN_restartWithReadNandTitle()
{
// AMNi_Alloc¨æÑAMNi_Free̓Zƒbƒg³êÄ¢é×µ
SDK_ASSERT( AMNi_Alloc != NULL && AMNi_Free != NULL );
AMN_initFlags_();
SDK_ASSERT( !sThreadStarted || OS_IsThreadTerminated(&sReadThread) );
sThreadStarted = TRUE;
OS_InitEvent(&sSubBannerFileBufferEvent);
AMN_unlockSubBannerFileBuffer();
OS_InitMessageQueue(&sCheckMsgQueue, sCheckMsgBuf, sizeof(sCheckMsgBuf) / sizeof(*sCheckMsgBuf));
OS_CreateThread(&sReadThread, AMN_procReadNandTitleOnly, NULL,
sReadThreadStack + (sizeof(sReadThreadStack) / sizeof(*sReadThreadStack)),
sizeof(sReadThreadStack),
cThreadPriority_Read);
OS_CreateThread(&sCheckThread, AMN_procCheck, NULL,
sCheckThreadStack + (sizeof(sCheckThreadStack) / sizeof(*sCheckThreadStack)),
sizeof(sCheckThreadStack),
cThreadPriority_Check);
// for safety, wakeup sCheckThread first
OS_WakeupThreadDirect(&sCheckThread);
OS_WakeupThreadDirect(&sReadThread);
}
/*!
NANDƒ^ƒCƒgƒÌROM_HEADER_SHORT¾¯Žæ“¾µÈªçÌ<E2809A>ÄN“®<E2809C>B
*/
void AMN_restartWithReadNandTitleHeaderShort()
{
// AMNi_Alloc¨æÑAMNi_Free̓Zƒbƒg³êÄ¢é×µ
SDK_ASSERT( AMNi_Alloc != NULL && AMNi_Free != NULL );
AMN_initFlags_();
SDK_ASSERT( !sThreadStarted || OS_IsThreadTerminated(&sReadThread) );
sThreadStarted = TRUE;
OS_CreateThread(&sReadThread, AMN_procReadNandTitleHeaderOnly, NULL,
sReadThreadStack + (sizeof(sReadThreadStack) / sizeof(*sReadThreadStack)),
sizeof(sReadThreadStack),
cThreadPriority_Read);
OS_WakeupThreadDirect(&sReadThread);
}
/*!
<20>I—¹<E28094>B
*/
void AMN_destroy()
{
sReadCancelFlag = TRUE;
while ( sThreadStarted && !OS_IsThreadTerminated(&sReadThread) ) {
OS_Sleep(1);
}
if( AMNi_Free != NULL && spSubBannerFileBuffer)
{
AMNi_Free( spSubBannerFileBuffer );
}
if( AMNi_Free != NULL && spEmptyBannerFileBuffer)
{
AMNi_Free( spEmptyBannerFileBuffer );
}
if( AMNi_Free != NULL && spNandBannerFileArray)
{
AMNi_Free( spNandBannerFileArray );
}
}
static void AMN_initFlags_()
{
sReadCancelFlag = FALSE;
sNandTitleListReady = FALSE;
sNandAllTitleListLength = 0;
sNandTitleListLengthForLauncher = 0;
sCardTitleListLength = 0;
sNandAppRomHeaderArrayLength = 0;
}
static void AMN_initCardTitleList_()
{
}
static void AMNi_getAndAddNandTitleData( NAMTitleId titleID, BOOL readShowData )
{
TitleProperty* pTitleProp;
// header<65>î•ñ̎擾
#if (MEASURE_BANNER_LOAD_TIME == 1)
OSTick start;
#endif
FSFile file[1];
BOOL bSuccess;
char path[FS_ENTRY_LONGNAME_MAX];
s32 readLen;
u32 offset;
s32 rhArrayLen = cNandTitleIndexStart + sNandAppRomHeaderArrayLength;
// ‚à‚¤“ü‚ç‚È‚¢
if (rhArrayLen >= OS_TITLEIDLIST_MAX) {
return;
}
FS_InitFile(file);
#if (MEASURE_BANNER_LOAD_TIME == 1)
start = OS_GetTick();
#endif
if( (titleID & TITLE_ID_DATA_ONLY_FLAG_MASK) == 0 )
{
// DataOnlyÅÈ¢<E2809A>ê<EFBFBD>
readLen = NAM_GetTitleBootContentPathFast( path, titleID );
#if (MEASURE_BANNER_LOAD_TIME == 1)
OS_TPrintf( "NAM_GetTitleBootContentPath : %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
#endif
// ƒtƒ@ƒCƒƒpƒXðŽæ“¾
if(readLen != NAM_OK){
// error
SDK_ASSERT( FALSE );
return;
}
#if (MEASURE_BANNER_LOAD_TIME == 1)
start = OS_GetTick();
#endif
// ƒtƒ@ƒCƒƒI<C692>[ƒvƒ“
bSuccess = FS_OpenFileEx(file, path, FS_FILEMODE_R);
if( ! bSuccess )
{
// error
SDK_ASSERT( FALSE );
return;
}
#if (MEASURE_BANNER_LOAD_TIME == 1)
OS_TPrintf( "OpenFileEX : %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
start = OS_GetTick();
#endif
readLen = FS_ReadFile(file, &s_AllRomHeaderArray[rhArrayLen], sizeof(ROM_Header_Short));
if( readLen != sizeof(ROM_Header_Short) )
{
// error
SDK_ASSERT( FALSE );
FS_CloseFile(file);
return;
}
offset = s_AllRomHeaderArray[rhArrayLen].banner_offset;
#if (MEASURE_BANNER_LOAD_TIME == 1)
OS_TPrintf( "FS_ReadFile header : %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
#endif
}
else
{
// DataOnlyÌ<E2809A>ê<EFBFBD>
int l;
NAMTitleInfo naminfo;
// ±ÌŠÖ<C5A0>Å“¾çêé<E2809A>î•ñͳŒŸ<C592>ØÈÌʼnü´ñ̉”\<5C>«ª éª<E2809A><41><C692>[ƒJ<C692>[ƒR<C692>[ƒhÌÝÌ”»èÈÌÅ<E2809A>A¬“xð—D<E28094>æ·é<E2809A>B(2008.06.20g‰ª)
// <20>iFast¯Ȣƈê‰ñ300ms®ç¢©©é<E2809A>j
NAM_ReadTitleInfoFast( &naminfo, titleID );
MI_CpuClear8(&s_AllRomHeaderArray[rhArrayLen], sizeof(ROM_Header_Short) );
OS_TPrintf( "0x%0.16llx dataonly-title : makercode = ", titleID );
for(l=0;l<MAKER_CODE_MAX;l++)
{
s_AllRomHeaderArray[rhArrayLen].maker_code[l] = ((char *)&naminfo.companyCode)[l];
OS_TPrintf( "0x%0.2x ", s_AllRomHeaderArray[rhArrayLen].maker_code[l] );
}
OS_TPrintf( "\n" );
s_AllRomHeaderArray[rhArrayLen].titleID = titleID;
sNandAppRomHeaderArrayLength++;
return;
}
if(s_AllRomHeaderArray[rhArrayLen].platform_code & PLATFORM_CODE_FLAG_TWL){
// ROMƒwƒbƒ_̃Š<C692>[ƒWƒ‡ƒ“ƒ`ƒFƒbƒNÆCRCƒ`ƒFƒbƒNð<E2809A>s¢<E2809A>A•s<E280A2>³ÈƒAƒvƒŠÍ³Ž·é<E2809A>B
if( !UTL_CheckAppRegion( s_AllRomHeaderArray[rhArrayLen].card_region_bitmap ) ) {
OS_TPrintf( "Region Check NG : %llx\n", titleID );
FS_CloseFile(file);
return;
}
}
if( !UTL_CheckAppCRC16( &s_AllRomHeaderArray[rhArrayLen] ) ) {
OS_TPrintf( "CRC16 Check NG : %llx\n", titleID );
FS_CloseFile(file);
return;
}
sNandAppRomHeaderArrayLength++;
// ‚à‚¤ƒ‰ƒ“ƒ`ƒƒ<C692>[•\ަ—p<E28094>î•ñÍ<E2809A>ªƒI<C692>[ƒo<C692>[µÄé©<E2809A>A•\ަ—p<E28094>î•ñð“ÇÜÈ¢<E2809A>Ýè
if ( ( sNandTitleListLengthForLauncher >= cNandTitleArrayMax ) || !readShowData ) {
FS_CloseFile(file);
return;
}
// ˆÈ‰º‚Í•\ަ·éƒAƒvƒŠÌÝ<E2809A>iŒ»<C592>ÝƒŠƒXƒgÉ éƒf<C692>[ƒ^<5E>ªNandƒ^ƒCƒgƒ<C692>Ì<E2809A>Ååð´¦Ä¢È¢<E2809A>ê<EFBFBD><EFBFBD>jÌ<E2809A>ˆ<CB86>
// ƒ^ƒCƒgƒƒŠƒXƒgÖÌljÁ
pTitleProp = &sAllTitlePropertyArray[cNandTitleIndexStart + sNandTitleListLengthForLauncher];
pTitleProp->titleID = titleID;
pTitleProp->pBanner = &spNandBannerFileArray[sNandTitleListLengthForLauncher];
pTitleProp->flags.isValid = TRUE;
pTitleProp->flags.bootType = LAUNCHER_BOOTTYPE_NAND;
// ƒoƒi<C692>[‚̎擾
// ƒoƒi<C692>[ª<E28098>Ý·é<E2809A>ê<EFBFBD>Ì݃Š<C692>[ƒh
if( offset ) {
#if (MEASURE_BANNER_LOAD_TIME == 1)
start = OS_GetTick();
#endif
bSuccess = FS_SeekFile(file, (s32)offset, FS_SEEK_SET);
if( ! bSuccess )
{
// error
SDK_ASSERT( FALSE );
FS_CloseFile(file);
return;
}
#if (MEASURE_BANNER_LOAD_TIME == 1)
OS_TPrintf( "FS_SeekFile banner: %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
start = OS_GetTick();
#endif
readLen = FS_ReadFile( file, pTitleProp->pBanner, (s32)sizeof(TWLBannerFile) );
if( readLen != (s32)sizeof(TWLBannerFile) )
{
// error
SDK_ASSERT( FALSE );
FS_CloseFile(file);
return;
}
#if (MEASURE_BANNER_LOAD_TIME == 1)
OS_TPrintf( "FS_ReadFile banner: %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
start = OS_GetTick();
#endif
// ƒoƒi<C692>[ƒ`ƒFƒbƒNƒŠƒNƒGƒXƒg<E28098>M<EFBFBD>B
OS_SendMessage(&sCheckMsgQueue, (OSMessage)(pTitleProp->pBanner), OS_MESSAGE_BLOCK);
#if (MEASURE_BANNER_LOAD_TIME == 1)
OS_TPrintf( "check banner: %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
#endif
}else {
// ƒoƒi<C692>[ª<E28098>ݵȢ<E2809A>ê<EFBFBD>̓oƒbƒtƒ@ƒNƒŠƒA
MI_CpuClearFast( pTitleProp->pBanner, sizeof(TWLBannerFile) );
}
#if (MEASURE_BANNER_LOAD_TIME == 1)
start = OS_GetTick();
#endif
FS_CloseFile(file);
#if (MEASURE_BANNER_LOAD_TIME == 1)
OS_TPrintf( "close file : %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
start = OS_GetTick();
#endif
// ƒTƒuƒoƒi<C692>[ƒtƒ@ƒCƒð“ÇÝ<E2809A>žñÅÝé
if(s_AllRomHeaderArray[rhArrayLen].exFlags.availableSubBannerFile &&
NAM_OK == NAM_GetTitleBannerFilePath( path, titleID ))
{
#if (MEASURE_BANNER_LOAD_TIME == 1)
OS_TPrintf( "NAM_GetTitleBannerFilePath : %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
start = OS_GetTick();
#endif
if (FS_OpenFileEx(file, path, FS_FILEMODE_R)) {
// ƒTƒuƒoƒi<C692>[ƒoƒbƒtƒ@Šm•Û<E280A2>B
AMN_lockSubBannerFileBuffer();
readLen = FS_ReadFile(file, spSubBannerFileBuffer, sizeof(*spSubBannerFileBuffer));
FS_CloseFile(file);
if (readLen == sizeof(TWLSubBannerFile)) {
// “ÇÝ<E2809A>žÝÉÍ<E2809A>¬Œ÷µ½ÌÅ<E2809A>³“<E2809C>«ƒ`ƒFƒbƒN
// ƒTƒuƒoƒi<C692>[ƒ`ƒFƒbƒNƒŠƒNƒGƒXƒg<E28098>M<EFBFBD>B
OS_SendMessage(&sCheckMsgQueue, (OSMessage)(cNandTitleIndexStart + sNandTitleListLengthForLauncher), OS_MESSAGE_BLOCK);
// ‰ð•úÍCHECKƒXƒŒƒbƒh¤Å<E2809A>s¤<E2809A>B
} else {
OS_TPrintf("subbanner read failed (%d)\n", readLen);
// ‰ð•ú<E280A2>B
AMN_unlockSubBannerFileBuffer();
}
}
#if (MEASURE_BANNER_LOAD_TIME == 1)
OS_TPrintf( "open-read-close-check subbanner : %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
#endif
}
sNandTitleListLengthForLauncher++;
}
/*!
see also SYSM_InitNandTitleList() and SYSM_GetNandTitleList()
ƒCƒ“ƒ|<7C>[ƒg³êÄ¢é·×ÄÌNANDƒAƒvƒŠð—ñµ½ƒŠƒXƒgÌ<E2809A>€”õ
*/
static void AMN_initNandTitleList_()
{
s32 ret;
s32 l;
NAMTitleId* pNandAllTitleIDList = NULL;
// ƒCƒ“ƒ|<7C>[ƒg³êÄ¢éƒ^ƒCƒgƒÌŽæ“¾
sNandAllTitleListLength = NAM_GetNumTitles();
OS_TPrintf("NAM_GetNumTitles()=%d\n", sNandAllTitleListLength);
// <20>­È­Æàƒ‰ƒ“ƒ`ƒƒ<C692>[Ƴ<E28093>üƒtƒ@<40>[ƒ€ªƒŠƒXƒgƒAƒbƒv³êé͸<E2809A>B
// ¾ª<E2809A>Aˆê‰ž0ÍÊ·<E2809A>B
SDK_ASSERT( sNandAllTitleListLength >= 0 );
if (sNandAllTitleListLength > 0) {
pNandAllTitleIDList = (NAMTitleId*)AMNi_Alloc( sizeof(NAMTitleId) * sNandAllTitleListLength );
SDK_ASSERT( pNandAllTitleIDList );
if (!pNandAllTitleIDList) {
// error
sNandAllTitleListLength = 0;
} else {
ret = NAM_GetTitleList(pNandAllTitleIDList, (u32)sNandAllTitleListLength);
OS_TPrintf("NAM_GetTitleList()=%d\n", ret);
SDK_ASSERT( ret == NAM_OK );
if (ret != NAM_OK) {
// error
sNandAllTitleListLength = 0;
}
}
}
// ƒ<>ƒƒŠÌŠm•ÛÆ‰ð•ú𓯶ŠÖ<C5A0>”“àÅ<E2809A>s¢½¢ÌÅ<E2809A>A
// Žæ“¾‚µ‚½ƒ^ƒCƒgƒªƒ<C2AA><C692>[ƒ“ƒ`Î<E28098>۩Ǥ©ðƒ`ƒFƒbƒN
// ð<E2809A>A±±Å<E2809A>s¤<E2809A>B
// ‚·‚ׂẴ^ƒCƒgƒÌƒwƒbƒ_ð“ÇÝ<E2809A>žÞÌÅ<E2809A>A<EFBFBD>i<EFBFBD>žÝÌ•K—vÍÈ¢
for (l = 0; l < sNandAllTitleListLength; l++) {
if (AMN_isTitleIdValidForLauncher(pNandAllTitleIDList[l])) {
AMNi_getAndAddNandTitleData( pNandAllTitleIDList[l], TRUE );
// {Ì<E28098>ÝèÌ<E2809A>ê<EFBFBD><EFBFBD>AƒAƒvƒŠƒ}ƒl<C692>[ƒWƒƒ—pindexÍ”òÑ”òÑÉÈÁ½è<E2809A>AForSetting()ª•Ô·l(ŒÂ<C592>”)‚æ‚è‘å‚«‚­‚È‚é‚Ì‚Å
// getNandTitleListLengthForSetting()Í—pˆÓµÈ¢<E2809A>B
}
}
// ƒ<><C692>[ƒ“ƒ`Î<E28098>ÛÅÈ¢ƒ^ƒCƒgƒÌ<E2809A>î•ñ̎擾
for (l = 0; l < sNandAllTitleListLength; l++) {
if (!AMN_isTitleIdValidForLauncher(pNandAllTitleIDList[l])) {
AMNi_getAndAddNandTitleData( pNandAllTitleIDList[l], FALSE );
}
}
if (pNandAllTitleIDList) {
AMNi_Free( pNandAllTitleIDList );
}
}
// ƒCƒ“ƒ|<7C>[ƒg³êÄ¢é·×Ä̃^ƒCƒgƒÌROM_HEADER_SHORTÌÝ“ÇÝ<E2809A>o·
static void AMN_initNandTitleRomHeaderShortList_()
{
s32 ret;
s32 l;
NAMTitleId* pNandAllTitleIDList = NULL;
// ƒCƒ“ƒ|<7C>[ƒg³êÄ¢éƒ^ƒCƒgƒÌŽæ“¾
sNandAllTitleListLength = NAM_GetNumTitles();
OS_TPrintf("NAM_GetNumTitles()=%d\n", sNandAllTitleListLength);
// <20>­È­Æàƒ‰ƒ“ƒ`ƒƒ<C692>[Ƴ<E28093>üƒtƒ@<40>[ƒ€ªƒŠƒXƒgƒAƒbƒv³êé͸<E2809A>B
// ¾ª<E2809A>Aˆê‰ž0ÍÊ·<E2809A>B
SDK_ASSERT( sNandAllTitleListLength >= 0 );
if (sNandAllTitleListLength > 0) {
pNandAllTitleIDList = (NAMTitleId*)AMNi_Alloc( sizeof(NAMTitleId) * sNandAllTitleListLength );
SDK_ASSERT( pNandAllTitleIDList );
if (!pNandAllTitleIDList) {
// error
sNandAllTitleListLength = 0;
} else {
ret = NAM_GetTitleList(pNandAllTitleIDList, (u32)sNandAllTitleListLength);
OS_TPrintf("NAM_GetTitleList()=%d\n", ret);
SDK_ASSERT( ret == NAM_OK );
if (ret != NAM_OK) {
// error
sNandAllTitleListLength = 0;
}
}
}
// ƒ^ƒCƒgƒÌ<E2809A>î•ñ(ƒwƒbƒ_ÌÝ)‚̎擾
for (l = 0; l < sNandAllTitleListLength; l++) {
AMNi_getAndAddNandTitleData( pNandAllTitleIDList[l], FALSE );
}
if (pNandAllTitleIDList) {
AMNi_Free( pNandAllTitleIDList );
}
}
// <20>¶ƒf<C692>[ƒ^<5E>iTitlePropertyÌƒŠƒXƒg<C692>AHeaderShortƒŠƒXƒg<C692>jɃAƒNƒZƒXū锲¯“¹ŠÖ<C5A0>
TitleProperty* AMN_getTitlePropertyList( void )
{
return sAllTitlePropertyArray;
}
ROM_Header_Short* AMN_getRomHeaderList( void )
{
return s_AllRomHeaderArray;
}
static void AMN_procRead()
{
MI_CpuClearFast(sAllTitlePropertyArray, sizeof(sAllTitlePropertyArray));
AMN_initCardTitleList_();
AMN_initNandTitleList_();
OS_SendMessage(&sCheckMsgQueue, NULL, OS_MESSAGE_BLOCK);
OS_JoinThread(&sCheckThread);
AMN_stepBannerAnimeAll( TRUE );
// for GX DMA
DC_StoreAll();
if (!sReadCancelFlag) {
sNandTitleListReady = TRUE;
}
}
// Nandƒ^ƒCƒgƒ¾¯Žæ“¾<E2809C>ACard•”•ªÍno care
static void AMN_procReadNandTitleOnly()
{
MI_CpuClearFast(&sAllTitlePropertyArray[cNandTitleIndexStart], sizeof(TitleProperty) * ( cAllTitleArrayMax - cNandTitleIndexStart ) );
AMN_initNandTitleList_();
OS_SendMessage(&sCheckMsgQueue, NULL, OS_MESSAGE_BLOCK);
OS_JoinThread(&sCheckThread);
AMN_stepBannerAnimeAll( TRUE );
// for GX DMA
DC_StoreAll();
if (!sReadCancelFlag) {
sNandTitleListReady = TRUE;
}
}
// Nandƒ^ƒCƒgƒÌROM_Header_Short¾¯Žæ“¾<E2809C>ACard•”•ªÍno care
static void AMN_procReadNandTitleHeaderOnly()
{
AMN_initNandTitleRomHeaderShortList_();
// for GX DMA
DC_StoreAll();
if (!sReadCancelFlag) {
sNandTitleListReady = TRUE;
}
}
static void AMN_procCheck()
{
OSMessage msg;
s32 index;
TWLBannerFile* pBanner;
while (TRUE) {
OS_ReceiveMessage(&sCheckMsgQueue, &msg, OS_MESSAGE_BLOCK);
// IPL_PRINT("procCheck: msg=0x%x\n", msg);
if (!msg) {
break;
}
index = (s32)msg;
// 0̓XƒŒƒbƒh<C692>I—¹ðˆÓ¡·éÌÅindexƵÄÍ•s“K<E2809C>Ø<EFBFBD>B
// ܽ<E2809A>ACARDÈÌŃTƒuƒoƒi<C692>[Í è¦È¢<E2809A>B
SDK_ASSERT( cNandTitleIndexStart > 0 );
if (cNandTitleIndexStart <= index && index < (cNandTitleIndexStart + cNandTitleArrayMax)) {
// ƒTƒuƒoƒi<C692>[
(void)AMN_checkAndReplaceBannerAnime(index);
AMN_unlockSubBannerFileBuffer();
} else {
pBanner = (TWLBannerFile*)msg;
if (!AMN_checkBannerFile(pBanner)) {
// <20>³“<E2809C>«ƒ`ƒFƒbƒNޏ”sÌ<E2809A>ê<EFBFBD>̓oƒbƒtƒ@ƒNƒŠƒA
MI_CpuClearFast(pBanner, sizeof(*pBanner));
OS_TPrintf("check NG! msg=0x%x propAry=0x%x\n", pBanner, sAllTitlePropertyArray);
}
}
}
}
static void AMN_lockSubBannerFileBuffer()
{
OS_WaitEventEx_And(&sSubBannerFileBufferEvent,
cEventMask_SubBannerFileBuffer,
cEventMask_SubBannerFileBuffer);
}
static void AMN_unlockSubBannerFileBuffer()
{
OS_SignalEvent(&sSubBannerFileBufferEvent,
cEventMask_SubBannerFileBuffer);
}
const TitleProperty* AMN_getTitleProperty(s32 index)
{
const TitleProperty* pTitleProp;
if (cAllTitleIndexStart <= index && index < cAllTitleArrayMax) {
pTitleProp = &sAllTitlePropertyArray[index];
if (pTitleProp->flags.isValid) {
return pTitleProp;
}
}
return NULL;
}
const ROM_Header_Short* AMN_getTitleRomHeaderShort(s32 index)
{
const ROM_Header_Short* pRhs;
if (cAllTitleIndexStart <= index && index < cAllTitleArrayMax) {
pRhs = &s_AllRomHeaderArray[index];
return pRhs;
}
return NULL;
}
BOOL AMN_isDSWirelessIcon(s32 index)
{
const ROM_Header_Short* pRhs = AMN_getTitleRomHeaderShort(index);
if (pRhs) {
return pRhs->exFlags.DSWirelessIcon;
}
return FALSE;
}
BOOL AMN_isWiFiConnectionIcon(s32 index)
{
const ROM_Header_Short* pRhs = AMN_getTitleRomHeaderShort(index);
if (pRhs) {
return pRhs->exFlags.WiFiConnectionIcon;
}
return FALSE;
}
BOOL AMN_isAgreeEULAFlag(s32 index)
{
const ROM_Header_Short* pRhs = AMN_getTitleRomHeaderShort(index);
if (pRhs) {
return pRhs->exFlags.agree_EULA;
}
return FALSE;
}
const u8* AMN_getParentalControlRatingInfo(s32 index)
{
const ROM_Header_Short* pRhs = AMN_getTitleRomHeaderShort(index);
if (pRhs) {
return pRhs->parental_control_rating_info;
}
return FALSE;
}
// ƒ^ƒCƒgƒIDª{Ì<E28098>Ýè—pƵÄͳŒøÅ ÁÄà<E2809A>A
// Ήž·éindexð•Եܷ<E2809A>B
s32 AMN_getIndexByTitleId(NAMTitleId titleId)
{
const TitleProperty* pTitleProp;
s32 index;
// ˆê‰ž<E280B0>ATitleID == 0 ̃AƒvƒŠª é©àµêÈ¢<E2809A>HÌÅ<E2809A>A
// NAND©ç—D<E28094>æ“IÉT·<E2809A>B
// CARDÍTITLE_ID_MEDIA_MASKª1ÉÈé͸<E2809A>B
// NAND
index = cNandTitleIndexStart + sNandTitleListLengthForLauncher - 1;
while (index >= cNandTitleIndexStart) {
pTitleProp = AMN_getTitleProperty(index);
if (pTitleProp &&
pTitleProp->titleID == titleId) {
return index;
}
index--;
}
// CARD
index = sCardTitleListLength - 1;
while (index >= cCardTitleIndexStart) {
pTitleProp = AMN_getTitleProperty(index);
if (pTitleProp &&
pTitleProp->titleID == titleId) {
return index;
}
index--;
}
return -1;
}
// indexª{Ì<E28098>Ýè—pƵÄͳŒøÅ ÁÄà<E2809A>A
// ‘Ήž‚·‚éƒ^ƒCƒgƒIDð•Եܷ<E2809A>B
NAMTitleId AMN_getTitleIdByIndex(s32 index)
{
const TitleProperty* pTitleProp = AMN_getTitleProperty(index);
if (pTitleProp) {
return pTitleProp->titleID;
}
return (NAMTitleId)0;
}
void AMN_stepBannerAnimeAll(BOOL restart)
{
s32 index;
for (index = cAllTitleIndexStart; index < cAllTitleArrayMax; index++) {
AMN_stepBannerAnime(index, restart);
}
}
void AMN_stepBannerAnime(s32 index, BOOL restart)
{
const TWLBannerFile* pBanner;
AMNBannerCounter* pBNC;
if (cAllTitleIndexStart <= index && index < cAllTitleArrayMax) {
pBNC = &sBannerCounterArray[index];
if (restart) {
pBanner = sAllTitlePropertyArray[index].pBanner;
if (!pBanner) {
pBanner = spEmptyBannerFileBuffer;
}
AMN_BNC_initCounter(pBNC, pBanner);
} else {
AMN_BNC_incrementCount(pBNC);
}
sFrameAnimeDataArray[index] = AMN_BNC_getFAD(pBNC);
}
}
const u8* AMN_getBannerImage(s32 index)
{
AMNFrameAnimeData ret = AMN_getBannerAnime(index);
return ret.image;
}
const u8* AMN_getBannerPltt(s32 index)
{
AMNFrameAnimeData ret = AMN_getBannerAnime(index);
return ret.pltt;
}
BOOL AMN_getBannerHFlip(s32 index)
{
AMNFrameAnimeData ret = AMN_getBannerAnime(index);
return ret.hflip;
}
BOOL AMN_getBannerVFlip(s32 index)
{
AMNFrameAnimeData ret = AMN_getBannerAnime(index);
return ret.vflip;
}
AMNFrameAnimeData AMN_getBannerAnime(s32 index)
{
if (cAllTitleIndexStart <= index && index < cAllTitleArrayMax) {
return sFrameAnimeDataArray[index];
}
return sEmptyAnimeData;
}
const u16* AMN_getBannerText2(s32 index, OSLanguage language)
{
const TitleProperty* pTitleProp = AMN_getTitleProperty(index);
if (language >= OS_LANGUAGE_CODE_MAX) {
language = OS_LANGUAGE_ENGLISH;
}
if (pTitleProp) {
if (language < BANNER_LANG_NUM_V1) {
return pTitleProp->pBanner->v1.gameName[language];
}
language = (OSLanguage)(language - BANNER_LANG_NUM_V1);
if (language < BANNER_LANG_NUM_V2) {
return pTitleProp->pBanner->v2.gameName[language];
}
language = (OSLanguage)(language - BANNER_LANG_NUM_V2);
return pTitleProp->pBanner->v3.gameName[language];
}
return spEmptyBannerFileBuffer->v1.gameName[language];
}
const u16* AMN_getBannerText(s32 index)
{
OSOwnerInfo info;
// Æè ¦¸<E2809A>B
// <20>³Ž®ÉÍ{Ì<E28098>ÝèÌLCFGƒ‰ƒbƒp<C692>[©çŽæçȢƃ_ƒ<5F><C692>H
OS_GetOwnerInfo(&info);
return AMN_getBannerText2(index, (OSLanguage)info.language);
}
// see also SYSMi_CheckBannerFile()
// ƒoƒi<C692>[ƒf<C692>[ƒ^Ì<E2809A>³Œëƒ`ƒFƒbƒN
BOOL AMN_checkBannerFile(TWLBannerFile* pBanner)
{
typedef struct BannerCheckParam {
u8 *pSrc;
u32 size;
}BannerCheckParam;
int i;
BOOL retval = TRUE;
u16 calc_crc = 0xffff;
u16 *pHeaderCRC = (u16 *)&pBanner->h.crc16_v1;
BannerCheckParam bannerCheckList[ BANNER_VER_NTR_MAX ];
BannerCheckParam *pChk = &bannerCheckList[ 0 ];
// NTRŒÝŠ·•”•ªÍ•W<E280A2>Ń`ƒFƒbƒN
bannerCheckList[ 0 ].pSrc = (u8 *)&( pBanner->v1 );
bannerCheckList[ 0 ].size = sizeof( BannerFileV1 );
bannerCheckList[ 1 ].pSrc = (u8 *)&( pBanner->v2 );
bannerCheckList[ 1 ].size = sizeof( BannerFileV2 );
bannerCheckList[ 2 ].pSrc = (u8 *)&( pBanner->v3 );
bannerCheckList[ 2 ].size = sizeof( BannerFileV3 );
for( i = 0; i < BANNER_VER_NTR_MAX; i++ ) {
if( i < pBanner->h.version ) {
calc_crc = SVC_GetCRC16( calc_crc, pChk->pSrc, pChk->size );
if( calc_crc != *pHeaderCRC++ ) {
retval = FALSE;
break;
}
}else {
MI_CpuClear16( pChk->pSrc, pChk->size );
}
pChk++;
}
// TWLƒoƒi<C692>[Èç<E2809A>Aƒoƒi<C692>[ƒAƒjƒ<6A>•”àƒ`ƒFƒbƒN
if( pBanner->h.platform == BANNER_PLATFORM_TWL ) {
if (pBanner->h.crc16_anime != AMN_getBannerAnimeCRC(&pBanner->anime)) {
retval = FALSE;
}
}
return retval;
}
// ƒAƒjƒ<6A>•”CRCŽZ<C5BD>o<EFBFBD>B
static u32 AMN_getBannerAnimeCRC(const BannerAnime* pAnime)
{
return SVC_GetCRC16(0xffff, pAnime, sizeof(*pAnime));
}
static BOOL AMN_checkAndReplaceBannerAnime(s32 index)
{
BOOL retval = FALSE;
TWLBannerFile* pBanner;
// ”͈͊OÌindexð³Ž<C5BD>B
if (cNandTitleIndexStart <= index && index < (cNandTitleIndexStart + sNandTitleListLengthForLauncher)) {
if (spSubBannerFileBuffer->h.crc16_anime == AMN_getBannerAnimeCRC(&spSubBannerFileBuffer->anime)) {
// <20>¬Œ÷µ½ÌŃRƒs<C692>[‚·‚é
pBanner = &spNandBannerFileArray[index-cNandTitleIndexStart];
// h.crc16_animeµ©ƒ`ƒFƒbƒNµÄ¢È¢ÌÅ<E2809A>A»êÆanime¾¯ƒRƒs<C692>[
pBanner->h.crc16_anime = spSubBannerFileBuffer->h.crc16_anime;
// MI_CpuCopy()Ì•ûªx­ÈÁ½<E2809A>c
pBanner->anime = spSubBannerFileBuffer->anime;
retval = TRUE;
}
}
// IPL_PRINT("checkAndReplaceBannerAnime(%d)=%d\n", index, retval);
return retval;
}
// see also TwlIPL_RED/build/systemmenu_RED/Launcher/ARM9/src/bannerCounter.c
void AMN_BNC_incrementCount( AMNBannerCounter *c )
{
// TWLÌ݃JƒEƒ“ƒgƒCƒ“ƒNƒŠƒ<C5A0>ƒ“ƒg
if( c->banner->h.platform == BANNER_PLATFORM_TWL )
{
if( c->banner->anime.control[0].frameCount == 0 )
{
// ƒAƒjƒ<6A>É<E2809A>I[µ©<E28098>ݵȢ
//OS_TPrintf( "BNC_incrementCount:Only a Terminator!\n" );
return;
}
c->count++;
if( c->count >= c->banner->anime.control[c->control].frameCount )
{
// ƒJƒEƒ“ƒglªƒRƒ“ƒgƒ<67><C692>̃tƒŒ<C692>[ƒ€ƒJƒEƒ“ƒg𴦽ÌÅŽŸÌƒRƒ“ƒgƒ<67><C692>[ƒ‹‚Ö
c->control++;
c->count = 0;
//ƒ<C692>[ƒvyÑâŽ~Ì<E2809A>ˆ<CB86>
if( c->control >= BANNER_ANIME_CONTROL_INFO_NUM )
{
// ƒRƒ“ƒgƒ<67><C692>ªŒÀŠE𴦽ç³<E28093>ðŒ<C3B0>Ń<C692>[ƒv
AMN_BNC_resetCount( c );
}
else if( c->banner->anime.control[c->control].frameCount == 0 )
{
// ƒRƒ“ƒgƒ<67><C692>̃tƒŒ<C692>[ƒ€ƒJƒEƒ“ƒgª0Èç<E2809A>I[“žB
if( c->banner->anime.control[c->control].animeType == 0 )
{
// ƒAƒjƒ<6A>ƒ^ƒCƒv0Èçƒ<C692>[ƒv
AMN_BNC_resetCount( c );
}
else if( c->banner->anime.control[c->control].animeType == 1 )
{
// ƒAƒjƒ<6A>ƒ^ƒCƒv1ÈçâŽ~<7E>iˆêÂÕRƒ“ƒgƒ<67><C692>Éß·<E2809A>j
c->control--;
}
}
}
}
}
AMNFrameAnimeData AMN_BNC_getFAD( AMNBannerCounter *c )
{
AMNFrameAnimeData ret;
if( c->banner->h.platform == BANNER_PLATFORM_NTR )
{
ret.image = c->banner->v1.image;
ret.pltt = c->banner->v1.pltt;
ret.hflip = FALSE;
ret.vflip = FALSE;
}
else
{
if( c->banner->anime.control[0].frameCount == 0 )
{
// ƒAƒjƒ<6A>É<E2809A>I[µ©<E28098>ݵȢ
//OS_TPrintf( "BNC_getFAD:Only a Terminator!\n" );
ret.image = c->banner->v1.image;
ret.pltt = c->banner->v1.pltt;
ret.hflip = FALSE;
ret.vflip = FALSE;
return ret;
}
// ƒRƒ“ƒgƒ<67><C692>ƒf<C692>[ƒ^ð“ÇñÅ<E2809A>AŒ»<C592>Ý̃tƒŒ<C692>[ƒ€ÉŠY“·éƒf<C692>[ƒ^‚ð•Ô‚·
ret.image = c->banner->anime.image[ c->banner->anime.control[c->control].normal.cellNo ];
ret.pltt = c->banner->anime.pltt[ c->banner->anime.control[c->control].normal.plttNo ];
ret.hflip = c->banner->anime.control[c->control].normal.flipType & 0x1;
ret.vflip = (c->banner->anime.control[c->control].normal.flipType & 0x2) >> 1;
}
return ret;
}
AMNFrameAnimeData AMN_BNC_getFADAndIncCount( AMNBannerCounter *c )
{
AMNFrameAnimeData ret = AMN_BNC_getFAD( c );
AMN_BNC_incrementCount( c );
return ret;
}
BOOL AMN_isTitleIdValidForLauncher(NAMTitleId id)
{
// "Not Launch"ÅÈ¢<E2809A>@©Â<E2809A>@"Data Only"ÅÈ¢<E2809A>@Èç—LŒøÈƒ^ƒCƒgƒÆµÄƒŠƒXƒgÉljÁ
return ((id & ( TITLE_ID_NOT_LAUNCH_FLAG_MASK | TITLE_ID_DATA_ONLY_FLAG_MASK )) == 0);
}
BOOL AMN_isIndexValidForSetting(s32 index)
{
const TitleProperty* pTitleProp = AMN_getTitleProperty(index);
if (pTitleProp) {
return NAM_IsUserTitle(pTitleProp->titleID);
}
return FALSE;
}
/*--------------------------------------------------------------------------------------------------------
// ƒAƒvƒŠƒP<C692>[ƒVƒ‡ƒ“Éß<E2809A>žÞƒeƒXƒgƒR<C692>[ƒh̃Tƒ“ƒvƒ
// ŽÀŒ±—pɃq<C692>[ƒvðŠg£ƒ<C2A3>ƒCƒ“ƒ<E2809C>ƒƒŠ©çŠm•۵ĢéÌÅ<C385>ˆÓ
// ŽOÉOS_EnableMainExArena<6E>AOS_Init<69>iOS_InitArena<6E>j<EFBFBD>A¨æÑNAM_InitðŒÄñŨ­•K—v è
static OSHeapHandle os_heap_handle;
static void *alloc_tmp(u32 size)
{
return OS_AllocFromHeap( OS_ARENA_MAINEX, os_heap_handle, size);
}
static void free_tmp( void *ptr )
{
OS_FreeToHeap( OS_ARENA_MAINEX, os_heap_handle, ptr );
}
static void test2()
{
s32 length;
s32 idx;
void *nstart;
nstart = OS_InitAlloc( OS_ARENA_MAINEX, OS_GetMainExArenaLo(), OS_GetMainExArenaHi(), 1 );
OS_SetMainExArenaLo( nstart );
os_heap_handle = OS_CreateHeap( OS_ARENA_MAINEX, OS_GetMainExArenaLo(), OS_GetMainExArenaHi() );
AMN_init( alloc_tmp, free_tmp );
// N“®¼Œã<C592>AŽ©“®“IɃoƒi<C692>[ƒf<C692>[ƒ^“ÇÝ<E2809A>žÝð<E2809A>s¢Ü·<E2809A>B
// ƒ<>ƒCƒ“ƒXƒŒƒbƒhÅÍ<E2809A>AÆè ¦¸Š®—¹ÜÅÒ¿Ü·<E2809A>B
while (!AMN_isNandTitleListReady()) {
OS_Sleep(1);
}
// ƒ^ƒCƒgƒˆê——ðOS_PrintfµÜ·<E2809A>B
// cmn::util::U16toSjisÍ<E2809A>ASTDƒ‰ƒCƒuƒ‰ƒŠÌŠÖ<C5A0>ðŒÄÑ<E2809A>oµÄUnicode©çShiftJISÖ•ÏŠ·µÜ·<E2809A>B
length = AMN_getNandTitleListLengthForLauncher();
for (idx = 0; idx < length; idx++) {
s32 i;
char dst[256];
int dstlen = 256;
i = cNandTitleIndexStart + idx;
MI_CpuClearFast(dst,256);
STD_ConvertStringUnicodeToSjis(dst, &dstlen, AMN_getBannerText(i), NULL, NULL);
OS_TPrintf("title idx=%2d, titleId=%016llx exp=%02x forStg=%d bannerText=%s\n",
i, (u64)AMN_getTitleIdByIndex(i),
AMN_getTitleProperty(i)->expansionFlags,
AMN_isIndexValidForSetting(i),
dst);
}
// ƒ^ƒCƒgƒID©çÌtˆø«
{
static const NAMTitleId table[] = {
0x00030015344e4141, // "4NAA" - UIG launcher default
0x0003001534303141, // "401A" - UIG launcher clone
0x0003001534303241, // "402A" - UIG launcher clone
0x00030017484e4141, // "HNAA" - RED launcher default
0x00030015484e4241, // "HNBA" - RED MachineSettings
0x0000000000000001, // nonexistent
0 // stopper
};
u32 i;
i = 0;
while (table[i]) {
OS_TPrintf("index by titleId(%016llx)=%d\n", (u64)table[i], AMN_getIndexByTitleId(table[i]));
i++;
}
}
// ƒoƒi<C692>[ƒCƒ<43><C692>[ƒWƒf<C692>[ƒ^
{
s32 index;
const u8* pImage;
index = 3; //app::Manager::cNandTitleIndexStart;
pImage = AMN_getBannerImage(index);
OS_TPrintf("banner image for index(%02d)=%02x %02x %02x %02x %02x %02x %02x %02x \n",
index,
pImage[0], pImage[1], pImage[2], pImage[3],
pImage[4], pImage[5], pImage[6], pImage[7]);
}
}
--------------------------------------------------------------------------------------------------------*/