New config, restructure some stuff for stability and to fix issues

This commit is contained in:
J-D-K 2021-08-06 22:21:24 -04:00
parent 730f7ffbca
commit b74349f7c0
19 changed files with 677 additions and 459 deletions

33
inc/cfg.h Normal file
View File

@ -0,0 +1,33 @@
#pragma once
#include <string>
#include <unordered_map>
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<std::string, bool> config;
extern uint8_t sortType;
}

View File

@ -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<user> 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<std::string, bool> config;
extern uint8_t sortType;
}

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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

322
src/cfg.cpp Normal file
View File

@ -0,0 +1,322 @@
#include <switch.h>
#include <string>
#include <unordered_map>
#include "cfg.h"
#include "data.h"
#include "file.h"
#include "ui.h"
#include "util.h"
#include "type.h"
std::unordered_map<std::string, bool> cfg::config;
static std::vector<uint64_t> blacklist;
static std::vector<uint64_t> favorites;
static std::unordered_map<uint64_t, std::string> pathDefs;
uint8_t cfg::sortType;
const char *cfgPath = "sdmc:/config/JKSV/JKSV.cfg";
static std::unordered_map<std::string, unsigned> 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);
}

View File

@ -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::user> 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<uint64_t> blacklist;
static std::vector<uint64_t> favorites;
static std::unordered_map<uint64_t, std::string> pathDefs;
std::unordered_map<uint64_t, data::titleInfo> data::titles;
std::unordered_map<std::string, bool> 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());
}

View File

@ -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<std::string> 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;

View File

@ -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];

View File

@ -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;

View File

@ -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();

View File

@ -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()

View File

@ -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);

View File

@ -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);

View File

@ -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<ui::titleview *> 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;

View File

@ -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;

View File

@ -2,6 +2,7 @@
#include <unordered_map>
#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;

View File

@ -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)