TwlIPL/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_import.c
kamikawa a383dda74e SystemUpdaterRegionSelect 中韓対応。
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@2789 b08762b0-b915-fc4b-9d8c-17b2551a87ff
2009-04-06 05:23:01 +00:00

587 lines
17 KiB
C
Raw Blame History

This file contains invisible Unicode characters

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

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

/*---------------------------------------------------------------------------*
Project: SystemUpdater
File: process_import.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 <twl.h>
#include <nitro/snd.h>
#include <twl/fatfs.h>
#include <nitro/card.h>
#include <twl/nam.h>
#include <twl/lcfg.h>
#include <sysmenu/namut.h>
#include "kami_font.h"
#include "hw_info.h"
#include "TWLHWInfo_api.h"
#include "graphics.h"
#include "kami_global.h"
#include "font.h"
#include "sort_title.h"
/*---------------------------------------------------------------------------*
Œ^’è‹`
*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*
è<E28099>è`
*---------------------------------------------------------------------------*/
#define THREAD_STACK_SIZE (16*1024)
#define DIR_NUM 3
#define FULLPATH_LEN ( FS_ENTRY_LONGNAME_MAX+6 )
static const char* sDirectoryNameRegion[] =
{
"japan",
"america",
"europe",
"australia",
"china",
"korea"
};
static const char* sDirectoryNameConsole[] =
{
"debugger", // IS_TWL_DEBUGGER
"standalone", // IS_TWL_CAPTURE
"standalone", // TWL
"" // UNKNOWN
};
typedef struct {
u8 dirNameIndex;
char fileName[FS_ENTRY_LONGNAME_MAX];
} ImportFileInfo;
/*---------------------------------------------------------------------------*
“à•”•Ï<E280A2>è`
*---------------------------------------------------------------------------*/
static u32 sCurrentProgress;
static vu8 sNowImport = FALSE;
static vu8 sProgress = FALSE;
static u8 sStack[THREAD_STACK_SIZE];
/*---------------------------------------------------------------------------*
“à•”ŠÖ<C5A0><EFBFBD>錾
*---------------------------------------------------------------------------*/
static s32 kamiImportTad(const char* path, BOOL erase);
static void ProgressThread(void* arg);
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 );
/*---------------------------------------------------------------------------*
<20>ˆ<CB86>ŠÖ<C5A0>è`
*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*
Name: ProcessImport
Description:
Arguments: ȵ<E2809A>B
Returns: ȵ<E2809A>B
*---------------------------------------------------------------------------*/
BOOL ProcessImport( void *(*alloc)(unsigned long), void (*free)(void *) )
{
const s32 MAX_RETRY_COUNT = 2;
BOOL result = TRUE;
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);
OS_WaitVBlankIntr();
NNS_G2dCharCanvasClearArea(&gCanvas2, TXT_COLOR_BLACK, 0, 130, 256, 62);
OS_WaitVBlankIntr();
NNS_G2dTextCanvasDrawText(&gTextCanvas, 40, 60,
TXT_COLOR_WHITE_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, (const char*)L"Now Import..");
while(!FadeInTick())
{
G3X_Reset();
G3_Identity();
G3_PolygonAttr(GX_LIGHTMASK_NONE, GX_POLYGONMODE_DECAL, GX_CULL_NONE, 0, 31, 0);
G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W);
OS_WaitVBlankIntr();
}
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/");
// ƒfƒBƒŒƒNƒgƒŠ“àÌ TAD ƒtƒ@ƒCƒ<C692>ðƒJƒEƒ“ƒg·é
fileCount = CountTadInDir(directory, DIR_NUM);
// ƒtƒ@ƒCƒ¼+ƒfƒBƒŒƒNƒgƒŠƒCƒ“ƒfƒbƒNƒX”z—ñ<E28094>ATitleSortInfo ”z—ñðŠm•Û
importFileInfoList = alloc( sizeof(ImportFileInfo) * fileCount );
titleSortSetList = alloc( sizeof(TitleSortSet) * fileCount );
// <20>î•ñð“ÇÝ<E2809A>žÞ
result &= MakeList( directory, DIR_NUM, importFileInfoList, titleSortSetList);
// TitleSortInfoðƒ\<5C>[ƒg
sortBuf = alloc( MATH_QSortStackSize( fileCount ) );
SortTitle( titleSortSetList, fileCount, sortBuf );
// ƒCƒ“ƒ|<7C>[ƒg
result &= ImportTadFromList( directory, importFileInfoList, titleSortSetList, fileCount );
// àÍâ•K—vÈ¢ƒŠƒXƒg̉ð•ú
free( importFileInfoList );
free( titleSortSetList );
while (!FadeOutTick())
{
OS_WaitVBlankIntr();
}
return result;
}
/*---------------------------------------------------------------------------*
Name: CountTadInDir
Description: ƒŠƒXƒgÅŽwèµ½ƒfƒBƒŒƒNƒgƒŠÉ é TAD Ì<C38C><E28098>ð•Եܷ<E2809A>B
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; l<dir_max; l++ )
{
char *dirName = dir_list[ l ];
FSFile dir;
FSDirectoryEntryInfo info[1];
FS_InitFile(&dir);
if (!FS_OpenDirectory(&dir, dirName, FS_FILEMODE_R))
{
// óƒfƒBƒŒƒNƒgƒŠÍMakeromŽžÉ<E2809A>í<EFBFBD>œ³ê鿤ÈÌű±ÅÍ”òη
continue;
}
while (FS_ReadDirectory(&dir, info))
{
if ((info->attributes & (FS_ATTRIBUTE_DOS_DIRECTORY | FS_ATTRIBUTE_IS_DIRECTORY)) == 0)
{
char* pExtension;
// Šg£Žq̃`ƒFƒbƒN
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: ƒŠƒXƒgÅŽwèµ½ƒfƒBƒŒƒNƒgƒŠ©ç ImportTadFromList
ð<E2809A>s¤ÌÉ•K—vÈƒŠƒXƒgð<E2809A>ì<EFBFBD>¬µÜ·<E2809A>B
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; l<dir_max; l++ )
{
char *dirName = dir_list[ l ];
FSFile dir;
FSDirectoryEntryInfo fsinfo[1];
FS_InitFile(&dir);
if (!FS_OpenDirectory(&dir, dirName, FS_FILEMODE_R))
{
// óƒfƒBƒŒƒNƒgƒŠÍMakeromŽžÉ<E2809A>í<EFBFBD>œ³ê鿤ÈÌű±ÅÍ”òη
continue;
}
while (FS_ReadDirectory(&dir, fsinfo))
{
if ((fsinfo->attributes & (FS_ATTRIBUTE_DOS_DIRECTORY | FS_ATTRIBUTE_IS_DIRECTORY)) == 0)
{
char* pExtension;
// Šg£Žq̃`ƒFƒbƒN
pExtension = STD_SearchCharReverse( fsinfo->longname, '.');
if (pExtension)
{
if (!STD_CompareString( pExtension, ".tad") || !STD_CompareString( pExtension, ".TAD") )
{
NAMTadInfo tadInfo;
char fullPath[FULLPATH_LEN];
// ƒtƒƒpƒX<C692>ì<EFBFBD>¬
STD_TSNPrintf(fullPath, sizeof(fullPath), "%s/%s", dirName, fsinfo->longname);
// TAD<41>î•ñŽæ“¾
// tadƒtƒ@ƒCƒÌ<E2809A>î•ñŽæ“¾
if (NAM_ReadTadInfo(&tadInfo, fullPath) != NAM_OK)
{
// ޏ”sµ½çƒGƒ‰<C692>[‚ð•\ަµÄŽŸÌƒtƒ@ƒCƒÖ<E2809A>‰ÊÍFalse
kamiFontPrintfConsole(CONSOLE_RED, "Error NAM_ReadTadInfo()\n");
kamiFontPrintfConsole(CONSOLE_RED, "file : %s\n",fsinfo->longname);
result = FALSE;
continue;
}
// ImportFileInfo ‚Æ TitleSortSet É<E2809A>î•ñð“]<5D>Ú
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 Å“¾½ƒŠƒXƒgÌ<E2809A>î•ñÉ<E2809A>]‚Á‚Ä TAD ðƒCƒ“ƒ|<7C>[ƒgµÜ·<E2809A>B
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; l<import_max; l++ )
{
char *longName = info[ sortset[ l ].index ].fileName;
char *dirName = dir_list[ info[ sortset[ l ].index ].dirNameIndex ];
char fullPath[FULLPATH_LEN];
char string1[256];
u16 string2[256];
const s32 MAX_RETRY_COUNT = 2;
s32 nam_result;
char *tlo = (char *)( &sortset[ l ].titleID );
// ƒtƒƒpƒX<C692>ì<EFBFBD>¬
STD_TSNPrintf(fullPath, sizeof(fullPath), "%s/%s", dirName, longName);
// ƒCƒ“ƒ|<7C>[ƒg
STD_TSPrintf(string1, "List %d ", ++listNo);
MI_CpuClear8(string2, sizeof(string2));
STD_ConvertStringSjisToUnicode(string2, NULL, string1, NULL, NULL);
NNS_G2dCharCanvasClearArea(&gCanvas, TXT_COLOR_WHITE, 0, 60, 256, 20);
NNS_G2dTextCanvasDrawText(&gTextCanvas, 40, 60,
TXT_COLOR_WHITE_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, (const char*)L"Now Import..");
NNS_G2dTextCanvasDrawText(&gTextCanvas, 135, 60,
TXT_COLOR_WHITE_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, (const char*)string2);
// MAX_RETRY_COUNTÜÅƒŠƒgƒ‰ƒC·é
for (j=0; j<MAX_RETRY_COUNT; j++)
{
nam_result = kamiImportTad(fullPath, j);
if (nam_result == NAM_OK)
{
break;
}
else
{
kamiFontPrintfConsole(CONSOLE_GREEN, "Import %d Retry!\n", listNo);
}
}
if ( nam_result == NAM_OK)
{
// kamiFontPrintfConsole(FONT_COLOR_GREEN, "List : %d(%c%c%c%c) Import Success.\n", listNo, tlo[3], tlo[2], tlo[1], tlo[0] );
kamiFontPrintfConsole(FONT_COLOR_GREEN, "List : %d Import Success.\n", listNo );
}
else
{
// kamiFontPrintfConsole(FONT_COLOR_RED, "Error: %d(%c%c%c%c) : RetCode = %d\n", listNo, tlo[3], tlo[2], tlo[1], tlo[0], nam_result );
kamiFontPrintfConsole(FONT_COLOR_RED, "Error: %d : RetCode = %d\n", listNo, nam_result );
result = FALSE;
}
kamiFontLoadScreenData();
}
return result;
}
/*---------------------------------------------------------------------------*
Name: ImportDirectoryTad
Description: Žwèµ½ƒfƒBƒŒƒNƒgƒŠÉ éTADð³<E28093>ðŒ<C3B0>ÉImportµÜ·<E2809A>B
Arguments: path
Returns: ȵ<E2809A>B
*---------------------------------------------------------------------------*/
BOOL ImportDirectoryTad(char* directory)
{
FSFile dir;
FSDirectoryEntryInfo info[1];
const s32 MAX_RETRY_COUNT = 2;
BOOL result = TRUE;
char full_path[FULLPATH_LEN];
static s32 listNo=0;
s32 j=0;
FS_InitFile(&dir);
if (!FS_OpenDirectory(&dir, directory, FS_FILEMODE_R))
{
// óƒfƒBƒŒƒNƒgƒŠÍMakeromŽžÉ<E2809A>í<EFBFBD>œ³ê鿤ÈÌű±ÅÍTRUEð•Ô·
// kamiFontPrintfConsole(CONSOLE_GREEN, "%s can not Open.\n", directory);
return TRUE;
}
// tadƒtƒ@ƒCƒðŒŸ<C592>õµÄƒCƒ“ƒ|<7C>[ƒg
// [TODO:]<5D>æÉfull_pathÌƒŠƒXƒgð<E2809A>ìÁÄ<E2809A>ANAM_ReadTadInfoÅŽæêéTitleID_loÌlŃ\<5C>[ƒgµÄ©ç
// <20>‡”ÔɃCƒ“ƒ|<7C>[ƒg·éæ¤É•Ï<E280A2>X·é<E2809A>B
// ±ÌŠÖ<C5A0>𕪯éƒCƒ<43><C692>[ƒWÅ<E2809A>AŠeƒtƒHƒƒ_̼<E28093>ÌƒŠƒXƒgð<E2809A>æÉ<E2809A>ì<EFBFBD>¬·é
//
while (FS_ReadDirectory(&dir, info))
{
s32 nam_result;
char string1[256];
u16 string2[256];
MI_CpuClear8(string2, sizeof(string2));
if ((info->attributes & (FS_ATTRIBUTE_DOS_DIRECTORY | FS_ATTRIBUTE_IS_DIRECTORY)) == 0)
{
char* pExtension;
// Šg£Žq̃`ƒFƒbƒN
pExtension = STD_SearchCharReverse( info->longname, '.');
if (pExtension)
{
if (!STD_CompareString( pExtension, ".tad") || !STD_CompareString( pExtension, ".TAD") )
{
STD_TSPrintf(string1, "List %d ", ++listNo);
STD_ConvertStringSjisToUnicode(string2, NULL, string1, NULL, NULL);
NNS_G2dCharCanvasClearArea(&gCanvas, TXT_COLOR_WHITE, 0, 60, 256, 20);
NNS_G2dTextCanvasDrawText(&gTextCanvas, 40, 60,
TXT_COLOR_WHITE_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, (const char*)L"Now Import..");
NNS_G2dTextCanvasDrawText(&gTextCanvas, 135, 60,
TXT_COLOR_WHITE_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, (const char*)string2);
STD_TSNPrintf(full_path, sizeof(full_path), "%s/%s", directory, info->longname);
// kamiFontPrintfConsole(CONSOLE_GREEN, " %s\n", full_path);
// MAX_RETRY_COUNTÜÅƒŠƒgƒ‰ƒC·é
for (j=0; j<MAX_RETRY_COUNT; j++)
{
nam_result = kamiImportTad(full_path, j);
if (nam_result == NAM_OK)
{
break;
}
else
{
kamiFontPrintfConsole(CONSOLE_GREEN, "Import %d Retry!\n", listNo);
}
}
if ( nam_result == NAM_OK)
{
kamiFontPrintfConsole(FONT_COLOR_GREEN, "List : %d Import Success.\n", listNo);
}
else
{
kamiFontPrintfConsole(FONT_COLOR_RED, "Error: %d : RetCode = %d\n", listNo, nam_result );
result = FALSE;
}
kamiFontLoadScreenData();
}
}
}
}
return result;
}
/*---------------------------------------------------------------------------*
Name: kamiImportTad
Description: .tad ƒtƒ@ƒCƒƒCƒ“ƒ|<7C>[ƒg
Arguments: no
Returns: None.
*---------------------------------------------------------------------------*/
static s32 kamiImportTad(const char* path, BOOL erase)
{
NAMTadInfo tadInfo;
OSThread thread;
s32 nam_result;
// tadƒtƒ@ƒCƒÌ<E2809A>î•ñŽæ“¾
nam_result = NAM_ReadTadInfo(&tadInfo, path);
if ( nam_result != NAM_OK )
{
return nam_result;
}
// ESÌŽd—lŌâ e-ticket ª éÆ<E2809A>Vµ¢ e-ticket ðŽgÁ½ƒCƒ“ƒ|<7C>[ƒgªÅ«È¢
// ŽbèΉžÆµÄŠY“ƒ^ƒCƒgƒðŠ®S<E28098>í<EFBFBD>œµÄ©çƒCƒ“ƒ|<7C>[ƒg·é
if (erase)
{
nam_result = NAM_DeleteTitleCompletely(tadInfo.titleInfo.titleId);
if ( nam_result != NAM_OK )
{
kamiFontPrintfConsole(CONSOLE_RED, "Fail! RetCode=%x\n", nam_result);
return FALSE;
}
}
// ƒCƒ“ƒ|<7C>[ƒgŠJŽnƒtƒ‰ƒOð—§Äé
sNowImport = TRUE;
// <20>i»ƒXƒŒƒbƒh<C692>ì<EFBFBD>¬
MI_CpuClear8(sStack, THREAD_STACK_SIZE);
OS_CreateThread(&thread, ProgressThread, NULL,
(void*)((u32)sStack + THREAD_STACK_SIZE), THREAD_STACK_SIZE, OS_GetCurrentThread()->priority - 1);
OS_WakeupThreadDirect(&thread);
// ImportŠJŽn
nam_result = NAM_ImportTad( path );
// ƒCƒ“ƒ|<7C>[ƒgŠJŽnƒtƒ‰ƒOð‰º°é
sNowImport = FALSE;
// <20>i»ƒXƒŒƒbƒhÌŽ©—Í<E28094>I—¹ðÒÂ
while (sProgress){};
// ‚«‚¿‚ñ‚Æ•\ަ‚·‚é
G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W);
OS_WaitVBlankIntr();
// InstalledSoftBoxCount, FreeSoftBoxCount ÌlðŒ»<C592>ÝÌNANDÌ<E2809A>óÔÉ<E2809A>í¹Ä<E2809A>X<EFBFBD>VµÜ·<E2809A>B
(void)NAMUT_UpdateSoftBoxCount();
return nam_result;
}
/*---------------------------------------------------------------------------*
Name: ProgressThread
Description: .tad ƒtƒ@ƒCƒƒCƒ“ƒ|<7C>[ƒgÌ<E2809A>i»ð•\ަ·éƒXƒŒƒbƒh<C692>B
<09>i»ª100%ÉB·éÆ<E2809A>ˆ<CB86>𔲯é<E2809A>B
Arguments: arg - Žg—pµÈ¢<E2809A>B
Returns: None.
*---------------------------------------------------------------------------*/
static void ProgressThread(void* /*arg*/)
{
u32 currentSize;
u32 totalSize = 0;
u32 totalSizeBk = 0;
sProgress = TRUE;
while (sNowImport)
{
NAM_GetProgress(&currentSize, &totalSize);
if ((totalSize > 0 && totalSize == currentSize) || totalSizeBk > totalSize)
{
// ŠùɃCƒ“ƒ|<7C>[ƒgª<E2809A>I—¹
ProgressDraw((f32)1.0);
break;
}
else if (totalSize > 0)
{
ProgressDraw((f32)currentSize/totalSize);
}
totalSizeBk = totalSize;
// Vƒuƒ‰ƒ“ƒNÒ¿
G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W);
OS_WaitVBlankIntr();
// 3D<33>‰Šú‰»
G3X_Reset();
G3_Identity();
G3_PolygonAttr(GX_LIGHTMASK_NONE, GX_POLYGONMODE_DECAL, GX_CULL_NONE, 0, 31, 0);
}
sProgress = FALSE;
}
/*---------------------------------------------------------------------------*
Name: ProgressDraw
Description: ƒCƒ“ƒ|<7C>[ƒgÌ<E2809A>i»ð•\ަ‚µ‚Ü‚·
Arguments:
Returns: None.
*---------------------------------------------------------------------------*/
void ProgressDraw(f32 ratio)
{
s16 x = (s16)(30 + (226 - 30)*ratio);
// ƒOƒŠ<C692>[ƒ“ƒo<C692>[
DrawQuadWithColors( 30, 86, x, 95, GX_RGB(22, 31, 22), GX_RGB(12, 25, 12));
// ƒOƒŒ<C692>[ƒo<C692>[
DrawQuad( 30, 86, 226, 95, GX_RGB(28, 28, 28));
}