*Added nand extract feature. You can extract everything or enter a path to a directory or file which to extract.

*Added cancel button to progress for extracting all saves or nand paths
This commit is contained in:
dimok321 2011-10-01 10:41:00 +00:00
parent c0b305b163
commit 4ce0b624d1
6 changed files with 147 additions and 43 deletions

View File

@ -2,7 +2,7 @@
<app version="1"> <app version="1">
<name> USB Loader GX</name> <name> USB Loader GX</name>
<coder>USB Loader GX Team</coder> <coder>USB Loader GX Team</coder>
<version>2.2 r1119</version> <version>2.2 r1120</version>
<release_date>201109250949</release_date> <release_date>201109250949</release_date>
<!-- // remove this line to enable arguments <!-- // remove this line to enable arguments
<arguments> <arguments>

View File

@ -22,13 +22,6 @@ static const char *serverURLFull = "http://wiitdb.com/wiitdb/artwork/coverfull/"
static const char *serverURLOrigDiscs = "http://wiitdb.com/wiitdb/artwork/disc/"; static const char *serverURLOrigDiscs = "http://wiitdb.com/wiitdb/artwork/disc/";
static const char *serverURLCustomDiscs = "http://wiitdb.com/wiitdb/artwork/disccustom/"; static const char *serverURLCustomDiscs = "http://wiitdb.com/wiitdb/artwork/disccustom/";
static bool AbortRequested = false;
static void AbortCallback(void)
{
AbortRequested = true;
}
void ImageDownloader::DownloadImages() void ImageDownloader::DownloadImages()
{ {
int choice = CheckboxWindow(tr( "Cover Download" ), 0, tr( "3D Covers" ), tr( "Flat Covers" ), tr("Full HQ Covers"), tr("Full LQ Covers"), tr( "Original Discarts" ), tr( "Custom Discarts" )); // ask for download choice int choice = CheckboxWindow(tr( "Cover Download" ), 0, tr( "3D Covers" ), tr( "Flat Covers" ), tr("Full HQ Covers"), tr("Full LQ Covers"), tr( "Original Discarts" ), tr( "Custom Discarts" )); // ask for download choice
@ -64,12 +57,12 @@ void ImageDownloader::Start()
return; return;
} }
AbortRequested = false; ProgressCancelEnable(true);
ProgressSetAbortCallback(AbortCallback);
DownloadProcess(TotalDownloadCount); DownloadProcess(TotalDownloadCount);
ProgressSetAbortCallback(NULL); ProgressCancelEnable(false);
ProgressStop(); ProgressStop();
if(MissingImagesCount == 0) if(MissingImagesCount == 0)
@ -145,7 +138,7 @@ int ImageDownloader::DownloadProcess(int TotalDownloadCount)
for(u32 i = 0, pos = 0; i < MissingImages.size(); ++i, ++pos) for(u32 i = 0, pos = 0; i < MissingImages.size(); ++i, ++pos)
{ {
if(AbortRequested) if(ProgressCanceled())
break; break;
snprintf(progressMsg, sizeof(progressMsg), "http://wiitdb.com : %s.png", MissingImages[i].gameID.c_str()); snprintf(progressMsg, sizeof(progressMsg), "http://wiitdb.com : %s.png", MissingImages[i].gameID.c_str());

View File

@ -24,7 +24,8 @@
/*** Variables used only in this file ***/ /*** Variables used only in this file ***/
static lwp_t progressthread = LWP_THREAD_NULL; static lwp_t progressthread = LWP_THREAD_NULL;
static mutex_t ProgressMutex = LWP_MUTEX_NULL; static mutex_t ProgressMutex = LWP_MUTEX_NULL;
static ProgressAbortCallback AbortCallback = NULL; static bool CancelEnabled = false;
static bool progressCanceled = false;
static char progressTitle[75]; static char progressTitle[75];
static char progressMsg1[75]; static char progressMsg1[75];
static char progressMsg2[75]; static char progressMsg2[75];
@ -57,6 +58,7 @@ extern "C" void StartProgress(const char * title, const char * msg1, const char
else else
progressMsg2[0] = '\0'; progressMsg2[0] = '\0';
progressCanceled = false;
showSize = swSize; showSize = swSize;
showTime = swTime; showTime = swTime;
showProgress = 1; showProgress = 1;
@ -166,6 +168,7 @@ void ShowProgress(const char *title, const char *msg1, const char *msg2, s64 don
***************************************************************************/ ***************************************************************************/
extern "C" void ProgressStop() extern "C" void ProgressStop()
{ {
progressCanceled = false;
showProgress = 0; showProgress = 0;
progressTitle[0] = 0; progressTitle[0] = 0;
progressMsg1[0] = 0; progressMsg1[0] = 0;
@ -181,13 +184,21 @@ extern "C" void ProgressStop()
} }
/**************************************************************************** /****************************************************************************
* ProgressSetAbortCallback * ProgressCancelEnable
* *
* Set a callback for the cancel button * Enable/disable the progress cancel button
***************************************************************************/ ***************************************************************************/
extern "C" void ProgressSetAbortCallback(ProgressAbortCallback callback) extern "C" void ProgressCancelEnable(bool enable)
{ {
AbortCallback = callback; CancelEnabled = enable;
}
/****************************************************************************
* ProgressCanceled
***************************************************************************/
extern "C" bool ProgressCanceled()
{
return progressCanceled;
} }
/**************************************************************************** /****************************************************************************
@ -270,6 +281,11 @@ static void UpdateProgressValues(GuiImage *progressbarImg, GuiText *prTxt, GuiTe
***************************************************************************/ ***************************************************************************/
static void ProgressWindow(const char *title, const char *msg1, const char *msg2) static void ProgressWindow(const char *title, const char *msg1, const char *msg2)
{ {
progressCanceled = false;
usleep(500000); // wait to see if progress flag changes soon
if (!showProgress) return;
GuiWindow promptWindow(472, 320); GuiWindow promptWindow(472, 320);
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
promptWindow.SetPosition(0, -10); promptWindow.SetPosition(0, -10);
@ -328,19 +344,19 @@ static void ProgressWindow(const char *title, const char *msg1, const char *msg2
prsTxt.SetAlignment(ALIGN_RIGHT, ALIGN_MIDDLE); prsTxt.SetAlignment(ALIGN_RIGHT, ALIGN_MIDDLE);
prsTxt.SetPosition(-178, 40); prsTxt.SetPosition(-178, 40);
GuiText timeTxt((char*) NULL, 22, thColor("r=0 g=0 b=0 a=255 - prompt windows text color")); GuiText timeTxt((char*) NULL, 20, thColor("r=0 g=0 b=0 a=255 - prompt windows text color"));
timeTxt.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM); timeTxt.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
timeTxt.SetPosition(280, -50); timeTxt.SetPosition(280, -50);
GuiText sizeTxt((char*) NULL, 22, thColor("r=0 g=0 b=0 a=255 - prompt windows text color")); GuiText sizeTxt((char*) NULL, 20, thColor("r=0 g=0 b=0 a=255 - prompt windows text color"));
sizeTxt.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM); sizeTxt.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
sizeTxt.SetPosition(50, -50); sizeTxt.SetPosition(50, -50);
GuiText speedTxt((char*) NULL, 22, thColor("r=0 g=0 b=0 a=255 - prompt windows text color")); GuiText speedTxt((char*) NULL, 20, thColor("r=0 g=0 b=0 a=255 - prompt windows text color"));
speedTxt.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM); speedTxt.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
speedTxt.SetPosition(50, -74); speedTxt.SetPosition(50, -74);
GuiText prTxt((char*) NULL, 26, thColor("r=0 g=0 b=0 a=255 - prompt windows text color")); GuiText prTxt((char*) NULL, 22, thColor("r=0 g=0 b=0 a=255 - prompt windows text color"));
prTxt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE); prTxt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
prTxt.SetPosition(210, 40); prTxt.SetPosition(210, 40);
@ -369,13 +385,11 @@ static void ProgressWindow(const char *title, const char *msg1, const char *msg2
cancelTxt.SetWidescreen(Settings.widescreen); cancelTxt.SetWidescreen(Settings.widescreen);
cancelImg.SetWidescreen(Settings.widescreen); cancelImg.SetWidescreen(Settings.widescreen);
} }
GuiButton cancelBtn(&cancelImg, &cancelImg, 2, 4, 0, -45, &trigA, btnSoundOver, btnSoundClick2, 1); GuiButton cancelBtn(&cancelImg, &cancelImg, 2, 4, 0, -45, &trigA, btnSoundOver, btnSoundClick2, 1);
cancelBtn.SetLabel(&cancelTxt); cancelBtn.SetLabel(&cancelTxt);
cancelBtn.SetState(STATE_SELECTED); cancelBtn.SetState(STATE_SELECTED);
usleep(400000); // wait to see if progress flag changes soon
if (!showProgress) return;
promptWindow.Append(&dialogBoxImg); promptWindow.Append(&dialogBoxImg);
promptWindow.Append(&progressbarEmptyImg); promptWindow.Append(&progressbarEmptyImg);
promptWindow.Append(&progressbarImg); promptWindow.Append(&progressbarImg);
@ -391,8 +405,12 @@ static void ProgressWindow(const char *title, const char *msg1, const char *msg2
promptWindow.Append(&sizeTxt); promptWindow.Append(&sizeTxt);
promptWindow.Append(&speedTxt); promptWindow.Append(&speedTxt);
} }
if(AbortCallback) if(CancelEnabled)
{
promptWindow.Append(&cancelBtn); promptWindow.Append(&cancelBtn);
if(showSize)
cancelBtn.SetPosition(90, -45);
}
HaltGui(); HaltGui();
promptWindow.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_IN, 50); promptWindow.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_IN, 50);
@ -423,7 +441,7 @@ static void ProgressWindow(const char *title, const char *msg1, const char *msg2
if(cancelBtn.GetState() == STATE_CLICKED) if(cancelBtn.GetState() == STATE_CLICKED)
{ {
if(AbortCallback) AbortCallback(); progressCanceled = true;
cancelBtn.ResetState(); cancelBtn.ResetState();
} }
} }

