From b74349f7c087c8956a6d7e42e1bd9b5a9b6d92fe Mon Sep 17 00:00:00 2001 From: J-D-K Date: Fri, 6 Aug 2021 22:21:24 -0400 Subject: [PATCH] New config, restructure some stuff for stability and to fix issues --- inc/cfg.h | 33 +++++ inc/data.h | 23 +--- inc/file.h | 6 +- inc/fsfile.h | 2 + inc/fsthrd.h | 4 +- inc/ui/uistr.h | 4 +- src/cfg.cpp | 322 ++++++++++++++++++++++++++++++++++++++++++++ src/data.cpp | 293 ++++------------------------------------ src/file.cpp | 125 ++++++----------- src/fsfile.c | 11 ++ src/fsthrd.cpp | 146 +++++++++++++++++--- src/main.cpp | 4 + src/ui/fm.cpp | 43 ++++-- src/ui/sett.cpp | 79 ++++++----- src/ui/sldpanel.cpp | 1 - src/ui/ttl.cpp | 26 ++-- src/ui/ttlview.cpp | 5 +- src/ui/uistr.cpp | 7 +- src/util.cpp | 2 +- 19 files changed, 677 insertions(+), 459 deletions(-) create mode 100644 inc/cfg.h create mode 100644 src/cfg.cpp diff --git a/inc/cfg.h b/inc/cfg.h new file mode 100644 index 0000000..e49a867 --- /dev/null +++ b/inc/cfg.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include + +namespace cfg +{ + typedef enum + { + ALPHA, + MOST_PLAYED, + LAST_PLAYED + } sortTypes; + + void resetConfig(); + void loadConfig(); + void saveConfig(); + + bool isBlacklisted(const uint64_t& tid); + void addTitleToBlacklist(void *a); + + bool isFavorite(const uint64_t& tid); + void addTitleToFavorites(const uint64_t& tid); + + bool isDefined(const uint64_t& tid); + void pathDefAdd(const uint64_t& tid, const std::string& newPath); + std::string getPathDefinition(const uint64_t& tid); + + void addPathToFilter(const uint64_t& tid, const std::string& _p); + + extern std::unordered_map config; + extern uint8_t sortType; +} diff --git a/inc/data.h b/inc/data.h index 05f605d..dbd0798 100644 --- a/inc/data.h +++ b/inc/data.h @@ -22,14 +22,7 @@ namespace data void init(); void exit(); bool loadUsersTitles(bool clearUsers); - void loadBlacklist(); - void saveBlackList(); - void loadCfg(); - void saveCfg(); - void loadFav(); - void saveFav(); - void loadDefs(); - void saveDefs(); + void sortUserTitles(); //Draws some stats to the upper left corner void dispStats(); @@ -88,14 +81,6 @@ namespace data SDL_Texture *userIcon; }; - //Adds title to blacklist - void blacklistAdd(void *a); - //Adds title to favorite list - void favoriteTitle(const uint64_t& tid); - //Adds path definition for title - void pathDefAdd(const uint64_t& tid, const std::string& newPath); - bool isFavorite(const uint64_t& tid); - //User vector extern std::vector users; //Title data/info map @@ -117,12 +102,6 @@ namespace data } return -1; } - - //Options and info - //Restores config to default - void restoreDefaultConfig(); extern int selUser, selData; extern SetLanguage sysLang; - extern std::unordered_map config; - extern uint8_t sortType; } diff --git a/inc/file.h b/inc/file.h index 30618e8..1dfb65f 100644 --- a/inc/file.h +++ b/inc/file.h @@ -43,7 +43,8 @@ namespace fs bool dirNotEmpty(const std::string& _dir); bool zipNotEmpty(unzFile unzip); - void mkdirRec(const std::string& _p); + void mkDir(const std::string& _p); + void mkDirRec(const std::string& _p); //deletes file void delfile(const std::string& path); //Recursively deletes 'path' @@ -71,6 +72,7 @@ namespace fs bool isDir(const std::string& _path); std::string getWorkDir(); + void setWorkDir(const std::string& _w); class dirItem { @@ -144,7 +146,7 @@ namespace fs zipFile z; unzFile unz; bool cleanup = false; - uint64_t offset = 0, fileSize = 0; + uint64_t offset = 0; ui::progBar *prog; threadStatus *thrdStatus; Mutex arglck = 0; diff --git a/inc/fsfile.h b/inc/fsfile.h index 40fb2b2..c84be82 100644 --- a/inc/fsfile.h +++ b/inc/fsfile.h @@ -25,6 +25,8 @@ Result fsDelDirRec(const char *_p); char *getDeviceFromPath(char *dev, size_t _max, const char *path); char *getFilePath(char *pathOut, size_t _max, const char *path); +bool fsMkDir(const char *_p); + /*Opens file. Device is fetched from path. Libnx romfs doesn't work with this. Mode needs to be: FsOpenMode_Read diff --git a/inc/fsthrd.h b/inc/fsthrd.h index 9d89cea..b208f72 100644 --- a/inc/fsthrd.h +++ b/inc/fsthrd.h @@ -6,8 +6,10 @@ namespace fs { void _fileDrawFunc(void *a); - void copyfile_t(void *a); + void copyFile_t(void *a); void copyFileCommit_t(void *a); + void copyDirToDir_t(void *a); + void copyDirToDirCommit_t(void *a); void copyDirToZip_t(void *a); void copyZipToDir_t(void *a); void wipesave_t(void *a); diff --git a/inc/ui/uistr.h b/inc/ui/uistr.h index 148232a..dd27f19 100644 --- a/inc/ui/uistr.h +++ b/inc/ui/uistr.h @@ -12,11 +12,11 @@ namespace ui saveDataReset, saveDataResetSuccess, saveDataDeleteSuccess; //Strings for file mode menu - extern std::string advMenuStr[6]; + extern std::string advMenuStr[7]; //Strings for extras menu extern std::string exMenuStr[11]; //Strings for options menu - extern std::string optMenuStr[17]; + extern std::string optMenuStr[18]; //Strings for the holding thing extern std::string holdingText[3]; //Strings for sort type diff --git a/src/cfg.cpp b/src/cfg.cpp new file mode 100644 index 0000000..5ba4556 --- /dev/null +++ b/src/cfg.cpp @@ -0,0 +1,322 @@ +#include +#include +#include + +#include "cfg.h" +#include "data.h" +#include "file.h" +#include "ui.h" +#include "util.h" +#include "type.h" + +std::unordered_map cfg::config; +static std::vector blacklist; +static std::vector favorites; +static std::unordered_map pathDefs; +uint8_t cfg::sortType; +const char *cfgPath = "sdmc:/config/JKSV/JKSV.cfg"; +static std::unordered_map cfgStrings = +{ + {"workDir", 0}, {"includeDeviceSaves", 1}, {"autoBackup", 2}, {"overclock", 3}, {"holdToDelete", 4}, {"holdToRestore", 5}, + {"holdToOverwrite", 6}, {"forceMount", 7}, {"accountSystemSaves", 8}, {"allowSystemSaveWrite", 9}, {"directFSCommands", 10}, + {"exportToZIP", 11}, {"languageOverride", 12}, {"enableTrashBin", 13}, {"titleSortType", 14}, {"animationScale", 15}, + {"favorite", 16}, {"blacklist", 17}, {"pathDef", 18} +}; + +const std::string _true_ = "true", _false_ = "false"; + +bool cfg::isBlacklisted(const uint64_t& tid) +{ + for(uint64_t& bid : blacklist) + if(tid == bid) return true; + + return false; +} + +//Has to be threaded to be compatible with ui::confirm +void cfg::addTitleToBlacklist(void *a) +{ + threadInfo *t = (threadInfo *)a; + uint64_t tid = data::curData.saveID; + 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); + } + ui::ttlRefresh(); + t->finished = true; +} + +bool cfg::isFavorite(const uint64_t& tid) +{ + for(uint64_t& fid : favorites) + if(tid == fid) return true; + + return false; +} + +static int getFavoriteIndex(const uint64_t& tid) +{ + for(unsigned i = 0; i < favorites.size(); i++) + { + if(tid == favorites[i]) + return i; + } + return -1; +} + +void cfg::addTitleToFavorites(const uint64_t& tid) +{ + if(cfg::isFavorite(tid)) + { + int rem = getFavoriteIndex(tid); + favorites.erase(favorites.begin() + rem); + } + else + favorites.push_back(tid); + + data::sortUserTitles(); + ui::ttlRefresh(); +} + +bool cfg::isDefined(const uint64_t& tid) +{ + for(auto& def : pathDefs) + if(def.first == tid) return true; + + return false; +} + +void cfg::pathDefAdd(const uint64_t& tid, const std::string& newPath) +{ + std::string oldSafe = data::titles[tid].safeTitle; + std::string tmp = util::safeString(newPath); + if(!tmp.empty()) + { + pathDefs[tid] = tmp; + data::titles[tid].safeTitle = tmp; + + std::string oldOutput = fs::getWorkDir() + oldSafe; + std::string newOutput = fs::getWorkDir() + tmp; + rename(oldOutput.c_str(), newOutput.c_str()); + + ui::showPopMessage(POP_FRAME_DEFAULT, "'%s' changed to '%s'", oldSafe.c_str(), tmp.c_str()); + } + else + ui::showPopMessage(POP_FRAME_DEFAULT, "'%s' contains illegal or non-ASCII characters.", newPath.c_str()); +} + +std::string cfg::getPathDefinition(const uint64_t& tid) +{ + return pathDefs[tid]; +} + +void cfg::addPathToFilter(const uint64_t& tid, const std::string& _p) +{ + char outpath[128]; + sprintf(outpath, "sdmc:/config/JKSV/0x%016lX_filter.txt", tid); + FILE *filters = fopen(outpath, "a"); + fprintf(filters, "%s\n", _p.c_str()); + fclose(filters); +} + +void cfg::resetConfig() +{ + cfg::config["incDev"] = false; + cfg::config["autoBack"] = true; + cfg::config["ovrClk"] = false; + cfg::config["holdDel"] = true; + cfg::config["holdRest"] = true; + cfg::config["holdOver"] = true; + cfg::config["forceMount"] = true; + cfg::config["accSysSave"] = false; + cfg::config["sysSaveWrite"] = false; + cfg::config["directFsCmd"] = false; + cfg::config["zip"] = false; + cfg::config["langOverride"] = false; + cfg::config["trashBin"] = true; + cfg::sortType = cfg::ALPHA; + ui::animScale = 3.0f; +} + +static inline bool textToBool(const std::string& _txt) +{ + return _txt == _true_ ? true : false; +} + +static inline std::string boolToText(bool _b) +{ + return _b ? _true_ : _false_; +} + +static inline std::string sortTypeText() +{ + switch(cfg::sortType) + { + case cfg::ALPHA: + return "ALPHA"; + break; + + case cfg::MOST_PLAYED: + return "MOST_PLAYED"; + break; + + case cfg::LAST_PLAYED: + return "LAST_PLAYED"; + break; + } + return ""; +} + +void cfg::loadConfig() +{ + if(fs::fileExists(cfgPath)) + { + fs::dataFile cfgRead(cfgPath); + while(cfgRead.readNextLine(true)) + { + switch(cfgStrings[cfgRead.getName()]) + { + case 0: + fs::setWorkDir(cfgRead.getNextValueStr()); + break; + + case 1: + cfg::config["incDev"] = textToBool(cfgRead.getNextValueStr()); + break; + + case 2: + cfg::config["autoBack"] = textToBool(cfgRead.getNextValueStr()); + break; + + case 3: + cfg::config["ovrClk"] = textToBool(cfgRead.getNextValueStr()); + break; + + case 4: + cfg::config["holdDel"] = textToBool(cfgRead.getNextValueStr()); + break; + + case 5: + cfg::config["holdRest"] = textToBool(cfgRead.getNextValueStr()); + break; + + case 6: + cfg::config["holdOver"] = textToBool(cfgRead.getNextValueStr()); + break; + + case 7: + cfg::config["forceMount"] = textToBool(cfgRead.getNextValueStr()); + break; + + case 8: + cfg::config["accSysSave"] = textToBool(cfgRead.getNextValueStr()); + break; + + case 9: + cfg::config["sysSaveWrite"] = textToBool(cfgRead.getNextValueStr()); + break; + + case 10: + cfg::config["directFsCmd"] = textToBool(cfgRead.getNextValueStr()); + break; + + case 11: + cfg::config["zip"] = textToBool(cfgRead.getNextValueStr()); + break; + + case 12: + cfg::config["langOverride"] = textToBool(cfgRead.getNextValueStr()); + break; + + case 13: + cfg::config["trashBin"] = textToBool(cfgRead.getNextValueStr()); + break; + + case 14: + { + std::string getSort = cfgRead.getNextValueStr(); + if(getSort == "ALPHA") + cfg::sortType = cfg::ALPHA; + else if(getSort == "MOST_PLAYED") + cfg::sortType = cfg::MOST_PLAYED; + else + cfg::sortType = cfg::LAST_PLAYED; + } + break; + + case 15: + { + std::string animFloat = cfgRead.getNextValueStr(); + ui::animScale = strtof(animFloat.c_str(), NULL); + } + break; + + case 16: + { + std::string tid = cfgRead.getNextValueStr(); + favorites.push_back(strtoul(tid.c_str(), NULL, 16)); + } + break; + + case 17: + { + std::string tid = cfgRead.getNextValueStr(); + blacklist.push_back(strtoul(tid.c_str(), NULL, 16)); + } + break; + + case 18: + { + uint64_t tid = strtoul(cfgRead.getNextValueStr().c_str(), NULL, 16); + pathDefs[tid] = cfgRead.getNextValueStr(); + } + break; + } + } + } +} + +void cfg::saveConfig() +{ + FILE *cfgOut = fopen("sdmc:/config/JKSV/JKSV.cfg", "w"); + fprintf(cfgOut, "#JKSV config.\nworkDir = \"%s\"\n\n", fs::getWorkDir().c_str()); + fprintf(cfgOut, "includeDeviceSaves = %s\n", boolToText(cfg::config["incDev"]).c_str()); + fprintf(cfgOut, "autoBackup = %s\n", boolToText(cfg::config["autoBack"]).c_str()); + fprintf(cfgOut, "overclock = %s\n", boolToText(cfg::config["ovrClk"]).c_str()); + fprintf(cfgOut, "holdToDelete = %s\n", boolToText(cfg::config["holdDel"]).c_str()); + fprintf(cfgOut, "holdToRestore = %s\n", boolToText(cfg::config["holdRest"]).c_str()); + fprintf(cfgOut, "holdToOverwrite = %s\n", boolToText(cfg::config["autoOver"]).c_str()); + fprintf(cfgOut, "forceMount = %s\n", boolToText(cfg::config["forceMount"]).c_str()); + fprintf(cfgOut, "accountSystemSaves = %s\n", boolToText(cfg::config["accSysSaves"]).c_str()); + fprintf(cfgOut, "allowSystemSaveWrite = %s\n", boolToText(cfg::config["sysSaveWrite"]).c_str()); + fprintf(cfgOut, "directFSCommands = %s\n", boolToText(cfg::config["directFsCmd"]).c_str()); + fprintf(cfgOut, "exportToZIP = %s\n", boolToText(cfg::config["zip"]).c_str()); + fprintf(cfgOut, "languageOverride = %s\n", boolToText(cfg::config["langOverride"]).c_str()); + fprintf(cfgOut, "enableTrashBin = %s\n", boolToText(cfg::config["trashBin"]).c_str()); + fprintf(cfgOut, "titleSortType = %s\n", sortTypeText().c_str()); + fprintf(cfgOut, "animationScale = %f\n", ui::animScale); + + if(!favorites.empty()) + { + fprintf(cfgOut, "\n#favorites\n"); + for(uint64_t& f : favorites) + fprintf(cfgOut, "favorite = 0x%016lX\n", f); + } + + if(!blacklist.empty()) + { + fprintf(cfgOut, "\n#blacklist\n"); + for(uint64_t& b : blacklist) + fprintf(cfgOut, "blacklist = 0x%016lX\n", b); + } + + if(!pathDefs.empty()) + { + fprintf(cfgOut, "\n#Output Path Definitions\n"); + for(auto& p : pathDefs) + fprintf(cfgOut, "pathDef(0x%016lX, \"%s\")\n", p.first, p.second.c_str()); + } + fclose(cfgOut); +} diff --git a/src/data.cpp b/src/data.cpp index d48f033..eeddd47 100644 --- a/src/data.cpp +++ b/src/data.cpp @@ -11,6 +11,7 @@ #include "file.h" #include "util.h" #include "type.h" +#include "cfg.h" //FsSaveDataSpaceId_All doesn't work for SD static const unsigned saveOrder [] = { 0, 1, 2, 3, 4, 100, 101 }; @@ -23,17 +24,9 @@ std::vector data::users; //System language SetLanguage data::sysLang; -uint8_t data::sortType = 0; - //For other save types static bool sysBCATPushed = false, tempPushed = false; - -static std::vector blacklist; -static std::vector favorites; -static std::unordered_map pathDefs; std::unordered_map data::titles; -std::unordered_map data::config; - static SDL_Texture *iconMask; //Sorts titles by sortType @@ -42,11 +35,11 @@ static struct bool operator()(const data::userTitleInfo& a, const data::userTitleInfo& b) { //Favorites override EVERYTHING - if(data::isFavorite(a.saveID) != data::isFavorite(b.saveID)) return data::isFavorite(a.saveID); + if(cfg::isFavorite(a.saveID) != cfg::isFavorite(b.saveID)) return cfg::isFavorite(a.saveID); - switch(data::sortType) + switch(cfg::sortType) { - case 0://Alpha + case cfg::ALPHA: { std::string titleA = data::getTitleNameByTID(a.saveID); std::string titleB = data::getTitleNameByTID(b.saveID); @@ -65,11 +58,11 @@ static struct } break; - case 1://Most played + case cfg::MOST_PLAYED: return a.playStats.playtimeMinutes > b.playStats.playtimeMinutes; break; - case 2://Last Played + case cfg::LAST_PLAYED: return a.playStats.last_timestampUser > b.playStats.last_timestampUser; break; } @@ -87,33 +80,9 @@ static int getUserIndex(const AccountUid& id) return -1; } -static bool blacklisted(const uint64_t& tid) -{ - for(uint64_t& bid : blacklist) - if(tid == bid) return true; - - return false; -} - -bool data::isFavorite(const uint64_t& tid) -{ - for(uint64_t& fid : favorites) - if(tid == fid) return true; - - return false; -} - -static bool isDefined(const uint64_t& id) -{ - for(auto& def : pathDefs) - if(def.first == id) return true; - - return false; -} - static inline bool accountSystemSaveCheck(const FsSaveDataInfo& _inf) { - if(_inf.save_data_type == FsSaveDataType_System && util::accountUIDToU128(_inf.uid) != 0 && !data::config["accSysSave"]) + if(_inf.save_data_type == FsSaveDataType_System && util::accountUIDToU128(_inf.uid) != 0 && !cfg::config["accSysSave"]) return false; return true; @@ -123,7 +92,7 @@ static inline bool accountSystemSaveCheck(const FsSaveDataInfo& _inf) static bool testMount(const FsSaveDataInfo& _inf) { bool ret = false; - if(!data::config["forceMount"]) + if(!cfg::config["forceMount"]) return true; if((ret = fs::mountSave(_inf))) @@ -151,12 +120,12 @@ static inline void addTitleToList(const uint64_t& tid) nacpGetLanguageEntry(&data::titles[tid].nacp, &ent); data::titles[tid].title = ent->name; data::titles[tid].author = ent->author; - if(isDefined(tid)) - data::titles[tid].safeTitle = pathDefs[tid]; + if(cfg::isDefined(tid)) + data::titles[tid].safeTitle = cfg::getPathDefinition(tid); else if((data::titles[tid].safeTitle = util::safeString(ent->name)) == "") data::titles[tid].safeTitle = util::getIDStr(tid); - if(data::isFavorite(tid)) + if(cfg::isFavorite(tid)) data::titles[tid].fav = true; data::titles[tid].icon = gfx::loadJPEGMem(ctrlData->icon, iconSize); @@ -168,8 +137,8 @@ static inline void addTitleToList(const uint64_t& tid) memset(&data::titles[tid].nacp, 0, sizeof(NacpStruct)); data::titles[tid].title = util::getIDStr(tid); data::titles[tid].author = "Someone?"; - if(isDefined(tid)) - data::titles[tid].safeTitle = pathDefs[tid]; + if(cfg::isDefined(tid)) + data::titles[tid].safeTitle = cfg::getPathDefinition(tid); else data::titles[tid].safeTitle = util::getIDStr(tid); @@ -251,7 +220,7 @@ bool data::loadUsersTitles(bool clearUsers) saveID = info.application_id; //Don't bother with this stuff - if(blacklisted(saveID) || !accountSystemSaveCheck(info) || !testMount(info)) + if(cfg::isBlacklisted(saveID) || !accountSystemSaveCheck(info) || !testMount(info)) continue; switch(info.save_data_type) @@ -310,7 +279,7 @@ bool data::loadUsersTitles(bool clearUsers) fsSaveDataInfoReaderClose(&it); } - if(data::config["incDev"]) + if(cfg::config["incDev"]) { //Get reference to device save user unsigned devPos = getUserIndex(util::u128ToAccountUID(3)); @@ -323,21 +292,21 @@ bool data::loadUsersTitles(bool clearUsers) } } - for(data::user& u : data::users) - std::sort(u.titleInfo.begin(), u.titleInfo.end(), sortTitles); + data::sortUserTitles(); return true; } +void data::sortUserTitles() +{ + + for(data::user& u : data::users) + std::sort(u.titleInfo.begin(), u.titleInfo.end(), sortTitles); +} + void data::init() { - loadBlacklist(); - loadFav(); - data::restoreDefaultConfig(); - loadCfg(); - loadDefs(); - - if(data::config["ovrClk"]) + if(cfg::config["ovrClk"]) util::setCPU(1224000000); uint64_t lang; @@ -355,11 +324,8 @@ void data::exit() SDL_DestroyTexture(iconMask); - saveFav(); - saveCfg(); - saveBlackList(); - saveDefs(); - util::setCPU(1020000000); + if(cfg::config["ovrClk"]) + util::setCPU(1020000000); } data::titleInfo *data::getTitleInfoByTID(const uint64_t& tid) @@ -443,211 +409,6 @@ void data::user::addUserTitleInfo(const uint64_t& tid, const FsSaveDataInfo *_sa titleInfo.push_back(newInfo); } -void data::loadBlacklist() -{ - fs::dataFile blk(fs::getWorkDir() + "blacklist.txt"); - if(blk.isOpen()) - { - while(blk.readNextLine(false)) - blacklist.push_back(strtoul(blk.getLine().c_str(), NULL, 16)); - } -} - -void data::saveBlackList() -{ - if(!blacklist.empty()) - { - std::string blPath = fs::getWorkDir() + "blacklist.txt"; - FILE *bl = fopen(blPath.c_str(), "w"); - for(uint64_t id : blacklist) - fprintf(bl, "#%s\n0x%016lX\n", data::getTitleNameByTID(id).c_str(), id); - - fclose(bl); - } -} - -void data::blacklistAdd(void *a) -{ - threadInfo *t = (threadInfo *)a; - t->status->setStatus("Adding title to blacklist..."); - uint64_t *tid = (uint64_t *)t->argPtr; - 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); - } - ui::ttlRefresh(); - delete tid; - t->finished = true; -} - -void data::favoriteTitle(const uint64_t& tid) -{ - if(!isFavorite(tid)) - { - titles[tid].fav = true; - favorites.push_back(tid); - } - else - { - titles[tid].fav = false; - auto ind = std::find(favorites.begin(), favorites.end(), tid); - favorites.erase(ind); - } - - for(auto &u : data::users) - std::sort(u.titleInfo.begin(), u.titleInfo.end(), sortTitles); -} - -void data::pathDefAdd(const uint64_t& tid, const std::string& newPath) -{ - std::string oldSafe = titles[tid].safeTitle; - std::string tmp = util::safeString(newPath); - if(!tmp.empty()) - { - pathDefs[tid] = tmp; - titles[tid].safeTitle = tmp; - - std::string oldOutput = fs::getWorkDir() + oldSafe; - std::string newOutput = fs::getWorkDir() + tmp; - rename(oldOutput.c_str(), newOutput.c_str()); - - ui::showPopMessage(POP_FRAME_DEFAULT, "\"%s\" changed to \"%s\"", oldSafe.c_str(), tmp.c_str()); - } - else - ui::showPopMessage(POP_FRAME_DEFAULT, "\"%s\" contains illegal or non-ASCII characters.", newPath.c_str()); -} - -void data::loadCfg() -{ - std::string cfgPath = fs::getWorkDir() + "cfg.bin"; - if(fs::fileExists(cfgPath)) - { - FILE *cfg = fopen(cfgPath.c_str(), "rb"); - - uint64_t cfgIn = 0; - fread(&cfgIn, sizeof(uint64_t), 1, cfg); - fread(&data::sortType, 1, 1, cfg); - fread(&ui::animScale, sizeof(float), 1, cfg); - if(ui::animScale == 0) - ui::animScale = 3.0f; - fclose(cfg); - - data::config["incDev"] = cfgIn >> 63 & 1; - data::config["autoBack"] = cfgIn >> 62 & 1; - data::config["ovrClk"] = cfgIn >> 61 & 1; - data::config["holdDel"] = cfgIn >> 60 & 1; - data::config["holdRest"] = cfgIn >> 59 & 1; - data::config["holdOver"] = cfgIn >> 58 & 1; - data::config["forceMount"] = cfgIn >> 57 & 1; - data::config["accSysSave"] = cfgIn >> 56 & 1; - data::config["sysSaveWrite"] = cfgIn >> 55 & 1; - data::config["directFsCmd"] = cfgIn >> 53 & 1; - data::config["zip"] = cfgIn >> 51 & 1; - data::config["langOverride"] = cfgIn >> 50 & 1; - data::config["trashBin"] = cfgIn >> 49 & 1; - } -} - -void data::saveCfg() -{ - std::string cfgPath = fs::getWorkDir() + "cfg.bin"; - FILE *cfg = fopen(cfgPath.c_str(), "wb"); - - //Use 64bit int for space future stuff. Like this for readability. - uint64_t cfgOut = 0; - cfgOut |= (uint64_t)data::config["incDev"] << 63; - cfgOut |= (uint64_t)data::config["autoBack"] << 62; - cfgOut |= (uint64_t)data::config["ovrClk"] << 61; - cfgOut |= (uint64_t)data::config["holdDel"] << 60; - cfgOut |= (uint64_t)data::config["holdRest"] << 59; - cfgOut |= (uint64_t)data::config["holdOver"] << 58; - cfgOut |= (uint64_t)data::config["forceMount"] << 57; - cfgOut |= (uint64_t)data::config["accSysSave"] << 56; - cfgOut |= (uint64_t)data::config["sysSaveWrite"] << 55; - cfgOut |= (uint64_t)data::config["directFsCmd"] << 53; - cfgOut |= (uint64_t)data::config["zip"] << 51; - cfgOut |= (uint64_t)data::config["langOverride"] << 50; - cfgOut |= (uint64_t)data::config["trashBin"] << 49; - fwrite(&cfgOut, sizeof(uint64_t), 1, cfg); - fwrite(&data::sortType, 1, 1, cfg); - fwrite(&ui::animScale, sizeof(float), 1, cfg); - - fclose(cfg); -} - -void data::restoreDefaultConfig() -{ - data::config["incDev"] = false; - data::config["autoBack"] = true; - data::config["ovrClk"] = false; - data::config["holdDel"] = true; - data::config["holdRest"] = true; - data::config["holdOver"] = true; - data::config["forceMount"] = true; - data::config["accSysSave"] = false; - data::config["sysSaveWrite"] = false; - data::config["directFsCmd"] = false; - data::config["zip"] = false; - data::config["langOverride"] = false; - data::config["trashBin"] = true; - data::sortType = 0; - ui::animScale = 3.0f; -} - -void data::loadFav() -{ - fs::dataFile fav(fs::getWorkDir() + "favorites.txt"); - if(fav.isOpen()) - { - while(fav.readNextLine(false)) - favorites.push_back(strtoul(fav.getLine().c_str(), NULL, 16)); - } -} - -void data::saveFav() -{ - if(!favorites.empty()) - { - std::string favPath = fs::getWorkDir() + "favorites.txt"; - FILE *fav = fopen(favPath.c_str(), "w"); - for(uint64_t& fid : favorites) - fprintf(fav, "0x%016lX\n", fid); - - fclose(fav); - } -} - -void data::loadDefs() -{ - std::string defPath = fs::getWorkDir() + "titleDefs.txt"; - if(fs::fileExists(defPath)) - { - fs::dataFile def(defPath); - while(def.readNextLine(true)) - { - uint64_t id = strtoull(def.getName().c_str(), NULL, 16); - pathDefs[id] = def.getNextValueStr(); - } - } -} - -void data::saveDefs() -{ - if(!pathDefs.empty()) - { - std::string defPath = fs::getWorkDir() + "titleDefs.txt"; - FILE *ttlDef = fopen(defPath.c_str(), "w"); - for(auto& d : pathDefs) - { - std::string title = data::titles[d.first].title; - fprintf(ttlDef, "#%s\n0x%016lX = \"%s\";\n", title.c_str(), d.first, d.second.c_str()); - } - fclose(ttlDef); - } -} - static const SDL_Color green = {0x00, 0xDD, 0x00, 0xFF}; void data::dispStats() @@ -659,6 +420,6 @@ void data::dispStats() stats += "Current User: " + data::curUser.getUsername() + "\n"; stats += "Current Title: " + data::getTitleNameByTID(data::curData.saveID) + "\n"; stats += "Safe Title: " + data::getTitleSafeNameByTID(data::curData.saveID) + "\n"; - stats += "Sort Type: " + std::to_string(data::sortType) + "\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 06f229f..2cd2f00 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -12,8 +12,9 @@ #include "ui.h" #include "gfx.h" #include "data.h" +#include "cfg.h" -static std::string wd; +static std::string wd = "sdmc:/JKSV/"; static std::vector pathFilter; @@ -31,7 +32,6 @@ fs::copyArgs *fs::copyArgsCreate(const std::string& from, const std::string& to, ret->unz = unz; ret->cleanup = _cleanup; ret->prog = new ui::progBar; - ret->fileSize = 0.0f; ret->offset = 0.0f; return ret; } @@ -61,13 +61,21 @@ static struct } } sortDirList; -void fs::mkdirRec(const std::string& _p) +void fs::mkDir(const std::string& _p) +{ + if(cfg::config["directFsCmd"]) + fsMkDir(_p.c_str()); + else + mkdir(_p.c_str(), 777); +} + +void fs::mkDirRec(const std::string& _p) { //skip first slash size_t pos = _p.find('/', 0) + 1; while((pos = _p.find('/', pos)) != _p.npos) { - mkdir(_p.substr(0, pos).c_str(), 777); + fs::mkDir(_p.substr(0, pos).c_str()); ++pos; } } @@ -87,20 +95,8 @@ bool fs::commitToDevice(const std::string& dev) void fs::init() { - if(fs::fileExists("sdmc:/switch/jksv_dir.txt")) - { - char tmp[256]; - FILE *getDir = fopen("sdmc:/switch/jksv_dir.txt", "r"); - fgets(tmp, 256, getDir); - fclose(getDir); - wd = tmp; - util::stripChar('\n', wd); - util::stripChar('\r', wd); - } - else - wd = "sdmc:/JKSV/"; - - mkdirRec(wd); + mkDirRec("sdmc:/config/JKSV/"); + mkDirRec(wd); mkdir(std::string(wd + "_TRASH_").c_str(), 777); fs::logOpen(); @@ -280,14 +276,15 @@ bool fs::dataFile::readNextLine(bool proc) void fs::dataFile::procLine() { - size_t pPos = line.find_first_of('('), ePos = line.find_first_of('='); - if(pPos != line.npos || ePos != line.npos) + size_t pPos = line.find_first_of("(=,"); + if(pPos != line.npos) { - lPos = ePos < pPos ? ePos : pPos; + lPos = pPos; name.assign(line.begin(), line.begin() + lPos); } else - name = "NULL"; + name = line; + util::stripChar(' ', name); ++lPos; } @@ -326,48 +323,24 @@ int fs::dataFile::getNextValueInt() void fs::copyFile(const std::string& from, const std::string& to) { copyArgs *send = copyArgsCreate(from, to, "", NULL, NULL, false); - send->fileSize = fs::fsize(from); - send->prog->setMax(send->fileSize); - ui::newThread(copyfile_t, send, _fileDrawFunc); + ui::newThread(copyFile_t, send, _fileDrawFunc); } void fs::copyFileCommit(const std::string& from, const std::string& to, const std::string& dev) { copyArgs *send = copyArgsCreate(from, to, dev, NULL, NULL, false); - send->fileSize = fs::fsize(from); - send->prog->setMax(send->fileSize); ui::newThread(copyFileCommit_t, send, _fileDrawFunc); } void fs::copyDirToDir(const std::string& from, const std::string& to) { - dirList list(from); - - for(unsigned i = 0; i < list.getCount(); i++) - { - if(pathIsFiltered(from + list.getItem(i))) - continue; - - if(list.isDir(i)) - { - std::string newFrom = from + list.getItem(i) + "/"; - std::string newTo = to + list.getItem(i) + "/"; - mkdir(newTo.substr(0, newTo.length() - 1).c_str(), 0777); - - copyDirToDir(newFrom, newTo); - } - else - { - std::string fullFrom = from + list.getItem(i); - std::string fullTo = to + list.getItem(i); - copyFile(fullFrom, fullTo); - } - } + fs::copyArgs *send = fs::copyArgsCreate(from, to, "", NULL, NULL, true); + ui::newThread(fs::copyDirToDir_t, send, _fileDrawFunc); } void fs::copyDirToZip(const std::string& from, zipFile to) { - if(data::config["ovrClk"]) + if(cfg::config["ovrClk"]) { util::setCPU(1785000000); ui::showPopMessage(POP_FRAME_DEFAULT, "CPU Boost Enabled for ZIP."); @@ -378,7 +351,7 @@ void fs::copyDirToZip(const std::string& from, zipFile to) void fs::copyZipToDir(unzFile unz, const std::string& to, const std::string& dev) { - if(data::config["ovrClk"]) + if(cfg::config["ovrClk"]) { util::setCPU(1785000000); ui::showPopMessage(POP_FRAME_DEFAULT, "CPU Boost Enabled for ZIP."); @@ -400,31 +373,13 @@ bool fs::zipNotEmpty(unzFile unzip) void fs::copyDirToDirCommit(const std::string& from, const std::string& to, const std::string& dev) { - dirList list(from); - - for(unsigned i = 0; i < list.getCount(); i++) - { - if(list.isDir(i)) - { - std::string newFrom = from + list.getItem(i) + "/"; - std::string newTo = to + list.getItem(i); - mkdir(newTo.c_str(), 0777); - newTo += "/"; - - copyDirToDirCommit(newFrom, newTo, dev); - } - else - { - std::string fullFrom = from + list.getItem(i); - std::string fullTo = to + list.getItem(i); - copyFileCommit(fullFrom, fullTo, dev); - } - } + fs::copyArgs *send = copyArgsCreate(from, to, dev, NULL, NULL, true); + ui::newThread(copyDirToDirCommit_t, send, _fileDrawFunc); } void fs::delfile(const std::string& path) { - if(data::config["directFsCmd"]) + if(cfg::config["directFsCmd"]) fsremove(path.c_str()); else remove(path.c_str()); @@ -502,7 +457,7 @@ bool fs::dumpAllUserSaves(const data::user& u) { util::createTitleDirectoryByTID(u.titleInfo[i].saveID); std::string basePath = util::generatePathByTID(u.titleInfo[i].saveID); - switch(data::config["zip"]) + switch(cfg::config["zip"]) { case true: { @@ -589,14 +544,12 @@ void fs::getDirProps(const std::string& _path, uint32_t& dirCount, uint32_t& fil bool fs::fileExists(const std::string& path) { + bool ret = false; FILE *test = fopen(path.c_str(), "rb"); if(test != NULL) - { - fclose(test); - return true; - } - - return false; + ret = true; + fclose(test); + return ret; } size_t fs::fsize(const std::string& _f) @@ -614,6 +567,8 @@ size_t fs::fsize(const std::string& _f) std::string fs::getWorkDir() { return wd; } +void fs::setWorkDir(const std::string& _w){ wd = _w; } + bool fs::isDir(const std::string& _path) { struct stat s; @@ -654,7 +609,7 @@ void fs::createNewBackup(void *a) { std::string ext = util::getExtensionFromString(out); std::string path = util::generatePathByTID(data::curData.saveID) + out; - if(data::config["zip"] || ext == "zip") + if(cfg::config["zip"] || ext == "zip") { if(ext != "zip")//data::zip is on but extension is not zip path += ".zip"; @@ -711,15 +666,15 @@ void fs::restoreBackup(void *a) unsigned ind = m->getSelected() - 1; std::string itemName = d->getItem(ind); - if((data::curData.saveInfo.save_data_type != FsSaveDataType_System || data::config["sysSaveWrite"]) && m->getSelected() > 0) + if((data::curData.saveInfo.save_data_type != FsSaveDataType_System || cfg::config["sysSaveWrite"]) && m->getSelected() > 0) { - if(data::config["autoBack"] && data::config["zip"]) + if(cfg::config["autoBack"] && cfg::config["zip"]) { std::string autoZip = util::generatePathByTID(data::curData.saveID) + "/AUTO " + data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + ".zip"; zipFile zip = zipOpen64(autoZip.c_str(), 0); fs::copyDirToZip("sv:/", zip); } - else if(data::config["autoBack"]) + else if(cfg::config["autoBack"]) { std::string autoFolder = util::generatePathByTID(data::curData.saveID) + "/AUTO - " + data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + "/"; mkdir(autoFolder.substr(0, autoFolder.length() - 1).c_str(), 777); @@ -758,7 +713,7 @@ void fs::restoreBackup(void *a) } } - if(data::config["autoBack"]) + if(cfg::config["autoBack"]) ui::populateFldMenu(); t->finished = true; @@ -776,7 +731,7 @@ void fs::deleteBackup(void *a) std::string itemName = d->getItem(ind); t->status->setStatus("Deleting '" + itemName + "'..."); - if(data::config["trashBin"]) + if(cfg::config["trashBin"]) { std::string oldPath = util::generatePathByTID(data::curData.saveID) + itemName; std::string trashPath = wd + "_TRASH_/" + itemName; diff --git a/src/fsfile.c b/src/fsfile.c index 8a0d6bf..3c350ac 100644 --- a/src/fsfile.c +++ b/src/fsfile.c @@ -31,6 +31,17 @@ char *getFilePath(char *pathOut, size_t _max, const char *path) return pathOut; } +bool fsMkDir(const char *_p) +{ + char devStr[16]; + char path[FS_MAX_PATH]; + if(!getDeviceFromPath(devStr, 16, _p) || !getFilePath(path, FS_MAX_PATH, _p)) + return false; + + Result res = fsFsCreateDirectory(fsdevGetDeviceFileSystem(devStr), path); + return res == 0; +} + int fsremove(const char *_p) { char devStr[16]; diff --git a/src/fsthrd.cpp b/src/fsthrd.cpp index eb21570..81beec0 100644 --- a/src/fsthrd.cpp +++ b/src/fsthrd.cpp @@ -2,6 +2,7 @@ #include "file.h" #include "util.h" +#include "cfg.h" static uint64_t getJournalSize(const data::titleInfo *t) { @@ -34,7 +35,6 @@ static uint64_t getJournalSize(const data::titleInfo *t) return journalSize; } -//Todo: Weird flickering? void fs::_fileDrawFunc(void *a) { threadInfo *t = (threadInfo *)a; @@ -49,14 +49,17 @@ void fs::_fileDrawFunc(void *a) } } -void fs::copyfile_t(void *a) +void fs::copyFile_t(void *a) { threadInfo *t = (threadInfo *)a; copyArgs *args = (copyArgs *)t->argPtr; t->status->setStatus("Copying '" + args->from + "'..."); + args->prog->setMax(fs::fsize(args->from)); + args->prog->update(0); + uint8_t *buff = new uint8_t[BUFF_SIZE]; - if(data::config["directFsCmd"]) + if(cfg::config["directFsCmd"]) { FSFILE *in = fsfopen(args->from.c_str(), FsOpenMode_Read); FSFILE *out = fsfopen(args->to.c_str(), FsOpenMode_Write); @@ -105,7 +108,8 @@ void fs::copyfile_t(void *a) fclose(out); } delete[] buff; - copyArgsDestroy(args); + if(args->cleanup) + copyArgsDestroy(args); t->finished = true; } @@ -116,10 +120,13 @@ void fs::copyFileCommit_t(void *a) data::titleInfo *info = data::getTitleInfoByTID(data::curData.saveID); t->status->setStatus("Copying '" + args->from + "'..."); + args->prog->setMax(fs::fsize(args->from)); + args->prog->update(0); + uint64_t journalSize = getJournalSize(info), writeCount = 0; uint8_t *buff = new uint8_t[BUFF_SIZE]; - if(data::config["directFsCmd"]) + if(cfg::config["directFsCmd"]) { FSFILE *in = fsfopen(args->from.c_str(), FsOpenMode_Read); FSFILE *out = fsfopen(args->to.c_str(), FsOpenMode_Write); @@ -192,7 +199,115 @@ void fs::copyFileCommit_t(void *a) delete[] buff; commitToDevice(args->dev.c_str()); - copyArgsDestroy(args); + + if(args->cleanup) + copyArgsDestroy(args); + t->finished = true; +} + +void fs::copyDirToDir_t(void *a) +{ + threadInfo *t = (threadInfo *)a; + copyArgs *args = (copyArgs *)t->argPtr; + + fs::dirList *list = new fs::dirList(args->from); + for(int i = 0; i < (int)list->getCount(); i++) + { + if(pathIsFiltered(args->from + list->getItem(i))) + continue; + + if(list->isDir(i)) + { + std::string newSrc = args->from + list->getItem(i) + "/"; + std::string newDst = args->to + list->getItem(i) + "/"; + fs::mkDir(newDst.substr(0, newDst.length() - 1)); + + threadInfo fakeThread; + fs::copyArgs tmpArgs; + fakeThread.status = t->status; + fakeThread.argPtr = &tmpArgs; + tmpArgs.from = newSrc; + tmpArgs.to = newDst; + tmpArgs.prog = args->prog; + tmpArgs.cleanup = false; + fs::copyDirToDir_t(&fakeThread); + } + else + { + std::string fullSrc = args->from + list->getItem(i); + std::string fullDst = args->to + list->getItem(i); + + threadInfo fakeThread; + fs::copyArgs tmpArgs; + fakeThread.status = t->status; + fakeThread.argPtr = &tmpArgs; + tmpArgs.from = fullSrc; + tmpArgs.to = fullDst; + tmpArgs.prog = args->prog; + tmpArgs.cleanup = false; + fs::copyFile_t(&fakeThread); + } + } + + delete list; + + if(args->cleanup) + copyArgsDestroy(args); + + t->finished = true; +} + +void fs::copyDirToDirCommit_t(void *a) +{ + threadInfo *t = (threadInfo *)a; + copyArgs *args = (copyArgs *)t->argPtr; + + fs::dirList *list = new fs::dirList(args->from); + for(int i = 0; i < (int)list->getCount(); i++) + { + if(pathIsFiltered(args->from + list->getItem(i))) + continue; + + if(list->isDir(i)) + { + std::string newSrc = args->from + list->getItem(i) + "/"; + std::string newDst = args->to + list->getItem(i) + "/"; + fs::mkDir(newDst.substr(0, newDst.length() - 1)); + + threadInfo fakeThread; + fs::copyArgs tmpArgs; + fakeThread.status = t->status; + fakeThread.argPtr = &tmpArgs; + tmpArgs.from = newSrc; + tmpArgs.to = newDst; + tmpArgs.dev = args->dev; + tmpArgs.prog = args->prog; + tmpArgs.cleanup = false; + fs::copyDirToDirCommit_t(&fakeThread); + } + else + { + std::string fullSrc = args->from + list->getItem(i); + std::string fullDst = args->to + list->getItem(i); + + threadInfo fakeThread; + fs::copyArgs tmpArgs; + fakeThread.status = t->status; + fakeThread.argPtr = &tmpArgs; + tmpArgs.from = fullSrc; + tmpArgs.to = fullDst; + tmpArgs.dev = args->dev; + tmpArgs.prog = args->prog; + tmpArgs.cleanup = false; + fs::copyFileCommit_t(&fakeThread); + } + } + + delete list; + + if(args->cleanup) + copyArgsDestroy(args); + t->finished = true; } @@ -236,10 +351,9 @@ void fs::copyDirToZip_t(void *a) if(zOpenFile == ZIP_OK) { std::string fullFrom = args->from + itm; - args->offset = 0; - args->fileSize = fs::fsize(fullFrom); - args->prog->setMax(args->fileSize); + args->prog->setMax(fs::fsize(fullFrom)); args->prog->update(0); + args->offset = 0; FILE *cpy = fopen(fullFrom.c_str(), "rb"); size_t readIn = 0; uint8_t *buff = new uint8_t[BUFF_SIZE]; @@ -258,7 +372,7 @@ void fs::copyDirToZip_t(void *a) delete list; if(args->cleanup) { - if(data::config["ovrClk"]) + if(cfg::config["ovrClk"]) util::setCPU(1224000000); ui::newThread(closeZip_t, args->z, NULL); delete args->prog; @@ -285,13 +399,13 @@ void fs::copyZipToDir_t(void *a) { t->status->setStatus("Copying '" + std::string(filename) + "'..."); std::string path = args->to + filename; - mkdirRec(path.substr(0, path.find_last_of('/') + 1)); + mkDirRec(path.substr(0, path.find_last_of('/') + 1)); - args->fileSize = info.uncompressed_size; - args->offset = 0.0f; - args->prog->setMax(args->fileSize); + args->prog->setMax(info.uncompressed_size); + args->prog->update(0); + args->offset = 0; size_t done = 0; - if(data::config["directFsCmd"]) + if(cfg::config["directFsCmd"]) { FSFILE *out = fsfopen(path.c_str(), FsOpenMode_Write); while((readIn = unzReadCurrentFile(args->unz, buff, BUFF_SIZE)) > 0) @@ -346,7 +460,7 @@ void fs::copyZipToDir_t(void *a) { unzClose(args->unz); copyArgsDestroy(args); - if(data::config["ovrClk"]) + if(cfg::config["ovrClk"]) util::setCPU(1224000000); } delete[] buff; diff --git a/src/main.cpp b/src/main.cpp index 2d47e10..52e0664 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,6 +5,7 @@ #include "data.h" #include "ui.h" #include "util.h" +#include "cfg.h" extern "C" { @@ -38,6 +39,8 @@ extern "C" int main(int argc, const char *argv[]) { romfsInit(); + cfg::resetConfig(); + cfg::loadConfig(); fs::init(); gfx::init(); ui::initTheme(); @@ -48,6 +51,7 @@ int main(int argc, const char *argv[]) while(ui::runApp()){ } + cfg::saveConfig(); ui::exit(); data::exit(); gfx::exit(); diff --git a/src/ui/fm.cpp b/src/ui/fm.cpp index 735079c..425fe60 100644 --- a/src/ui/fm.cpp +++ b/src/ui/fm.cpp @@ -4,6 +4,7 @@ #include "file.h" #include "util.h" #include "fm.h" +#include "cfg.h" #include "type.h" //This is going to be a mess but the old one was too. @@ -246,7 +247,7 @@ static void _copyMenuCopy(void *a) dstPath = *devArgs->path + b->d->getItem(b->m->getSelected() - 2); } - if(ma == devArgs || (ma == sdmcArgs && (type != FsSaveDataType_System || data::config["sysSaveWrite"]))) + if(ma == devArgs || (ma == sdmcArgs && (type != FsSaveDataType_System || cfg::config["sysSaveWrite"]))) { ui::confirmArgs *send = ui::confirmArgsCreate(false, _copyMenuCopy_t, ma, true, ui::confCopy.c_str(), srcPath.c_str(), dstPath.c_str()); ui::confirm(send); @@ -318,9 +319,9 @@ static void _copyMenuDelete(void *a) else if(sel > 1) itmPath = *ma->path + b->d->getItem(sel - 2); - if(ma == sdmcArgs || (ma == devArgs && (sel == 0 || sel > 1) && (type != FsSaveDataType_System || data::config["sysSaveWrite"]))) + if(ma == sdmcArgs || (ma == devArgs && (sel == 0 || sel > 1) && (type != FsSaveDataType_System || cfg::config["sysSaveWrite"]))) { - ui::confirmArgs *send = ui::confirmArgsCreate(data::config["holdDel"], _copyMenuDelete_t, a, true, ui::confDel.c_str(), itmPath.c_str()); + ui::confirmArgs *send = ui::confirmArgsCreate(cfg::config["holdDel"], _copyMenuDelete_t, a, true, ui::confDel.c_str(), itmPath.c_str()); ui::confirm(send); } } @@ -381,6 +382,20 @@ static void _copyMenuClose(void *a) } } +static void _devMenuAddToPathFilter(void *a) +{ + menuFuncArgs *ma = (menuFuncArgs *)a; + fs::backupArgs *b = ma->b; + + int sel = b->m->getSelected(); + if(sel > 1) + { + std::string filterPath = *ma->path + b->d->getItem(sel - 2); + cfg::addPathToFilter(data::curData.saveID, filterPath); + ui::showPopMessage(POP_FRAME_DEFAULT, "'%s' added to path filter.", filterPath.c_str()); + } +} + void ui::fmInit() { //This needs to be done in a strange order so everything works @@ -397,18 +412,24 @@ void ui::fmInit() devMenu->setActive(true); devArgs->b->m = devMenu; - devPanel = new ui::slideOutPanel(260, 720, 0, ui::SLD_LEFT, _devCopyPanelDraw); - devCopyMenu = new ui::menu(10, 236, 246, 20, 5); + devPanel = new ui::slideOutPanel(288, 720, 0, ui::SLD_LEFT, _devCopyPanelDraw); + devCopyMenu = new ui::menu(10, 185, 268, 20, 5); devCopyMenu->setActive(false); devCopyMenu->setCallback(_devCopyMenuCallback, NULL); devCopyMenu->addOpt(NULL, ui::advMenuStr[0] + "SDMC"); - for(int i = 1; i < 6; i++) + for(int i = 1; i < 4; i++) devCopyMenu->addOpt(NULL, advMenuStr[i]); + //Manually do this so I can place the last option higher up + devCopyMenu->addOpt(NULL, advMenuStr[6]); + devCopyMenu->addOpt(NULL, advMenuStr[4]); + devCopyMenu->addOpt(NULL, advMenuStr[5]); + devCopyMenu->optAddButtonEvent(0, HidNpadButton_A, _copyMenuCopy, devArgs); devCopyMenu->optAddButtonEvent(1, HidNpadButton_A, _copyMenuDelete, devArgs); devCopyMenu->optAddButtonEvent(2, HidNpadButton_A, _copyMenuRename, devArgs); devCopyMenu->optAddButtonEvent(3, HidNpadButton_A, _copyMenuMkDir, devArgs); - devCopyMenu->optAddButtonEvent(5, HidNpadButton_A, _copyMenuClose, devArgs); + devCopyMenu->optAddButtonEvent(4, HidNpadButton_A, _devMenuAddToPathFilter, devArgs); + devCopyMenu->optAddButtonEvent(6, HidNpadButton_A, _copyMenuClose, devArgs); ui::registerPanel(devPanel); sdMenu = new ui::menu(620, 8, 590, 18, 5); @@ -416,8 +437,8 @@ void ui::fmInit() sdMenu->setActive(false); sdmcArgs->b->m = sdMenu; - sdPanel = new ui::slideOutPanel(260, 720, 0, ui::SLD_RIGHT, _sdCopyPanelDraw); - sdCopyMenu = new ui::menu(10, 236, 246, 20, 5); + sdPanel = new ui::slideOutPanel(288, 720, 0, ui::SLD_RIGHT, _sdCopyPanelDraw); + sdCopyMenu = new ui::menu(10, 210, 268, 20, 5); sdCopyMenu->setActive(false); sdCopyMenu->setCallback(_sdCopyMenuCallback, NULL); for(int i = 0; i < 6; i++) @@ -463,15 +484,11 @@ void ui::fmPrep(const FsSaveDataType& _type, const std::string& _dev, bool _comm sdList->reassign(sdPath); util::copyDirListToMenu(*devList, *devMenu); for(int i = 1; i < devMenu->getCount(); i++) - { devMenu->optAddButtonEvent(i, HidNpadButton_A, _listFunctionA, devArgs); - } util::copyDirListToMenu(*sdList, *sdMenu); for(int i = 1; i < sdMenu->getCount(); i++) - { sdMenu->optAddButtonEvent(i, HidNpadButton_A, _listFunctionA, sdmcArgs); - } } void ui::fmUpdate() diff --git a/src/ui/sett.cpp b/src/ui/sett.cpp index a4b8774..de7bea1 100644 --- a/src/ui/sett.cpp +++ b/src/ui/sett.cpp @@ -4,6 +4,7 @@ #include "ui.h" #include "file.h" #include "sett.h" +#include "cfg.h" #include "util.h" ui::menu *ui::settMenu; @@ -34,7 +35,7 @@ static void settMenuCallback(void *a) break; case HidNpadButton_X: - data::restoreDefaultConfig(); + cfg::resetConfig(); break; } } @@ -55,65 +56,77 @@ static void toggleOpt(void *a) break; case 2: - toggleBool(data::config["incDev"]); + { + std::string oldWD = fs::getWorkDir(); + std::string getWD = util::getStringInput(SwkbdType_QWERTY, fs::getWorkDir(), "Enter a new Output Path", 64, 0, NULL); + if(!getWD.empty()) + { + rename(oldWD.c_str(), getWD.c_str()); + fs::setWorkDir(getWD); + } + } break; case 3: - toggleBool(data::config["autoBack"]); + toggleBool(cfg::config["incDev"]); break; case 4: - toggleBool(data::config["ovrClk"]); + toggleBool(cfg::config["autoBack"]); break; case 5: - toggleBool(data::config["holdDel"]); + toggleBool(cfg::config["ovrClk"]); break; case 6: - toggleBool(data::config["holdRest"]); + toggleBool(cfg::config["holdDel"]); break; case 7: - toggleBool(data::config["holdOver"]); + toggleBool(cfg::config["holdRest"]); break; case 8: - toggleBool(data::config["forceMount"]); + toggleBool(cfg::config["holdOver"]); break; case 9: - toggleBool(data::config["accSysSave"]); + toggleBool(cfg::config["forceMount"]); break; case 10: - toggleBool(data::config["sysSaveWrite"]); + toggleBool(cfg::config["accSysSave"]); break; case 11: - toggleBool(data::config["directFsCmd"]); + toggleBool(cfg::config["sysSaveWrite"]); break; case 12: - toggleBool(data::config["zip"]); + toggleBool(cfg::config["directFsCmd"]); break; case 13: - toggleBool(data::config["langOverride"]); + toggleBool(cfg::config["zip"]); break; case 14: - toggleBool(data::config["trashBin"]); + toggleBool(cfg::config["langOverride"]); break; case 15: - if(++data::sortType > 2) - data::sortType = 0; + toggleBool(cfg::config["trashBin"]); + break; + + case 16: + if(++cfg::sortType > 2) + cfg::sortType = 0; data::loadUsersTitles(false); ui::ttlRefresh(); break; - case 16: + case 17: ui::animScale += 0.5f; if(ui::animScale > 8) ui::animScale = 1; @@ -123,24 +136,24 @@ static void toggleOpt(void *a) static void updateMenuText() { - ui::settMenu->editOpt(2, NULL, ui::optMenuStr[2] + getBoolText(data::config["incDev"])); - ui::settMenu->editOpt(3, NULL, ui::optMenuStr[3] + getBoolText(data::config["autoBack"])); - ui::settMenu->editOpt(4, NULL, ui::optMenuStr[4] + getBoolText(data::config["ovrClk"])); - ui::settMenu->editOpt(5, NULL, ui::optMenuStr[5] + getBoolText(data::config["holdDel"])); - ui::settMenu->editOpt(6, NULL, ui::optMenuStr[6] + getBoolText(data::config["holdRest"])); - ui::settMenu->editOpt(7, NULL, ui::optMenuStr[7] + getBoolText(data::config["holdOver"])); - ui::settMenu->editOpt(8, NULL, ui::optMenuStr[8] + getBoolText(data::config["forceMount"])); - ui::settMenu->editOpt(9, NULL, ui::optMenuStr[9] + getBoolText(data::config["accSysSave"])); - ui::settMenu->editOpt(10, NULL, ui::optMenuStr[10] + getBoolText(data::config["sysSaveWrite"])); - ui::settMenu->editOpt(11, NULL, ui::optMenuStr[11] + getBoolText(data::config["directFsCmd"])); - ui::settMenu->editOpt(12, NULL, ui::optMenuStr[12] + getBoolText(data::config["zip"])); - ui::settMenu->editOpt(13, NULL, ui::optMenuStr[13] + getBoolText(data::config["langOverride"])); - ui::settMenu->editOpt(14, NULL, ui::optMenuStr[14] + getBoolText(data::config["trashBin"])); - ui::settMenu->editOpt(15, NULL, ui::optMenuStr[15] + ui::sortString[data::sortType]); + ui::settMenu->editOpt(3, NULL, ui::optMenuStr[3] + getBoolText(cfg::config["incDev"])); + ui::settMenu->editOpt(4, NULL, ui::optMenuStr[4] + getBoolText(cfg::config["autoBack"])); + ui::settMenu->editOpt(5, NULL, ui::optMenuStr[5] + getBoolText(cfg::config["ovrClk"])); + ui::settMenu->editOpt(6, NULL, ui::optMenuStr[6] + getBoolText(cfg::config["holdDel"])); + ui::settMenu->editOpt(7, NULL, ui::optMenuStr[7] + getBoolText(cfg::config["holdRest"])); + ui::settMenu->editOpt(8, NULL, ui::optMenuStr[8] + getBoolText(cfg::config["holdOver"])); + ui::settMenu->editOpt(9, NULL, ui::optMenuStr[9] + getBoolText(cfg::config["forceMount"])); + ui::settMenu->editOpt(10, NULL, ui::optMenuStr[10] + getBoolText(cfg::config["accSysSave"])); + ui::settMenu->editOpt(11, NULL, ui::optMenuStr[11] + getBoolText(cfg::config["sysSaveWrite"])); + ui::settMenu->editOpt(12, NULL, ui::optMenuStr[12] + getBoolText(cfg::config["directFsCmd"])); + ui::settMenu->editOpt(13, NULL, ui::optMenuStr[13] + getBoolText(cfg::config["zip"])); + ui::settMenu->editOpt(14, NULL, ui::optMenuStr[14] + getBoolText(cfg::config["langOverride"])); + ui::settMenu->editOpt(15, NULL, ui::optMenuStr[15] + getBoolText(cfg::config["trashBin"])); + ui::settMenu->editOpt(16, NULL, ui::optMenuStr[16] + ui::sortString[cfg::sortType]); char tmp[16]; sprintf(tmp, "%.1f", ui::animScale); - ui::settMenu->editOpt(16, NULL, ui::optMenuStr[16] + std::string(tmp)); + ui::settMenu->editOpt(17, NULL, ui::optMenuStr[17] + std::string(tmp)); } void ui::settInit() @@ -151,7 +164,7 @@ void ui::settInit() optHelpX = 1220 - gfx::getTextWidth(ui::optHelp.c_str(), 18); - for(unsigned i = 0; i < 17; i++) + for(unsigned i = 0; i < 18; i++) { ui::settMenu->addOpt(NULL, ui::optMenuStr[i]); ui::settMenu->optAddButtonEvent(i, HidNpadButton_A, toggleOpt, NULL); diff --git a/src/ui/sldpanel.cpp b/src/ui/sldpanel.cpp index 32cd46d..33faaa0 100644 --- a/src/ui/sldpanel.cpp +++ b/src/ui/sldpanel.cpp @@ -68,7 +68,6 @@ void ui::slideOutPanel::draw(const SDL_Color *backCol) x += ceil(add); } - //don't waste time drawing if you can't even see it. if((sldSide == ui::SLD_LEFT && x > -w) || (sldSide == ui::SLD_RIGHT && x < 1280)) { (*drawFunc)(panel); diff --git a/src/ui/ttl.cpp b/src/ui/ttl.cpp index 553ffb9..cb0b118 100644 --- a/src/ui/ttl.cpp +++ b/src/ui/ttl.cpp @@ -4,6 +4,7 @@ #include "ttl.h" #include "file.h" #include "util.h" +#include "cfg.h" static int ttlHelpX = 0, fldHelpWidth = 0; static std::vector ttlViews; @@ -30,7 +31,7 @@ static void fldFuncOverwrite(void *a) int sel = m->getSelected() - 1;//Skip 'New' std::string itm = d->getItem(sel); - ui::confirmArgs *conf = ui::confirmArgsCreate(data::config["holdOver"], fs::overwriteBackup, a, true, ui::confOverwrite.c_str(), itm.c_str()); + ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdOver"], fs::overwriteBackup, a, true, ui::confOverwrite.c_str(), itm.c_str()); ui::confirm(conf); } @@ -43,7 +44,7 @@ static void fldFuncDelete(void *a) int sel = m->getSelected() - 1;//Skip 'New' std::string itm = d->getItem(sel); - ui::confirmArgs *conf = ui::confirmArgsCreate(data::config["holdDel"], fs::deleteBackup, a, true, ui::confDel.c_str(), itm.c_str()); + ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdDel"], fs::deleteBackup, a, true, ui::confDel.c_str(), itm.c_str()); ui::confirm(conf); } @@ -56,7 +57,7 @@ static void fldFuncRestore(void *a) int sel = m->getSelected() - 1;//Skip 'New' std::string itm = d->getItem(sel); - ui::confirmArgs *conf = ui::confirmArgsCreate(data::config["holdRest"], fs::restoreBackup, a, true, ui::confRestore.c_str(), itm.c_str()); + ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdRest"], fs::restoreBackup, a, true, ui::confRestore.c_str(), itm.c_str()); ui::confirm(conf); } @@ -68,7 +69,10 @@ void ui::populateFldMenu() std::string targetDir = util::generatePathByTID(data::curData.saveID); fldList->reassign(targetDir); - fs::loadPathFilters(targetDir + "pathFilters.txt"); + + char filterPath[128]; + sprintf(filterPath, "sdmc:/config/JKSV/0x%016lX_filter.txt", data::curData.saveID); + fs::loadPathFilters(filterPath); *backargs = {fldMenu, fldList}; @@ -83,7 +87,6 @@ void ui::populateFldMenu() fldMenu->optAddButtonEvent(i + 1, HidNpadButton_X, fldFuncDelete, backargs); fldMenu->optAddButtonEvent(i + 1, HidNpadButton_Y, fldFuncRestore, backargs); } - fldMenu->setActive(true); fldPanel->openPanel(); } @@ -114,7 +117,7 @@ static void ttlViewCallback(void *a) case HidNpadButton_Y: { uint64_t sid = data::curData.saveID; - data::favoriteTitle(sid); + cfg::addTitleToFavorites(sid); int newSel = data::getTitleIndexInUser(data::curUser, sid); ui::ttlRefresh(); ttlViews[data::selUser]->setSelected(newSel); @@ -152,10 +155,8 @@ static void ttlOptsShowInfoPanel(void *a) static void ttlOptsBlacklistTitle(void *a) { - uint64_t *sendTid = new uint64_t; - *sendTid = data::curData.saveID; std::string title = data::getTitleNameByTID(data::curData.saveID); - ui::confirmArgs *conf = ui::confirmArgsCreate(false, data::blacklistAdd, sendTid, true, ui::confBlacklist.c_str(), title.c_str()); + ui::confirmArgs *conf = ui::confirmArgsCreate(false, cfg::addTitleToBlacklist, NULL, true, ui::confBlacklist.c_str(), title.c_str()); ui::confirm(conf); } @@ -165,7 +166,7 @@ static void ttlOptsDefinePath(void *a) 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()) - data::pathDefAdd(tid, newSafeTitle); + cfg::pathDefAdd(tid, newSafeTitle); } static void ttlOptsToFileMode(void *a) @@ -198,7 +199,7 @@ static void ttlOptsResetSaveData(void *a) if(data::curData.saveInfo.save_data_type != FsSaveDataType_System) { std::string title = data::getTitleNameByTID(data::curData.saveID); - ui::confirmArgs *conf = ui::confirmArgsCreate(data::config["holdDel"], ttlOptsResetSaveData_t, NULL, true, ui::saveDataReset.c_str(), title.c_str()); + ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdDel"], ttlOptsResetSaveData_t, NULL, true, ui::saveDataReset.c_str(), title.c_str()); ui::confirm(conf); } } @@ -231,7 +232,7 @@ static void ttlOptsDeleteSaveData(void *a) if(data::curData.saveInfo.save_data_type != FsSaveDataType_System) { std::string title = data::getTitleNameByTID(data::curData.saveID); - ui::confirmArgs *conf = ui::confirmArgsCreate(data::config["holdDel"], ttlOptsDeleteSaveData_t, NULL, true, ui::confEraseNand.c_str(), title.c_str()); + ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdDel"], ttlOptsDeleteSaveData_t, NULL, true, ui::confEraseNand.c_str(), title.c_str()); ui::confirm(conf); } } @@ -329,6 +330,7 @@ static void fldMenuCallback(void *a) { case HidNpadButton_B: fs::unmountSave(); + fs::freePathFilters(); fldMenu->setActive(false); fldPanel->closePanel(); break; diff --git a/src/ui/ttlview.cpp b/src/ui/ttlview.cpp index 5e19d47..1fa75b3 100644 --- a/src/ui/ttlview.cpp +++ b/src/ui/ttlview.cpp @@ -1,5 +1,6 @@ #include "ui.h" #include "ui/ttlview.h" +#include "cfg.h" //Todo make less hardcoded void ui::titleTile::draw(SDL_Texture *target, int x, int y, bool sel) @@ -38,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, data::isFavorite(t.saveID), data::getTitleIconByTID(t.saveID))); + tiles.emplace_back(new ui::titleTile(_iconW, _iconH, cfg::isFavorite(t.saveID), data::getTitleIconByTID(t.saveID))); } ui::titleview::~titleview() @@ -54,7 +55,7 @@ void ui::titleview::refresh() tiles.clear(); for(const data::userTitleInfo& t : u->titleInfo) - tiles.emplace_back(new ui::titleTile(iconW, iconH, data::isFavorite(t.saveID), data::getTitleIconByTID(t.saveID))); + tiles.emplace_back(new ui::titleTile(iconW, iconH, cfg::isFavorite(t.saveID), data::getTitleIconByTID(t.saveID))); 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 56487e5..90782d9 100644 --- a/src/ui/uistr.cpp +++ b/src/ui/uistr.cpp @@ -2,6 +2,7 @@ #include #include "file.h" +#include "cfg.h" #include "uistr.h" //Map to associate external string names to unsigned ints for switch case. @@ -39,9 +40,9 @@ std::string ui::saveDataResetSuccess = "Save for %s reset!"; std::string ui::saveDataDeleteSuccess = "Save data for %s deleted!"; std::string ui::errorConnecting = "Error Connecting!"; std::string ui::noUpdate = "No updates available!"; -std::string ui::advMenuStr[6] = { "Copy to ", "Delete", "Rename", "Make Dir", "Properties", "Close" }; +std::string ui::advMenuStr[7] = { "Copy to ", "Delete", "Rename", "Make Dir", "Properties", "Close", "Add to Path Filter" }; std::string ui::exMenuStr[11] = { "SD to SD Browser", "BIS: PRODINFOF", "BIS: SAFE", "BIS: SYSTEM", "BIS: USER", "Remove Update", "Terminate Process", "Mount System Save", "Rescan Titles", "Mount Process RomFS", "Backup JKSV Folder" }; -std::string ui::optMenuStr[17] = { "Empty Trash Bin", "Check for Update", "Include Device Saves: ", "AutoBackup: ", "Overclock: ", "Hold to Delete: ", "Hold to Restore: ", "Hold to Overwrite: ", "Force Mount: ", "Account Sys. Saves: ", "Write to Sys. Saves: ", "Direct FS Cmd: ", "Export to ZIP: ", "Language Override: ", "Enable Trash Bin: ", "Sort: ", "Animation Scale: "}; +std::string ui::optMenuStr[18] = { "Empty Trash Bin", "Check for Update", "Set Output Folder", "Include Device Saves: ", "AutoBackup: ", "Overclock: ", "Hold to Delete: ", "Hold to Restore: ", "Hold to Overwrite: ", "Force Mount: ", "Account Sys. Saves: ", "Write to Sys. Saves: ", "Direct FS Cmd: ", "Export to ZIP: ", "Language Override: ", "Enable Trash Bin: ", "Sort: ", "Animation Scale: "}; std::string ui::holdingText[3] = { "(Hold) ", "(Keep Holding) ", "(Almost there!) " }; std::string ui::sortString[3] = { "Alphabetical", "Time Played", "Last Played" }; std::string ui::usrOptString[2] = { "Create Save Data", "Delete All User Saves" }; @@ -53,7 +54,7 @@ void ui::loadTrans() return; bool transFile = fs::fileExists(fs::getWorkDir() + "trans.txt"); - if(!transFile && (data::sysLang == SetLanguage_ENUS || data::config["langOverride"])) + if(!transFile && (data::sysLang == SetLanguage_ENUS || cfg::config["langOverride"])) return;//Don't bother loading from file. It serves as a translation guide std::string file; diff --git a/src/util.cpp b/src/util.cpp index 8531cfa..ed1251a 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -251,7 +251,7 @@ std::string util::getStringInput(SwkbdType _type, const std::string& def, const swkbdConfigSetInitialCursorPos(&swkbd, SwkbdPosEnd); swkbdConfigSetType(&swkbd, _type); swkbdConfigSetStringLenMax(&swkbd, maxLength); - swkbdConfigSetKeySetDisableBitmask(&swkbd, SwkbdKeyDisableBitmask_Backslash | SwkbdKeyDisableBitmask_ForwardSlash | SwkbdKeyDisableBitmask_Percent); + swkbdConfigSetKeySetDisableBitmask(&swkbd, SwkbdKeyDisableBitmask_Backslash | SwkbdKeyDisableBitmask_Percent); swkbdConfigSetDicFlag(&swkbd, 1); if(dictCnt > 0)