Use Free Bird's CPU speed definitions, Fix ZIP headers, Mass Backup in user options

This commit is contained in:
J-D-K 2021-08-17 22:25:06 -04:00
parent 2b6f91e20f
commit 92e780d284
16 changed files with 277 additions and 186 deletions

View File

@ -38,7 +38,7 @@ INCLUDES := inc inc/ui
EXEFS_SRC := exefs_src
APP_TITLE := JKSV
APP_AUTHOR := JK
APP_VERSION := 08.16.2021
APP_VERSION := 08.17.2021
ROMFS := romfs
ICON := icon.jpg

View File

@ -8,7 +8,7 @@
#include "gfx.h"
#define BLD_MON 8
#define BLD_DAY 16
#define BLD_DAY 17
#define BLD_YEAR 2021
namespace data
@ -37,7 +37,7 @@ namespace data
typedef struct
{
//Makes it easier to grab id
uint64_t saveID;
uint64_t tid;
FsSaveDataInfo saveInfo;
PdmPlayStatistics playStats;
} userTitleInfo;
@ -99,14 +99,6 @@ namespace data
std::string getTitleNameByTID(const uint64_t& tid);
std::string getTitleSafeNameByTID(const uint64_t& tid);
SDL_Texture *getTitleIconByTID(const uint64_t& tid);
inline int getTitleIndexInUser(const data::user& u, const uint64_t& sid)
{
for(unsigned i = 0; i < u.titleInfo.size(); i++)
{
if(u.titleInfo[i].saveID == sid)
return i;
}
return -1;
}
int getTitleIndexInUser(const data::user *u, const uint64_t& tid);
extern SetLanguage sysLang;
}

View File

@ -52,14 +52,14 @@ namespace fs
void delDir(const std::string& path);
//Loads paths to filter from backup/deletion
void loadPathFilters(const std::string& _file);
void loadPathFilters(const uint64_t& tid);
bool pathIsFiltered(const std::string& _path);
void freePathFilters();
void wipeSave();
//Dumps all titles for 'user'. returns false to bail
bool dumpAllUserSaves(const data::user& u);
//Dumps all titles for current user
void dumpAllUserSaves();
//returns file properties as C++ string
std::string getFileProps(const std::string& _path);

View File

@ -15,4 +15,6 @@ namespace fs
void copyZipToDir_t(void *a);
void wipesave_t(void *a);
void closeZip_t(void *a);
void backupUserSaves_t(void *a);
}

View File

@ -18,62 +18,10 @@ namespace gfx
size_t getTextWidth(const char *str, int fontSize);
//Shortcuts for drawing
inline void texDraw(SDL_Texture *target, SDL_Texture *tex, int x, int y)
{
int tW = 0, tH = 0;
if(SDL_QueryTexture(tex, NULL, NULL, &tW, &tH) == 0)
{
SDL_SetRenderTarget(gfx::render, target);
SDL_Rect src = {0, 0, tW, tH};
SDL_Rect pos = {x, y, tW, tH};
SDL_RenderCopy(gfx::render, tex, &src, &pos);
}
}
inline void texDrawStretch(SDL_Texture *target, SDL_Texture *tex, int x, int y, int w, int h)
{
int tW = 0, tH = 0;
if(SDL_QueryTexture(tex, NULL, NULL, &tW, &tH) == 0)
{
SDL_SetRenderTarget(gfx::render, target);
SDL_Rect src = {0, 0, tW, tH};
SDL_Rect pos = {x, y, w, h};
SDL_RenderCopy(gfx::render, tex, &src, &pos);
}
}
inline void texDrawPart(SDL_Texture *target, SDL_Texture *tex, int srcX, int srcY, int srcW, int srcH, int dstX, int dstY)
{
SDL_Rect src = {srcX, srcY, srcW, srcH};
SDL_Rect dst = {dstX, dstY, srcW, srcH};
SDL_SetRenderTarget(gfx::render, target);
SDL_RenderCopy(gfx::render, tex, &src, &dst);
}
inline void drawLine(SDL_Texture *target, const SDL_Color *c, int x1, int y1, int x2, int y2)
{
SDL_SetRenderTarget(gfx::render, target);
SDL_SetRenderDrawColor(gfx::render, c->r, c->g, c->b, c->a);
SDL_RenderDrawLine(gfx::render, x1, y1, x2, y2);
}
inline void drawRect(SDL_Texture *target, const SDL_Color *c, int x, int y, int w, int h)
{
SDL_SetRenderTarget(gfx::render, target);
SDL_SetRenderDrawColor(gfx::render, c->r, c->g, c->b, c->a);
SDL_Rect rect = {x, y, w, h};
SDL_RenderFillRect(gfx::render, &rect);
}
inline void clearTarget(SDL_Texture *target, const SDL_Color *clear)
{
SDL_SetRenderTarget(gfx::render, target);
SDL_SetRenderDrawColor(gfx::render, clear->r, clear->g, clear->b, clear->a);
SDL_RenderClear(gfx::render);
}
inline void resetRender()
{
SDL_SetRenderDrawColor(gfx::render, 0xFF, 0xFF, 0xFF, 0xFF);
}
void texDraw(SDL_Texture *target, SDL_Texture *tex, int x, int y);
void texDrawStretch(SDL_Texture *target, SDL_Texture *tex, int x, int y, int w, int h);
void texDrawPart(SDL_Texture *target, SDL_Texture *tex, int srcX, int srcY, int srcW, int srcH, int dstX, int dstY);
void drawLine(SDL_Texture *target, const SDL_Color *c, int x1, int y1, int x2, int y2);
void drawRect(SDL_Texture *target, const SDL_Color *c, int x, int y, int w, int h);
void clearTarget(SDL_Texture *target, const SDL_Color *clear);
}

