タイトル列挙時に、特定の法則にしたがってソートするように変更

この並び順によって、オート実行時のインポート順序も決定されます

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@2755 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
yoshida_teruhisa 2009-02-26 07:51:02 +00:00
parent a162b0dc93
commit 2af4e9a6e0
4 changed files with 226 additions and 11 deletions

View File

@ -81,7 +81,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 = ../common/include \
$(ROOT)/build/libraries/lcfg/ARM9.TWL/include \

View File

@ -0,0 +1,100 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK - NandInitializer
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 ].path = sFilePath[ counter ];
counter++;
}
SortTitle( sTitleSortSet, counter, qsortBuf );
// ソート完了
*/
#ifndef TWL_SORT_TITLE_H_
#define TWL_SORT_TITLE_H_
/*---------------------------------------------------------------------------*
定数定義
*---------------------------------------------------------------------------*/
#ifdef __cplusplus
extern "C" {
#endif
#include <twl.h>
/*===========================================================================*/
typedef struct {
OSTitleId titleID;
char *path;
} 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
*---------------------------------------------------------------------------*/

View File

@ -15,6 +15,8 @@
$Author$
*---------------------------------------------------------------------------*/
#include "sort_title.h"
#include <twl.h>
#include <nitro/snd.h>
#include <twl/fatfs.h>
@ -65,6 +67,7 @@ typedef enum {
// 表示&インポートできる.TADファイルは最大16個まで
// しかもSDカードのルートに存在するファイルのみというお手軽実装
#define FILE_NUM_MAX 256
#define QSORT_BUF_SIZE ((8+1) * 8) // サイズは(Log2(FILE_NUM_MAX)+1) * 8 bytes 必要 動的確保できるならそっちの方が楽
#define VIEW_LINES_MAX 16
@ -78,6 +81,7 @@ static s32 sMenuSelectNoIndividually;
static LCFGReadResult (*s_pReadSecureInfoFunc)( void );
static char sFilePath[FILE_NUM_MAX][FS_ENTRY_LONGNAME_MAX];
static TitleSortSet sTitleSortSet[FILE_NUM_MAX];
static u8 sFileNum;
@ -159,6 +163,7 @@ void* ImportProcess0(void)
// 配列クリア
MI_CpuClear8( sFilePath, sizeof(sFilePath) );
MI_CpuClear8( sTitleSortSet, sizeof(sTitleSortSet) );
// ファイル数初期化
sFileNum = 0;
@ -176,6 +181,8 @@ void* ImportProcess0(void)
kamiFontFillChar( 0, BG_COLOR_PINK, BG_COLOR_PINK );
kamiFontFillChar( 1, BG_COLOR_PINK, BG_COLOR_PINK );
kamiFontFillChar( 2, BG_COLOR_PINK, BG_COLOR_TRANS );
FS_InitFile(&dir);
// SDカードのルートディレクトリを検索
if ( !FS_OpenDirectory(&dir, "sdmc:/", FS_FILEMODE_R | FS_FILEMODE_W) )
@ -184,6 +191,8 @@ void* ImportProcess0(void)
}
else
{
int l;
char qsortBuf[QSORT_BUF_SIZE];
FSDirectoryEntryInfo info[1];
OS_Printf("[%s]:\n", "sdmc:/");
@ -208,13 +217,24 @@ void* ImportProcess0(void)
{
if (!STD_CompareString( pExtension, ".tad") || !STD_CompareString( pExtension, ".TAD") )
{
NAMTadInfo tadInfo;
char full_path[FS_ENTRY_LONGNAME_MAX+6];
// フルパスを作成
MakeFullPathForSD(info->longname, full_path);
STD_CopyString( sFilePath[sFileNum], info->longname );
kamiFontPrintfConsole(CONSOLE_ORANGE, "%d:%s\n", sFileNum, info->longname);
// kamiFontPrintfConsole(CONSOLE_ORANGE, "%d:%s\n", sFileNum, info->longname);
// tadファイルの情報取得
if (NAM_ReadTadInfo(&tadInfo, full_path) != NAM_OK)
{
// 失敗したらエラーを表示して現在のファイルを飛ばして先へ進む
kamiFontPrintfConsole(CONSOLE_RED, "Error NAM_ReadTadInfo()\n");
continue;
}
sTitleSortSet[sFileNum].titleID = tadInfo.titleInfo.titleId;
sTitleSortSet[sFileNum].path = sFilePath[sFileNum];
if (++sFileNum >= FILE_NUM_MAX)
{
@ -225,7 +245,15 @@ void* ImportProcess0(void)
}
}
(void)FS_CloseDirectory(&dir);
// ファイルパスをTitleID_lo順にソートする
SortTitle( sTitleSortSet, sFileNum, qsortBuf );
for( l=0; l<sFileNum; l++ )
{
kamiFontPrintfConsole(CONSOLE_ORANGE, "%d:%s\n", l, sTitleSortSet[l].path);
}
kamiFontPrintfConsole(CONSOLE_ORANGE, "--------------------------\n");
// DumpTadInfo();
@ -357,7 +385,7 @@ static void* ImportAllOverwriteProcess0(void)
for (i=0;i<sFileNum;i++)
{
// 強制上書き
if (ImportTad(sFilePath[i], TAD_WRITE_OPTION_OVERWRITE) == FALSE)
if (ImportTad(sTitleSortSet[i].path, TAD_WRITE_OPTION_OVERWRITE) == FALSE)
{
result = FALSE;
}
@ -408,7 +436,7 @@ static void* ImportAllNonexistentProcess0(void)
for (i=0;i<sFileNum;i++)
{
// 書き込みチャレンジ
if (ImportTad(sFilePath[i], TAD_WRITE_OPTION_NONEXISTENT) == FALSE)
if (ImportTad(sTitleSortSet[i].path, TAD_WRITE_OPTION_NONEXISTENT) == FALSE)
{
result = FALSE;
}
@ -536,10 +564,10 @@ void* ImportIndividuallyProcess2(void)
{
BOOL ret;
if (STD_GetStringLength(sFilePath[sMenuSelectNoIndividually]))
if (STD_GetStringLength(sTitleSortSet[sMenuSelectNoIndividually].path))
{
// 個別インポート
ret = ImportTad(sFilePath[sMenuSelectNoIndividually], TAD_WRITE_OPTION_USER);
ret = ImportTad(sTitleSortSet[sMenuSelectNoIndividually].path, TAD_WRITE_OPTION_USER);
}
else
{
@ -774,7 +802,7 @@ static void ShowTadList(void)
for (i=0;i<sLines; i++)
{
// ファイル名追加
kamiFontPrintf(3, (s16)(5+CHAR_OF_MENU_SPACE_INDIVIDUALLY*i), FONT_COLOR_BLACK, "l %-16.16s l l", sFilePath[sTadListViewOffset+i]);
kamiFontPrintf(3, (s16)(5+CHAR_OF_MENU_SPACE_INDIVIDUALLY*i), FONT_COLOR_BLACK, "l %-16.16s l l", sTitleSortSet[sTadListViewOffset+i].path);
}
}
@ -793,12 +821,12 @@ static void DumpTadInfo(void)
NAMTadInfo info;
// ファイル名の有無を確認
if (STD_GetStringLength(sFilePath[sMenuSelectNoIndividually]))
if (STD_GetStringLength(sTitleSortSet[sMenuSelectNoIndividually].path))
{
char full_path[FS_ENTRY_LONGNAME_MAX+6];
// フルパスを作成
MakeFullPathForSD( sFilePath[sMenuSelectNoIndividually], full_path );
MakeFullPathForSD( sTitleSortSet[sMenuSelectNoIndividually].path, full_path );
// TADファイルの情報取得
if (NAM_ReadTadInfo(&info, full_path) == NAM_OK)
@ -811,7 +839,7 @@ static void DumpTadInfo(void)
kamiFontPrintfConsole(CONSOLE_ORANGE, "------ tad profile -----\n");
// File Name
kamiFontPrintfConsole(CONSOLE_ORANGE, "%s\n", sFilePath[sMenuSelectNoIndividually]);
kamiFontPrintfConsole(CONSOLE_ORANGE, "%s\n", sTitleSortSet[sMenuSelectNoIndividually].path);
// File Size
kamiFontPrintfConsole(CONSOLE_ORANGE, "fileSize = %d Byte\n", info.fileSize);

View File

@ -0,0 +1,86 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK - NandInitializer
File: sort_title.c
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$
*---------------------------------------------------------------------------*/
#include "sort_title.h"
/*---------------------------------------------------------------------------*
定数定義
*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*
定数定義
*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*
内部変数定義
*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*
関数定義
*---------------------------------------------------------------------------*/
// ソート用 Compare 関数
static s32 TitleCompareFunc(void *elem1, void *elem2)
{
TitleSortSet *ipp1 = (TitleSortSet *)elem1;
TitleSortSet *ipp2 = (TitleSortSet *)elem2;
u32 titleID_lo1 = (u32)(0xffffffff & ipp1->titleID);
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 );
}