*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">
<name> USB Loader GX</name>
<coder>USB Loader GX Team</coder>
<version>2.2 r1119</version>
<version>2.2 r1120</version>
<release_date>201109250949</release_date>
<!-- // remove this line to enable 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 *serverURLCustomDiscs = "http://wiitdb.com/wiitdb/artwork/disccustom/";
static bool AbortRequested = false;
static void AbortCallback(void)
{
AbortRequested = true;
}
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
@ -64,12 +57,12 @@ void ImageDownloader::Start()
return;
}
AbortRequested = false;
ProgressSetAbortCallback(AbortCallback);
ProgressCancelEnable(true);
DownloadProcess(TotalDownloadCount);
ProgressSetAbortCallback(NULL);
ProgressCancelEnable(false);
ProgressStop();
if(MissingImagesCount == 0)
@ -145,7 +138,7 @@ int ImageDownloader::DownloadProcess(int TotalDownloadCount)
for(u32 i = 0, pos = 0; i < MissingImages.size(); ++i, ++pos)
{
if(AbortRequested)
if(ProgressCanceled())
break;
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 ***/
static lwp_t progressthread = LWP_THREAD_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 progressMsg1[75];
static char progressMsg2[75];
@ -57,6 +58,7 @@ extern "C" void StartProgress(const char * title, const char * msg1, const char
else
progressMsg2[0] = '\0';
progressCanceled = false;
showSize = swSize;
showTime = swTime;
showProgress = 1;
@ -166,6 +168,7 @@ void ShowProgress(const char *title, const char *msg1, const char *msg2, s64 don
***************************************************************************/
extern "C" void ProgressStop()
{
progressCanceled = false;
showProgress = 0;
progressTitle[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)
{
progressCanceled = false;
usleep(500000); // wait to see if progress flag changes soon
if (!showProgress) return;
GuiWindow promptWindow(472, 320);
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
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.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.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.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.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.SetPosition(210, 40);
@ -369,13 +385,11 @@ static void ProgressWindow(const char *title, const char *msg1, const char *msg2
cancelTxt.SetWidescreen(Settings.widescreen);
cancelImg.SetWidescreen(Settings.widescreen);
}
GuiButton cancelBtn(&cancelImg, &cancelImg, 2, 4, 0, -45, &trigA, btnSoundOver, btnSoundClick2, 1);
cancelBtn.SetLabel(&cancelTxt);
cancelBtn.SetState(STATE_SELECTED);
usleep(400000); // wait to see if progress flag changes soon
if (!showProgress) return;
promptWindow.Append(&dialogBoxImg);
promptWindow.Append(&progressbarEmptyImg);
promptWindow.Append(&progressbarImg);
@ -391,8 +405,12 @@ static void ProgressWindow(const char *title, const char *msg1, const char *msg2
promptWindow.Append(&sizeTxt);
promptWindow.Append(&speedTxt);
}
if(AbortCallback)
if(CancelEnabled)
{
promptWindow.Append(&cancelBtn);
if(showSize)
cancelBtn.SetPosition(90, -45);
}
HaltGui();
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(AbortCallback) AbortCallback();
progressCanceled = true;
cancelBtn.ResetState();
}
}

View File

@ -8,10 +8,10 @@
#ifndef _PROGRESSWINDOW_H_
#define _PROGRESSWINDOW_H_
typedef void (*ProgressAbortCallback)(void);
#ifdef __cplusplus
#define PROGRESS_CANCELED -12345
void InitProgressThread();
void ExitProgressThread();
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
void ProgressCancelEnable(bool allowCancel);
void StartProgress(const char * title, const char * msg1, const char * msg2, bool swSize, bool swTime);
void ShowProgress(s64 done, s64 total);
void ProgressSetAbortCallback(ProgressAbortCallback callback);
bool ProgressCanceled();
void ProgressStop();
#ifdef __cplusplus

View File

@ -62,6 +62,7 @@ FeatureSettingsMenu::FeatureSettingsMenu()
Options->SetName(Idx++, "%s", tr( "Wiinnertag" ));
Options->SetName(Idx++, "%s", tr( "Import Categories" ));
Options->SetName(Idx++, "%s", tr( "Export All Saves to EmuNand" ));
Options->SetName(Idx++, "%s", tr( "Dump NAND to EmuNand" ));
OldTitlesOverride = Settings.titlesOverride;
@ -108,6 +109,9 @@ void FeatureSettingsMenu::SetOptionValues()
//! Settings: Export Savegames to EmuNand
Options->SetValue(Idx++, " ");
//! Settings: Dump NAND to EmuNand
Options->SetValue(Idx++, " ");
}
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" ));
if (choice == 1)
{
ProgressCancelEnable(true);
StartProgress(tr("Extracting files:"), 0, 0, true, false);
char filePath[512];
char nandPath[ISFS_MAXPATH];
@ -242,7 +247,11 @@ int FeatureSettingsMenu::GetMenuInternal()
ShowProgress(tr("Extracting files:"), GameTitles.GetTitle(gameList[i]), 0, 0, -1, true, false);
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(filePath, sizeof(filePath), "%s%s", Settings.NandEmuPath, nandPath);
@ -264,16 +273,77 @@ int FeatureSettingsMenu::GetMenuInternal()
}
ProgressStop();
ProgressCancelEnable(false);
if(ret != PROGRESS_CANCELED)
{
if(noErrors)
WindowPrompt(tr("Success."), tr("All files extracted."), tr("OK"));
else
WindowPrompt(tr("Process finished."), tr("Errors occured."), tr("OK"));
}
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();
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;
u32 done = 0;
int done = 0;
int fd = -1;
u32 blocksize = 32*1024;
int blocksize = 32*1024;
u8 *buffer = (u8 *) memalign(32, ALIGN32(blocksize));
if(!buffer)
return -666;
@ -573,7 +573,7 @@ int NandTitle::ExtractFile(const char *nandPath, const char *filepath, bool isfs
if (ret < 0)
break;
u32 filesize = stats->file_length;
int filesize = stats->file_length;
FILE *pFile = fopen(filepath, "wb");
if(!pFile)
@ -581,6 +581,9 @@ int NandTitle::ExtractFile(const char *nandPath, const char *filepath, bool isfs
while(done < filesize)
{
if(ProgressCanceled())
break;
if(filesize-done < blocksize)
blocksize = filesize-done;
@ -589,7 +592,7 @@ int NandTitle::ExtractFile(const char *nandPath, const char *filepath, bool isfs
ret = ISFS_Read(fd, buffer, blocksize);
if(ret < 0)
{
done = 0;
done = ret;
break;
}
@ -598,6 +601,9 @@ int NandTitle::ExtractFile(const char *nandPath, const char *filepath, bool isfs
done += ret;
}
// Show last size information
ShowProgress(filename, done, filesize);
fclose(pFile);
} while(0);
@ -611,6 +617,9 @@ int NandTitle::ExtractFile(const char *nandPath, const char *filepath, bool isfs
if(isfsInit)
ISFS_Deinitialize();
if(ProgressCanceled())
return PROGRESS_CANCELED;
return done;
}
@ -639,12 +648,18 @@ int NandTitle::InternalExtractDir(char *nandPath, std::string &filepath)
for(u32 i = 0; i < list_len; ++i)
{
if(ProgressCanceled())
break;
u32 dummy;
int posNandPath = strlen(nandPath);
int posFilePath = filepath.size();
if(posFilePath > 0 && filepath[posFilePath-1] != '/')
filepath += '/';
filepath += entry;
if(posNandPath > 0 && nandPath[posNandPath-1] != '/')
strcat(nandPath, "/");
strcat(nandPath, entry);
@ -654,15 +669,19 @@ int NandTitle::InternalExtractDir(char *nandPath, std::string &filepath)
ConvertInvalidCharacters(filepathCpy);
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;
}
}
else
{
int res = InternalExtractDir(nandPath, filepath);
if(res < 0)
if(res < 0) {
gprintf("InternalExtractDir: Error %i occured in: %s\n", res, nandPath);
ret = -3;
}
}
nandPath[posNandPath] = 0;
filepath.erase(posFilePath);
@ -671,6 +690,9 @@ int NandTitle::InternalExtractDir(char *nandPath, std::string &filepath)
free(name_list);
if(ProgressCanceled())
return PROGRESS_CANCELED;
return ret;
}