View File

@ -17,6 +17,26 @@ namespace util
DATE_FMT_ASC
};
typedef enum
{
cpu204MHz = 204000000,
cpu306MHz = 306000000,
cpu408MHz = 408000000,
cpu510MHz = 510000000,
cpu612MHz = 612000000,
cpu714MHz = 714000000,
cpu816MHz = 816000000,
cpu918MHz = 918000000,
cpu1020MHz = 1020000000, //Default
cpu1122MHz = 1122000000,
cpu1224MHz = 1224000000,
cpu1326MHz = 1326000000,
cpu1428MHz = 1428000000,
cpu1581MHz = 1581000000,
cpu1683MHz = 1683000000,
cpu1785MHz = 1785000000
} cpuSpds;
//Returns string with date S+ time
std::string getDateTime(int fmt);

View File

@ -38,12 +38,12 @@ void cfg::addTitleToBlacklist(void *a)
{
threadInfo *t = (threadInfo *)a;
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
uint64_t tid = d->saveID;
uint64_t tid = d->tid;
blacklist.push_back(tid);
for(data::user& u : data::users)
{
for(unsigned i = 0; i < u.titleInfo.size(); i++)
if(u.titleInfo[i].saveID == tid) u.titleInfo.erase(u.titleInfo.begin() + i);
if(u.titleInfo[i].tid == tid) u.titleInfo.erase(u.titleInfo.begin() + i);
}
ui::ttlRefresh();
t->finished = true;

View File

@ -35,14 +35,14 @@ static struct
bool operator()(const data::userTitleInfo& a, const data::userTitleInfo& b)
{
//Favorites override EVERYTHING
if(cfg::isFavorite(a.saveID) != cfg::isFavorite(b.saveID)) return cfg::isFavorite(a.saveID);
if(cfg::isFavorite(a.tid) != cfg::isFavorite(b.tid)) return cfg::isFavorite(a.tid);
switch(cfg::sortType)
{
case cfg::ALPHA:
{
std::string titleA = data::getTitleNameByTID(a.saveID);
std::string titleB = data::getTitleNameByTID(b.saveID);
std::string titleA = data::getTitleNameByTID(a.tid);
std::string titleB = data::getTitleNameByTID(b.tid);
uint32_t pointA, pointB;
for(unsigned i = 0, j = 0; i < titleA.length(); )
{
@ -213,14 +213,14 @@ bool data::loadUsersTitles(bool clearUsers)
while(R_SUCCEEDED(fsSaveDataInfoReaderRead(&it, &info, 1, &total)) && total != 0)
{
uint64_t saveID = 0;
uint64_t tid = 0;
if(info.save_data_type == FsSaveDataType_System || info.save_data_type == FsSaveDataType_SystemBcat)
saveID = info.system_save_data_id;
tid = info.system_save_data_id;
else
saveID = info.application_id;
tid = info.application_id;
//Don't bother with this stuff
if(cfg::isBlacklisted(saveID) || !accountSystemSaveCheck(info) || !testMount(info))
if(cfg::isBlacklisted(tid) || !accountSystemSaveCheck(info) || !testMount(info))
continue;
switch(info.save_data_type)
@ -258,8 +258,8 @@ bool data::loadUsersTitles(bool clearUsers)
break;
}
if(!titleIsLoaded(saveID))
addTitleToList(saveID);
if(!titleIsLoaded(tid))
addTitleToList(tid);
int u = getUserIndex(info.uid);
if(u == -1)
@ -274,7 +274,7 @@ bool data::loadUsersTitles(bool clearUsers)
else
memset(&playStats, 0, sizeof(PdmPlayStatistics));
users[u].addUserTitleInfo(saveID, &info, &playStats);
users[u].addUserTitleInfo(tid, &info, &playStats);
}
fsSaveDataInfoReaderClose(&it);
}
@ -307,7 +307,7 @@ void data::sortUserTitles()
void data::init()
{
if(cfg::config["ovrClk"])
util::setCPU(1224000000);
util::setCPU(util::cpu1224MHz);
uint64_t lang;
setGetSystemLanguage(&lang);
@ -325,7 +325,7 @@ void data::exit()
SDL_DestroyTexture(iconMask);
if(cfg::config["ovrClk"])
util::setCPU(1020000000);
util::setCPU(util::cpu1020MHz);
}
void data::setUserIndex(unsigned _sUser)
@ -380,6 +380,16 @@ SDL_Texture *data::getTitleIconByTID(const uint64_t& tid)
return titles[tid].icon;
}
int data::getTitleIndexInUser(const data::user *u, const uint64_t& tid)
{
for(unsigned i = 0; i < u->titleInfo.size(); i++)
{
if(u->titleInfo[i].tid == tid)
return i;
}
return -1;
}
data::user::user(const AccountUid& _id, const std::string& _backupName)
{
userID = _id;
@ -433,7 +443,7 @@ void data::user::setUID(const AccountUid& _id)
void data::user::addUserTitleInfo(const uint64_t& tid, const FsSaveDataInfo *_saveInfo, const PdmPlayStatistics *_stats)
{
data::userTitleInfo newInfo;
newInfo.saveID = tid;
newInfo.tid = tid;
memcpy(&newInfo.saveInfo, _saveInfo, sizeof(FsSaveDataInfo));
memcpy(&newInfo.playStats, _stats, sizeof(PdmPlayStatistics));
titleInfo.push_back(newInfo);
@ -451,8 +461,8 @@ void data::dispStats()
for(data::user& u : data::users)
stats += u.getUsername() + ": " + std::to_string(u.titleInfo.size()) + "\n";
stats += "Current User: " + cu->getUsername() + "\n";
stats += "Current Title: " + data::getTitleNameByTID(d->saveID) + "\n";
stats += "Safe Title: " + data::getTitleSafeNameByTID(d->saveID) + "\n";
stats += "Current Title: " + data::getTitleNameByTID(d->tid) + "\n";
stats += "Safe Title: " + data::getTitleSafeNameByTID(d->tid) + "\n";
stats += "Sort Type: " + std::to_string(cfg::sortType) + "\n";
gfx::drawTextf(NULL, 16, 2, 2, &green, stats.c_str());
}

View File

@ -32,7 +32,9 @@ fs::copyArgs *fs::copyArgsCreate(const std::string& from, const std::string& to,
ret->unz = unz;
ret->cleanup = _cleanup;
ret->prog = new ui::progBar;
ret->offset = 0.0f;
ret->prog->setMax(0);
ret->prog->update(0);
ret->offset = 0;
return ret;
}
@ -97,7 +99,7 @@ void fs::createSaveData(FsSaveDataType _type, uint64_t _tid, AccountUid _userID)
{
std::string indexStr;
uint16_t index = 0;
if(_type == FsSaveDataType_Cache && !(indexStr = util::getStringInput(SwkbdType_NumPad, "0", ui::getUIString("swkbdSaveIndex", 0), 3, 0, NULL)).empty())
if(_type == FsSaveDataType_Cache && !(indexStr = util::getStringInput(SwkbdType_NumPad, "0", ui::getUIString("swkbdSaveIndex", 0), 2, 0, NULL)).empty())
index = strtoul(indexStr.c_str(), NULL, 10);
svCreateArgs *send = new svCreateArgs;
@ -357,7 +359,7 @@ void fs::copyDirToZip(const std::string& from, zipFile to)
{
if(cfg::config["ovrClk"])
{
util::setCPU(1785000000);
util::setCPU(util::cpu1785MHz);
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popCPUBoostEnabled", 0));
}
copyArgs *send = copyArgsCreate(from, "", "", to, NULL, true);
@ -368,7 +370,7 @@ void fs::copyZipToDir(unzFile unz, const std::string& to, const std::string& dev
{
if(cfg::config["ovrClk"])
{
util::setCPU(1785000000);
util::setCPU(util::cpu1785MHz);
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popCPUBoostEnabled", 0));
}
copyArgs *send = copyArgsCreate("", to, dev, NULL, unz, true);
@ -425,11 +427,13 @@ void fs::delDir(const std::string& path)
rmdir(path.c_str());
}
void fs::loadPathFilters(const std::string& _file)
void fs::loadPathFilters(const uint64_t& tid)
{
if(fs::fileExists(_file))
char path[256];
sprintf(path, "sdmc:/config/JKSV/0x%016lX_filter.txt", tid);
if(fs::fileExists(path))
{
fs::dataFile filter(_file);
fs::dataFile filter(path);
while(filter.readNextLine(false))
pathFilter.push_back(filter.getLine());
}
@ -459,45 +463,11 @@ void fs::wipeSave()
ui::newThread(fs::wipesave_t, NULL, NULL);
}
bool fs::dumpAllUserSaves(const data::user& u)
void fs::dumpAllUserSaves()
{
for(unsigned i = 0; i < u.titleInfo.size(); i++)
{
ui::updateInput();
if(ui::padKeysDown() & HidNpadButton_B)
return false;
if(fs::mountSave(u.titleInfo[i].saveInfo))
{
util::createTitleDirectoryByTID(u.titleInfo[i].saveID);
std::string basePath = util::generatePathByTID(u.titleInfo[i].saveID);
switch(cfg::config["zip"])
{
case true:
{
std::string outPath = basePath + u.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + ".zip";
zipFile zip = zipOpen(outPath.c_str(), 0);
fs::copyDirToZip("sv:/", zip);
zipClose(zip, NULL);
}
break;
case false:
{
std::string outPath = basePath + u.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + "/";
mkdir(outPath.substr(0, outPath.length() - 1).c_str(), 777);
fs::copyDirToDir("sv:/", outPath);
}
break;
}
fsdevUnmountDevice("sv");
}
}
ui::updateInput();
return true;//?
//This is only really used for the progress bar
fs::copyArgs *send = fs::copyArgsCreate("", "", "", NULL, NULL, true);
ui::newThread(fs::backupUserSaves_t, send, _fileDrawFunc);
}
std::string fs::getFileProps(const std::string& _path)
@ -596,7 +566,7 @@ void fs::createNewBackup(void *a)
data::user *u = data::getCurrentUser();
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
data::titleInfo *t = data::getTitleInfoByTID(d->saveID);
data::titleInfo *t = data::getTitleInfoByTID(d->tid);
std::string out;
@ -617,7 +587,7 @@ void fs::createNewBackup(void *a)
util::getDateTime(util::DATE_FMT_ASC),
u->getUsernameSafe(),
t->safeTitle,
util::generateAbbrev(d->saveID),
util::generateAbbrev(d->tid),
".zip"
};
std::string defaultText = u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD);
@ -627,7 +597,7 @@ void fs::createNewBackup(void *a)
if(!out.empty())
{
std::string ext = util::getExtensionFromString(out);
std::string path = util::generatePathByTID(d->saveID) + out;
std::string path = util::generatePathByTID(d->tid) + out;
if(cfg::config["zip"] || ext == "zip")
{
if(ext != "zip")//data::zip is on but extension is not zip
@ -661,7 +631,7 @@ void fs::overwriteBackup(void *a)
std::string itemName = d->getItem(ind);
if(d->isDir(ind))
{
std::string toPath = util::generatePathByTID(cd->saveID) + itemName + "/";
std::string toPath = util::generatePathByTID(cd->tid) + itemName + "/";
//Delete and recreate
fs::delDir(toPath);
mkdir(toPath.c_str(), 777);
@ -669,7 +639,7 @@ void fs::overwriteBackup(void *a)
}
else if(!d->isDir(ind) && d->getItemExt(ind) == "zip")
{
std::string toPath = util::generatePathByTID(cd->saveID) + itemName;
std::string toPath = util::generatePathByTID(cd->tid) + itemName;
fs::delfile(toPath);
zipFile zip = zipOpen64(toPath.c_str(), 0);
fs::copyDirToZip("sv:/", zip);
@ -693,20 +663,20 @@ void fs::restoreBackup(void *a)
{
if(cfg::config["autoBack"] && cfg::config["zip"])
{
std::string autoZip = util::generatePathByTID(cd->saveID) + "/AUTO " + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + ".zip";
std::string autoZip = util::generatePathByTID(cd->tid) + "/AUTO " + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + ".zip";
zipFile zip = zipOpen64(autoZip.c_str(), 0);
fs::copyDirToZip("sv:/", zip);
}
else if(cfg::config["autoBack"])
{
std::string autoFolder = util::generatePathByTID(cd->saveID) + "/AUTO - " + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + "/";
std::string autoFolder = util::generatePathByTID(cd->tid) + "/AUTO - " + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + "/";
mkdir(autoFolder.substr(0, autoFolder.length() - 1).c_str(), 777);
fs::copyDirToDir("sv:/", autoFolder);
}
if(d->isDir(ind))
{
std::string fromPath = util::generatePathByTID(cd->saveID) + itemName + "/";
std::string fromPath = util::generatePathByTID(cd->tid) + itemName + "/";
if(fs::dirNotEmpty(fromPath))
{
fs::wipeSave();
@ -717,7 +687,7 @@ void fs::restoreBackup(void *a)
}
else if(!d->isDir(ind) && d->getItemExt(ind) == "zip")
{
std::string path = util::generatePathByTID(cd->saveID) + itemName;
std::string path = util::generatePathByTID(cd->tid) + itemName;
unzFile unz = unzOpen64(path.c_str());
if(unz && fs::zipNotEmpty(unz))
{
@ -730,7 +700,7 @@ void fs::restoreBackup(void *a)
else
{
//Just copy file over
std::string fromPath = util::generatePathByTID(cd->saveID) + itemName;
std::string fromPath = util::generatePathByTID(cd->tid) + itemName;
std::string toPath = "sv:/" + itemName;
fs::copyFileCommit(fromPath, toPath, "sv");
}
@ -756,20 +726,20 @@ void fs::deleteBackup(void *a)
t->status->setStatus("Deleting...");
if(cfg::config["trashBin"])
{
std::string oldPath = util::generatePathByTID(cd->saveID) + itemName;
std::string oldPath = util::generatePathByTID(cd->tid) + itemName;
std::string trashPath = wd + "_TRASH_/" + itemName;
rename(oldPath.c_str(), trashPath.c_str());
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("saveDataBackupMovedToTrash", 0), itemName.c_str());
}
else if(d->isDir(ind))
{
std::string delPath = util::generatePathByTID(cd->saveID) + itemName + "/";
std::string delPath = util::generatePathByTID(cd->tid) + itemName + "/";
fs::delDir(delPath);
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("saveDataBackupDeleted", 0), itemName.c_str());
}
else
{
std::string delPath = util::generatePathByTID(cd->saveID) + itemName;
std::string delPath = util::generatePathByTID(cd->tid) + itemName;
fs::delfile(delPath);
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("saveDataBackupDeleted", 0), itemName.c_str());
}

View File

@ -198,7 +198,7 @@ void fs::copyFileCommit_t(void *a)
threadInfo *t = (threadInfo *)a;
copyArgs *args = (copyArgs *)t->argPtr;
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
data::titleInfo *info = data::getTitleInfoByTID(d->saveID);
data::titleInfo *info = data::getTitleInfoByTID(d->tid);
t->status->setStatus(ui::getUICString("threadStatusCopyingFile", 0), args->from.c_str());
args->prog->setMax(fs::fsize(args->from));
@ -424,7 +424,13 @@ void fs::copyDirToZip_t(void *a)
}
else
{
zip_fileinfo inf = {0};
time_t raw;
time(&raw);
tm *locTime = localtime(&raw);
zip_fileinfo inf = { (unsigned)locTime->tm_sec, (unsigned)locTime->tm_min, (unsigned)locTime->tm_hour,
(unsigned)locTime->tm_mday, (unsigned)locTime->tm_mon, (unsigned)(1900 + locTime->tm_year), 0, 0, 0 };
std::string filename = args->from + itm;
size_t devPos = filename.find_first_of('/') + 1;
t->status->setStatus(ui::getUICString("threadStatusAddingFileToZip", 0), itm.c_str());
@ -454,7 +460,7 @@ void fs::copyDirToZip_t(void *a)
if(args->cleanup)
{
if(cfg::config["ovrClk"])
util::setCPU(1224000000);
util::setCPU(util::cpu1224MHz);
ui::newThread(closeZip_t, args->z, NULL);
delete args->prog;
delete args;
@ -468,7 +474,7 @@ void fs::copyZipToDir_t(void *a)
copyArgs *args = (copyArgs *)t->argPtr;
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
data::titleInfo *tinfo = data::getTitleInfoByTID(d->saveID);
data::titleInfo *tinfo = data::getTitleInfoByTID(d->tid);
uint64_t journalSize = getJournalSize(tinfo), writeCount = 0;
char filename[FS_MAX_PATH];
uint8_t *buff = new uint8_t[BUFF_SIZE];
@ -543,7 +549,7 @@ void fs::copyZipToDir_t(void *a)
unzClose(args->unz);
copyArgsDestroy(args);
if(cfg::config["ovrClk"])
util::setCPU(1224000000);
util::setCPU(util::cpu1224MHz);
}
delete[] buff;
t->finished = true;
@ -565,3 +571,70 @@ void fs::closeZip_t(void *a)
zipClose(z, NULL);
t->finished = true;
}
void fs::backupUserSaves_t(void *a)
{
threadInfo *t = (threadInfo *)a;
fs::copyArgs *c = (fs::copyArgs *)t->argPtr;
data::user *u = data::getCurrentUser();
if(cfg::config["ovrClk"] && cfg::config["zip"])
{
util::setCPU(util::cpu1785MHz);
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popCPUBoostEnabled", 0));
}
for(unsigned i = 0; i < u->titleInfo.size(); i++)
{
std::string title = data::getTitleNameByTID(u->titleInfo[i].tid);
t->status->setStatus(std::string("#" + title + "#").c_str());
if((ui::padKeysDown() & HidNpadButton_B) || (ui::padKeysHeld() & HidNpadButton_B))
{
delete c;
t->finished = true;
return;
}
bool saveMounted = fs::mountSave(u->titleInfo[i].saveInfo);
util::createTitleDirectoryByTID(u->titleInfo[i].tid);
if(saveMounted && cfg::config["zip"] && fs::dirNotEmpty("sv:/"))
{
fs::loadPathFilters(u->titleInfo[i].tid);
std::string outPath = util::generatePathByTID(u->titleInfo[i].tid) + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + ".zip";
zipFile zip = zipOpen64(outPath.c_str(), 0);
threadInfo fakeThread;
fs::copyArgs tmpArgs;
tmpArgs.from = "sv:/";
tmpArgs.z = zip;
tmpArgs.cleanup = false;
tmpArgs.prog = c->prog;
fakeThread.status = t->status;
fakeThread.argPtr = &tmpArgs;
copyDirToZip_t(&fakeThread);
zipClose(zip, NULL);
fs::freePathFilters();
}
else if(saveMounted && fs::dirNotEmpty("sv:/"))
{
fs::loadPathFilters(u->titleInfo[i].tid);
std::string outPath = util::generatePathByTID(u->titleInfo[i].tid) + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + "/";
fs::mkDir(outPath.substr(0, outPath.length() - 1));
threadInfo fakeThread;
fs::copyArgs tmpArgs;
tmpArgs.from = "sv:/";
tmpArgs.to = outPath;
tmpArgs.cleanup = false;
tmpArgs.prog = c->prog;
fakeThread.status = t->status;
fakeThread.argPtr = &tmpArgs;
copyDirToDir_t(&fakeThread);
fs::freePathFilters();
}
fs::unmountSave();
}
delete c;
if(cfg::config["ovrClk"] && cfg::config["zip"])
util::setCPU(util::cpu1224MHz);
t->finished = true;
}

View File

@ -412,3 +412,57 @@ size_t gfx::getTextWidth(const char *str, int fontSize)
}
return width;
}
void gfx::texDraw(SDL_Texture *target, SDL_Texture *tex, int x, int y)
{
int tW = 0, tH = 0;
if(SDL_QueryTexture(tex, NULL, NULL, &tW, &tH) == 0)
{
SDL_SetRenderTarget(gfx::render, target);
SDL_Rect src = {0, 0, tW, tH};
SDL_Rect pos = {x, y, tW, tH};
SDL_RenderCopy(gfx::render, tex, &src, &pos);
}
}
void gfx::texDrawStretch(SDL_Texture *target, SDL_Texture *tex, int x, int y, int w, int h)
{
int tW = 0, tH = 0;
if(SDL_QueryTexture(tex, NULL, NULL, &tW, &tH) == 0)
{
SDL_SetRenderTarget(gfx::render, target);
SDL_Rect src = {0, 0, tW, tH};
SDL_Rect pos = {x, y, w, h};
SDL_RenderCopy(gfx::render, tex, &src, &pos);
}
}
void gfx::texDrawPart(SDL_Texture *target, SDL_Texture *tex, int srcX, int srcY, int srcW, int srcH, int dstX, int dstY)
{
SDL_Rect src = {srcX, srcY, srcW, srcH};
SDL_Rect dst = {dstX, dstY, srcW, srcH};
SDL_SetRenderTarget(gfx::render, target);
SDL_RenderCopy(gfx::render, tex, &src, &dst);
}
void gfx::drawLine(SDL_Texture *target, const SDL_Color *c, int x1, int y1, int x2, int y2)
{
SDL_SetRenderTarget(gfx::render, target);
SDL_SetRenderDrawColor(gfx::render, c->r, c->g, c->b, c->a);
SDL_RenderDrawLine(gfx::render, x1, y1, x2, y2);
}
void gfx::drawRect(SDL_Texture *target, const SDL_Color *c, int x, int y, int w, int h)
{
SDL_SetRenderTarget(gfx::render, target);
SDL_SetRenderDrawColor(gfx::render, c->r, c->g, c->b, c->a);
SDL_Rect rect = {x, y, w, h};
SDL_RenderFillRect(gfx::render, &rect);
}
void gfx::clearTarget(SDL_Texture *target, const SDL_Color *clear)
{
SDL_SetRenderTarget(gfx::render, target);
SDL_SetRenderDrawColor(gfx::render, clear->r, clear->g, clear->b, clear->a);
SDL_RenderClear(gfx::render);
}

View File

@ -392,7 +392,7 @@ static void _devMenuAddToPathFilter(void *a)
{
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
std::string filterPath = *ma->path + b->d->getItem(sel - 2);
cfg::addPathToFilter(d->saveID, filterPath);
cfg::addPathToFilter(d->tid, filterPath);
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popAddedToPathFilter", 0), filterPath.c_str());
}
}

View File

@ -66,14 +66,14 @@ void ui::populateFldMenu()
fldMenu->reset();
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
util::createTitleDirectoryByTID(d->saveID);
std::string targetDir = util::generatePathByTID(d->saveID);
util::createTitleDirectoryByTID(d->tid);
std::string targetDir = util::generatePathByTID(d->tid);
fldList->reassign(targetDir);
char filterPath[128];
sprintf(filterPath, "sdmc:/config/JKSV/0x%016lX_filter.txt", d->saveID);
fs::loadPathFilters(filterPath);
sprintf(filterPath, "sdmc:/config/JKSV/0x%016lX_filter.txt", d->tid);
fs::loadPathFilters(d->tid);
*backargs = {fldMenu, fldList};
@ -113,7 +113,6 @@ static void ttlViewCallback(void *a)
break;
case HidNpadButton_X:
data::setTitleIndex(ttlViews[curUserIndex]->getSelected());
ttlViews[curUserIndex]->setActive(false, true);
ttlOpts->setActive(true);
ui::ttlOptsPanel->openPanel();
@ -121,9 +120,9 @@ static void ttlViewCallback(void *a)
case HidNpadButton_Y:
{
cfg::addTitleToFavorites(d->saveID);
int newSel = data::getTitleIndexInUser(*data::getCurrentUser(), d->saveID);
ui::ttlRefresh();
cfg::addTitleToFavorites(d->tid);
data::user *u = data::getCurrentUser();
int newSel = data::getTitleIndexInUser(u, d->tid);
ttlViews[curUserIndex]->setSelected(newSel);
}
break;
@ -156,20 +155,20 @@ static void ttlOptsShowInfoPanel(void *a)
{
ttlOpts->setActive(false);
ui::ttlOptsPanel->closePanel();
infoPanelString = util::getInfoString(*data::getCurrentUser(), data::getCurrentUserTitleInfo()->saveID);
infoPanelString = util::getInfoString(*data::getCurrentUser(), data::getCurrentUserTitleInfo()->tid);
infoPanel->openPanel();
}
static void ttlOptsBlacklistTitle(void *a)
{
std::string title = data::getTitleNameByTID(data::getCurrentUserTitleInfo()->saveID);
std::string title = data::getTitleNameByTID(data::getCurrentUserTitleInfo()->tid);
ui::confirmArgs *conf = ui::confirmArgsCreate(false, cfg::addTitleToBlacklist, NULL, true, ui::getUICString("confirmBlacklist", 0), title.c_str());
ui::confirm(conf);
}
static void ttlOptsDefinePath(void *a)
{
uint64_t tid = data::getCurrentUserTitleInfo()->saveID;
uint64_t tid = data::getCurrentUserTitleInfo()->tid;
std::string safeTitle = data::getTitleInfoByTID(tid)->safeTitle;
std::string newSafeTitle = util::getStringInput(SwkbdType_QWERTY, safeTitle, "Input New Output Folder", 0x200, 0, NULL);
if(!newSafeTitle.empty())
@ -192,7 +191,7 @@ static void ttlOptsResetSaveData_t(void *a)
{
threadInfo *t = (threadInfo *)a;
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
std::string title = data::getTitleNameByTID(d->saveID);
std::string title = data::getTitleNameByTID(d->tid);
t->status->setStatus(ui::getUICString("threadStatusResettingSaveData", 0), title.c_str());
fs::mountSave(d->saveInfo);
@ -208,7 +207,7 @@ static void ttlOptsResetSaveData(void *a)
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
if(d->saveInfo.save_data_type != FsSaveDataType_System)
{
std::string title = data::getTitleNameByTID(d->saveID);
std::string title = data::getTitleNameByTID(d->tid);
ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdDel"], ttlOptsResetSaveData_t, NULL, true, ui::getUICString("confirmResetSaveData", 0), title.c_str());
ui::confirm(conf);
}
@ -221,7 +220,7 @@ static void ttlOptsDeleteSaveData_t(void *a)
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
unsigned userIndex = data::getCurrentUserIndex();
std::string title = data::getTitleNameByTID(d->saveID);
std::string title = data::getTitleNameByTID(d->tid);
t->status->setStatus(ui::getUICString("threadStatusDeletingSaveData", 0), title.c_str());
if(R_SUCCEEDED(fsDeleteSaveDataFileSystemBySaveDataSpaceId((FsSaveDataSpaceId)d->saveInfo.save_data_space_id, d->saveInfo.save_data_id)))
{
@ -246,7 +245,7 @@ static void ttlOptsDeleteSaveData(void *a)
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
if(d->saveInfo.save_data_type != FsSaveDataType_System)
{
std::string title = data::getTitleNameByTID(d->saveID);
std::string title = data::getTitleNameByTID(d->tid);
ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdDel"], ttlOptsDeleteSaveData_t, NULL, true, ui::getUICString("confirmDeleteSaveData", 0), title.c_str());
ui::confirm(conf);
}
@ -261,7 +260,7 @@ static void ttlOptsExtendSaveData_t(void *a)
if(!expSizeStr.empty())
{
int64_t journ = 0, expSize;
data::titleInfo *extend = data::getTitleInfoByTID(d->saveID);
data::titleInfo *extend = data::getTitleInfoByTID(d->tid);
t->status->setStatus(ui::getUICString("threadStatusExtendingSaveData", 0), extend->title.c_str());
//Get journal size
switch(d->saveInfo.save_data_type)
@ -328,7 +327,7 @@ static void infoPanelDraw(void *a)
{
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
SDL_Texture *panel = (SDL_Texture *)a;
gfx::texDraw(panel, data::getTitleIconByTID(d->saveID), 77, 32);
gfx::texDraw(panel, data::getTitleIconByTID(d->tid), 77, 32);
gfx::drawTextfWrap(panel, 18, 32, 320, 362, &ui::txtCont, infoPanelString.c_str());
}

View File

@ -39,7 +39,7 @@ ui::titleview::titleview(const data::user& _u, int _iconW, int _iconH, int _horG
u = &_u;
for(const data::userTitleInfo& t : u->titleInfo)
tiles.emplace_back(new ui::titleTile(_iconW, _iconH, cfg::isFavorite(t.saveID), data::getTitleIconByTID(t.saveID)));
tiles.emplace_back(new ui::titleTile(_iconW, _iconH, cfg::isFavorite(t.tid), data::getTitleIconByTID(t.tid)));
}
ui::titleview::~titleview()
@ -55,7 +55,7 @@ void ui::titleview::refresh()
tiles.clear();
for(const data::userTitleInfo& t : u->titleInfo)
tiles.emplace_back(new ui::titleTile(iconW, iconH, cfg::isFavorite(t.saveID), data::getTitleIconByTID(t.saveID)));
tiles.emplace_back(new ui::titleTile(iconW, iconH, cfg::isFavorite(t.tid), data::getTitleIconByTID(t.tid)));
if(selected > (int)tiles.size() - 1 && selected > 0)
selected = tiles.size() - 1;

View File

@ -38,6 +38,7 @@ void ui::initStrings()
addUIString("confirmCopy", 0, "Are you sure you want to copy #%s# to #%s#?");
addUIString("confirmDeleteSaveData", 0, "*WARNING*: This *will* erase the save data for #%s# *from your system*. Are you sure you want to do this?");
addUIString("confirmResetSaveData", 0, "*WARNING*: This *will* reset the save data for this game as if it was never ran before. Are you sure you want to do this?");
addUIString("confirmCreateAllSaveData", 0, "Are you sure you would like to create all save data on this system for #%s#? This can take a while depending on how many titles are found.");
//Save Data related strings
addUIString("saveDataNoneFound", 0, "No saves found for #%s#!");
@ -104,18 +105,20 @@ void ui::initStrings()
addUIString("extrasMenu", 11, "*[DEV]* Output en-US");
//User Options
addUIString("userOptions", 0, "Create Save Data");
addUIString("userOptions", 1, "Create All Save Data");
addUIString("userOptions", 2, "Delete All User Saves");
addUIString("userOptions", 0, "Dump All For ");
addUIString("userOptions", 1, "Create Save Data");
addUIString("userOptions", 2, "Create All Save Data");
addUIString("userOptions", 3, "Delete All User Saves");
//Title Options
addUIString("titleOptions", 0, "Information");
addUIString("titleOptions", 1, "Blacklist");
addUIString("titleOptions", 2, "Change Output Folder");
addUIString("titleOptions", 3, "Open in File Mode");
addUIString("titleOptions", 4, "Reset Save Data");
addUIString("titleOptions", 5, "Delete Save Data");
addUIString("titleOptions", 6, "Extend Save Data");
addUIString("titleOptions", 3, "Export");
addUIString("titleOptions", 4, "Open in File Mode");
addUIString("titleOptions", 5, "Reset Save Data");
addUIString("titleOptions", 6, "Delete Save Data");
addUIString("titleOptions", 7, "Extend Save Data");
//Thread Status Strings
addUIString("threadStatusCreatingSaveData", 0, "Creating save data for #%s#...");

View File

@ -170,7 +170,7 @@ static void usrOptDeleteAllUserSaves_t(void *a)
{
if(tinf.saveInfo.save_data_type != FsSaveDataType_System && (tinf.saveInfo.save_data_type != FsSaveDataType_Device || curUserIndex == devUser))
{
t->status->setStatus(ui::getUICString("threadStatusDeletingSaveData", 0), data::getTitleNameByTID(tinf.saveID).c_str());
t->status->setStatus(ui::getUICString("threadStatusDeletingSaveData", 0), data::getTitleNameByTID(tinf.tid).c_str());
fsDeleteSaveDataFileSystemBySaveDataSpaceId(FsSaveDataSpaceId_User, tinf.saveInfo.save_data_id);
}
}
@ -216,6 +216,13 @@ static void cacheSavePanelDraw(void *a)
cacheSaveMenu->draw(panel, &ui::txtCont, true);
}
static void usrOptDumpAllUserSaves(void *a)
{
data::user *u = data::getCurrentUser();
if(u->titleInfo.size() > 0)
fs::dumpAllUserSaves();
}
static void createSaveData(void *a)
{
data::user *u = data::getCurrentUser();
@ -250,8 +257,9 @@ static void createSaveData(void *a)
}
}
static void usrOptCreateAllSaves(void *a)
static void usrOptCreateAllSaves_t(void *a)
{
threadInfo *t = (threadInfo *)a;
data::user *u = data::getCurrentUser();
int devPos = ui::usrMenu->getOptPos("Device");
int bcatPos = ui::usrMenu->getOptPos("BCAT");
@ -272,6 +280,14 @@ static void usrOptCreateAllSaves(void *a)
for(unsigned i = 0; i < bcatSids.size(); i++)
fs::createSaveData(FsSaveDataType_Bcat, bcatSids[i], util::u128ToAccountUID(0));
}
t->finished = true;
}
static void usrOptCreateAllSaves(void *a)
{
data::user *u = data::getCurrentUser();
ui::confirmArgs *send = ui::confirmArgsCreate(true, usrOptCreateAllSaves_t, NULL, true, ui::getUICString("confirmCreateAllSaveData", 0), u->getUsername().c_str());
ui::confirm(send);
}
//Sets up save create menus
@ -385,15 +401,17 @@ void ui::usrInit()
usrOptPanel = new ui::slideOutPanel(410, 720, 0, ui::SLD_RIGHT, usrOptPanelDraw);
ui::registerPanel(usrOptPanel);
for(int i = 0; i < 3; i++)
for(int i = 0; i < 4; i++)
usrOptMenu->addOpt(NULL, ui::getUIString("userOptions", i));
//Dump All User Saves
usrOptMenu->optAddButtonEvent(0, HidNpadButton_A, usrOptDumpAllUserSaves, NULL);
//Create Save Data
usrOptMenu->optAddButtonEvent(0, HidNpadButton_A, usrOptSaveCreate, usrMenu);
usrOptMenu->optAddButtonEvent(1, HidNpadButton_A, usrOptSaveCreate, usrMenu);
//Create All
usrOptMenu->optAddButtonEvent(1, HidNpadButton_A, usrOptCreateAllSaves, NULL);
usrOptMenu->optAddButtonEvent(2, HidNpadButton_A, usrOptCreateAllSaves, NULL);
//Delete All
usrOptMenu->optAddButtonEvent(2, HidNpadButton_A, usrOptDeleteAllUserSaves, NULL);
usrOptMenu->optAddButtonEvent(3, HidNpadButton_A, usrOptDeleteAllUserSaves, NULL);
usrOptMenu->setActive(false);
saveCreatePanel = new ui::slideOutPanel(512, 720, 0, ui::SLD_RIGHT, saveCreatePanelDraw);
@ -449,6 +467,8 @@ void ui::usrUpdate()
int cachePos = usrMenu->getOptPos("Cache");
if(usrMenu->getSelected() <= cachePos)
{
data::user *u = data::getCurrentUser();
usrOptMenu->editOpt(0, NULL, ui::getUIString("userOptions", 0) + u->getUsername());
usrOptMenu->setActive(true);
usrMenu->setActive(false);
usrOptPanel->openPanel();