mirror of
https://github.com/rvtr/TwlIPL.git
synced 2025-10-31 06:01:12 -04:00
util_menuAppManagerにてNANDタイトル情報を取得する際に、InstalledSoftBoxCountおよびFreeSoftBoxCountを正しい値に修正する処理を追加
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@2118 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
parent
f818fd7e7d
commit
7030e95953
@ -40,6 +40,8 @@ static void AMN_unlockSubBannerFileBuffer();
|
|||||||
static u32 AMN_getBannerAnimeCRC(const BannerAnime* pAnime);
|
static u32 AMN_getBannerAnimeCRC(const BannerAnime* pAnime);
|
||||||
static BOOL AMN_checkAndReplaceBannerAnime(s32 index);
|
static BOOL AMN_checkAndReplaceBannerAnime(s32 index);
|
||||||
|
|
||||||
|
static void AMNi_updateFreeBoxCount( u8 count );
|
||||||
|
|
||||||
static vu8 sThreadStarted;
|
static vu8 sThreadStarted;
|
||||||
static vu8 sReadCancelFlag; // とりあえず無視。
|
static vu8 sReadCancelFlag; // とりあえず無視。
|
||||||
static vu8 sNandTitleListReady;
|
static vu8 sNandTitleListReady;
|
||||||
@ -92,24 +94,24 @@ static ROM_Header_Short s_AllRomHeaderArray[OS_TITLEIDLIST_MAX];
|
|||||||
// see also TwlIPL_RED/build/systemmenu_RED/Launcher/ARM9/src/bannerCounter.h
|
// see also TwlIPL_RED/build/systemmenu_RED/Launcher/ARM9/src/bannerCounter.h
|
||||||
inline void AMN_BNC_resetCount( AMNBannerCounter *c )
|
inline void AMN_BNC_resetCount( AMNBannerCounter *c )
|
||||||
{
|
{
|
||||||
c->count = 0;
|
c->count = 0;
|
||||||
c->control = 0;
|
c->control = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void AMN_BNC_setBanner( AMNBannerCounter *c, const TWLBannerFile *b)
|
inline void AMN_BNC_setBanner( AMNBannerCounter *c, const TWLBannerFile *b)
|
||||||
{
|
{
|
||||||
c->banner = b;
|
c->banner = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void AMN_BNC_initCounter( AMNBannerCounter *c, const TWLBannerFile *b)
|
inline void AMN_BNC_initCounter( AMNBannerCounter *c, const TWLBannerFile *b)
|
||||||
{
|
{
|
||||||
AMN_BNC_setBanner( c, b );
|
AMN_BNC_setBanner( c, b );
|
||||||
AMN_BNC_resetCount( c );
|
AMN_BNC_resetCount( c );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const TWLBannerFile* AMN_BNC_getBanner( AMNBannerCounter *c )
|
inline const TWLBannerFile* AMN_BNC_getBanner( AMNBannerCounter *c )
|
||||||
{
|
{
|
||||||
return c->banner;
|
return c->banner;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AMN_BNC_incrementCount( AMNBannerCounter *c );
|
static void AMN_BNC_incrementCount( AMNBannerCounter *c );
|
||||||
@ -163,7 +165,7 @@ static void AMN_Manager( )
|
|||||||
*/
|
*/
|
||||||
void AMN_init( void *(*pAlloc)(u32), void (*pFree)(void*) )
|
void AMN_init( void *(*pAlloc)(u32), void (*pFree)(void*) )
|
||||||
{
|
{
|
||||||
// 元コンストラクタ
|
// 元コンストラクタ
|
||||||
AMN_Manager();
|
AMN_Manager();
|
||||||
// この時点でAMNi_AllocとAMNi_FreeがNULLであるべし
|
// この時点でAMNi_AllocとAMNi_FreeがNULLであるべし
|
||||||
SDK_ASSERT( AMNi_Alloc == NULL && AMNi_Free == NULL );
|
SDK_ASSERT( AMNi_Alloc == NULL && AMNi_Free == NULL );
|
||||||
@ -350,18 +352,18 @@ void AMN_destroy()
|
|||||||
OS_Sleep(1);
|
OS_Sleep(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( AMNi_Free != NULL && spSubBannerFileBuffer)
|
if( AMNi_Free != NULL && spSubBannerFileBuffer)
|
||||||
{
|
{
|
||||||
AMNi_Free( spSubBannerFileBuffer );
|
AMNi_Free( spSubBannerFileBuffer );
|
||||||
}
|
}
|
||||||
if( AMNi_Free != NULL && spEmptyBannerFileBuffer)
|
if( AMNi_Free != NULL && spEmptyBannerFileBuffer)
|
||||||
{
|
{
|
||||||
AMNi_Free( spEmptyBannerFileBuffer );
|
AMNi_Free( spEmptyBannerFileBuffer );
|
||||||
}
|
}
|
||||||
if( AMNi_Free != NULL && spNandBannerFileArray)
|
if( AMNi_Free != NULL && spNandBannerFileArray)
|
||||||
{
|
{
|
||||||
AMNi_Free( spNandBannerFileArray );
|
AMNi_Free( spNandBannerFileArray );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AMN_initFlags_()
|
static void AMN_initFlags_()
|
||||||
@ -384,118 +386,118 @@ static void AMNi_getAndAddNandTitleData( NAMTitleId titleID, BOOL readShowData )
|
|||||||
// header情報の取得
|
// header情報の取得
|
||||||
|
|
||||||
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
||||||
OSTick start;
|
OSTick start;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FSFile file[1];
|
FSFile file[1];
|
||||||
BOOL bSuccess;
|
BOOL bSuccess;
|
||||||
char path[FS_ENTRY_LONGNAME_MAX];
|
char path[FS_ENTRY_LONGNAME_MAX];
|
||||||
s32 readLen;
|
s32 readLen;
|
||||||
u32 offset;
|
u32 offset;
|
||||||
|
|
||||||
s32 rhArrayLen = cNandTitleIndexStart + sNandAppRomHeaderArrayLength;
|
s32 rhArrayLen = cNandTitleIndexStart + sNandAppRomHeaderArrayLength;
|
||||||
|
|
||||||
// もう入らない
|
// もう入らない
|
||||||
if (rhArrayLen >= OS_TITLEIDLIST_MAX) {
|
if (rhArrayLen >= OS_TITLEIDLIST_MAX) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FS_InitFile(file);
|
FS_InitFile(file);
|
||||||
|
|
||||||
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
||||||
start = OS_GetTick();
|
start = OS_GetTick();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if( (titleID & TITLE_ID_DATA_ONLY_FLAG_MASK) == 0 )
|
if( (titleID & TITLE_ID_DATA_ONLY_FLAG_MASK) == 0 )
|
||||||
{
|
{
|
||||||
// DataOnlyでない場合
|
// DataOnlyでない場合
|
||||||
readLen = NAM_GetTitleBootContentPathFast( path, titleID );
|
readLen = NAM_GetTitleBootContentPathFast( path, titleID );
|
||||||
|
|
||||||
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
||||||
OS_TPrintf( "NAM_GetTitleBootContentPath : %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
|
OS_TPrintf( "NAM_GetTitleBootContentPath : %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ファイルパスを取得
|
// ファイルパスを取得
|
||||||
if(readLen != NAM_OK){
|
if(readLen != NAM_OK){
|
||||||
// error
|
// error
|
||||||
SDK_ASSERT( FALSE );
|
SDK_ASSERT( FALSE );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
||||||
start = OS_GetTick();
|
start = OS_GetTick();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ファイルオープン
|
// ファイルオープン
|
||||||
bSuccess = FS_OpenFileEx(file, path, FS_FILEMODE_R);
|
bSuccess = FS_OpenFileEx(file, path, FS_FILEMODE_R);
|
||||||
if( ! bSuccess )
|
if( ! bSuccess )
|
||||||
{
|
{
|
||||||
// error
|
// error
|
||||||
SDK_ASSERT( FALSE );
|
SDK_ASSERT( FALSE );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
||||||
OS_TPrintf( "OpenFileEX : %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
|
OS_TPrintf( "OpenFileEX : %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
|
||||||
start = OS_GetTick();
|
start = OS_GetTick();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
readLen = FS_ReadFile(file, &s_AllRomHeaderArray[rhArrayLen], sizeof(ROM_Header_Short));
|
readLen = FS_ReadFile(file, &s_AllRomHeaderArray[rhArrayLen], sizeof(ROM_Header_Short));
|
||||||
if( readLen != sizeof(ROM_Header_Short) )
|
if( readLen != sizeof(ROM_Header_Short) )
|
||||||
{
|
{
|
||||||
// error
|
// error
|
||||||
SDK_ASSERT( FALSE );
|
SDK_ASSERT( FALSE );
|
||||||
FS_CloseFile(file);
|
FS_CloseFile(file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = s_AllRomHeaderArray[rhArrayLen].banner_offset;
|
offset = s_AllRomHeaderArray[rhArrayLen].banner_offset;
|
||||||
|
|
||||||
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
||||||
OS_TPrintf( "FS_ReadFile header : %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
|
OS_TPrintf( "FS_ReadFile header : %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// DataOnlyの場合
|
// DataOnlyの場合
|
||||||
int l;
|
int l;
|
||||||
NAMTitleInfo naminfo;
|
NAMTitleInfo naminfo;
|
||||||
// この関数で得られる情報は無検証なので改ざんの可能性があるが、メーカーコードのみの判定なので、速度を優先する。(2008.06.20吉岡)
|
// この関数で得られる情報は無検証なので改ざんの可能性があるが、メーカーコードのみの判定なので、速度を優先する。(2008.06.20吉岡)
|
||||||
// (Fastつけないと一回300msぐらいかかる)
|
// (Fastつけないと一回300msぐらいかかる)
|
||||||
NAM_ReadTitleInfoFast( &naminfo, titleID );
|
NAM_ReadTitleInfoFast( &naminfo, titleID );
|
||||||
MI_CpuClear8(&s_AllRomHeaderArray[rhArrayLen], sizeof(ROM_Header_Short) );
|
MI_CpuClear8(&s_AllRomHeaderArray[rhArrayLen], sizeof(ROM_Header_Short) );
|
||||||
OS_TPrintf( "0x%0.16llx dataonly-title : makercode = ", titleID );
|
OS_TPrintf( "0x%0.16llx dataonly-title : makercode = ", titleID );
|
||||||
for(l=0;l<MAKER_CODE_MAX;l++)
|
for(l=0;l<MAKER_CODE_MAX;l++)
|
||||||
{
|
{
|
||||||
s_AllRomHeaderArray[rhArrayLen].maker_code[l] = ((char *)&naminfo.companyCode)[l];
|
s_AllRomHeaderArray[rhArrayLen].maker_code[l] = ((char *)&naminfo.companyCode)[l];
|
||||||
OS_TPrintf( "0x%0.2x ", s_AllRomHeaderArray[rhArrayLen].maker_code[l] );
|
OS_TPrintf( "0x%0.2x ", s_AllRomHeaderArray[rhArrayLen].maker_code[l] );
|
||||||
}
|
}
|
||||||
OS_TPrintf( "\n" );
|
OS_TPrintf( "\n" );
|
||||||
s_AllRomHeaderArray[rhArrayLen].titleID = titleID;
|
s_AllRomHeaderArray[rhArrayLen].titleID = titleID;
|
||||||
|
|
||||||
sNandAppRomHeaderArrayLength++;
|
sNandAppRomHeaderArrayLength++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(s_AllRomHeaderArray[rhArrayLen].platform_code & PLATFORM_CODE_FLAG_TWL){
|
if(s_AllRomHeaderArray[rhArrayLen].platform_code & PLATFORM_CODE_FLAG_TWL){
|
||||||
// ROMヘッダのリージョンチェックとCRCチェックを行い、不正なアプリは無視する。
|
// ROMヘッダのリージョンチェックとCRCチェックを行い、不正なアプリは無視する。
|
||||||
if( !UTL_CheckAppRegion( s_AllRomHeaderArray[rhArrayLen].card_region_bitmap ) ) {
|
if( !UTL_CheckAppRegion( s_AllRomHeaderArray[rhArrayLen].card_region_bitmap ) ) {
|
||||||
OS_TPrintf( "Region Check NG : %llx\n", titleID );
|
OS_TPrintf( "Region Check NG : %llx\n", titleID );
|
||||||
FS_CloseFile(file);
|
FS_CloseFile(file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if( !UTL_CheckAppCRC16( &s_AllRomHeaderArray[rhArrayLen] ) ) {
|
||||||
|
OS_TPrintf( "CRC16 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++;
|
sNandAppRomHeaderArrayLength++;
|
||||||
|
|
||||||
// もうランチャー表示用情報は数がオーバーしてるか、表示用情報を読まない設定
|
// もうランチャー表示用情報は数がオーバーしてるか、表示用情報を読まない設定
|
||||||
if ( ( sNandTitleListLengthForLauncher >= cNandTitleArrayMax ) || !readShowData ) {
|
if ( ( sNandTitleListLengthForLauncher >= cNandTitleArrayMax ) || !readShowData ) {
|
||||||
FS_CloseFile(file);
|
FS_CloseFile(file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,72 +510,72 @@ static void AMNi_getAndAddNandTitleData( NAMTitleId titleID, BOOL readShowData )
|
|||||||
pTitleProp->flags.bootType = LAUNCHER_BOOTTYPE_NAND;
|
pTitleProp->flags.bootType = LAUNCHER_BOOTTYPE_NAND;
|
||||||
|
|
||||||
// バナーの取得
|
// バナーの取得
|
||||||
// バナーが存在する場合のみリード
|
// バナーが存在する場合のみリード
|
||||||
if( offset ) {
|
if( offset ) {
|
||||||
|
|
||||||
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
||||||
start = OS_GetTick();
|
start = OS_GetTick();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bSuccess = FS_SeekFile(file, (s32)offset, FS_SEEK_SET);
|
bSuccess = FS_SeekFile(file, (s32)offset, FS_SEEK_SET);
|
||||||
if( ! bSuccess )
|
if( ! bSuccess )
|
||||||
{
|
{
|
||||||
// error
|
// error
|
||||||
SDK_ASSERT( FALSE );
|
SDK_ASSERT( FALSE );
|
||||||
FS_CloseFile(file);
|
FS_CloseFile(file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
||||||
OS_TPrintf( "FS_SeekFile banner: %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
|
OS_TPrintf( "FS_SeekFile banner: %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
|
||||||
start = OS_GetTick();
|
start = OS_GetTick();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
readLen = FS_ReadFile( file, pTitleProp->pBanner, (s32)sizeof(TWLBannerFile) );
|
readLen = FS_ReadFile( file, pTitleProp->pBanner, (s32)sizeof(TWLBannerFile) );
|
||||||
if( readLen != (s32)sizeof(TWLBannerFile) )
|
if( readLen != (s32)sizeof(TWLBannerFile) )
|
||||||
{
|
{
|
||||||
// error
|
// error
|
||||||
SDK_ASSERT( FALSE );
|
SDK_ASSERT( FALSE );
|
||||||
FS_CloseFile(file);
|
FS_CloseFile(file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
||||||
OS_TPrintf( "FS_ReadFile banner: %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
|
OS_TPrintf( "FS_ReadFile banner: %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
|
||||||
start = OS_GetTick();
|
start = OS_GetTick();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// バナーチェックリクエスト送信。
|
// バナーチェックリクエスト送信。
|
||||||
OS_SendMessage(&sCheckMsgQueue, (OSMessage)(pTitleProp->pBanner), OS_MESSAGE_BLOCK);
|
OS_SendMessage(&sCheckMsgQueue, (OSMessage)(pTitleProp->pBanner), OS_MESSAGE_BLOCK);
|
||||||
|
|
||||||
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
||||||
OS_TPrintf( "check banner: %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
|
OS_TPrintf( "check banner: %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}else {
|
}else {
|
||||||
// バナーが存在しない場合はバッファクリア
|
// バナーが存在しない場合はバッファクリア
|
||||||
MI_CpuClearFast( pTitleProp->pBanner, sizeof(TWLBannerFile) );
|
MI_CpuClearFast( pTitleProp->pBanner, sizeof(TWLBannerFile) );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
||||||
start = OS_GetTick();
|
start = OS_GetTick();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FS_CloseFile(file);
|
FS_CloseFile(file);
|
||||||
|
|
||||||
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
||||||
OS_TPrintf( "close file : %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
|
OS_TPrintf( "close file : %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
|
||||||
start = OS_GetTick();
|
start = OS_GetTick();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// サブバナーファイルを読み込んでみる
|
// サブバナーファイルを読み込んでみる
|
||||||
if(s_AllRomHeaderArray[rhArrayLen].exFlags.availableSubBannerFile &&
|
if(s_AllRomHeaderArray[rhArrayLen].exFlags.availableSubBannerFile &&
|
||||||
NAM_OK == NAM_GetTitleBannerFilePath( path, titleID ))
|
NAM_OK == NAM_GetTitleBannerFilePath( path, titleID ))
|
||||||
{
|
{
|
||||||
|
|
||||||
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
||||||
OS_TPrintf( "NAM_GetTitleBannerFilePath : %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
|
OS_TPrintf( "NAM_GetTitleBannerFilePath : %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
|
||||||
start = OS_GetTick();
|
start = OS_GetTick();
|
||||||
#endif
|
#endif
|
||||||
if (FS_OpenFileEx(file, path, FS_FILEMODE_R)) {
|
if (FS_OpenFileEx(file, path, FS_FILEMODE_R)) {
|
||||||
// サブバナーバッファ確保。
|
// サブバナーバッファ確保。
|
||||||
@ -593,9 +595,9 @@ static void AMNi_getAndAddNandTitleData( NAMTitleId titleID, BOOL readShowData )
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
#if (MEASURE_BANNER_LOAD_TIME == 1)
|
||||||
OS_TPrintf( "open-read-close-check subbanner : %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
|
OS_TPrintf( "open-read-close-check subbanner : %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
sNandTitleListLengthForLauncher++;
|
sNandTitleListLengthForLauncher++;
|
||||||
}
|
}
|
||||||
@ -609,6 +611,7 @@ static void AMN_initNandTitleList_()
|
|||||||
s32 ret;
|
s32 ret;
|
||||||
s32 l;
|
s32 l;
|
||||||
NAMTitleId* pNandAllTitleIDList = NULL;
|
NAMTitleId* pNandAllTitleIDList = NULL;
|
||||||
|
u8 count_valid_app_for_launcher = 0;
|
||||||
|
|
||||||
// インポートされているタイトルの取得
|
// インポートされているタイトルの取得
|
||||||
sNandAllTitleListLength = NAM_GetNumTitles();
|
sNandAllTitleListLength = NAM_GetNumTitles();
|
||||||
@ -646,9 +649,16 @@ static void AMN_initNandTitleList_()
|
|||||||
AMNi_getAndAddNandTitleData( pNandAllTitleIDList[l], TRUE );
|
AMNi_getAndAddNandTitleData( pNandAllTitleIDList[l], TRUE );
|
||||||
// 本体設定の場合、アプリマネージャ用indexは飛び飛びになったり、ForSetting()が返す値(個数)より大きくなるので
|
// 本体設定の場合、アプリマネージャ用indexは飛び飛びになったり、ForSetting()が返す値(個数)より大きくなるので
|
||||||
// getNandTitleListLengthForSetting()は用意しない。
|
// getNandTitleListLengthForSetting()は用意しない。
|
||||||
|
|
||||||
|
// FreeboxCount更新のためのカウンタ
|
||||||
|
count_valid_app_for_launcher++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FreeboxCount更新
|
||||||
|
AMNi_updateFreeBoxCount( count_valid_app_for_launcher );
|
||||||
|
|
||||||
|
|
||||||
// ローンチ対象でないタイトルの情報の取得
|
// ローンチ対象でないタイトルの情報の取得
|
||||||
for (l = 0; l < sNandAllTitleListLength; l++) {
|
for (l = 0; l < sNandAllTitleListLength; l++) {
|
||||||
if (!AMN_isTitleIdValidForLauncher(pNandAllTitleIDList[l])) {
|
if (!AMN_isTitleIdValidForLauncher(pNandAllTitleIDList[l])) {
|
||||||
@ -667,6 +677,7 @@ static void AMN_initNandTitleRomHeaderShortList_()
|
|||||||
s32 ret;
|
s32 ret;
|
||||||
s32 l;
|
s32 l;
|
||||||
NAMTitleId* pNandAllTitleIDList = NULL;
|
NAMTitleId* pNandAllTitleIDList = NULL;
|
||||||
|
u8 count_valid_app_for_launcher = 0;
|
||||||
|
|
||||||
// インポートされているタイトルの取得
|
// インポートされているタイトルの取得
|
||||||
sNandAllTitleListLength = NAM_GetNumTitles();
|
sNandAllTitleListLength = NAM_GetNumTitles();
|
||||||
@ -697,7 +708,14 @@ static void AMN_initNandTitleRomHeaderShortList_()
|
|||||||
// タイトルの情報(ヘッダのみ)の取得
|
// タイトルの情報(ヘッダのみ)の取得
|
||||||
for (l = 0; l < sNandAllTitleListLength; l++) {
|
for (l = 0; l < sNandAllTitleListLength; l++) {
|
||||||
AMNi_getAndAddNandTitleData( pNandAllTitleIDList[l], FALSE );
|
AMNi_getAndAddNandTitleData( pNandAllTitleIDList[l], FALSE );
|
||||||
|
if (AMN_isTitleIdValidForLauncher(pNandAllTitleIDList[l])) {
|
||||||
|
// FreeboxCount更新のためのカウンタ
|
||||||
|
count_valid_app_for_launcher++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FreeboxCount更新
|
||||||
|
AMNi_updateFreeBoxCount( count_valid_app_for_launcher );
|
||||||
|
|
||||||
if (pNandAllTitleIDList) {
|
if (pNandAllTitleIDList) {
|
||||||
AMNi_Free( pNandAllTitleIDList );
|
AMNi_Free( pNandAllTitleIDList );
|
||||||
@ -707,12 +725,12 @@ static void AMN_initNandTitleRomHeaderShortList_()
|
|||||||
// 生データ(TitlePropertyのリスト、HeaderShortリスト)にアクセスできる抜け道関数
|
// 生データ(TitlePropertyのリスト、HeaderShortリスト)にアクセスできる抜け道関数
|
||||||
TitleProperty* AMN_getTitlePropertyList( void )
|
TitleProperty* AMN_getTitlePropertyList( void )
|
||||||
{
|
{
|
||||||
return sAllTitlePropertyArray;
|
return sAllTitlePropertyArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
ROM_Header_Short* AMN_getRomHeaderList( void )
|
ROM_Header_Short* AMN_getRomHeaderList( void )
|
||||||
{
|
{
|
||||||
return s_AllRomHeaderArray;
|
return s_AllRomHeaderArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AMN_procRead()
|
static void AMN_procRead()
|
||||||
@ -1036,45 +1054,45 @@ const u16* AMN_getBannerText(s32 index)
|
|||||||
BOOL AMN_checkBannerFile(TWLBannerFile* pBanner)
|
BOOL AMN_checkBannerFile(TWLBannerFile* pBanner)
|
||||||
{
|
{
|
||||||
typedef struct BannerCheckParam {
|
typedef struct BannerCheckParam {
|
||||||
u8 *pSrc;
|
u8 *pSrc;
|
||||||
u32 size;
|
u32 size;
|
||||||
}BannerCheckParam;
|
}BannerCheckParam;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
BOOL retval = TRUE;
|
BOOL retval = TRUE;
|
||||||
u16 calc_crc = 0xffff;
|
u16 calc_crc = 0xffff;
|
||||||
u16 *pHeaderCRC = (u16 *)&pBanner->h.crc16_v1;
|
u16 *pHeaderCRC = (u16 *)&pBanner->h.crc16_v1;
|
||||||
BannerCheckParam bannerCheckList[ BANNER_VER_NTR_MAX ];
|
BannerCheckParam bannerCheckList[ BANNER_VER_NTR_MAX ];
|
||||||
BannerCheckParam *pChk = &bannerCheckList[ 0 ];
|
BannerCheckParam *pChk = &bannerCheckList[ 0 ];
|
||||||
|
|
||||||
// NTR互換部分は標準でチェック
|
// NTR互換部分は標準でチェック
|
||||||
bannerCheckList[ 0 ].pSrc = (u8 *)&( pBanner->v1 );
|
bannerCheckList[ 0 ].pSrc = (u8 *)&( pBanner->v1 );
|
||||||
bannerCheckList[ 0 ].size = sizeof( BannerFileV1 );
|
bannerCheckList[ 0 ].size = sizeof( BannerFileV1 );
|
||||||
bannerCheckList[ 1 ].pSrc = (u8 *)&( pBanner->v2 );
|
bannerCheckList[ 1 ].pSrc = (u8 *)&( pBanner->v2 );
|
||||||
bannerCheckList[ 1 ].size = sizeof( BannerFileV2 );
|
bannerCheckList[ 1 ].size = sizeof( BannerFileV2 );
|
||||||
bannerCheckList[ 2 ].pSrc = (u8 *)&( pBanner->v3 );
|
bannerCheckList[ 2 ].pSrc = (u8 *)&( pBanner->v3 );
|
||||||
bannerCheckList[ 2 ].size = sizeof( BannerFileV3 );
|
bannerCheckList[ 2 ].size = sizeof( BannerFileV3 );
|
||||||
|
|
||||||
for( i = 0; i < BANNER_VER_NTR_MAX; i++ ) {
|
for( i = 0; i < BANNER_VER_NTR_MAX; i++ ) {
|
||||||
if( i < pBanner->h.version ) {
|
if( i < pBanner->h.version ) {
|
||||||
calc_crc = SVC_GetCRC16( calc_crc, pChk->pSrc, pChk->size );
|
calc_crc = SVC_GetCRC16( calc_crc, pChk->pSrc, pChk->size );
|
||||||
if( calc_crc != *pHeaderCRC++ ) {
|
if( calc_crc != *pHeaderCRC++ ) {
|
||||||
retval = FALSE;
|
retval = FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
MI_CpuClear16( pChk->pSrc, pChk->size );
|
MI_CpuClear16( pChk->pSrc, pChk->size );
|
||||||
}
|
}
|
||||||
pChk++;
|
pChk++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TWLバナーなら、バナーアニメ部もチェック
|
// TWLバナーなら、バナーアニメ部もチェック
|
||||||
if( pBanner->h.platform == BANNER_PLATFORM_TWL ) {
|
if( pBanner->h.platform == BANNER_PLATFORM_TWL ) {
|
||||||
if (pBanner->h.crc16_anime != AMN_getBannerAnimeCRC(&pBanner->anime)) {
|
if (pBanner->h.crc16_anime != AMN_getBannerAnimeCRC(&pBanner->anime)) {
|
||||||
retval = FALSE;
|
retval = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
// アニメ部CRC算出。
|
// アニメ部CRC算出。
|
||||||
@ -1109,83 +1127,83 @@ static BOOL AMN_checkAndReplaceBannerAnime(s32 index)
|
|||||||
// see also TwlIPL_RED/build/systemmenu_RED/Launcher/ARM9/src/bannerCounter.c
|
// see also TwlIPL_RED/build/systemmenu_RED/Launcher/ARM9/src/bannerCounter.c
|
||||||
void AMN_BNC_incrementCount( AMNBannerCounter *c )
|
void AMN_BNC_incrementCount( AMNBannerCounter *c )
|
||||||
{
|
{
|
||||||
// TWLのみカウントインクリメント
|
// TWLのみカウントインクリメント
|
||||||
if( c->banner->h.platform == BANNER_PLATFORM_TWL )
|
if( c->banner->h.platform == BANNER_PLATFORM_TWL )
|
||||||
{
|
{
|
||||||
if( c->banner->anime.control[0].frameCount == 0 )
|
if( c->banner->anime.control[0].frameCount == 0 )
|
||||||
{
|
{
|
||||||
// アニメに終端しか存在しない
|
// アニメに終端しか存在しない
|
||||||
//OS_TPrintf( "BNC_incrementCount:Only a Terminator!\n" );
|
//OS_TPrintf( "BNC_incrementCount:Only a Terminator!\n" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
c->count++;
|
c->count++;
|
||||||
if( c->count >= c->banner->anime.control[c->control].frameCount )
|
if( c->count >= c->banner->anime.control[c->control].frameCount )
|
||||||
{
|
{
|
||||||
// カウント値がコントロールのフレームカウントを超えたので次のコントロールへ
|
// カウント値がコントロールのフレームカウントを超えたので次のコントロールへ
|
||||||
c->control++;
|
c->control++;
|
||||||
c->count = 0;
|
c->count = 0;
|
||||||
|
|
||||||
//ループ及び停止の処理
|
//ループ及び停止の処理
|
||||||
if( c->control >= BANNER_ANIME_CONTROL_INFO_NUM )
|
if( c->control >= BANNER_ANIME_CONTROL_INFO_NUM )
|
||||||
{
|
{
|
||||||
// コントロールが限界を超えたら無条件でループ
|
// コントロールが限界を超えたら無条件でループ
|
||||||
AMN_BNC_resetCount( c );
|
AMN_BNC_resetCount( c );
|
||||||
}
|
}
|
||||||
else if( c->banner->anime.control[c->control].frameCount == 0 )
|
else if( c->banner->anime.control[c->control].frameCount == 0 )
|
||||||
{
|
{
|
||||||
// コントロールのフレームカウントが0なら終端到達
|
// コントロールのフレームカウントが0なら終端到達
|
||||||
if( c->banner->anime.control[c->control].animeType == 0 )
|
if( c->banner->anime.control[c->control].animeType == 0 )
|
||||||
{
|
{
|
||||||
// アニメタイプ0ならループ
|
// アニメタイプ0ならループ
|
||||||
AMN_BNC_resetCount( c );
|
AMN_BNC_resetCount( c );
|
||||||
}
|
}
|
||||||
else if( c->banner->anime.control[c->control].animeType == 1 )
|
else if( c->banner->anime.control[c->control].animeType == 1 )
|
||||||
{
|
{
|
||||||
// アニメタイプ1なら停止(一つ前のコントロールに戻す)
|
// アニメタイプ1なら停止(一つ前のコントロールに戻す)
|
||||||
c->control--;
|
c->control--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AMNFrameAnimeData AMN_BNC_getFAD( AMNBannerCounter *c )
|
AMNFrameAnimeData AMN_BNC_getFAD( AMNBannerCounter *c )
|
||||||
{
|
{
|
||||||
AMNFrameAnimeData ret;
|
AMNFrameAnimeData ret;
|
||||||
if( c->banner->h.platform == BANNER_PLATFORM_NTR )
|
if( c->banner->h.platform == BANNER_PLATFORM_NTR )
|
||||||
{
|
{
|
||||||
ret.image = c->banner->v1.image;
|
ret.image = c->banner->v1.image;
|
||||||
ret.pltt = c->banner->v1.pltt;
|
ret.pltt = c->banner->v1.pltt;
|
||||||
ret.hflip = FALSE;
|
ret.hflip = FALSE;
|
||||||
ret.vflip = FALSE;
|
ret.vflip = FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( c->banner->anime.control[0].frameCount == 0 )
|
if( c->banner->anime.control[0].frameCount == 0 )
|
||||||
{
|
{
|
||||||
// アニメに終端しか存在しない
|
// アニメに終端しか存在しない
|
||||||
//OS_TPrintf( "BNC_getFAD:Only a Terminator!\n" );
|
//OS_TPrintf( "BNC_getFAD:Only a Terminator!\n" );
|
||||||
ret.image = c->banner->v1.image;
|
ret.image = c->banner->v1.image;
|
||||||
ret.pltt = c->banner->v1.pltt;
|
ret.pltt = c->banner->v1.pltt;
|
||||||
ret.hflip = FALSE;
|
ret.hflip = FALSE;
|
||||||
ret.vflip = FALSE;
|
ret.vflip = FALSE;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
// コントロールデータを読んで、現在のフレームに該当するデータを返す
|
// コントロールデータを読んで、現在のフレームに該当するデータを返す
|
||||||
ret.image = c->banner->anime.image[ c->banner->anime.control[c->control].normal.cellNo ];
|
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.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.hflip = c->banner->anime.control[c->control].normal.flipType & 0x1;
|
||||||
ret.vflip = (c->banner->anime.control[c->control].normal.flipType & 0x2) >> 1;
|
ret.vflip = (c->banner->anime.control[c->control].normal.flipType & 0x2) >> 1;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
AMNFrameAnimeData AMN_BNC_getFADAndIncCount( AMNBannerCounter *c )
|
AMNFrameAnimeData AMN_BNC_getFADAndIncCount( AMNBannerCounter *c )
|
||||||
{
|
{
|
||||||
AMNFrameAnimeData ret = AMN_BNC_getFAD( c );
|
AMNFrameAnimeData ret = AMN_BNC_getFAD( c );
|
||||||
AMN_BNC_incrementCount( c );
|
AMN_BNC_incrementCount( c );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL AMN_isTitleIdValidForLauncher(NAMTitleId id)
|
BOOL AMN_isTitleIdValidForLauncher(NAMTitleId id)
|
||||||
@ -1205,6 +1223,58 @@ BOOL AMN_isIndexValidForSetting(s32 index)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void AMNi_updateFreeBoxCount( u8 count )
|
||||||
|
{
|
||||||
|
u32 installed;
|
||||||
|
u8 free;
|
||||||
|
BOOL changed = FALSE;
|
||||||
|
u8 *pBuffer;
|
||||||
|
BOOL retval = TRUE;
|
||||||
|
|
||||||
|
installed = LCFG_TSD_GetInstalledSoftBoxCount();
|
||||||
|
free = LCFG_TSD_GetFreeSoftBoxCount();
|
||||||
|
|
||||||
|
if( count > LCFG_TWL_FREE_SOFT_BOX_COUNT_MAX )
|
||||||
|
{
|
||||||
|
count = LCFG_TWL_FREE_SOFT_BOX_COUNT_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
OS_TPrintf( "AMNi_updateFreeBoxCount : Install:%d, Free:%d, LCFG_Install:%d, LCFG_Free:%d, MAX:%d\n",
|
||||||
|
count, LCFG_TWL_FREE_SOFT_BOX_COUNT_MAX - count, installed, free, LCFG_TWL_FREE_SOFT_BOX_COUNT_MAX );
|
||||||
|
|
||||||
|
if( (u8)installed != count )
|
||||||
|
{
|
||||||
|
LCFG_TSD_SetInstalledSoftBoxCount( ( u8 )count );
|
||||||
|
changed = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( LCFG_TWL_FREE_SOFT_BOX_COUNT_MAX - count != free )
|
||||||
|
{
|
||||||
|
LCFG_TSD_SetFreeSoftBoxCount( (u8)( LCFG_TWL_FREE_SOFT_BOX_COUNT_MAX - count ) );
|
||||||
|
changed = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(changed)
|
||||||
|
{
|
||||||
|
// LCFGライブラリの静的変数の値をNANDに反映
|
||||||
|
pBuffer = AMNi_Alloc( LCFG_WRITE_TEMP );
|
||||||
|
if (!pBuffer) {
|
||||||
|
OS_TPrintf( "AMNi_updateFreeBoxCount : AMNi_Alloc failed.\n" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
retval = LCFG_WriteTWLSettings( (u8 (*)[ LCFG_WRITE_TEMP ] )pBuffer );
|
||||||
|
AMNi_Free( pBuffer );
|
||||||
|
if (!retval) {
|
||||||
|
OS_TPrintf( "AMNi_updateFreeBoxCount : LCFG_WriteTWLSettings failed.\n" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
OS_TPrintf( "AMNi_updateFreeBoxCount : FreeBoxCount is updated.\n" );
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
OS_TPrintf( "AMNi_updateFreeBoxCount : FreeBoxCount is not updated.\n" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------------------------------------
|
/*--------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// アプリケーションに埋め込むテストコードのサンプル
|
// アプリケーションに埋め込むテストコードのサンプル
|
||||||
@ -1213,48 +1283,48 @@ BOOL AMN_isIndexValidForSetting(s32 index)
|
|||||||
static OSHeapHandle os_heap_handle;
|
static OSHeapHandle os_heap_handle;
|
||||||
static void *alloc_tmp(u32 size)
|
static void *alloc_tmp(u32 size)
|
||||||
{
|
{
|
||||||
return OS_AllocFromHeap( OS_ARENA_MAINEX, os_heap_handle, size);
|
return OS_AllocFromHeap( OS_ARENA_MAINEX, os_heap_handle, size);
|
||||||
}
|
}
|
||||||
static void free_tmp( void *ptr )
|
static void free_tmp( void *ptr )
|
||||||
{
|
{
|
||||||
OS_FreeToHeap( OS_ARENA_MAINEX, os_heap_handle, ptr );
|
OS_FreeToHeap( OS_ARENA_MAINEX, os_heap_handle, ptr );
|
||||||
}
|
}
|
||||||
static void test2()
|
static void test2()
|
||||||
{
|
{
|
||||||
|
|
||||||
s32 length;
|
s32 length;
|
||||||
s32 idx;
|
s32 idx;
|
||||||
void *nstart;
|
void *nstart;
|
||||||
|
|
||||||
nstart = OS_InitAlloc( OS_ARENA_MAINEX, OS_GetMainExArenaLo(), OS_GetMainExArenaHi(), 1 );
|
nstart = OS_InitAlloc( OS_ARENA_MAINEX, OS_GetMainExArenaLo(), OS_GetMainExArenaHi(), 1 );
|
||||||
OS_SetMainExArenaLo( nstart );
|
OS_SetMainExArenaLo( nstart );
|
||||||
|
|
||||||
os_heap_handle = OS_CreateHeap( OS_ARENA_MAINEX, OS_GetMainExArenaLo(), OS_GetMainExArenaHi() );
|
os_heap_handle = OS_CreateHeap( OS_ARENA_MAINEX, OS_GetMainExArenaLo(), OS_GetMainExArenaHi() );
|
||||||
|
|
||||||
AMN_init( alloc_tmp, free_tmp );
|
AMN_init( alloc_tmp, free_tmp );
|
||||||
|
|
||||||
// 起動直後、自動的にバナーデータ読み込みを行います。
|
// 起動直後、自動的にバナーデータ読み込みを行います。
|
||||||
// メインスレッドでは、とりあえず完了まで待ちます。
|
// メインスレッドでは、とりあえず完了まで待ちます。
|
||||||
while (!AMN_isNandTitleListReady()) {
|
while (!AMN_isNandTitleListReady()) {
|
||||||
OS_Sleep(1);
|
OS_Sleep(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// タイトル一覧をOS_Printfします。
|
// タイトル一覧をOS_Printfします。
|
||||||
// cmn::util::U16toSjisは、STDライブラリの関数を呼び出してUnicodeからShiftJISへ変換します。
|
// cmn::util::U16toSjisは、STDライブラリの関数を呼び出してUnicodeからShiftJISへ変換します。
|
||||||
length = AMN_getNandTitleListLengthForLauncher();
|
length = AMN_getNandTitleListLengthForLauncher();
|
||||||
for (idx = 0; idx < length; idx++) {
|
for (idx = 0; idx < length; idx++) {
|
||||||
s32 i;
|
s32 i;
|
||||||
char dst[256];
|
char dst[256];
|
||||||
int dstlen = 256;
|
int dstlen = 256;
|
||||||
i = cNandTitleIndexStart + idx;
|
i = cNandTitleIndexStart + idx;
|
||||||
MI_CpuClearFast(dst,256);
|
MI_CpuClearFast(dst,256);
|
||||||
STD_ConvertStringUnicodeToSjis(dst, &dstlen, AMN_getBannerText(i), NULL, NULL);
|
STD_ConvertStringUnicodeToSjis(dst, &dstlen, AMN_getBannerText(i), NULL, NULL);
|
||||||
OS_TPrintf("title idx=%2d, titleId=%016llx exp=%02x forStg=%d bannerText=%s\n",
|
OS_TPrintf("title idx=%2d, titleId=%016llx exp=%02x forStg=%d bannerText=%s\n",
|
||||||
i, (u64)AMN_getTitleIdByIndex(i),
|
i, (u64)AMN_getTitleIdByIndex(i),
|
||||||
AMN_getTitleProperty(i)->expansionFlags,
|
AMN_getTitleProperty(i)->expansionFlags,
|
||||||
AMN_isIndexValidForSetting(i),
|
AMN_isIndexValidForSetting(i),
|
||||||
dst);
|
dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
// タイトルIDからの逆引き
|
// タイトルIDからの逆引き
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user