diff --git a/build/systemMenu_tools/NandInitializerProduction/ARM9.TWL/Makefile b/build/systemMenu_tools/NandInitializerProduction/ARM9.TWL/Makefile index 81d792c5..da630970 100644 --- a/build/systemMenu_tools/NandInitializerProduction/ARM9.TWL/Makefile +++ b/build/systemMenu_tools/NandInitializerProduction/ARM9.TWL/Makefile @@ -85,7 +85,8 @@ SRCS = main.c \ process_mcu.c \ process_wireless_setting.c \ hwi.c \ - debugger_hw_reset_control.c + debugger_hw_reset_control.c \ + sort_title.c LINCLUDES = ../../NandInitializerRed/common/include \ ../../NandInitializerRed/ARM9.TWL/include \ diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/Makefile b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/Makefile index 5926556a..a7c4709a 100644 --- a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/Makefile +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/Makefile @@ -21,7 +21,7 @@ #============================================================================ # SystemMenuファイルの置かれているフォルダを指定(相対もしくは絶対) -UPDATER_HOST_ROOT_DIR = s:/v1_2 +UPDATER_HOST_ROOT_DIR = ./v1_2 # COMPILE SWITCH for build SystemUpdater(TRUEにすると、ダミーdev.kpを生成しないようになります。) FOR_LOTCHECK ?= FALSE @@ -79,7 +79,8 @@ SRCS = main.c \ process_nandfirm.c \ process_namut_format.c \ process_delete_other_region_sysmenu.c \ - fade.c + fade.c \ + sort_title.c LINCLUDES = include \ ../common/include \ diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_global.h b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_global.h index 46401b84..5fd17548 100644 --- a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_global.h +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_global.h @@ -73,7 +73,7 @@ extern BOOL ProcessFormat(void); extern BOOL ProcessHwinfo(void); extern void ProcessLog(void); extern void ProcessFinish(BOOL result); -extern BOOL ProcessImport(void); +extern BOOL ProcessImport( void *(*alloc)(unsigned long), void (*free)(void *) ); extern BOOL ProcessWriteFont(void); extern BOOL ProcessWriteCert(void); extern BOOL ProcessWriteDummy(void); diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/sort_title.h b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/sort_title.h new file mode 100644 index 00000000..bce41688 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/sort_title.h @@ -0,0 +1,103 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - SystemUpdaterRegionSelect + File: sort_title.h + + Copyright 2008 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$ + *---------------------------------------------------------------------------*/ + +/* + +【つかいかた】 + +TitleID と、インデックスを TitleSortSet 構造体にセットして +TitleSortSet 構造体を SortTitle 関数に引き渡します。 + +次に使用例を示します。 + + +【擬似コード】 + +#define FILE_NUM_MAX 256 // 手抜き +#define QSORT_BUF_SIZE ((8+1) * 8) // サイズは(log2(num)+1) * 8 bytes + + char sFilePath[FILE_NUM_MAX][FS_ENTRY_LONGNAME_MAX]; + TitleSortSet sTitleSortSet[FILE_NUM_MAX]; + FSDirectoryEntryInfo info[1]; + NAMTadInfo tadInfo; + char qsortBuf[QSORT_BUF_SIZE]; + + while (ファイル全部舐めるまで) + { + // 〜 info にファイル情報読み込み〜 + // 〜 tadInfo に tad 情報取得〜 + + STD_CopyString( sFilePath[ counter ], info->longname ); + sTitleSortSet[ counter ].titleID = tadInfo.titleInfo.titleId; + sTitleSortSet[ counter ].index = counter; + + counter++; + } + + SortTitle( sTitleSortSet, counter, qsortBuf ); + + // ソート完了 + // 例えば、ソートされた順に要素を表示する場合は次のようにする。 + for( i=0; i + +/*===========================================================================*/ + +typedef struct { + OSTitleId titleID; + u32 index; +} TitleSortSet; + +// TitleSortSet の配列をある法則にしたがってソートします。 +// 内部で MATH_QSort を使用しているので、MATH_QSortStackSize() 関数で取得できる +// サイズの作業バッファを buf に与える必要があります。 +// このサイズは (log2(num)+1) * 8 byte となっています。 +// 作業バッファを渡さない場合には、スタックからこのサイズの作業領域が確保されます。 +// +// info ソートする TitleSortSet 配列の先頭アドレス +// num ソートする配列の要素数 +// buf 作業バッファ +void SortTitle( TitleSortSet *info, u32 num, void *buf ); + +/*===========================================================================*/ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* TWL_SORT_TITLE_H_ */ + +/*---------------------------------------------------------------------------* + End of file + *---------------------------------------------------------------------------*/ diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/main.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/main.c index cbf256c5..f7989cbe 100644 --- a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/main.c +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/main.c @@ -189,7 +189,7 @@ TwlMain() result &= ProcessWriteDummy(); // TADのインポート開始 - result &= ProcessImport(); + result &= ProcessImport( OS_AllocFromMain, OS_FreeToMain ); // 選択リージョン以外のSystemMenuの消去を行う result &= ProcessDeleteOtherResionSysmenu(); diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_import.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_import.c index 0f27eed4..6ac91a59 100644 --- a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_import.c +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_import.c @@ -28,6 +28,7 @@ #include "graphics.h" #include "kami_global.h" #include "font.h" +#include "sort_title.h" /*---------------------------------------------------------------------------* 型定義 @@ -39,6 +40,9 @@ #define THREAD_STACK_SIZE (16*1024) +#define DIR_NUM 3 +#define FULLPATH_LEN ( FS_ENTRY_LONGNAME_MAX+6 ) + static const char* sDirectoryNameRegion[] = { "japan", @@ -55,6 +59,11 @@ static const char* sDirectoryNameConsole[] = "" // UNKNOWN }; +typedef struct { + u8 dirNameIndex; + char fileName[FS_ENTRY_LONGNAME_MAX]; +} ImportFileInfo; + /*---------------------------------------------------------------------------* 内部変数定義 *---------------------------------------------------------------------------*/ @@ -74,6 +83,10 @@ static void Destructor(void* arg); void ProgressDraw(f32 ratio); BOOL ImportDirectoryTad(char* directory); +static u32 CountTadInDir( char (*dir_path)[FULLPATH_LEN], u32 dir_num ); +static BOOL MakeList( char (*dir)[FULLPATH_LEN], u32 dir_max, ImportFileInfo *info, TitleSortSet *sortset ); +static BOOL ImportTadFromList( char (*dir)[FULLPATH_LEN], ImportFileInfo *info, TitleSortSet *sortset, u32 import_max ); + /*---------------------------------------------------------------------------* 処理関数定義 *---------------------------------------------------------------------------*/ @@ -87,13 +100,17 @@ BOOL ImportDirectoryTad(char* directory); Returns: なし。 *---------------------------------------------------------------------------*/ -BOOL ProcessImport(void) +BOOL ProcessImport( void *(*alloc)(unsigned long), void (*free)(void *) ) { const s32 MAX_RETRY_COUNT = 2; BOOL result = TRUE; - char directory[FS_ENTRY_LONGNAME_MAX+6]; + char directory[DIR_NUM][FULLPATH_LEN]; s32 i=0; s32 j=0; + u32 fileCount = 0; + ImportFileInfo *importFileInfoList = NULL; + TitleSortSet *titleSortSetList = NULL; + void *sortBuf = NULL; OS_WaitVBlankIntr(); NNS_G2dCharCanvasClearArea(&gCanvas, TXT_COLOR_WHITE, 0, 30, 256, 100); @@ -112,14 +129,30 @@ BOOL ProcessImport(void) OS_WaitVBlankIntr(); } - STD_TSNPrintf(directory, sizeof(directory), "rom:/data/%s/%s/", sDirectoryNameConsole[GetConsole()], sDirectoryNameRegion[gRegion]); - result &= ImportDirectoryTad(directory); + STD_TSNPrintf(directory[0], sizeof(directory[0]), "rom:/data/%s/%s/", sDirectoryNameConsole[GetConsole()], sDirectoryNameRegion[gRegion]); + STD_TSNPrintf(directory[1], sizeof(directory[1]), "rom:/data/common/%s/", sDirectoryNameRegion[gRegion]); + STD_TSNPrintf(directory[2], sizeof(directory[2]), "rom:/data/common/"); + + // ディレクトリ内の TAD ファイル数をカウントする + fileCount = CountTadInDir(directory, DIR_NUM); - STD_TSNPrintf(directory, sizeof(directory), "rom:/data/common/%s/", sDirectoryNameRegion[gRegion]); - result &= ImportDirectoryTad(directory); - - STD_TSNPrintf(directory, sizeof(directory), "rom:/data/common/"); - result &= ImportDirectoryTad(directory); + // ファイル名+ディレクトリインデックス配列、TitleSortInfo 配列を確保 + importFileInfoList = alloc( sizeof(ImportFileInfo) * fileCount ); + titleSortSetList = alloc( sizeof(TitleSortSet) * fileCount ); + + // 情報を読み込む + result &= MakeList( directory, DIR_NUM, importFileInfoList, titleSortSetList); + + // TitleSortInfoをソート + sortBuf = alloc( MATH_QSortStackSize( fileCount ) ); + SortTitle( titleSortSetList, fileCount, sortBuf ); + + // インポート + result &= ImportTadFromList( directory, importFileInfoList, titleSortSetList, fileCount ); + + // もはや必要ないリストの解放 + free( importFileInfoList ); + free( titleSortSetList ); while (!FadeOutTick()) { @@ -129,6 +162,199 @@ BOOL ProcessImport(void) return result; } +/*---------------------------------------------------------------------------* + Name: CountTadInDir + + Description: リストで指定したディレクトリにある TAD の総数を返します。 + + Arguments: dir_list,dir_max + + Returns: u32 + *---------------------------------------------------------------------------*/ +static u32 CountTadInDir( char (*dir_list)[FULLPATH_LEN], u32 dir_max ) +{ + int l; + u32 count = 0; + for( l=0; lattributes & (FS_ATTRIBUTE_DOS_DIRECTORY | FS_ATTRIBUTE_IS_DIRECTORY)) == 0) + { + char* pExtension; + // 拡張子のチェック + pExtension = STD_SearchCharReverse( info->longname, '.'); + if (pExtension) + { + if (!STD_CompareString( pExtension, ".tad") || !STD_CompareString( pExtension, ".TAD") ) + { + count++; + } + } + } + } + FS_CloseDirectory( &dir ); + } + return count; +} + +/*---------------------------------------------------------------------------* + Name: MakeList + + Description: リストで指定したディレクトリから ImportTadFromList + を行うのに必要なリストを作成します。 + + Arguments: dir_list, dir_max, info, sortset + + Returns: BOOL + *---------------------------------------------------------------------------*/ +static BOOL MakeList( char (*dir_list)[FULLPATH_LEN], u32 dir_max, ImportFileInfo *info, TitleSortSet *sortset ) +{ + int l; + u32 count = 0; + BOOL result = TRUE; + + for( l=0; lattributes & (FS_ATTRIBUTE_DOS_DIRECTORY | FS_ATTRIBUTE_IS_DIRECTORY)) == 0) + { + char* pExtension; + // 拡張子のチェック + pExtension = STD_SearchCharReverse( fsinfo->longname, '.'); + if (pExtension) + { + if (!STD_CompareString( pExtension, ".tad") || !STD_CompareString( pExtension, ".TAD") ) + { + NAMTadInfo tadInfo; + char fullPath[FULLPATH_LEN]; + + // フルパス作成 + STD_TSNPrintf(fullPath, sizeof(fullPath), "%s/%s", dirName, fsinfo->longname); + + // TAD情報取得 + // tadファイルの情報取得 + if (NAM_ReadTadInfo(&tadInfo, fullPath) != NAM_OK) + { + // 失敗したらエラーを表示して次のファイルへ、結果はFalse + kamiFontPrintfConsole(CONSOLE_RED, "Error NAM_ReadTadInfo()\n"); + kamiFontPrintfConsole(CONSOLE_RED, "file : %s\n",fsinfo->longname); + result = FALSE; + continue; + } + + // ImportFileInfo と TitleSortSet に情報を転載 + info[count].dirNameIndex = (u8)l; + STD_TSNPrintf(info[count].fileName, FS_ENTRY_LONGNAME_MAX, fsinfo->longname); + sortset[count].index = count; + sortset[count].titleID = tadInfo.titleInfo.titleId; + + count++; + } + } + } + } + } + return result; +} + +/*---------------------------------------------------------------------------* + Name: ImportTadFromList + + Description: MakeList で得たリストの情報に従って TAD をインポートします。 + + Arguments: dir_list, info, sortset, import_max + + Returns: BOOL + *---------------------------------------------------------------------------*/ +static BOOL ImportTadFromList( char (*dir_list)[FULLPATH_LEN], ImportFileInfo *info, TitleSortSet *sortset, u32 import_max ) +{ + int l; + int j; + BOOL result = TRUE; + s32 listNo=0; + + for( l=0; ltitleID); + u32 titleID_lo2 = (u32)(0xffffffff & ipp2->titleID); + BOOL isSystem1 = (u32)( 0x1 & ( ipp1->titleID >> 32 ) ) ? TRUE : FALSE; + BOOL isSystem2 = (u32)( 0x1 & ( ipp2->titleID >> 32 ) ) ? TRUE : FALSE; + BOOL isH1 = ( (u8)( 0xff & ( titleID_lo1 >> 24 ) ) == 'H' ) ? TRUE : FALSE; + BOOL isH2 = ( (u8)( 0xff & ( titleID_lo2 >> 24 ) ) == 'H' ) ? TRUE : FALSE; + + if( isSystem1 && !isSystem2 ) + { + // 要素1が System であり、要素2が System でない場合、要素1が前 (-1) + return -1; + }else if( !isSystem1 && isSystem2 ) + { + // 要素1が System でなく、要素2が System である場合、要素1が後 (1) + return 1; + }else if( isH1 && !isH2 ) + { + // 要素1が "H***" であり、要素2が "H***" でない場合、要素1が前 (-1) + return -1; + }else if( !isH1 && isH2 ) + { + // 要素1が "H***" でなく、要素2が "H***" である場合、要素1が後 (1) + return 1; + }else + { + // その他の場合、titleID_loの小さいほうが前 + return ( titleID_lo1 > titleID_lo2 ) ? + 1 : + ( (titleID_lo1 < titleID_lo2) ? -1 : 0 ); + } + +} + +// TitleSortSet の配列をある法則にしたがってソートします。 +// 内部で MATH_QSort を使用しているので、MATH_QSortStackSize() 関数で取得できる +// サイズの作業バッファを buf に与える必要があります。 +// このサイズは (log2(num)+1) * 8 byte となっています。 +// 作業バッファを渡さない場合には、スタックからこのサイズの作業領域が確保されます。 +// +// info ソートする TitleSortSet 配列の先頭アドレス +// num ソートする配列の要素数 +// buf 作業バッファ +void SortTitle( TitleSortSet *info, u32 num, void *buf ) +{ + MATH_QSort( info, num, sizeof(TitleSortSet), TitleCompareFunc, buf ); +} \ No newline at end of file