mirror of
https://github.com/rvtr/TwlIPL.git
synced 2025-10-31 06:01:12 -04:00
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@1887 b08762b0-b915-fc4b-9d8c-17b2551a87ff
1295 lines
38 KiB
C
1295 lines
38 KiB
C
/*---------------------------------------------------------------------------*
|
||
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>AŠˆ<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>Aƒ<41><C692>[ƒJ<C692>[ƒR<C692>[ƒh‚݂̂̔»’è‚Ȃ̂Å<E2809A>A‘¬“x‚ð—D<E28094>æ‚·‚é<E2809A>B(2008.06.20‹g‰ª)
|
||
// <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ƒ“ƒg’l‚ªƒRƒ“ƒgƒ<67><C692>[ƒ‹‚̃tƒŒ<C692>[ƒ€ƒJƒEƒ“ƒg‚ð’´‚¦‚½‚̂ŎŸ‚̃Rƒ“ƒgƒ<67><C692>[ƒ‹‚Ö
|
||
c->control++;
|
||
c->count = 0;
|
||
|
||
//ƒ‹<C692>[ƒv‹y‚Ñ’âŽ~‚Ì<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ˆê‚‘O‚̃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]);
|
||
}
|
||
|
||
}
|
||
|
||
--------------------------------------------------------------------------------------------------------*/
|