diff --git a/Makefile b/Makefile index 6b0c128..94f0947 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ INCLUDES := inc inc/ui EXEFS_SRC := exefs_src APP_TITLE := JKSV APP_AUTHOR := JK -APP_VERSION := 08.16.2021 +APP_VERSION := 08.17.2021 ROMFS := romfs ICON := icon.jpg diff --git a/inc/data.h b/inc/data.h index 0326b57..0ea71c6 100644 --- a/inc/data.h +++ b/inc/data.h @@ -8,7 +8,7 @@ #include "gfx.h" #define BLD_MON 8 -#define BLD_DAY 16 +#define BLD_DAY 17 #define BLD_YEAR 2021 namespace data @@ -37,7 +37,7 @@ namespace data typedef struct { //Makes it easier to grab id - uint64_t saveID; + uint64_t tid; FsSaveDataInfo saveInfo; PdmPlayStatistics playStats; } userTitleInfo; @@ -99,14 +99,6 @@ namespace data std::string getTitleNameByTID(const uint64_t& tid); std::string getTitleSafeNameByTID(const uint64_t& tid); SDL_Texture *getTitleIconByTID(const uint64_t& tid); - inline int getTitleIndexInUser(const data::user& u, const uint64_t& sid) - { - for(unsigned i = 0; i < u.titleInfo.size(); i++) - { - if(u.titleInfo[i].saveID == sid) - return i; - } - return -1; - } + int getTitleIndexInUser(const data::user *u, const uint64_t& tid); extern SetLanguage sysLang; } diff --git a/inc/file.h b/inc/file.h index 19f50f8..5f04491 100644 --- a/inc/file.h +++ b/inc/file.h @@ -52,14 +52,14 @@ namespace fs void delDir(const std::string& path); //Loads paths to filter from backup/deletion - void loadPathFilters(const std::string& _file); + void loadPathFilters(const uint64_t& tid); bool pathIsFiltered(const std::string& _path); void freePathFilters(); void wipeSave(); - //Dumps all titles for 'user'. returns false to bail - bool dumpAllUserSaves(const data::user& u); + //Dumps all titles for current user + void dumpAllUserSaves(); //returns file properties as C++ string std::string getFileProps(const std::string& _path); diff --git a/inc/fsthrd.h b/inc/fsthrd.h index fb37b84..fd0fd6e 100644 --- a/inc/fsthrd.h +++ b/inc/fsthrd.h @@ -15,4 +15,6 @@ namespace fs void copyZipToDir_t(void *a); void wipesave_t(void *a); void closeZip_t(void *a); + + void backupUserSaves_t(void *a); } diff --git a/inc/gfx.h b/inc/gfx.h index 0b8ede8..2a9c75b 100644 --- a/inc/gfx.h +++ b/inc/gfx.h @@ -18,62 +18,10 @@ namespace gfx size_t getTextWidth(const char *str, int fontSize); //Shortcuts for drawing - inline void texDraw(SDL_Texture *target, SDL_Texture *tex, int x, int y) - { - int tW = 0, tH = 0; - if(SDL_QueryTexture(tex, NULL, NULL, &tW, &tH) == 0) - { - SDL_SetRenderTarget(gfx::render, target); - SDL_Rect src = {0, 0, tW, tH}; - SDL_Rect pos = {x, y, tW, tH}; - SDL_RenderCopy(gfx::render, tex, &src, &pos); - } - } - - inline void texDrawStretch(SDL_Texture *target, SDL_Texture *tex, int x, int y, int w, int h) - { - int tW = 0, tH = 0; - if(SDL_QueryTexture(tex, NULL, NULL, &tW, &tH) == 0) - { - SDL_SetRenderTarget(gfx::render, target); - SDL_Rect src = {0, 0, tW, tH}; - SDL_Rect pos = {x, y, w, h}; - SDL_RenderCopy(gfx::render, tex, &src, &pos); - } - } - - inline void texDrawPart(SDL_Texture *target, SDL_Texture *tex, int srcX, int srcY, int srcW, int srcH, int dstX, int dstY) - { - SDL_Rect src = {srcX, srcY, srcW, srcH}; - SDL_Rect dst = {dstX, dstY, srcW, srcH}; - SDL_SetRenderTarget(gfx::render, target); - SDL_RenderCopy(gfx::render, tex, &src, &dst); - } - - inline void drawLine(SDL_Texture *target, const SDL_Color *c, int x1, int y1, int x2, int y2) - { - SDL_SetRenderTarget(gfx::render, target); - SDL_SetRenderDrawColor(gfx::render, c->r, c->g, c->b, c->a); - SDL_RenderDrawLine(gfx::render, x1, y1, x2, y2); - } - - inline void drawRect(SDL_Texture *target, const SDL_Color *c, int x, int y, int w, int h) - { - SDL_SetRenderTarget(gfx::render, target); - SDL_SetRenderDrawColor(gfx::render, c->r, c->g, c->b, c->a); - SDL_Rect rect = {x, y, w, h}; - SDL_RenderFillRect(gfx::render, &rect); - } - - inline void clearTarget(SDL_Texture *target, const SDL_Color *clear) - { - SDL_SetRenderTarget(gfx::render, target); - SDL_SetRenderDrawColor(gfx::render, clear->r, clear->g, clear->b, clear->a); - SDL_RenderClear(gfx::render); - } - - inline void resetRender() - { - SDL_SetRenderDrawColor(gfx::render, 0xFF, 0xFF, 0xFF, 0xFF); - } + void texDraw(SDL_Texture *target, SDL_Texture *tex, int x, int y); + void texDrawStretch(SDL_Texture *target, SDL_Texture *tex, int x, int y, int w, int h); + void texDrawPart(SDL_Texture *target, SDL_Texture *tex, int srcX, int srcY, int srcW, int srcH, int dstX, int dstY); + void drawLine(SDL_Texture *target, const SDL_Color *c, int x1, int y1, int x2, int y2); + void drawRect(SDL_Texture *target, const SDL_Color *c, int x, int y, int w, int h); + void clearTarget(SDL_Texture *target, const SDL_Color *clear); } diff --git a/inc/util.h b/inc/util.h index 27248ed..bdf38b8 100644 --- a/inc/util.h +++ b/inc/util.h @@ -17,6 +17,26 @@ namespace util DATE_FMT_ASC }; + typedef enum + { + cpu204MHz = 204000000, + cpu306MHz = 306000000, + cpu408MHz = 408000000, + cpu510MHz = 510000000, + cpu612MHz = 612000000, + cpu714MHz = 714000000, + cpu816MHz = 816000000, + cpu918MHz = 918000000, + cpu1020MHz = 1020000000, //Default + cpu1122MHz = 1122000000, + cpu1224MHz = 1224000000, + cpu1326MHz = 1326000000, + cpu1428MHz = 1428000000, + cpu1581MHz = 1581000000, + cpu1683MHz = 1683000000, + cpu1785MHz = 1785000000 + } cpuSpds; + //Returns string with date S+ time std::string getDateTime(int fmt); diff --git a/src/cfg.cpp b/src/cfg.cpp index 411ccbf..0e6773b 100644 --- a/src/cfg.cpp +++ b/src/cfg.cpp @@ -38,12 +38,12 @@ void cfg::addTitleToBlacklist(void *a) { threadInfo *t = (threadInfo *)a; data::userTitleInfo *d = data::getCurrentUserTitleInfo(); - uint64_t tid = d->saveID; + uint64_t tid = d->tid; blacklist.push_back(tid); for(data::user& u : data::users) { for(unsigned i = 0; i < u.titleInfo.size(); i++) - if(u.titleInfo[i].saveID == tid) u.titleInfo.erase(u.titleInfo.begin() + i); + if(u.titleInfo[i].tid == tid) u.titleInfo.erase(u.titleInfo.begin() + i); } ui::ttlRefresh(); t->finished = true; diff --git a/src/data.cpp b/src/data.cpp index f90733d..c4cc9af 100644 --- a/src/data.cpp +++ b/src/data.cpp @@ -35,14 +35,14 @@ static struct bool operator()(const data::userTitleInfo& a, const data::userTitleInfo& b) { //Favorites override EVERYTHING - if(cfg::isFavorite(a.saveID) != cfg::isFavorite(b.saveID)) return cfg::isFavorite(a.saveID); + if(cfg::isFavorite(a.tid) != cfg::isFavorite(b.tid)) return cfg::isFavorite(a.tid); switch(cfg::sortType) { case cfg::ALPHA: { - std::string titleA = data::getTitleNameByTID(a.saveID); - std::string titleB = data::getTitleNameByTID(b.saveID); + std::string titleA = data::getTitleNameByTID(a.tid); + std::string titleB = data::getTitleNameByTID(b.tid); uint32_t pointA, pointB; for(unsigned i = 0, j = 0; i < titleA.length(); ) { @@ -213,14 +213,14 @@ bool data::loadUsersTitles(bool clearUsers) while(R_SUCCEEDED(fsSaveDataInfoReaderRead(&it, &info, 1, &total)) && total != 0) { - uint64_t saveID = 0; + uint64_t tid = 0; if(info.save_data_type == FsSaveDataType_System || info.save_data_type == FsSaveDataType_SystemBcat) - saveID = info.system_save_data_id; + tid = info.system_save_data_id; else - saveID = info.application_id; + tid = info.application_id; //Don't bother with this stuff - if(cfg::isBlacklisted(saveID) || !accountSystemSaveCheck(info) || !testMount(info)) + if(cfg::isBlacklisted(tid) || !accountSystemSaveCheck(info) || !testMount(info)) continue; switch(info.save_data_type) @@ -258,8 +258,8 @@ bool data::loadUsersTitles(bool clearUsers) break; } - if(!titleIsLoaded(saveID)) - addTitleToList(saveID); + if(!titleIsLoaded(tid)) + addTitleToList(tid); int u = getUserIndex(info.uid); if(u == -1) @@ -274,7 +274,7 @@ bool data::loadUsersTitles(bool clearUsers) else memset(&playStats, 0, sizeof(PdmPlayStatistics)); - users[u].addUserTitleInfo(saveID, &info, &playStats); + users[u].addUserTitleInfo(tid, &info, &playStats); } fsSaveDataInfoReaderClose(&it); } @@ -307,7 +307,7 @@ void data::sortUserTitles() void data::init() { if(cfg::config["ovrClk"]) - util::setCPU(1224000000); + util::setCPU(util::cpu1224MHz); uint64_t lang; setGetSystemLanguage(&lang); @@ -325,7 +325,7 @@ void data::exit() SDL_DestroyTexture(iconMask); if(cfg::config["ovrClk"]) - util::setCPU(1020000000); + util::setCPU(util::cpu1020MHz); } void data::setUserIndex(unsigned _sUser) @@ -380,6 +380,16 @@ SDL_Texture *data::getTitleIconByTID(const uint64_t& tid) return titles[tid].icon; } +int data::getTitleIndexInUser(const data::user *u, const uint64_t& tid) +{ + for(unsigned i = 0; i < u->titleInfo.size(); i++) + { + if(u->titleInfo[i].tid == tid) + return i; + } + return -1; +} + data::user::user(const AccountUid& _id, const std::string& _backupName) { userID = _id; @@ -433,7 +443,7 @@ void data::user::setUID(const AccountUid& _id) void data::user::addUserTitleInfo(const uint64_t& tid, const FsSaveDataInfo *_saveInfo, const PdmPlayStatistics *_stats) { data::userTitleInfo newInfo; - newInfo.saveID = tid; + newInfo.tid = tid; memcpy(&newInfo.saveInfo, _saveInfo, sizeof(FsSaveDataInfo)); memcpy(&newInfo.playStats, _stats, sizeof(PdmPlayStatistics)); titleInfo.push_back(newInfo); @@ -451,8 +461,8 @@ void data::dispStats() for(data::user& u : data::users) stats += u.getUsername() + ": " + std::to_string(u.titleInfo.size()) + "\n"; stats += "Current User: " + cu->getUsername() + "\n"; - stats += "Current Title: " + data::getTitleNameByTID(d->saveID) + "\n"; - stats += "Safe Title: " + data::getTitleSafeNameByTID(d->saveID) + "\n"; + stats += "Current Title: " + data::getTitleNameByTID(d->tid) + "\n"; + stats += "Safe Title: " + data::getTitleSafeNameByTID(d->tid) + "\n"; stats += "Sort Type: " + std::to_string(cfg::sortType) + "\n"; gfx::drawTextf(NULL, 16, 2, 2, &green, stats.c_str()); } diff --git a/src/file.cpp b/src/file.cpp index 465f684..269ac2c 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -32,7 +32,9 @@ fs::copyArgs *fs::copyArgsCreate(const std::string& from, const std::string& to, ret->unz = unz; ret->cleanup = _cleanup; ret->prog = new ui::progBar; - ret->offset = 0.0f; + ret->prog->setMax(0); + ret->prog->update(0); + ret->offset = 0; return ret; } @@ -97,7 +99,7 @@ void fs::createSaveData(FsSaveDataType _type, uint64_t _tid, AccountUid _userID) { std::string indexStr; uint16_t index = 0; - if(_type == FsSaveDataType_Cache && !(indexStr = util::getStringInput(SwkbdType_NumPad, "0", ui::getUIString("swkbdSaveIndex", 0), 3, 0, NULL)).empty()) + if(_type == FsSaveDataType_Cache && !(indexStr = util::getStringInput(SwkbdType_NumPad, "0", ui::getUIString("swkbdSaveIndex", 0), 2, 0, NULL)).empty()) index = strtoul(indexStr.c_str(), NULL, 10); svCreateArgs *send = new svCreateArgs; @@ -357,7 +359,7 @@ void fs::copyDirToZip(const std::string& from, zipFile to) { if(cfg::config["ovrClk"]) { - util::setCPU(1785000000); + util::setCPU(util::cpu1785MHz); ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popCPUBoostEnabled", 0)); } copyArgs *send = copyArgsCreate(from, "", "", to, NULL, true); @@ -368,7 +370,7 @@ void fs::copyZipToDir(unzFile unz, const std::string& to, const std::string& dev { if(cfg::config["ovrClk"]) { - util::setCPU(1785000000); + util::setCPU(util::cpu1785MHz); ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popCPUBoostEnabled", 0)); } copyArgs *send = copyArgsCreate("", to, dev, NULL, unz, true); @@ -425,11 +427,13 @@ void fs::delDir(const std::string& path) rmdir(path.c_str()); } -void fs::loadPathFilters(const std::string& _file) +void fs::loadPathFilters(const uint64_t& tid) { - if(fs::fileExists(_file)) + char path[256]; + sprintf(path, "sdmc:/config/JKSV/0x%016lX_filter.txt", tid); + if(fs::fileExists(path)) { - fs::dataFile filter(_file); + fs::dataFile filter(path); while(filter.readNextLine(false)) pathFilter.push_back(filter.getLine()); } @@ -459,45 +463,11 @@ void fs::wipeSave() ui::newThread(fs::wipesave_t, NULL, NULL); } -bool fs::dumpAllUserSaves(const data::user& u) +void fs::dumpAllUserSaves() { - for(unsigned i = 0; i < u.titleInfo.size(); i++) - { - ui::updateInput(); - - if(ui::padKeysDown() & HidNpadButton_B) - return false; - - if(fs::mountSave(u.titleInfo[i].saveInfo)) - { - util::createTitleDirectoryByTID(u.titleInfo[i].saveID); - std::string basePath = util::generatePathByTID(u.titleInfo[i].saveID); - switch(cfg::config["zip"]) - { - case true: - { - std::string outPath = basePath + u.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + ".zip"; - zipFile zip = zipOpen(outPath.c_str(), 0); - fs::copyDirToZip("sv:/", zip); - zipClose(zip, NULL); - } - break; - - case false: - { - std::string outPath = basePath + u.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + "/"; - mkdir(outPath.substr(0, outPath.length() - 1).c_str(), 777); - fs::copyDirToDir("sv:/", outPath); - } - break; - } - fsdevUnmountDevice("sv"); - } - } - - ui::updateInput(); - - return true;//? + //This is only really used for the progress bar + fs::copyArgs *send = fs::copyArgsCreate("", "", "", NULL, NULL, true); + ui::newThread(fs::backupUserSaves_t, send, _fileDrawFunc); } std::string fs::getFileProps(const std::string& _path) @@ -596,7 +566,7 @@ void fs::createNewBackup(void *a) data::user *u = data::getCurrentUser(); data::userTitleInfo *d = data::getCurrentUserTitleInfo(); - data::titleInfo *t = data::getTitleInfoByTID(d->saveID); + data::titleInfo *t = data::getTitleInfoByTID(d->tid); std::string out; @@ -617,7 +587,7 @@ void fs::createNewBackup(void *a) util::getDateTime(util::DATE_FMT_ASC), u->getUsernameSafe(), t->safeTitle, - util::generateAbbrev(d->saveID), + util::generateAbbrev(d->tid), ".zip" }; std::string defaultText = u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD); @@ -627,7 +597,7 @@ void fs::createNewBackup(void *a) if(!out.empty()) { std::string ext = util::getExtensionFromString(out); - std::string path = util::generatePathByTID(d->saveID) + out; + std::string path = util::generatePathByTID(d->tid) + out; if(cfg::config["zip"] || ext == "zip") { if(ext != "zip")//data::zip is on but extension is not zip @@ -661,7 +631,7 @@ void fs::overwriteBackup(void *a) std::string itemName = d->getItem(ind); if(d->isDir(ind)) { - std::string toPath = util::generatePathByTID(cd->saveID) + itemName + "/"; + std::string toPath = util::generatePathByTID(cd->tid) + itemName + "/"; //Delete and recreate fs::delDir(toPath); mkdir(toPath.c_str(), 777); @@ -669,7 +639,7 @@ void fs::overwriteBackup(void *a) } else if(!d->isDir(ind) && d->getItemExt(ind) == "zip") { - std::string toPath = util::generatePathByTID(cd->saveID) + itemName; + std::string toPath = util::generatePathByTID(cd->tid) + itemName; fs::delfile(toPath); zipFile zip = zipOpen64(toPath.c_str(), 0); fs::copyDirToZip("sv:/", zip); @@ -693,20 +663,20 @@ void fs::restoreBackup(void *a) { if(cfg::config["autoBack"] && cfg::config["zip"]) { - std::string autoZip = util::generatePathByTID(cd->saveID) + "/AUTO " + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + ".zip"; + std::string autoZip = util::generatePathByTID(cd->tid) + "/AUTO " + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + ".zip"; zipFile zip = zipOpen64(autoZip.c_str(), 0); fs::copyDirToZip("sv:/", zip); } else if(cfg::config["autoBack"]) { - std::string autoFolder = util::generatePathByTID(cd->saveID) + "/AUTO - " + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + "/"; + std::string autoFolder = util::generatePathByTID(cd->tid) + "/AUTO - " + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + "/"; mkdir(autoFolder.substr(0, autoFolder.length() - 1).c_str(), 777); fs::copyDirToDir("sv:/", autoFolder); } if(d->isDir(ind)) { - std::string fromPath = util::generatePathByTID(cd->saveID) + itemName + "/"; + std::string fromPath = util::generatePathByTID(cd->tid) + itemName + "/"; if(fs::dirNotEmpty(fromPath)) { fs::wipeSave(); @@ -717,7 +687,7 @@ void fs::restoreBackup(void *a) } else if(!d->isDir(ind) && d->getItemExt(ind) == "zip") { - std::string path = util::generatePathByTID(cd->saveID) + itemName; + std::string path = util::generatePathByTID(cd->tid) + itemName; unzFile unz = unzOpen64(path.c_str()); if(unz && fs::zipNotEmpty(unz)) { @@ -730,7 +700,7 @@ void fs::restoreBackup(void *a) else { //Just copy file over - std::string fromPath = util::generatePathByTID(cd->saveID) + itemName; + std::string fromPath = util::generatePathByTID(cd->tid) + itemName; std::string toPath = "sv:/" + itemName; fs::copyFileCommit(fromPath, toPath, "sv"); } @@ -756,20 +726,20 @@ void fs::deleteBackup(void *a) t->status->setStatus("Deleting..."); if(cfg::config["trashBin"]) { - std::string oldPath = util::generatePathByTID(cd->saveID) + itemName; + std::string oldPath = util::generatePathByTID(cd->tid) + itemName; std::string trashPath = wd + "_TRASH_/" + itemName; rename(oldPath.c_str(), trashPath.c_str()); ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("saveDataBackupMovedToTrash", 0), itemName.c_str()); } else if(d->isDir(ind)) { - std::string delPath = util::generatePathByTID(cd->saveID) + itemName + "/"; + std::string delPath = util::generatePathByTID(cd->tid) + itemName + "/"; fs::delDir(delPath); ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("saveDataBackupDeleted", 0), itemName.c_str()); } else { - std::string delPath = util::generatePathByTID(cd->saveID) + itemName; + std::string delPath = util::generatePathByTID(cd->tid) + itemName; fs::delfile(delPath); ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("saveDataBackupDeleted", 0), itemName.c_str()); } diff --git a/src/fsthrd.cpp b/src/fsthrd.cpp index 33b3dda..bd04232 100644 --- a/src/fsthrd.cpp +++ b/src/fsthrd.cpp @@ -198,7 +198,7 @@ void fs::copyFileCommit_t(void *a) threadInfo *t = (threadInfo *)a; copyArgs *args = (copyArgs *)t->argPtr; data::userTitleInfo *d = data::getCurrentUserTitleInfo(); - data::titleInfo *info = data::getTitleInfoByTID(d->saveID); + data::titleInfo *info = data::getTitleInfoByTID(d->tid); t->status->setStatus(ui::getUICString("threadStatusCopyingFile", 0), args->from.c_str()); args->prog->setMax(fs::fsize(args->from)); @@ -424,7 +424,13 @@ void fs::copyDirToZip_t(void *a) } else { - zip_fileinfo inf = {0}; + time_t raw; + time(&raw); + tm *locTime = localtime(&raw); + + zip_fileinfo inf = { (unsigned)locTime->tm_sec, (unsigned)locTime->tm_min, (unsigned)locTime->tm_hour, + (unsigned)locTime->tm_mday, (unsigned)locTime->tm_mon, (unsigned)(1900 + locTime->tm_year), 0, 0, 0 }; + std::string filename = args->from + itm; size_t devPos = filename.find_first_of('/') + 1; t->status->setStatus(ui::getUICString("threadStatusAddingFileToZip", 0), itm.c_str()); @@ -454,7 +460,7 @@ void fs::copyDirToZip_t(void *a) if(args->cleanup) { if(cfg::config["ovrClk"]) - util::setCPU(1224000000); + util::setCPU(util::cpu1224MHz); ui::newThread(closeZip_t, args->z, NULL); delete args->prog; delete args; @@ -468,7 +474,7 @@ void fs::copyZipToDir_t(void *a) copyArgs *args = (copyArgs *)t->argPtr; data::userTitleInfo *d = data::getCurrentUserTitleInfo(); - data::titleInfo *tinfo = data::getTitleInfoByTID(d->saveID); + data::titleInfo *tinfo = data::getTitleInfoByTID(d->tid); uint64_t journalSize = getJournalSize(tinfo), writeCount = 0; char filename[FS_MAX_PATH]; uint8_t *buff = new uint8_t[BUFF_SIZE]; @@ -543,7 +549,7 @@ void fs::copyZipToDir_t(void *a) unzClose(args->unz); copyArgsDestroy(args); if(cfg::config["ovrClk"]) - util::setCPU(1224000000); + util::setCPU(util::cpu1224MHz); } delete[] buff; t->finished = true; @@ -565,3 +571,70 @@ void fs::closeZip_t(void *a) zipClose(z, NULL); t->finished = true; } + +void fs::backupUserSaves_t(void *a) +{ + threadInfo *t = (threadInfo *)a; + fs::copyArgs *c = (fs::copyArgs *)t->argPtr; + data::user *u = data::getCurrentUser(); + + if(cfg::config["ovrClk"] && cfg::config["zip"]) + { + util::setCPU(util::cpu1785MHz); + ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popCPUBoostEnabled", 0)); + } + + for(unsigned i = 0; i < u->titleInfo.size(); i++) + { + std::string title = data::getTitleNameByTID(u->titleInfo[i].tid); + t->status->setStatus(std::string("#" + title + "#").c_str()); + if((ui::padKeysDown() & HidNpadButton_B) || (ui::padKeysHeld() & HidNpadButton_B)) + { + delete c; + t->finished = true; + return; + } + + bool saveMounted = fs::mountSave(u->titleInfo[i].saveInfo); + util::createTitleDirectoryByTID(u->titleInfo[i].tid); + if(saveMounted && cfg::config["zip"] && fs::dirNotEmpty("sv:/")) + { + fs::loadPathFilters(u->titleInfo[i].tid); + std::string outPath = util::generatePathByTID(u->titleInfo[i].tid) + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + ".zip"; + zipFile zip = zipOpen64(outPath.c_str(), 0); + threadInfo fakeThread; + fs::copyArgs tmpArgs; + tmpArgs.from = "sv:/"; + tmpArgs.z = zip; + tmpArgs.cleanup = false; + tmpArgs.prog = c->prog; + fakeThread.status = t->status; + fakeThread.argPtr = &tmpArgs; + copyDirToZip_t(&fakeThread); + zipClose(zip, NULL); + fs::freePathFilters(); + } + else if(saveMounted && fs::dirNotEmpty("sv:/")) + { + fs::loadPathFilters(u->titleInfo[i].tid); + std::string outPath = util::generatePathByTID(u->titleInfo[i].tid) + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + "/"; + fs::mkDir(outPath.substr(0, outPath.length() - 1)); + threadInfo fakeThread; + fs::copyArgs tmpArgs; + tmpArgs.from = "sv:/"; + tmpArgs.to = outPath; + tmpArgs.cleanup = false; + tmpArgs.prog = c->prog; + fakeThread.status = t->status; + fakeThread.argPtr = &tmpArgs; + copyDirToDir_t(&fakeThread); + fs::freePathFilters(); + } + fs::unmountSave(); + } + delete c; + if(cfg::config["ovrClk"] && cfg::config["zip"]) + util::setCPU(util::cpu1224MHz); + + t->finished = true; +} diff --git a/src/gfx.cpp b/src/gfx.cpp index 8dcb42d..66ba092 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -412,3 +412,57 @@ size_t gfx::getTextWidth(const char *str, int fontSize) } return width; } + +void gfx::texDraw(SDL_Texture *target, SDL_Texture *tex, int x, int y) +{ + int tW = 0, tH = 0; + if(SDL_QueryTexture(tex, NULL, NULL, &tW, &tH) == 0) + { + SDL_SetRenderTarget(gfx::render, target); + SDL_Rect src = {0, 0, tW, tH}; + SDL_Rect pos = {x, y, tW, tH}; + SDL_RenderCopy(gfx::render, tex, &src, &pos); + } +} + +void gfx::texDrawStretch(SDL_Texture *target, SDL_Texture *tex, int x, int y, int w, int h) +{ + int tW = 0, tH = 0; + if(SDL_QueryTexture(tex, NULL, NULL, &tW, &tH) == 0) + { + SDL_SetRenderTarget(gfx::render, target); + SDL_Rect src = {0, 0, tW, tH}; + SDL_Rect pos = {x, y, w, h}; + SDL_RenderCopy(gfx::render, tex, &src, &pos); + } +} + +void gfx::texDrawPart(SDL_Texture *target, SDL_Texture *tex, int srcX, int srcY, int srcW, int srcH, int dstX, int dstY) +{ + SDL_Rect src = {srcX, srcY, srcW, srcH}; + SDL_Rect dst = {dstX, dstY, srcW, srcH}; + SDL_SetRenderTarget(gfx::render, target); + SDL_RenderCopy(gfx::render, tex, &src, &dst); +} + +void gfx::drawLine(SDL_Texture *target, const SDL_Color *c, int x1, int y1, int x2, int y2) +{ + SDL_SetRenderTarget(gfx::render, target); + SDL_SetRenderDrawColor(gfx::render, c->r, c->g, c->b, c->a); + SDL_RenderDrawLine(gfx::render, x1, y1, x2, y2); +} + +void gfx::drawRect(SDL_Texture *target, const SDL_Color *c, int x, int y, int w, int h) +{ + SDL_SetRenderTarget(gfx::render, target); + SDL_SetRenderDrawColor(gfx::render, c->r, c->g, c->b, c->a); + SDL_Rect rect = {x, y, w, h}; + SDL_RenderFillRect(gfx::render, &rect); +} + +void gfx::clearTarget(SDL_Texture *target, const SDL_Color *clear) +{ + SDL_SetRenderTarget(gfx::render, target); + SDL_SetRenderDrawColor(gfx::render, clear->r, clear->g, clear->b, clear->a); + SDL_RenderClear(gfx::render); +} diff --git a/src/ui/fm.cpp b/src/ui/fm.cpp index c19eed3..369b729 100644 --- a/src/ui/fm.cpp +++ b/src/ui/fm.cpp @@ -392,7 +392,7 @@ static void _devMenuAddToPathFilter(void *a) { data::userTitleInfo *d = data::getCurrentUserTitleInfo(); std::string filterPath = *ma->path + b->d->getItem(sel - 2); - cfg::addPathToFilter(d->saveID, filterPath); + cfg::addPathToFilter(d->tid, filterPath); ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popAddedToPathFilter", 0), filterPath.c_str()); } } diff --git a/src/ui/ttl.cpp b/src/ui/ttl.cpp index d273f2b..3199132 100644 --- a/src/ui/ttl.cpp +++ b/src/ui/ttl.cpp @@ -66,14 +66,14 @@ void ui::populateFldMenu() fldMenu->reset(); data::userTitleInfo *d = data::getCurrentUserTitleInfo(); - util::createTitleDirectoryByTID(d->saveID); - std::string targetDir = util::generatePathByTID(d->saveID); + util::createTitleDirectoryByTID(d->tid); + std::string targetDir = util::generatePathByTID(d->tid); fldList->reassign(targetDir); char filterPath[128]; - sprintf(filterPath, "sdmc:/config/JKSV/0x%016lX_filter.txt", d->saveID); - fs::loadPathFilters(filterPath); + sprintf(filterPath, "sdmc:/config/JKSV/0x%016lX_filter.txt", d->tid); + fs::loadPathFilters(d->tid); *backargs = {fldMenu, fldList}; @@ -113,7 +113,6 @@ static void ttlViewCallback(void *a) break; case HidNpadButton_X: - data::setTitleIndex(ttlViews[curUserIndex]->getSelected()); ttlViews[curUserIndex]->setActive(false, true); ttlOpts->setActive(true); ui::ttlOptsPanel->openPanel(); @@ -121,9 +120,9 @@ static void ttlViewCallback(void *a) case HidNpadButton_Y: { - cfg::addTitleToFavorites(d->saveID); - int newSel = data::getTitleIndexInUser(*data::getCurrentUser(), d->saveID); - ui::ttlRefresh(); + cfg::addTitleToFavorites(d->tid); + data::user *u = data::getCurrentUser(); + int newSel = data::getTitleIndexInUser(u, d->tid); ttlViews[curUserIndex]->setSelected(newSel); } break; @@ -156,20 +155,20 @@ static void ttlOptsShowInfoPanel(void *a) { ttlOpts->setActive(false); ui::ttlOptsPanel->closePanel(); - infoPanelString = util::getInfoString(*data::getCurrentUser(), data::getCurrentUserTitleInfo()->saveID); + infoPanelString = util::getInfoString(*data::getCurrentUser(), data::getCurrentUserTitleInfo()->tid); infoPanel->openPanel(); } static void ttlOptsBlacklistTitle(void *a) { - std::string title = data::getTitleNameByTID(data::getCurrentUserTitleInfo()->saveID); + std::string title = data::getTitleNameByTID(data::getCurrentUserTitleInfo()->tid); ui::confirmArgs *conf = ui::confirmArgsCreate(false, cfg::addTitleToBlacklist, NULL, true, ui::getUICString("confirmBlacklist", 0), title.c_str()); ui::confirm(conf); } static void ttlOptsDefinePath(void *a) { - uint64_t tid = data::getCurrentUserTitleInfo()->saveID; + uint64_t tid = data::getCurrentUserTitleInfo()->tid; std::string safeTitle = data::getTitleInfoByTID(tid)->safeTitle; std::string newSafeTitle = util::getStringInput(SwkbdType_QWERTY, safeTitle, "Input New Output Folder", 0x200, 0, NULL); if(!newSafeTitle.empty()) @@ -192,7 +191,7 @@ static void ttlOptsResetSaveData_t(void *a) { threadInfo *t = (threadInfo *)a; data::userTitleInfo *d = data::getCurrentUserTitleInfo(); - std::string title = data::getTitleNameByTID(d->saveID); + std::string title = data::getTitleNameByTID(d->tid); t->status->setStatus(ui::getUICString("threadStatusResettingSaveData", 0), title.c_str()); fs::mountSave(d->saveInfo); @@ -208,7 +207,7 @@ static void ttlOptsResetSaveData(void *a) data::userTitleInfo *d = data::getCurrentUserTitleInfo(); if(d->saveInfo.save_data_type != FsSaveDataType_System) { - std::string title = data::getTitleNameByTID(d->saveID); + std::string title = data::getTitleNameByTID(d->tid); ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdDel"], ttlOptsResetSaveData_t, NULL, true, ui::getUICString("confirmResetSaveData", 0), title.c_str()); ui::confirm(conf); } @@ -221,7 +220,7 @@ static void ttlOptsDeleteSaveData_t(void *a) data::userTitleInfo *d = data::getCurrentUserTitleInfo(); unsigned userIndex = data::getCurrentUserIndex(); - std::string title = data::getTitleNameByTID(d->saveID); + std::string title = data::getTitleNameByTID(d->tid); t->status->setStatus(ui::getUICString("threadStatusDeletingSaveData", 0), title.c_str()); if(R_SUCCEEDED(fsDeleteSaveDataFileSystemBySaveDataSpaceId((FsSaveDataSpaceId)d->saveInfo.save_data_space_id, d->saveInfo.save_data_id))) { @@ -246,7 +245,7 @@ static void ttlOptsDeleteSaveData(void *a) data::userTitleInfo *d = data::getCurrentUserTitleInfo(); if(d->saveInfo.save_data_type != FsSaveDataType_System) { - std::string title = data::getTitleNameByTID(d->saveID); + std::string title = data::getTitleNameByTID(d->tid); ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdDel"], ttlOptsDeleteSaveData_t, NULL, true, ui::getUICString("confirmDeleteSaveData", 0), title.c_str()); ui::confirm(conf); } @@ -261,7 +260,7 @@ static void ttlOptsExtendSaveData_t(void *a) if(!expSizeStr.empty()) { int64_t journ = 0, expSize; - data::titleInfo *extend = data::getTitleInfoByTID(d->saveID); + data::titleInfo *extend = data::getTitleInfoByTID(d->tid); t->status->setStatus(ui::getUICString("threadStatusExtendingSaveData", 0), extend->title.c_str()); //Get journal size switch(d->saveInfo.save_data_type) @@ -328,7 +327,7 @@ static void infoPanelDraw(void *a) { data::userTitleInfo *d = data::getCurrentUserTitleInfo(); SDL_Texture *panel = (SDL_Texture *)a; - gfx::texDraw(panel, data::getTitleIconByTID(d->saveID), 77, 32); + gfx::texDraw(panel, data::getTitleIconByTID(d->tid), 77, 32); gfx::drawTextfWrap(panel, 18, 32, 320, 362, &ui::txtCont, infoPanelString.c_str()); } diff --git a/src/ui/ttlview.cpp b/src/ui/ttlview.cpp index 1fa75b3..03f2d11 100644 --- a/src/ui/ttlview.cpp +++ b/src/ui/ttlview.cpp @@ -39,7 +39,7 @@ ui::titleview::titleview(const data::user& _u, int _iconW, int _iconH, int _horG u = &_u; for(const data::userTitleInfo& t : u->titleInfo) - tiles.emplace_back(new ui::titleTile(_iconW, _iconH, cfg::isFavorite(t.saveID), data::getTitleIconByTID(t.saveID))); + tiles.emplace_back(new ui::titleTile(_iconW, _iconH, cfg::isFavorite(t.tid), data::getTitleIconByTID(t.tid))); } ui::titleview::~titleview() @@ -55,7 +55,7 @@ void ui::titleview::refresh() tiles.clear(); for(const data::userTitleInfo& t : u->titleInfo) - tiles.emplace_back(new ui::titleTile(iconW, iconH, cfg::isFavorite(t.saveID), data::getTitleIconByTID(t.saveID))); + tiles.emplace_back(new ui::titleTile(iconW, iconH, cfg::isFavorite(t.tid), data::getTitleIconByTID(t.tid))); if(selected > (int)tiles.size() - 1 && selected > 0) selected = tiles.size() - 1; diff --git a/src/ui/uistr.cpp b/src/ui/uistr.cpp index 9a4cc24..8e9443f 100644 --- a/src/ui/uistr.cpp +++ b/src/ui/uistr.cpp @@ -38,6 +38,7 @@ void ui::initStrings() addUIString("confirmCopy", 0, "Are you sure you want to copy #%s# to #%s#?"); addUIString("confirmDeleteSaveData", 0, "*WARNING*: This *will* erase the save data for #%s# *from your system*. Are you sure you want to do this?"); addUIString("confirmResetSaveData", 0, "*WARNING*: This *will* reset the save data for this game as if it was never ran before. Are you sure you want to do this?"); + addUIString("confirmCreateAllSaveData", 0, "Are you sure you would like to create all save data on this system for #%s#? This can take a while depending on how many titles are found."); //Save Data related strings addUIString("saveDataNoneFound", 0, "No saves found for #%s#!"); @@ -104,18 +105,20 @@ void ui::initStrings() addUIString("extrasMenu", 11, "*[DEV]* Output en-US"); //User Options - addUIString("userOptions", 0, "Create Save Data"); - addUIString("userOptions", 1, "Create All Save Data"); - addUIString("userOptions", 2, "Delete All User Saves"); + addUIString("userOptions", 0, "Dump All For "); + addUIString("userOptions", 1, "Create Save Data"); + addUIString("userOptions", 2, "Create All Save Data"); + addUIString("userOptions", 3, "Delete All User Saves"); //Title Options addUIString("titleOptions", 0, "Information"); addUIString("titleOptions", 1, "Blacklist"); addUIString("titleOptions", 2, "Change Output Folder"); - addUIString("titleOptions", 3, "Open in File Mode"); - addUIString("titleOptions", 4, "Reset Save Data"); - addUIString("titleOptions", 5, "Delete Save Data"); - addUIString("titleOptions", 6, "Extend Save Data"); + addUIString("titleOptions", 3, "Export"); + addUIString("titleOptions", 4, "Open in File Mode"); + addUIString("titleOptions", 5, "Reset Save Data"); + addUIString("titleOptions", 6, "Delete Save Data"); + addUIString("titleOptions", 7, "Extend Save Data"); //Thread Status Strings addUIString("threadStatusCreatingSaveData", 0, "Creating save data for #%s#..."); diff --git a/src/ui/usr.cpp b/src/ui/usr.cpp index 2c69a39..e6a8bc9 100644 --- a/src/ui/usr.cpp +++ b/src/ui/usr.cpp @@ -170,7 +170,7 @@ static void usrOptDeleteAllUserSaves_t(void *a) { if(tinf.saveInfo.save_data_type != FsSaveDataType_System && (tinf.saveInfo.save_data_type != FsSaveDataType_Device || curUserIndex == devUser)) { - t->status->setStatus(ui::getUICString("threadStatusDeletingSaveData", 0), data::getTitleNameByTID(tinf.saveID).c_str()); + t->status->setStatus(ui::getUICString("threadStatusDeletingSaveData", 0), data::getTitleNameByTID(tinf.tid).c_str()); fsDeleteSaveDataFileSystemBySaveDataSpaceId(FsSaveDataSpaceId_User, tinf.saveInfo.save_data_id); } } @@ -216,6 +216,13 @@ static void cacheSavePanelDraw(void *a) cacheSaveMenu->draw(panel, &ui::txtCont, true); } +static void usrOptDumpAllUserSaves(void *a) +{ + data::user *u = data::getCurrentUser(); + if(u->titleInfo.size() > 0) + fs::dumpAllUserSaves(); +} + static void createSaveData(void *a) { data::user *u = data::getCurrentUser(); @@ -250,8 +257,9 @@ static void createSaveData(void *a) } } -static void usrOptCreateAllSaves(void *a) +static void usrOptCreateAllSaves_t(void *a) { + threadInfo *t = (threadInfo *)a; data::user *u = data::getCurrentUser(); int devPos = ui::usrMenu->getOptPos("Device"); int bcatPos = ui::usrMenu->getOptPos("BCAT"); @@ -272,6 +280,14 @@ static void usrOptCreateAllSaves(void *a) for(unsigned i = 0; i < bcatSids.size(); i++) fs::createSaveData(FsSaveDataType_Bcat, bcatSids[i], util::u128ToAccountUID(0)); } + t->finished = true; +} + +static void usrOptCreateAllSaves(void *a) +{ + data::user *u = data::getCurrentUser(); + ui::confirmArgs *send = ui::confirmArgsCreate(true, usrOptCreateAllSaves_t, NULL, true, ui::getUICString("confirmCreateAllSaveData", 0), u->getUsername().c_str()); + ui::confirm(send); } //Sets up save create menus @@ -385,15 +401,17 @@ void ui::usrInit() usrOptPanel = new ui::slideOutPanel(410, 720, 0, ui::SLD_RIGHT, usrOptPanelDraw); ui::registerPanel(usrOptPanel); - for(int i = 0; i < 3; i++) + for(int i = 0; i < 4; i++) usrOptMenu->addOpt(NULL, ui::getUIString("userOptions", i)); + //Dump All User Saves + usrOptMenu->optAddButtonEvent(0, HidNpadButton_A, usrOptDumpAllUserSaves, NULL); //Create Save Data - usrOptMenu->optAddButtonEvent(0, HidNpadButton_A, usrOptSaveCreate, usrMenu); + usrOptMenu->optAddButtonEvent(1, HidNpadButton_A, usrOptSaveCreate, usrMenu); //Create All - usrOptMenu->optAddButtonEvent(1, HidNpadButton_A, usrOptCreateAllSaves, NULL); + usrOptMenu->optAddButtonEvent(2, HidNpadButton_A, usrOptCreateAllSaves, NULL); //Delete All - usrOptMenu->optAddButtonEvent(2, HidNpadButton_A, usrOptDeleteAllUserSaves, NULL); + usrOptMenu->optAddButtonEvent(3, HidNpadButton_A, usrOptDeleteAllUserSaves, NULL); usrOptMenu->setActive(false); saveCreatePanel = new ui::slideOutPanel(512, 720, 0, ui::SLD_RIGHT, saveCreatePanelDraw); @@ -449,6 +467,8 @@ void ui::usrUpdate() int cachePos = usrMenu->getOptPos("Cache"); if(usrMenu->getSelected() <= cachePos) { + data::user *u = data::getCurrentUser(); + usrOptMenu->editOpt(0, NULL, ui::getUIString("userOptions", 0) + u->getUsername()); usrOptMenu->setActive(true); usrMenu->setActive(false); usrOptPanel->openPanel();