diff --git a/include/menu/MainMenuState.h b/include/menu/MainMenuState.h index 4f6c95b..8c1e273 100644 --- a/include/menu/MainMenuState.h +++ b/include/menu/MainMenuState.h @@ -18,7 +18,6 @@ class MainMenuState : public ApplicationState { void render() override; ApplicationState::eSubState update(Input *input) override; - std::string tag; private: std::unique_ptr subState{}; diff --git a/include/savemng.h b/include/savemng.h index ee95fdd..dd43047 100644 --- a/include/savemng.h +++ b/include/savemng.h @@ -37,7 +37,8 @@ struct backupInfo { bool selected; bool hasUserSavedata; bool hasCommonSavedata; - eBatchRestoreState batchRestoreState; + eBatchRestoreState batchRestoreState; + int lastErrCode; }; struct Title { diff --git a/src/main.cpp b/src/main.cpp index 090df85..2957bba 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -446,14 +446,35 @@ int main() { DrawUtils::setFont(); + DrawUtils::beginDraw(); + DrawUtils::clear(COLOR_BLACK); + consolePrintPosAligned(10, 0, 1, LanguageUtils::gettext("Initializing WPAD and KAPD")); + DrawUtils::endDraw(); + WPADInit(); KPADInit(); WPADEnableURCC(1); + DrawUtils::beginDraw(); + DrawUtils::clear(COLOR_BLACK); + consolePrintPosAligned(10, 0, 1, LanguageUtils::gettext("Getting Serial ID")); + DrawUtils::endDraw(); + getWiiUSerialId(); + DrawUtils::beginDraw(); + DrawUtils::clear(COLOR_BLACK); + consolePrintPosAligned(10, 0, 1, LanguageUtils::gettext("Initializing loadWiiU Titles")); + DrawUtils::endDraw(); + loadWiiUTitles(0); + + DrawUtils::beginDraw(); + DrawUtils::clear(COLOR_BLACK); + consolePrintPosAligned(10, 0, 1, LanguageUtils::gettext("Initializing ROMFS")); + DrawUtils::endDraw(); + int res = romfsInit(); if (res) { promptError("Failed to init romfs: %d", res); @@ -464,6 +485,7 @@ int main() { Swkbd_LanguageType systemLanguage = LanguageUtils::getSystemLanguage(); LanguageUtils::loadLanguage(systemLanguage); + // notUsed if (!DrawUtils::initKFont()) { promptError("Failed to init keyboardFont"); DrawUtils::endDraw(); @@ -482,6 +504,7 @@ int main() { DrawUtils::clear(COLOR_BLACK); DrawUtils::endDraw(); + Title *wiiutitles = loadWiiUTitles(1); Title *wiititles = loadWiiTitles(); getAccountsWiiU(); diff --git a/src/menu/BRTitleSelectState.cpp b/src/menu/BRTitleSelectState.cpp index d0fef43..8e45936 100644 --- a/src/menu/BRTitleSelectState.cpp +++ b/src/menu/BRTitleSelectState.cpp @@ -24,6 +24,7 @@ BRTitleSelectState::BRTitleSelectState(int sduser, int wiiuuser, bool common, bo titlesCount(titlesCount), isWiiUBatchRestore(isWiiUBatchRestore) { + WHBLogPrintf("IN BRTitleSelectState. Inputs:"); WHBLogPrintf("sduser %d",sduser); WHBLogPrintf("wiiuuser %d",wiiuuser); WHBLogPrintf("common %c",common ? '0':'1'); @@ -45,21 +46,21 @@ BRTitleSelectState::BRTitleSelectState(int sduser, int wiiuuser, bool common, bo if ( this->titles[i].currentBackup.hasBatchBackup == false ) continue; - WHBLogPrintf("get id %u",i); - WHBLogPrintf("shortname %s",this->titles[i].shortName); + //WHBLogPrintf("get id %u",i); + //WHBLogPrintf("shortname %s",this->titles[i].shortName); uint32_t highID = this->titles[i].highID; uint32_t lowID = this->titles[i].lowID; bool isWii = titles[i].is_Wii; - WHBLogPrintf("is wii %s",isWii ? "si" : "no"); + //WHBLogPrintf("is wii %s",isWii ? "si" : "no"); std::string srcPath = getDynamicBackupPath(highID, lowID, 0); if (! isWii) { std::string usersavePath = srcPath+"/"+getSDacc()[sduser].persistentID; - WHBLogPrintf("check user - %u",i); - WHBLogPrintf("check empty path - %s",usersavePath.c_str()); + //WHBLogPrintf("check user - %u",i); + //WHBLogPrintf("check empty path - %s",usersavePath.c_str()); if (! folderEmpty(usersavePath.c_str())) this->titles[i].currentBackup.hasUserSavedata = true; @@ -75,8 +76,8 @@ BRTitleSelectState::BRTitleSelectState(int sduser, int wiiuuser, bool common, bo if ( sduser != -1 && ! this->titles[i].currentBackup.hasCommonSavedata && ! this->titles[i].currentBackup.hasUserSavedata ) continue; - WHBLogPrintf("candiadte/select set to true - %u", i); - WHBLogPrintf("init select wiiU - is wii %s",isWii ? "si" : "no"); + //WHBLogPrintf("candiadte/select set to true - %u", i); + //WHBLogPrintf("init select wiiU - is wii %s",isWii ? "si" : "no"); this->titles[i].currentBackup.candidateToBeRestored = true; // backup has enough data to try restore this->titles[i].currentBackup.selected = true; // from candidates list, user can select/deselest at wish if (! test) { @@ -88,14 +89,16 @@ BRTitleSelectState::BRTitleSelectState(int sduser, int wiiuuser, bool common, bo } else { - WHBLogPrintf("init select wii - is wii %s",isWii ? "si" : "no"); + //WHBLogPrintf("init select wii - is wii %s",isWii ? "si" : "no"); this->titles[i].currentBackup.candidateToBeRestored = true; this->titles[i].currentBackup.selected = true; } // to recover title from "candidate title" index this->c2t.push_back(i); + this->titles[i].currentBackup.lastErrCode = 0; + } - WHBLogPrintf("out of loop"); + //WHBLogPrintf("out of loop"); candidatesCount = (int) this->c2t.size(); WHBLogPrintf("init done. size: %u",candidatesCount); @@ -138,14 +141,14 @@ void BRTitleSelectState::render() { std::string nxtAction; std::string lastState; for (int i = 0; i < MAX_TITLE_SHOW; i++) { - WHBLogPrintf("iteracio %d",i); + //WHBLogPrintf("iteracio %d",i); if (i + this->scroll < 0 || i + this->scroll >= (int) this->candidatesCount) break; bool isWii = this->titles[c2t[i + this->scroll]].is_Wii; DrawUtils::setFontColor(static_cast(0x00FF00FF)); - WHBLogPrintf("candidates %d",candidatesCount); - WHBLogPrintf("scroll %d ",scroll); - WHBLogPrintf("c2t %d",c2t[i + this->scroll]); + //WHBLogPrintf("candidates %d",candidatesCount); + //WHBLogPrintf("scroll %d ",scroll); + //WHBLogPrintf("c2t %d",c2t[i + this->scroll]); if ( ! this->titles[c2t[i + this->scroll]].currentBackup.selected) DrawUtils::setFontColor(static_cast(0x888800FF)); @@ -157,45 +160,51 @@ void BRTitleSelectState::render() { DrawUtils::setFontColor(static_cast(0xFF0000FF)); if (this->titles[c2t[i + this->scroll]].currentBackup.batchRestoreState == OK) DrawUtils::setFontColor(static_cast(0xFFFFFFFF)); - WHBLogPrintf("nom"); + //WHBLogPrintf("nom"); switch (this->titles[c2t[i + this->scroll]].currentBackup.batchRestoreState) { case NOT_TRIED : lastState = "[]"; - nxtAction = this->titles[c2t[i + this->scroll]].currentBackup.selected ? LanguageUtils::gettext("[Restore]") : LanguageUtils::gettext("[Skip]"); + nxtAction = this->titles[c2t[i + this->scroll]].currentBackup.selected ? LanguageUtils::gettext(">> Restore") : LanguageUtils::gettext(">> Skip"); break; case OK : - lastState = LanguageUtils::gettext("[Ok]"); - nxtAction = LanguageUtils::gettext("[Restored]"); + lastState = LanguageUtils::gettext("[OK]"); + nxtAction = LanguageUtils::gettext("|Restored|"); break; case ABORTED : - lastState = LanguageUtils::gettext("[AbortedByUser]"); - nxtAction = this->titles[c2t[i + this->scroll]].currentBackup.selected ? LanguageUtils::gettext("[Retry]") : LanguageUtils::gettext("[Skip]"); + lastState = LanguageUtils::gettext("[AB]"); + nxtAction = this->titles[c2t[i + this->scroll]].currentBackup.selected ? LanguageUtils::gettext(">> Retry") : LanguageUtils::gettext(">> Skip"); break; case WR : - lastState = LanguageUtils::gettext("[Warning-CheckSave]"); - nxtAction = this->titles[c2t[i + this->scroll]].currentBackup.selected ? LanguageUtils::gettext("[Retry]") : LanguageUtils::gettext("[Skip]"); + lastState = LanguageUtils::gettext("[WR]"); + nxtAction = this->titles[c2t[i + this->scroll]].currentBackup.selected ? LanguageUtils::gettext(">> Retry") : LanguageUtils::gettext(">> Skip"); break; case KO: - nxtAction = this->titles[c2t[i + this->scroll]].currentBackup.selected ? LanguageUtils::gettext("[Retry]") : LanguageUtils::gettext("[Skip]"); - lastState = LanguageUtils::gettext("[Failed]"); + lastState = LanguageUtils::gettext("[KO]"); + nxtAction = this->titles[c2t[i + this->scroll]].currentBackup.selected ? LanguageUtils::gettext(">> Retry") : LanguageUtils::gettext(">> Skip"); break; default: - nxtAction = ""; lastState = ""; + nxtAction = ""; break; } - + //int lastErrCode = this->titles[c2t[i + this->scroll]].currentBackup.lastErrCode; + //std::string lastErrCodeString = "(Err: "+std::to_string(lastErrCode)+")"; + char shortName[32]; + for (int p=0;p<32;p++) + shortName[p] = this->titles[c2t[i + this->scroll]].shortName[p]; + shortName[31] = '\0'; consolePrintPos(M_OFF, i + 2, " %s %s %s %s %s %s", - this->titles[c2t[i + this->scroll]].shortName, + shortName, this->titles[c2t[i + this->scroll]].isTitleOnUSB ? "(USB)" : "(NAND)", - this->titles[c2t[i + this->scroll]].isTitleDupe ? " [D]" : "", - this->titles[c2t[i + this->scroll]].saveInit ? "" : " [No Init]", - nxtAction.c_str(),lastState.c_str()); - //WHBLogPrintf("shortname %s",this->titles[c2t[i + this->scroll]].shortName); + this->titles[c2t[i + this->scroll]].isTitleDupe ? "[D]" : "", + this->titles[c2t[i + this->scroll]].saveInit ? "" : "[No Init]", + lastState.c_str(), + nxtAction.c_str()); + WHBLogPrintf("shortname %s nextAction: %s",this->titles[c2t[i + this->scroll]].shortName, + nxtAction.c_str()); DrawUtils::setFontColor(COLOR_TEXT); - //WHBLogPrintf("icona"); if (this->titles[c2t[i + this->scroll]].iconBuf != nullptr) { if (isWii) DrawUtils::drawRGB5A3((M_OFF + 2) * 12 - 2, (i + 3) * 24 + 3, 0.25, @@ -256,15 +265,19 @@ ApplicationState::eSubState BRTitleSelectState::update(Input *input) { fullBackup ? LanguageUtils::gettext("- Perform full backup: Y") : LanguageUtils::gettext("- Perform full backup: N")); } - if (!promptConfirm(ST_WARNING,summary)) - return SUBSTATE_RUNNING; + if (!promptConfirm(ST_WARNING,summary)) { + DrawUtils::setRedraw(true); + return SUBSTATE_RUNNING; + } for (int i = 0; i < titlesCount ; i++) { if (! this->titles[i].currentBackup.selected ) continue; if (! this->titles[i].saveInit) { - if (!promptConfirm(ST_ERROR, LanguageUtils::gettext("You have selected uniniilized titles (not recommended). Are you 100% sure?"))) + if (!promptConfirm(ST_ERROR, LanguageUtils::gettext("You have selected uninitialized titles (not recommended). Are you 100%% sure?"))) { + DrawUtils::setRedraw(true); return SUBSTATE_RUNNING; + } break; } } @@ -275,7 +288,7 @@ ApplicationState::eSubState BRTitleSelectState::update(Input *input) { WHBLogPrintf("perform all backup"); } - int retCode; + int retCode = 0; for (int i = 0; i < titlesCount ; i++) { if (! this->titles[i].currentBackup.selected ) @@ -301,11 +314,15 @@ ApplicationState::eSubState BRTitleSelectState::update(Input *input) { } retCode = wipeSavedata(&this->titles[i], wiiuuser, effectiveCommon, false); + WHBLogPrintf("wipe retcode: %d",retCode); if (retCode > 0) this->titles[i].currentBackup.batchRestoreState = WR; WHBLogPrintf("%u - wipe user: %d common: %s",i,wiiuuser,effectiveCommon ? "si":"no"); } + wipeDone: + int globalRetCode = retCode<<8; + WHBLogPrintf("wipe ret code %d",retCode); WHBLogPrintf("restoring"); if (sduser != -1) { if ( ! this->titles[i].currentBackup.hasUserSavedata && effectiveCommon) { @@ -314,30 +331,34 @@ ApplicationState::eSubState BRTitleSelectState::update(Input *input) { if (retCode > 0) this->titles[i].currentBackup.batchRestoreState = KO; WHBLogPrintf("%u - restore user: %d common: %s",i,-2,effectiveCommon ? "si":"no"); - continue; + goto restoreDone; } } retCode = restoreSavedata(&this->titles[i], 0, sduser, wiiuuser, effectiveCommon, false); //always from slot 0 if (retCode > 0) this->titles[i].currentBackup.batchRestoreState = KO; WHBLogPrintf("%u - restore user: %d common: %s",i,wiiuuser,effectiveCommon ? "si":"no"); + + restoreDone: if (this->titles[i].currentBackup.batchRestoreState == OK || this->titles[i].currentBackup.batchRestoreState == WR ) this->titles[i].currentBackup.selected = false; + + globalRetCode = globalRetCode + retCode; + this->titles[i].currentBackup.lastErrCode = globalRetCode; + WHBLogPrintf("restore ret code %d",retCode); } - WHBLogPrintf("restore done"); + + WHBLogPrintf("restore process done"); int titlesOK = 0; int titlesAborted = 0; int titlesWarning = 0; int titlesKO = 0; int titlesSkipped = 0; - for (int i = 0; i < titlesCount ; i++) { - if (this->titles[i].currentBackup.candidateToBeRestored && ! this->titles[i].currentBackup.selected) { - titlesSkipped++; - continue; - } - switch (this->titles[i].currentBackup.batchRestoreState) { + for (int i = 0; i < this->candidatesCount ; i++) { + WHBLogPrintf("%s restoreState %d",this->titles[c2t[i]].shortName,this->titles[c2t[i]].currentBackup.batchRestoreState); + switch (this->titles[c2t[i]].currentBackup.batchRestoreState) { case OK : titlesOK++; break; @@ -350,9 +371,12 @@ ApplicationState::eSubState BRTitleSelectState::update(Input *input) { case ABORTED : titlesAborted++; break; + default: + titlesSkipped++; + break; } } - summaryTemplate = LanguageUtils::gettext("Restore done\n OK: %d\n Warning: %d\n KO: %d\n Aborted: %d\n Skipped: %d\n"); + summaryTemplate = LanguageUtils::gettext("Restore completed. Results:\n- OK: %d\n- Warning: %d\n- KO: %d\n- Aborted: %d\n- Skipped: %d\n"); snprintf(summary,512,summaryTemplate,titlesOK,titlesWarning,titlesKO,titlesAborted,titlesSkipped); promptMessage(COLOR_BG_SUCCESS,summary); DrawUtils::setRedraw(true); diff --git a/src/menu/BackupSetListState.cpp b/src/menu/BackupSetListState.cpp index 0617ca2..f73cd74 100644 --- a/src/menu/BackupSetListState.cpp +++ b/src/menu/BackupSetListState.cpp @@ -54,15 +54,13 @@ void BackupSetListState::render() { } if (this->state == STATE_BACKUPSET_MENU) { std::string backupSetItem; + DrawUtils::setFontColor(COLOR_INFO); if (BackupSetList::currentBackupSetList->entriesView == BackupSetList::currentBackupSetList->entries) { consolePrintPosAligned(0, 4, 1, LanguageUtils::gettext("BackupSets")); } else { - DrawUtils::setFontColor(COLOR_INFO); consolePrintPosAligned(0, 4, 1, LanguageUtils::gettext("BackupSets (filter applied)")); } DrawUtils::setFontColor(COLOR_TEXT); - //consolePrintPos(47, 0, LanguageUtils::gettext("\ue083 Sort: %s \ue084"), - // this->sortAscending ? "\u2191" : "\u2193"); consolePrintPosAligned(0,4,2, LanguageUtils::gettext("\ue083 Sort: %s \ue084"), this->sortAscending ? "\u2191" : "\u2193"); for (int i = 0; i < MAX_ROWS_SHOW; i++) { @@ -84,7 +82,6 @@ void BackupSetListState::render() { consolePrintPosAligned(17, 4, 2, LanguageUtils::gettext("\ue000: Select BS \ue045: Tag BS \ue046: Wipe BS \ue003: Filter List \ue001: Back")); else consolePrintPosAligned(17, 4, 2, LanguageUtils::gettext("\ue000: Select BackupSet \ue003: Filter List \ue001: Back")); - consolePrintPos (40,2,"tag %s, newtag %s",tag.c_str(),newTag.c_str()); } } diff --git a/src/menu/BatchBackupState.cpp b/src/menu/BatchBackupState.cpp index db51628..a646c8d 100644 --- a/src/menu/BatchBackupState.cpp +++ b/src/menu/BatchBackupState.cpp @@ -41,12 +41,15 @@ ApplicationState::eSubState BatchBackupState::update(Input *input) { case 0: backupAllSave(this->wiiutitles, this->wiiuTitlesCount, batchDatetime); backupAllSave(this->wiititles, this->vWiiTitlesCount, batchDatetime); + writeBackupAllMetadata(batchDatetime,"WiiU and vWii titles"); break; case 1: backupAllSave(this->wiiutitles, this->wiiuTitlesCount, batchDatetime); + writeBackupAllMetadata(batchDatetime,"WiiU titles"); break; case 2: backupAllSave(this->wiititles, this->vWiiTitlesCount, batchDatetime); + writeBackupAllMetadata(batchDatetime,"vWii titles"); break; default: return SUBSTATE_RETURN; diff --git a/src/menu/BatchRestoreOptions.cpp b/src/menu/BatchRestoreOptions.cpp index 4807d2b..6e689ac 100644 --- a/src/menu/BatchRestoreOptions.cpp +++ b/src/menu/BatchRestoreOptions.cpp @@ -22,7 +22,7 @@ BatchRestoreOptions::BatchRestoreOptions(Title *titles, WHBLogPrintf("restore type %s",isWiiUBatchRestore ? "wiiU" : "vWii"); minCursorPos = isWiiUBatchRestore ? 0 : 3; cursorPos = minCursorPos; - WHBLogPrintf("cursorPos %d minCursospos %d",cursorPos,minCursorPos); + //WHBLogPrintf("cursorPos %d minCursospos %d",cursorPos,minCursorPos); for (int i = 0; ititlesCount; i++) { this->titles[i].currentBackup= { .hasBatchBackup = false, @@ -127,10 +127,12 @@ ApplicationState::eSubState BatchRestoreOptions::update(Input *input) { if (this->state == STATE_BATCH_RESTORE_OPTIONS_MENU) { if (input->get(TRIGGER, PAD_BUTTON_A)) { this->state = STATE_DO_SUBSTATE; + /* WHBLogPrintf("to title select"); WHBLogPrintf("sduser %d",sduser); WHBLogPrintf("wiiuuser %d",wiiuuser); WHBLogPrintf("titles %u",titles); + */ this->subState = std::make_unique(sduser, wiiuuser, common, wipeBeforeRestore, fullBackup, this->titles, this->titlesCount, isWiiUBatchRestore); } if (input->get(TRIGGER, PAD_BUTTON_B)) diff --git a/src/menu/BatchRestoreState.cpp b/src/menu/BatchRestoreState.cpp index b7424d5..0874435 100644 --- a/src/menu/BatchRestoreState.cpp +++ b/src/menu/BatchRestoreState.cpp @@ -24,12 +24,15 @@ void BatchRestoreState::render() { consolePrintPosAligned(0, 4, 1,LanguageUtils::gettext("Batch Restore")); DrawUtils::setFontColor(COLOR_TEXT); - consolePrintPos(M_OFF, 4, LanguageUtils::gettext(" Batch Restore is .... \n bla bla bla")); - consolePrintPos(M_OFF, 8, LanguageUtils::gettext(" Restore Wii U (%u Title%s)"), this->wiiuTitlesCount, + + consolePrintPos(M_OFF, 3, LanguageUtils::gettext(" Restore Wii U (%u Title%s)"), this->wiiuTitlesCount, (this->wiiuTitlesCount > 1) ? "s" : ""); - consolePrintPos(M_OFF, 9, LanguageUtils::gettext(" Restore vWii (%u Title%s)"), this->vWiiTitlesCount, + consolePrintPos(M_OFF, 4, LanguageUtils::gettext(" Restore vWii (%u Title%s)"), this->vWiiTitlesCount, (this->vWiiTitlesCount > 1) ? "s" : ""); - consolePrintPos(M_OFF, 8 + cursorPos, "\u2192"); + consolePrintPos(M_OFF, 3 + cursorPos, "\u2192"); + DrawUtils::setFontColor(COLOR_INFO); + consolePrintPos(M_OFF, 6, LanguageUtils::gettext("Batch Restore allows you to restore all savedata from a BatchBackup \n* to a different user in the same console \n* or to a different console where the games are previouly installed.\nIn the later case, it is recommended to first run the game to \n initialize the savedata.")); + DrawUtils::setFontColor(COLOR_TEXT); consolePrintPosAligned(17, 4, 2, LanguageUtils::gettext("\ue000: Continue to batch restore \ue001: Back")); } } diff --git a/src/menu/KeyboardState.cpp b/src/menu/KeyboardState.cpp index 8fb6a4d..2fea9db 100644 --- a/src/menu/KeyboardState.cpp +++ b/src/menu/KeyboardState.cpp @@ -39,7 +39,6 @@ void KeyboardState::render() { consolePrintPosAligned(17, 4, 2, LanguageUtils::gettext("\ue000: Press Key \uE003: Shift \uE002: Del \ue045: OK! \ue001: Back")); } } -// cursor , A -> select , X -> delete, Y -> shift, B -> Back, + = return ApplicationState::eSubState KeyboardState::update(Input *input) { if (input->get(TRIGGER, PAD_BUTTON_B)) { diff --git a/src/menu/MainMenuState.cpp b/src/menu/MainMenuState.cpp index f7c3725..1e96d23 100644 --- a/src/menu/MainMenuState.cpp +++ b/src/menu/MainMenuState.cpp @@ -10,7 +10,6 @@ #include #include -#include #include #define ENTRYCOUNT 4 @@ -36,7 +35,6 @@ void MainMenuState::render() { consolePrintPos(M_OFF, 4, LanguageUtils::gettext(" Batch Backup")); consolePrintPos(M_OFF, 5, LanguageUtils::gettext(" Batch Restore")); consolePrintPos(M_OFF, 2 + cursorPos, "\u2192"); - consolePrintPos(M_OFF, 10, "tag: %s",tag.c_str()); consolePrintPosAligned(17, 4, 2, LanguageUtils::gettext("\uE002: Options \ue000: Select Mode")); } } @@ -75,12 +73,8 @@ ApplicationState::eSubState MainMenuState::update(Input *input) { if (input->get(TRIGGER, PAD_BUTTON_DOWN)) if (++cursorPos == ENTRYCOUNT) --cursorPos; - if (input->get(TRIGGER, PAD_BUTTON_Y)) { - this->state = STATE_DO_SUBSTATE; - this->subState = std::make_unique(tag); - } /* - if (input->get(TRIGGER, PAD_BUTTON_X)) { + if (input->get(TRIGGER, PAD_BUTTON_Y)) { this->state = STATE_DO_SUBSTATE; this->subState = std::make_unique(); } diff --git a/src/savemng.cpp b/src/savemng.cpp index 951c510..f02347c 100644 --- a/src/savemng.cpp +++ b/src/savemng.cpp @@ -23,7 +23,7 @@ const char *batchBackupPath = "fs:/vol/external01/wiiu/backups/batch"; // Must b const char *loadiineSavePath = "fs:/vol/external01/wiiu/saves"; const char *legacyBackupPath = "fs:/vol/external01/savegames"; -static char *p1; +//static char *p1; Account *wiiuacc; Account *sdacc; uint8_t wiiuaccn = 0, sdaccn = 5; @@ -44,6 +44,24 @@ static file_buffer buffers[16]; static char *fileBuf[2]; static bool buffersInitialized = false; + + +//#define MOCK +#ifdef MOCK + // number of times the function will return a failed operation + int f_copyDir = 1; + // TODO checkEntry is called from main to initialize title list + // so the approach of globally mock it to test restores cannot be used + //int f_checkEntry = 3; + int f_removeDir = 1; + //unlink will fail if false + bool unlink_c = true; + bool unlink_b = true; +#endif + + + + std::string newlibtoFSA(std::string path) { if (path.rfind("storage_slccmpt01:", 0) == 0) { StringUtils::replace(path, "storage_slccmpt01:", "/vol/storage_slccmpt01"); @@ -90,6 +108,8 @@ Account *getSDacc() { return sdacc; } +// TODO how to mock checkEntry only for restore ops +#ifndef MOCK_CHECKENTRY int checkEntry(const char *fPath) { struct stat st {}; if (stat(fPath, &st) == -1) @@ -100,6 +120,15 @@ int checkEntry(const char *fPath) { return 1; } +#else +int checkEntry(const char *fPath) { + WHBLogPrintf("checkEntry %s --> %s (%d)",fPath,f_checkEntry >0 ? "KO":"OK",f_checkEntry); + if (f_checkEntry-- > 0 ) + return 1; + else + return 2; +} +#endif bool initFS() { FSAInit(); @@ -654,6 +683,7 @@ static bool copyFile(const std::string &pPath, const std::string &oPath) { return true; } +#ifndef MOCK static bool copyDir(const std::string &pPath, const std::string &tPath) { // Source: ft2sd DIR *dir = opendir(pPath.c_str()); if (dir == nullptr) @@ -680,7 +710,7 @@ static bool copyDir(const std::string &pPath, const std::string &tPath) { // Sou return false; } } else { - p1 = data->d_name; + //p1 = data->d_name; showFileOperation(data->d_name, pPath + StringUtils::stringFormat("/%s", data->d_name), targetPath); if (!copyFile(pPath + StringUtils::stringFormat("/%s", data->d_name), targetPath)) { @@ -694,7 +724,18 @@ static bool copyDir(const std::string &pPath, const std::string &tPath) { // Sou return true; } +#else +static bool copyDir(const std::string &pPath, const std::string &tPath) { + WHBLogPrintf("copy %s %s --> %s(%d)",pPath.c_str(),tPath.c_str(),f_copyDir >0 ? "KO":"OK",f_copyDir); + if (f_copyDir-- > 0) + return false; + else + return true; +} +#endif + +#ifndef MOCK static bool removeDir(const std::string &pPath) { DIR *dir = opendir(pPath.c_str()); if (dir == nullptr) @@ -732,6 +773,15 @@ static bool removeDir(const std::string &pPath) { closedir(dir); return true; } +#else +static bool removeDir(const std::string &pPath) { + WHBLogPrintf("removeDir %s --> %s(%d)",pPath.c_str(),f_removeDir >0 ? "KO":"OK",f_removeDir); + if (f_removeDir-- > 0) + return false; + else + return true; +} +#endif static std::string getUserID() { // Source: loadiine_gx2 /* get persistent ID - thanks to Maschell */ @@ -1053,8 +1103,6 @@ void writeBackupAllMetadata(const std::string & batchDatetime, const std::string } void backupAllSave(Title *titles, int count, const std::string & batchDatetime) { - bool hasWii = false; - bool hasWiiU = false; for ( int sourceStorage = 0; sourceStorage < 2 ; sourceStorage++ ) { for (int i = 0; i < count; i++) { if (titles[i].highID == 0 || titles[i].lowID == 0 || !titles[i].saveInit) @@ -1063,10 +1111,6 @@ void backupAllSave(Title *titles, int count, const std::string & batchDatetime) uint32_t lowID = titles[i].lowID; bool isUSB = titles[i].isTitleOnUSB; bool isWii = titles[i].is_Wii; - if (isWii) - hasWii = true; - else - hasWiiU = true; if ((sourceStorage == 0 && !isUSB) || (sourceStorage == 1 && isUSB)) // backup first WiiU USB savedata to slot 0 continue; uint8_t slot = getEmptySlot(highID,lowID,batchDatetime); @@ -1081,16 +1125,6 @@ void backupAllSave(Title *titles, int count, const std::string & batchDatetime) writeMetadata(highID,lowID,slot,isUSB,batchDatetime); } } - std::string batchBackupTag; - if (hasWii && hasWiiU) - batchBackupTag = "WiiU and vWii titles"; - else { - if (hasWii) - batchBackupTag = "vWii titles"; - else - batchBackupTag = "WiiU titles"; - } - writeBackupAllMetadata(batchDatetime,batchBackupTag); } void backupSavedata(Title *title, uint8_t slot, int8_t wiiuuser, bool common) { @@ -1132,85 +1166,6 @@ void backupSavedata(Title *title, uint8_t slot, int8_t wiiuuser, bool common) { } -/* - bool copyDir_c = true; - bool checkEntry_b = true; - bool copyDir_b = true; - bool copyDir2_b = true; -*/ - bool saveinit = true; - // if true, first occurrance will fail - bool f_copyDir_c = true; - bool f_checkEntry_b = true; - bool f_copyDir_b = true; - bool f_copyDir2_b = true; - bool f_removeDir_c = true; - bool f_removeDir_b = true; - - -static bool copyDir_c(const std::string &pPath, const std::string &tPath) { // Source: ft2sd - WHBLogPrintf("copy %s %s --> %s",pPath.c_str(),tPath.c_str(),f_copyDir_c ? "KO" : "OK"); - if (f_copyDir_c) { - f_copyDir_c = false; - return false; - } else - return true; -} - -int checkEntry_b(const char *fPath) { - WHBLogPrintf("checkEntry %s --> %s",fPath,f_checkEntry_b ? "KO" : "OK"); - if (f_checkEntry_b) { - f_checkEntry_b = false; - return 1; - } else - return 2; -} - -static bool copyDir_b(const std::string &pPath, const std::string &tPath) { // Source: ft2sd - WHBLogPrintf("copy %s %s --> %s",pPath.c_str(),tPath.c_str(),f_copyDir_b ? "KO" : "OK"); - if (f_copyDir_b) { - f_copyDir_b = false; - return false; - } else - return true; -} - -static bool copyDir2_b(const std::string &pPath, const std::string &tPath) { // Source: ft2sd - WHBLogPrintf("copy %s %s --> %s",pPath.c_str(),tPath.c_str(),f_copyDir2_b ? "KO" : "OK"); - if (f_copyDir2_b) { - f_copyDir2_b = false; - return false; - } else - return true; -} - - -/* - bool removeDir_c = true; - bool removeDir_b = true; -*/ - bool unlink_c = true; - bool unlink_b = true; - -static bool removeDir_c(const std::string &pPath) { - WHBLogPrintf("removeDir %s --> %s",pPath.c_str(),f_removeDir_c ? "KO" : "OK"); - if (f_removeDir_c) { - f_removeDir_c = false; - return false; - } else - return true; -} - - -static bool removeDir_b(const std::string &pPath) { - WHBLogPrintf("removeDir %s --> %s",pPath.c_str(),f_removeDir_b ? "KO" : "OK"); - if (f_removeDir_c) { - f_removeDir_c = false; - return false; - } else - return true; -} - int restoreSavedata(Title *title, uint8_t slot, int8_t sduser, int8_t wiiuuser, bool common, bool interactive /*= true*/) { int errorCode = 0; if (isSlotEmpty(title->highID, title->lowID, slot)) { @@ -1274,9 +1229,10 @@ int restoreSavedata(Title *title, uint8_t slot, int8_t sduser, int8_t wiiuuser, } if (doCommon) { - //FSAMakeQuota(handle, newlibtoFSA(dstCommonPath).c_str(), 0x666, title->accountSaveSize); - //if (copyDir(srcCommonPath, dstCommonPath)) - if (copyDir_c(srcCommonPath, dstCommonPath)) + #ifndef MOCK + FSAMakeQuota(handle, newlibtoFSA(dstCommonPath).c_str(), 0x666, title->accountSaveSize); + #endif + if (copyDir(srcCommonPath, dstCommonPath)) commonSaved = true; else { promptError(LanguageUtils::gettext("%s\nCommon save not restored."),title->shortName); @@ -1287,11 +1243,11 @@ int restoreSavedata(Title *title, uint8_t slot, int8_t sduser, int8_t wiiuuser, if (doBase) { if (singleUser) { - //if (checkEntry(srcPath.c_str()) == 2) { - if (checkEntry_b(srcPath.c_str()) == 2) { - //FSAMakeQuota(handle, newlibtoFSA(dstPath).c_str(), 0x666, title->accountSaveSize); - //if (!copyDir(srcPath, dstPath)) { - if (!copyDir_b(srcPath, dstPath)) { + if (checkEntry(srcPath.c_str()) == 2) { + #ifndef MOCK + FSAMakeQuota(handle, newlibtoFSA(dstPath).c_str(), 0x666, title->accountSaveSize); + #endif + if (!copyDir(srcPath, dstPath)) { promptError(LanguageUtils::gettext("%s\nRestore failed."),title->shortName); errorCode += 2; } @@ -1302,9 +1258,10 @@ int restoreSavedata(Title *title, uint8_t slot, int8_t sduser, int8_t wiiuuser, } else { - //FSAMakeQuotaFromDir(srcPath.c_str(), dstPath.c_str(), title->accountSaveSize); - //if (!copyDir(srcPath, dstPath)) { - if (!copyDir2_b(srcPath, dstPath)) { + #ifndef MOCK + FSAMakeQuotaFromDir(srcPath.c_str(), dstPath.c_str(), title->accountSaveSize); + #endif + if (!copyDir(srcPath, dstPath)) { promptError(LanguageUtils::gettext("%s\nRestore failed."),title->shortName); errorCode += 4; } @@ -1340,8 +1297,8 @@ int restoreSavedata(Title *title, uint8_t slot, int8_t sduser, int8_t wiiuuser, } */ - //if (!title->saveInit && !isWii) { - if (!saveinit) { +#ifndef MOCK + if (!title->saveInit && !isWii) { std::string userPath = StringUtils::stringFormat("%s/%08x/%08x/user", path.c_str(), highID, lowID); FSAShimBuffer *shim = (FSAShimBuffer *) memalign(0x40, sizeof(FSAShimBuffer)); @@ -1369,6 +1326,7 @@ int restoreSavedata(Title *title, uint8_t slot, int8_t sduser, int8_t wiiuuser, copyFile(titleMetaPath + "/meta.xml", metaPath + "/meta.xml"); copyFile(titleMetaPath + "/iconTex.tga", metaPath + "/iconTex.tga"); } +#endif if (dstPath.rfind("storage_slccmpt01:", 0) == 0) { FSAFlushVolume(handle, "/vol/storage_slccmpt01"); @@ -1431,29 +1389,32 @@ int wipeSavedata(Title *title, int8_t wiiuuser, bool common, bool interactive /* } if (doCommon) { - //if (!removeDir(commonPath)) { - if (!removeDir_c(commonPath)) { + if (!removeDir(commonPath)) { promptError(LanguageUtils::gettext("%s \n Common save not found."),title->shortName); errorCode = 1; } - //if (unlink(commonPath.c_str()) == -1) { + #ifndef MOCK + if (unlink(commonPath.c_str()) == -1) { + #else if (!unlink_c) { + #endif promptError(LanguageUtils::gettext("%s \n Failed to delete common folder:\n %s"), title->shortName,strerror(errno)); errorCode += 2; } } if (doBase) { - //if (checkEntry(srcPath.c_str()) == 2) { - if (checkEntry_b(srcPath.c_str()) == 2) { - //if (!removeDir(srcPath)) { - if (!removeDir_b(srcPath)) { + if (checkEntry(srcPath.c_str()) == 2) { + if (!removeDir(srcPath)) { promptError(LanguageUtils::gettext("%s \n Failed to delete savefile."),title->shortName); errorCode += 4; } if ((wiiuuser > -1) && !isWii) { - //if (unlink(srcPath.c_str()) == -1) { + #ifndef MOCK + if (unlink(srcPath.c_str()) == -1) { + #else if (!unlink_b) { + #endif promptError(LanguageUtils::gettext("%s \n Failed to delete user folder:\n %s"), title->shortName,strerror(errno)); errorCode += 8; } diff --git a/src/utils/DrawUtils.cpp b/src/utils/DrawUtils.cpp index eb87997..fc49812 100644 --- a/src/utils/DrawUtils.cpp +++ b/src/utils/DrawUtils.cpp @@ -312,9 +312,8 @@ void DrawUtils::print(uint32_t x, uint32_t y, const wchar_t *string, bool alignR if (*string == '\n') { - //WHBLogPrintf("minHeight: %d",mtx.minHeight); //penY += mtx.minHeight; - penY += 36; // temporal fix for multiline output + penY += 30; // temporal fix for multiline output penX = x; continue; }