View File

@ -8,10 +8,10 @@
#ifndef _PROGRESSWINDOW_H_ #ifndef _PROGRESSWINDOW_H_
#define _PROGRESSWINDOW_H_ #define _PROGRESSWINDOW_H_
typedef void (*ProgressAbortCallback)(void);
#ifdef __cplusplus #ifdef __cplusplus
#define PROGRESS_CANCELED -12345
void InitProgressThread(); void InitProgressThread();
void ExitProgressThread(); void ExitProgressThread();
void ShowProgress(const char *title, const char *msg1, const char *msg2, s64 done, s64 total, bool swSize = false, bool swTime = false); void ShowProgress(const char *title, const char *msg1, const char *msg2, s64 done, s64 total, bool swSize = false, bool swTime = false);
@ -21,9 +21,10 @@ extern "C"
{ {
#endif #endif
void ProgressCancelEnable(bool allowCancel);
void StartProgress(const char * title, const char * msg1, const char * msg2, bool swSize, bool swTime); void StartProgress(const char * title, const char * msg1, const char * msg2, bool swSize, bool swTime);
void ShowProgress(s64 done, s64 total); void ShowProgress(s64 done, s64 total);
void ProgressSetAbortCallback(ProgressAbortCallback callback); bool ProgressCanceled();
void ProgressStop(); void ProgressStop();
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -62,6 +62,7 @@ FeatureSettingsMenu::FeatureSettingsMenu()
Options->SetName(Idx++, "%s", tr( "Wiinnertag" )); Options->SetName(Idx++, "%s", tr( "Wiinnertag" ));
Options->SetName(Idx++, "%s", tr( "Import Categories" )); Options->SetName(Idx++, "%s", tr( "Import Categories" ));
Options->SetName(Idx++, "%s", tr( "Export All Saves to EmuNand" )); Options->SetName(Idx++, "%s", tr( "Export All Saves to EmuNand" ));
Options->SetName(Idx++, "%s", tr( "Dump NAND to EmuNand" ));
OldTitlesOverride = Settings.titlesOverride; OldTitlesOverride = Settings.titlesOverride;
@ -108,6 +109,9 @@ void FeatureSettingsMenu::SetOptionValues()
//! Settings: Export Savegames to EmuNand //! Settings: Export Savegames to EmuNand
Options->SetValue(Idx++, " "); Options->SetValue(Idx++, " ");
//! Settings: Dump NAND to EmuNand
Options->SetValue(Idx++, " ");
} }
int FeatureSettingsMenu::GetMenuInternal() int FeatureSettingsMenu::GetMenuInternal()
@ -226,6 +230,7 @@ int FeatureSettingsMenu::GetMenuInternal()
int choice = WindowPrompt(tr( "Do you want to extract all the save games?" ), tr("The save games will be extracted to your emu nand path. Attention: All existing saves will be overwritten."), tr( "Yes" ), tr( "Cancel" )); int choice = WindowPrompt(tr( "Do you want to extract all the save games?" ), tr("The save games will be extracted to your emu nand path. Attention: All existing saves will be overwritten."), tr( "Yes" ), tr( "Cancel" ));
if (choice == 1) if (choice == 1)
{ {
ProgressCancelEnable(true);
StartProgress(tr("Extracting files:"), 0, 0, true, false); StartProgress(tr("Extracting files:"), 0, 0, true, false);
char filePath[512]; char filePath[512];
char nandPath[ISFS_MAXPATH]; char nandPath[ISFS_MAXPATH];
@ -242,7 +247,11 @@ int FeatureSettingsMenu::GetMenuInternal()
ShowProgress(tr("Extracting files:"), GameTitles.GetTitle(gameList[i]), 0, 0, -1, true, false); ShowProgress(tr("Extracting files:"), GameTitles.GetTitle(gameList[i]), 0, 0, -1, true, false);
int ret = NandTitle::ExtractDir(nandPath, filePath); int ret = NandTitle::ExtractDir(nandPath, filePath);
if(ret < 0) //! Games with installable channels: Mario Kart, Wii Fit, etc. if(ret == PROGRESS_CANCELED)
{
break;
}
else if(ret < 0) //! Games with installable channels: Mario Kart, Wii Fit, etc.
{ {
snprintf(nandPath, sizeof(nandPath), "/title/00010004/%02x%02x%02x%02x", gameList[i]->id[0], gameList[i]->id[1], gameList[i]->id[2], gameList[i]->id[3]); snprintf(nandPath, sizeof(nandPath), "/title/00010004/%02x%02x%02x%02x", gameList[i]->id[0], gameList[i]->id[1], gameList[i]->id[2], gameList[i]->id[3]);
snprintf(filePath, sizeof(filePath), "%s%s", Settings.NandEmuPath, nandPath); snprintf(filePath, sizeof(filePath), "%s%s", Settings.NandEmuPath, nandPath);
@ -264,16 +273,77 @@ int FeatureSettingsMenu::GetMenuInternal()
} }
ProgressStop(); ProgressStop();
ProgressCancelEnable(false);
if(ret != PROGRESS_CANCELED)
{
if(noErrors) if(noErrors)
WindowPrompt(tr("Success."), tr("All files extracted."), tr("OK")); WindowPrompt(tr("Success."), tr("All files extracted."), tr("OK"));
else else
WindowPrompt(tr("Process finished."), tr("Errors occured."), tr("OK")); WindowPrompt(tr("Process finished."), tr("Errors occured."), tr("OK"));
}
gameList.FilterList(filter.c_str()); gameList.FilterList(filter.c_str());
} }
} }
//! Settings: Dump NAND to EmuNand
else if (ret == ++Idx)
{
int choice = WindowPrompt(tr( "What to extract from NAND?" ), tr("The files will be extracted to your emu nand path. Attention: All existing files will be overwritten."), tr( "Everything" ), tr("Enter Path"), tr( "Cancel" ));
if (choice)
{
char filePath[255];
char *nandPath = (char *) memalign(32, ISFS_MAXPATH);
if(!nandPath)
{
WindowPrompt(tr("Error"), tr("Not enough memory."), tr("OK"));
return MENU_NONE;
}
snprintf(nandPath, sizeof(nandPath), "/");
if(choice == 2)
{
choice = OnScreenKeyboard(nandPath, ISFS_MAXPATH, 1);
if(strlen(nandPath) > 1 && nandPath[strlen(nandPath)-1] == '/')
nandPath[strlen(nandPath)-1] = 0;
}
snprintf(filePath, sizeof(filePath), "%s%s", Settings.NandEmuPath, nandPath);
if(choice)
{
u32 dummy;
int ret = -1;
ProgressCancelEnable(true);
StartProgress(tr("Extracting nand files:"), 0, 0, true, false);
ShowProgress(tr("Extracting nand files:"), 0, 0, -1, true, false);
ISFS_Initialize();
if(ISFS_ReadDir(nandPath, NULL, &dummy) < 0)
ret = NandTitle::ExtractFile(nandPath, filePath, false);
else
ret = NandTitle::ExtractDir(nandPath, filePath, false);
ISFS_Deinitialize();
ProgressStop();
ProgressCancelEnable(false);
if(ret != PROGRESS_CANCELED)
{
if(ret < 0)
WindowPrompt(tr("Process finished."), tr("Errors occured."), tr("OK"));
else
WindowPrompt(tr("Success."), tr("All files extracted."), tr("OK"));
}
}
free(nandPath);
}
}
SetOptionValues(); SetOptionValues();
return MENU_NONE; return MENU_NONE;

