mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-04 18:45:05 +01:00
*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:
parent
c0b305b163
commit
4ce0b624d1
@ -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>
|
||||
|
@ -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());
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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(noErrors)
|
||||
WindowPrompt(tr("Success."), tr("All files extracted."), tr("OK"));
|
||||
else
|
||||
WindowPrompt(tr("Process finished."), tr("Errors occured."), tr("OK"));
|
||||
|
||||
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;
|
||||
|
@ -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,13 +648,19 @@ 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();
|
||||
|
||||
filepath += '/';
|
||||
if(posFilePath > 0 && filepath[posFilePath-1] != '/')
|
||||
filepath += '/';
|
||||
filepath += entry;
|
||||
strcat(nandPath, "/");
|
||||
|
||||
if(posNandPath > 0 && nandPath[posNandPath-1] != '/')
|
||||
strcat(nandPath, "/");
|
||||
strcat(nandPath, entry);
|
||||
|
||||
if(ISFS_ReadDir(nandPath, NULL, &dummy) < 0)
|
||||
@ -654,14 +669,18 @@ 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;
|
||||
@ -671,6 +690,9 @@ int NandTitle::InternalExtractDir(char *nandPath, std::string &filepath)
|
||||
|
||||
free(name_list);
|
||||
|
||||
if(ProgressCanceled())
|
||||
return PROGRESS_CANCELED;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user