View File

@ -546,9 +546,9 @@ int NandTitle::ExtractFile(const char *nandPath, const char *filepath, bool isfs
} }
const char *filename = strrchr(filepath, '/')+1; const char *filename = strrchr(filepath, '/')+1;
u32 done = 0; int done = 0;
int fd = -1; int fd = -1;
u32 blocksize = 32*1024; int blocksize = 32*1024;
u8 *buffer = (u8 *) memalign(32, ALIGN32(blocksize)); u8 *buffer = (u8 *) memalign(32, ALIGN32(blocksize));
if(!buffer) if(!buffer)
return -666; return -666;
@ -573,7 +573,7 @@ int NandTitle::ExtractFile(const char *nandPath, const char *filepath, bool isfs
if (ret < 0) if (ret < 0)
break; break;
u32 filesize = stats->file_length; int filesize = stats->file_length;
FILE *pFile = fopen(filepath, "wb"); FILE *pFile = fopen(filepath, "wb");
if(!pFile) if(!pFile)
@ -581,6 +581,9 @@ int NandTitle::ExtractFile(const char *nandPath, const char *filepath, bool isfs
while(done < filesize) while(done < filesize)
{ {
if(ProgressCanceled())
break;
if(filesize-done < blocksize) if(filesize-done < blocksize)
blocksize = filesize-done; blocksize = filesize-done;
@ -589,7 +592,7 @@ int NandTitle::ExtractFile(const char *nandPath, const char *filepath, bool isfs
ret = ISFS_Read(fd, buffer, blocksize); ret = ISFS_Read(fd, buffer, blocksize);
if(ret < 0) if(ret < 0)
{ {
done = 0; done = ret;
break; break;
} }
@ -598,6 +601,9 @@ int NandTitle::ExtractFile(const char *nandPath, const char *filepath, bool isfs
done += ret; done += ret;
} }
// Show last size information
ShowProgress(filename, done, filesize);
fclose(pFile); fclose(pFile);
} while(0); } while(0);
@ -611,6 +617,9 @@ int NandTitle::ExtractFile(const char *nandPath, const char *filepath, bool isfs
if(isfsInit) if(isfsInit)
ISFS_Deinitialize(); ISFS_Deinitialize();
if(ProgressCanceled())
return PROGRESS_CANCELED;
return done; return done;
} }
@ -639,12 +648,18 @@ int NandTitle::InternalExtractDir(char *nandPath, std::string &filepath)
for(u32 i = 0; i < list_len; ++i) for(u32 i = 0; i < list_len; ++i)
{ {
if(ProgressCanceled())
break;
u32 dummy; u32 dummy;
int posNandPath = strlen(nandPath); int posNandPath = strlen(nandPath);
int posFilePath = filepath.size(); int posFilePath = filepath.size();
if(posFilePath > 0 && filepath[posFilePath-1] != '/')
filepath += '/'; filepath += '/';
filepath += entry; filepath += entry;
if(posNandPath > 0 && nandPath[posNandPath-1] != '/')
strcat(nandPath, "/"); strcat(nandPath, "/");
strcat(nandPath, entry); strcat(nandPath, entry);
@ -654,15 +669,19 @@ int NandTitle::InternalExtractDir(char *nandPath, std::string &filepath)
ConvertInvalidCharacters(filepathCpy); ConvertInvalidCharacters(filepathCpy);
int res = ExtractFile(nandPath, filepathCpy.c_str(), false); int res = ExtractFile(nandPath, filepathCpy.c_str(), false);
if(res == 0) if(res < 0) {
gprintf("ExtractFile: Error %i occured on file extract: %s\n", res, nandPath);
ret = -2; ret = -2;
} }
}
else else
{ {
int res = InternalExtractDir(nandPath, filepath); int res = InternalExtractDir(nandPath, filepath);
if(res < 0) if(res < 0) {
gprintf("InternalExtractDir: Error %i occured in: %s\n", res, nandPath);
ret = -3; ret = -3;
} }
}
nandPath[posNandPath] = 0; nandPath[posNandPath] = 0;
filepath.erase(posFilePath); filepath.erase(posFilePath);
@ -671,6 +690,9 @@ int NandTitle::InternalExtractDir(char *nandPath, std::string &filepath)
free(name_list); free(name_list);
if(ProgressCanceled())
return PROGRESS_CANCELED;
return ret; return ret;
} }