Newer threading stuff, trash bin, extend/keyboard length fix

This commit is contained in:
J-D-K 2021-07-19 19:51:33 -04:00
parent d40cd33872
commit eaf6bed3de
17 changed files with 457 additions and 333 deletions

View File

@ -38,7 +38,7 @@ INCLUDES := inc
EXEFS_SRC := exefs_src
APP_TITLE := JKSV
APP_AUTHOR := JK
APP_VERSION := 07.15.2021
APP_VERSION := 07.18.2021
ROMFS := romfs
ICON := icon.jpg

View File

@ -11,7 +11,7 @@
#define curData users[data::selUser].titleInfo[data::selData]
#define BLD_MON 7
#define BLD_DAY 15
#define BLD_DAY 18
#define BLD_YEAR 2021
namespace data
@ -94,7 +94,6 @@ namespace data
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

View File

@ -20,7 +20,6 @@ namespace fs
//Mounts usr's save data for open. Returns false it fails
bool mountSave(const FsSaveDataInfo& _m);
inline bool unmountSave() { return fsdevUnmountDevice("sv") == 0; }
Result extendSaveDataFileSystem(FsSaveDataSpaceId _id, uint64_t _saveID, uint64_t _expSize, uint64_t _journal);
void copyFile(const std::string& from, const std::string& to);
void copyFileCommit(const std::string& from, const std::string& to, const std::string& dev);
@ -29,13 +28,13 @@ namespace fs
void copyDirToDir(const std::string& from, const std::string& to);
//Copies from to zipFile to
void copyDirToZip(const std::string& from, zipFile *to);
void copyDirToZip(const std::string& from, zipFile to);
//Same as above, but commits data to 'dev' after every file is closed
void copyDirToDirCommit(const std::string& from, const std::string& to, const std::string& dev);
//Copies unzfile to 'to'
void copyZipToDir(unzFile *unz, const std::string& to, const std::string& dev);
void copyZipToDir(unzFile unz, const std::string& to, const std::string& dev);
//deletes file
void delfile(const std::string& path);

View File

@ -205,6 +205,22 @@ namespace ui
std::vector<popMessage> message;
};
class threadProcMngr
{
public:
~threadProcMngr();
void newThread(ThreadFunc func, void *args);
void addThread(threadInfo *t);
void update();
void draw();
bool empty(){ return threads.empty(); }
private:
std::vector<threadInfo *> threads;
uint8_t lgFrame = 0;
unsigned frameCount = 0;
};
//General use
void showMessage(const char *head, const char *fmt, ...);
bool confirm(bool hold, const char *fmt, ...);

View File

@ -2,3 +2,10 @@
//Misc stuff for new menu code
typedef void (*funcPtr)(void *);
typedef struct
{
bool running = false, finished = false;
Thread *thrdPtr = NULL;
void *argPtr = NULL;
std::string status = "";
} threadInfo;

View File

@ -32,6 +32,9 @@ namespace ui
//Slide/animation scaling
extern float animScale;
//Loading glyph
extern const std::string loadGlyphArray[];
//pad data cause i don't know where else to put it
extern PadState pad;
extern HidTouchScreenState touchState;
@ -58,7 +61,7 @@ namespace ui
txtCont = text that contrasts clearClr
txtDiag = text color for dialogs
*/
extern SDL_Color clearClr, transparent, txtCont, txtDiag, rectLt, rectSh, tboxClr, sideRect, divClr, heartColor, slidePanelColor;
extern SDL_Color clearClr, transparent, txtCont, txtDiag, rectLt, rectSh, tboxClr, sideRect, divClr, heartColor, slidePanelColor, loadGlyphClr;
//Textbox graphics
extern SDL_Texture *cornerTopLeft, *cornerTopRight, *cornerBottomLeft, *cornerBottomRight;
@ -81,6 +84,7 @@ namespace ui
//Adds a panel pointer to a vector since they need to be drawn over everything else
int registerMenu(ui::menu *m);
int registerPanel(ui::slideOutPanel *sop);
int newThread(ThreadFunc func, void *args);
//Just draws a screen and flips JIC boot takes long.
void showLoadScreen();

View File

@ -16,7 +16,7 @@ namespace ui
//Strings for extras menu
extern std::string exMenuStr[11];
//Strings for options menu
extern std::string optMenuStr[14];
extern std::string optMenuStr[16];
//Strings for the holding thing
extern std::string holdingText[3];
//Strings for sort type

View File

@ -32,6 +32,15 @@ namespace util
std::string getStringInput(const std::string& def, const std::string& head, size_t maxLength, unsigned dictCnt, const std::string dictWords[]);
inline std::string getExtensionFromString(const std::string& get)
{
size_t ext = get.find_last_of('.');
if(ext != get.npos)
return get.substr(ext + 1, get.npos);
else
return "";
}
std::string generateAbbrev(const uint64_t& tid);
//removes char from C++ string

View File

@ -438,7 +438,7 @@ void data::user::addUserTitleInfo(const uint64_t& tid, const FsSaveDataInfo *_sa
newInfo.saveID = tid;
memcpy(&newInfo.saveInfo, _saveInfo, sizeof(FsSaveDataInfo));
memcpy(&newInfo.playStats, _stats, sizeof(PdmPlayStatistics));
titleInfo.emplace_back(newInfo);
titleInfo.push_back(newInfo);
}
void data::loadBlacklist()
@ -523,7 +523,7 @@ void data::loadCfg()
fread(&data::sortType, 1, 1, cfg);
fread(&ui::animScale, sizeof(float), 1, cfg);
if(ui::animScale == 0)
ui::animScale = 3.5f;
ui::animScale = 3.0f;
fclose(cfg);
data::config["incDev"] = cfgIn >> 63 & 1;
@ -538,6 +538,7 @@ void data::loadCfg()
data::config["directFsCmd"] = cfgIn >> 53 & 1;
data::config["zip"] = cfgIn >> 51 & 1;
data::config["langOverride"] = cfgIn >> 50 & 1;
data::config["trashBin"] = cfgIn >> 49 & 1;
}
}
@ -560,6 +561,7 @@ void data::saveCfg()
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);
@ -580,8 +582,10 @@ void data::restoreDefaultConfig()
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.5f;
ui::animScale = 3.0f;
}
void data::loadFav()

View File

@ -29,28 +29,21 @@ static FsFileSystem sv;
typedef struct
{
std::string to, from, dev;
uint64_t *offset;
zipFile *z;
zipFile z;
bool fin;
} copyArgs;
static copyArgs *copyArgsCreate(const std::string& from, const std::string& to, const std::string& dev, zipFile *z, uint64_t *offset)
static copyArgs *copyArgsCreate(const std::string& from, const std::string& to, const std::string& dev, zipFile z)
{
copyArgs *ret = new copyArgs;
ret->to = to;
ret->from = from;
ret->dev = dev;
ret->z = z;
ret->offset = offset;
ret->fin = false;
return ret;
}
static inline void copyArgsDestroy(copyArgs *args)
{
delete args;
}
static struct
{
bool operator()(const fs::dirItem& a, const fs::dirItem& b)
@ -104,13 +97,13 @@ void fs::init()
wd = tmp;
util::stripChar('\n', wd);
util::stripChar('\r', wd);
mkdirRec(wd);
}
else
{
mkdir("sdmc:/JKSV", 777);
wd = "sdmc:/JKSV/";
}
mkdirRec(wd);
mkdir(std::string(wd + "_TRASH_").c_str(), 777);
fs::logOpen();
}
@ -122,54 +115,69 @@ void fs::exit()
bool fs::mountSave(const FsSaveDataInfo& _m)
{
Result svOpen;
FsSaveDataAttribute attr = {0};
switch(_m.save_data_type)
{
case FsSaveDataType_System:
svOpen = fsOpen_SystemSaveData(&sv, FsSaveDataSpaceId_System, _m.save_data_id, _m.uid);
case FsSaveDataType_SystemBcat:
{
attr.uid = _m.uid;
attr.system_save_data_id = _m.system_save_data_id;
attr.save_data_type = _m.save_data_type;
svOpen = fsOpenSaveDataFileSystemBySystemSaveDataId(&sv, (FsSaveDataSpaceId)_m.save_data_space_id, &attr);
}
break;
case FsSaveDataType_Account:
svOpen = fsOpen_SaveData(&sv, _m.application_id, _m.uid);
break;
case FsSaveDataType_Bcat:
svOpen = fsOpen_BcatSaveData(&sv, _m.application_id);
{
attr.uid = _m.uid;
attr.application_id = _m.application_id;
attr.save_data_type = _m.save_data_type;
attr.save_data_rank = _m.save_data_rank;
attr.save_data_index = _m.save_data_index;
svOpen = fsOpenSaveDataFileSystem(&sv, (FsSaveDataSpaceId)_m.save_data_space_id, &attr);
}
break;
case FsSaveDataType_Device:
svOpen = fsOpen_DeviceSaveData(&sv, _m.application_id);
{
attr.application_id = _m.application_id;
attr.save_data_type = FsSaveDataType_Device;
svOpen = fsOpenSaveDataFileSystem(&sv, (FsSaveDataSpaceId)_m.save_data_space_id, &attr);
}
break;
case FsSaveDataType_Temporary:
svOpen = fsOpen_TemporaryStorage(&sv);
case FsSaveDataType_Bcat:
{
attr.application_id = _m.application_id;
attr.save_data_type = FsSaveDataType_Bcat;
svOpen = fsOpenSaveDataFileSystem(&sv, (FsSaveDataSpaceId)_m.save_data_space_id, &attr);
}
break;
case FsSaveDataType_Cache:
svOpen = fsOpen_CacheStorage(&sv, _m.application_id, _m.save_data_rank);
{
attr.application_id = _m.application_id;
attr.save_data_type = FsSaveDataType_Cache;
attr.save_data_index = _m.save_data_index;
svOpen = fsOpenSaveDataFileSystem(&sv, (FsSaveDataSpaceId)_m.save_data_space_id, &attr);
}
break;
case FsSaveDataType_SystemBcat:
svOpen = fsOpen_SystemBcatSaveData(&sv, _m.application_id);
case FsSaveDataType_Temporary:
{
attr.application_id = _m.application_id;
attr.save_data_type = _m.save_data_type;
svOpen = fsOpenSaveDataFileSystem(&sv, (FsSaveDataSpaceId)_m.save_data_space_id, &attr);
}
break;
default:
svOpen = 1;
break;
}
return R_SUCCEEDED(svOpen) && fsdevMountDevice("sv", sv) != -1;
}
Result fs::extendSaveDataFileSystem(FsSaveDataSpaceId _id, uint64_t _saveID, uint64_t _expSize, uint64_t _journal)
{
Service *fs = fsGetServiceSession();
struct
{
uint8_t id;
uint64_t saveID;
uint64_t expSize;
uint64_t journal;
} in = {(uint8_t)_id, _saveID, _expSize, _journal};
return serviceDispatchIn(fs, 32, in);
return R_SUCCEEDED(svOpen) && fsdevMountDevice("sv", sv) != -1;
}
fs::dirItem::dirItem(const std::string& pathTo, const std::string& sItem)
@ -193,10 +201,7 @@ std::string fs::dirItem::getName() const
std::string fs::dirItem::getExt() const
{
size_t extPos = itm.find_last_of('.');
if(extPos == itm.npos)
return "";//Folder or no extension
return itm.substr(extPos + 1, itm.npos);
return util::getExtensionFromString(itm);
}
fs::dirList::dirList(const std::string& _path)
@ -314,9 +319,19 @@ int fs::dataFile::getNextValueInt()
return ret;
}
static inline std::string fileStatusString(const std::string& itm, float complete, float total)
{
char tmp[512];
sprintf(tmp, "Copying \"%s\" : %.2f MB / %.2f MB", itm.c_str(), complete, total);
return std::string(tmp);
}
static void copyfile_t(void *a)
{
copyArgs *args = (copyArgs *)a;
threadInfo *t = (threadInfo *)a;
copyArgs *args = (copyArgs *)t->argPtr;
float srcSizeMB = (float)fs::fsize(args->from) / 1024.0f / 1024.0f;
uint8_t *buff = new uint8_t[BUFF_SIZE];
if(data::config["directFsCmd"])
@ -331,12 +346,11 @@ static void copyfile_t(void *a)
args->fin = true;
return;
}
size_t readIn = 0;
while((readIn = fsfread(buff, 1, BUFF_SIZE, in)) > 0)
{
fsfwrite(buff, 1, readIn, out);
*args->offset = in->offset;
t->status = fileStatusString(args->from, (float)in->offset / 1024.0f / 1024.0f, srcSizeMB);
}
fsfclose(in);
fsfclose(out);
@ -357,41 +371,29 @@ static void copyfile_t(void *a)
while((readIn = fread(buff, 1, BUFF_SIZE, in)) > 0)
{
fwrite(buff, 1, readIn, out);
*args->offset = ftell(in);
t->status = fileStatusString(args->from, (float)ftell(in) / 1024.0f / 1024.0f, srcSizeMB);
}
fclose(in);
fclose(out);
}
delete[] buff;
args->fin = true;
delete args;
t->finished = true;
}
void fs::copyFile(const std::string& from, const std::string& to)
{
uint64_t progress = 0;
copyArgs *send = copyArgsCreate(from, to, "", NULL, &progress);
//Setup progress bar. This thread updates screen, other handles copying
ui::progBar prog(fsize(from));
Thread cpyThread;
threadCreate(&cpyThread, copyfile_t, send, NULL, 0x4000, 0x2B, 1);
threadStart(&cpyThread);
while(!send->fin)
{
prog.update(progress);
prog.draw(from, ui::copyHead);
gfx::present();
}
threadClose(&cpyThread);
copyArgsDestroy(send);
copyArgs *send = copyArgsCreate(from, to, "", NULL);
ui::newThread(copyfile_t, send);
}
void copyFileCommit_t(void *a)
{
copyArgs *args = (copyArgs *)a;
threadInfo *t = (threadInfo *)a;
copyArgs *args = (copyArgs *)t->argPtr;
data::titleInfo *info = data::getTitleInfoByTID(data::curData.saveID);
float srcSizeMB = (float)fs::fsize(args->from) / 1024.0f / 1024.0f;
uint64_t journalSize = info->nacp.user_account_save_data_journal_size, writeCount = 0;
uint8_t *buff = new uint8_t[BUFF_SIZE];
@ -422,8 +424,7 @@ void copyFileCommit_t(void *a)
out = fsfopen(args->to.c_str(), FsOpenMode_Write | FsOpenMode_Append);
}
*args->offset = in->offset;
t->status = fileStatusString(args->from, (float)out->offset / 1024.0f / 1024.0f, srcSizeMB);
}
fsfclose(in);
fsfclose(out);
@ -455,8 +456,7 @@ void copyFileCommit_t(void *a)
out = fopen(args->to.c_str(), "ab");
}
*args->offset = ftell(in);
t->status = fileStatusString(args->from, (float)ftell(out) / 1024.0f / 1024.0f, srcSizeMB);
}
fclose(in);
fclose(out);
@ -464,27 +464,15 @@ void copyFileCommit_t(void *a)
delete[] buff;
commitToDevice(args->dev.c_str());
args->fin = true;
delete args;
t->finished = true;
}
void fs::copyFileCommit(const std::string& from, const std::string& to, const std::string& dev)
{
uint64_t offset = 0;
ui::progBar prog(fsize(from));
copyArgs *send = copyArgsCreate(from, to, dev, NULL, &offset);
Thread cpyThread;
threadCreate(&cpyThread, copyFileCommit_t, send, NULL, 0x4000, 0x2B, 1);
threadStart(&cpyThread);
while(!send->fin)
{
prog.update(offset);
prog.draw(from, ui::copyHead);
gfx::present();
}
threadClose(&cpyThread);
copyArgsDestroy(send);
copyArgs *send = copyArgsCreate(from, to, dev, NULL);
ui::newThread(copyFileCommit_t, send);
}
void fs::copyDirToDir(const std::string& from, const std::string& to)
@ -522,13 +510,11 @@ void copyFileToZip_t(void *a)
uint8_t *inBuff= new uint8_t[BUFF_SIZE];
while((readIn = fread(inBuff, 1, BUFF_SIZE, cpy)) > 0)
{
if(zipWriteInFileInZip(*args->z, inBuff, readIn) != 0)
if(zipWriteInFileInZip(args->z, inBuff, readIn) != 0)
{
fs::logWrite("Failed", "zipWriteInFileInZip -> \"%s\"\n", args->from.c_str());
break;
}
*args->offset = ftell(cpy);
}
delete[] inBuff;
@ -536,11 +522,11 @@ void copyFileToZip_t(void *a)
args->fin = true;
}
void copyFileToZip(const std::string& from, zipFile *z)
void copyFileToZip(const std::string& from, zipFile z)
{
ui::progBar prog(fs::fsize(from));
uint64_t progress = 0;
copyArgs *send = copyArgsCreate(from, "", "", z, &progress);
copyArgs *send = copyArgsCreate(from, "", "", z);
Thread cpyThread;
threadCreate(&cpyThread, copyFileToZip_t, send, NULL, 0x4000, 0x2B, 1);
@ -552,10 +538,10 @@ void copyFileToZip(const std::string& from, zipFile *z)
gfx::present();
}
threadClose(&cpyThread);
copyArgsDestroy(send);
free(send);
}
void fs::copyDirToZip(const std::string& from, zipFile *to)
void fs::copyDirToZip(const std::string& from, zipFile to)
{
fs::dirList list(from);
@ -574,14 +560,14 @@ void fs::copyDirToZip(const std::string& from, zipFile *to)
zip_fileinfo inf = { 0 };
std::string filename = from + list.getItem(i);
size_t devPos = filename.find_first_of('/') + 1;
if(zipOpenNewFileInZip(*to, filename.substr(devPos, filename.length()).c_str(), &inf, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION) == ZIP_OK)
if(zipOpenNewFileInZip(to, filename.substr(devPos, filename.length()).c_str(), &inf, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION) == ZIP_OK)
copyFileToZip(std::string(from) + list.getItem(i).c_str(), to);
zipCloseFileInZip(*to);
zipCloseFileInZip(to);
}
}
}
void fs::copyZipToDir(unzFile *unz, const std::string& to, const std::string& dev)
void fs::copyZipToDir(unzFile unz, const std::string& to, const std::string& dev)
{
data::titleInfo *tinfo = data::getTitleInfoByTID(data::curData.saveID);
@ -590,12 +576,12 @@ void fs::copyZipToDir(unzFile *unz, const std::string& to, const std::string& de
uint8_t *buff = new uint8_t[BUFF_SIZE];
int readIn = 0;
unz_file_info info;
if(unzGoToFirstFile(*unz) == UNZ_OK)
if(unzGoToFirstFile(unz) == UNZ_OK)
{
do
{
unzGetCurrentFileInfo(*unz, &info, filename, FS_MAX_PATH, NULL, 0, NULL, 0);
if(unzOpenCurrentFile(*unz) == UNZ_OK)
unzGetCurrentFileInfo(unz, &info, filename, FS_MAX_PATH, NULL, 0, NULL, 0);
if(unzOpenCurrentFile(unz) == UNZ_OK)
{
std::string path = to + filename;
mkdirRec(path.substr(0, path.find_last_of('/') + 1));
@ -604,7 +590,7 @@ void fs::copyZipToDir(unzFile *unz, const std::string& to, const std::string& de
if(data::config["directFsCmd"])
{
FSFILE *out = fsfopen(path.c_str(), FsOpenMode_Write);
while((readIn = unzReadCurrentFile(*unz, buff, BUFF_SIZE)) > 0)
while((readIn = unzReadCurrentFile(unz, buff, BUFF_SIZE)) > 0)
{
done += readIn;
writeCount += readIn;
@ -630,7 +616,7 @@ void fs::copyZipToDir(unzFile *unz, const std::string& to, const std::string& de
{
FILE *out = fopen(path.c_str(), "wb");
while((readIn = unzReadCurrentFile(*unz, buff, BUFF_SIZE)) > 0)
while((readIn = unzReadCurrentFile(unz, buff, BUFF_SIZE)) > 0)
{
done += readIn;
writeCount += readIn;
@ -652,11 +638,11 @@ void fs::copyZipToDir(unzFile *unz, const std::string& to, const std::string& de
}
fclose(out);
}
unzCloseCurrentFile(*unz);
unzCloseCurrentFile(unz);
commitToDevice(dev.c_str());
}
}
while(unzGoToNextFile(*unz) != UNZ_END_OF_LIST_OF_FILE);
while(unzGoToNextFile(unz) != UNZ_END_OF_LIST_OF_FILE);
}
else
ui::showPopMessage(POP_FRAME_DEFAULT, "ZIP file is empty!");
@ -769,7 +755,7 @@ bool fs::dumpAllUserSaves(const data::user& u)
{
std::string outPath = basePath + u.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + ".zip";
zipFile zip = zipOpen(outPath.c_str(), 0);
fs::copyDirToZip("sv:/", &zip);
fs::copyDirToZip("sv:/", zip);
zipClose(zip, NULL);
}
break;
@ -904,32 +890,31 @@ void fs::createNewBackup(void *a)
util::getDateTime(util::DATE_FMT_ASC),
data::users[data::selUser].getUsernameSafe(),
data::getTitleInfoByTID(data::curData.saveID)->safeTitle,
util::generateAbbrev(data::curData.saveID)
util::generateAbbrev(data::curData.saveID),
".zip"
};
out = util::getStringInput("", "Enter a name", 64, 8, dict);
out = util::getStringInput("", "Enter a name", 64, 9, dict);
}
if(!out.empty())
{
std::string ext = util::getExtensionFromString(out);
std::string path = util::generatePathByTID(data::curData.saveID) + out;
switch(data::config["zip"])
if(data::config["zip"] || ext == "zip")
{
case true:
{
path += ".zip";
zipFile zip = zipOpen(path.c_str(), 0);
fs::copyDirToZip("sv:/", &zip);
zipClose(zip, NULL);
}
break;
if(ext != "zip")//data::zip is on but extension is not zip
path += ".zip";
case false:
{
mkdir(path.c_str(), 777);
path += "/";
fs::copyDirToDir("sv:/", path);
}
break;
zipFile zip = zipOpen(path.c_str(), 0);
fs::copyDirToZip("sv:/", zip);
zipClose(zip, NULL);
}
else
{
mkdir(path.c_str(), 777);
path += "/";
fs::copyDirToDir("sv:/", path);
}
ui::populateFldMenu();
}
@ -959,7 +944,7 @@ void fs::overwriteBackup(void *a)
std::string toPath = util::generatePathByTID(data::curData.saveID) + itemName;
fs::delfile(toPath);
zipFile zip = zipOpen(toPath.c_str(), 0);
fs::copyDirToZip("sv:/", &zip);
fs::copyDirToZip("sv:/", zip);
zipClose(zip, NULL);
}
}
@ -977,27 +962,18 @@ void fs::restoreBackup(void *a)
std::string itemName = d->getItem(ind);
if((data::curData.saveInfo.save_data_type != FsSaveDataType_System || data::config["sysSaveWrite"]) && m->getSelected() > 0 && ui::confirm(data::config["holdRest"], ui::confRestore.c_str(), itemName.c_str()))
{
if(data::config["autoBack"])
if(data::config["autoBack"] && data::config["zip"])
{
switch(data::config["zip"])
{
case true:
{
std::string autoZip = util::generatePathByTID(data::curData.saveID) + "/AUTO " + data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + ".zip";
zipFile zip = zipOpen(autoZip.c_str(), 0);
fs::copyDirToZip("sv:/", &zip);
zipClose(zip, NULL);
}
break;
case false:
{
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);
fs::copyDirToDir("sv:/", autoFolder);
}
break;
}
std::string autoZip = util::generatePathByTID(data::curData.saveID) + "/AUTO " + data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + ".zip";
zipFile zip = zipOpen(autoZip.c_str(), 0);
fs::copyDirToZip("sv:/", zip);
zipClose(zip, NULL);
}
else if(data::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);
fs::copyDirToDir("sv:/", autoFolder);
}
if(d->isDir(ind))
@ -1011,7 +987,7 @@ void fs::restoreBackup(void *a)
fs::wipeSave();
std::string path = util::generatePathByTID(data::curData.saveID) + itemName;
unzFile unz = unzOpen(path.c_str());
fs::copyZipToDir(&unz, "sv:/", "sv");
fs::copyZipToDir(unz, "sv:/", "sv");
unzClose(unz);
}
else
@ -1038,15 +1014,24 @@ void fs::deleteBackup(void *a)
std::string itemName = d->getItem(ind);
if(ui::confirmDelete(itemName))
{
if(d->isDir(ind))
if(data::config["trashBin"])
{
std::string oldPath = util::generatePathByTID(data::curData.saveID) + itemName;
std::string trashPath = wd + "_TRASH_/" + itemName;
rename(oldPath.c_str(), trashPath.c_str());
ui::showPopMessage(POP_FRAME_DEFAULT, "%s moved to trash.", itemName.c_str());
}
else if(d->isDir(ind))
{
std::string delPath = util::generatePathByTID(data::curData.saveID) + itemName + "/";
fs::delDir(delPath);
ui::showPopMessage(POP_FRAME_DEFAULT, "%s has been deleted.", itemName.c_str());
}
else
{
std::string delPath = util::generatePathByTID(data::curData.saveID) + itemName;
fs::delfile(delPath);
ui::showPopMessage(POP_FRAME_DEFAULT, "%s has been deleted.", itemName.c_str());
}
ui::populateFldMenu();
}

View File

@ -14,7 +14,7 @@
//Current menu state
int ui::mstate = USR_SEL, ui::prevState = USR_SEL;
float ui::animScale = 3.5f;
float ui::animScale = 3.0f;
//pad data?
PadState ui::pad;
@ -28,7 +28,7 @@ std::string ui::folderMenuInfo;
//UI colors
SDL_Color ui::clearClr, ui::txtCont, ui::txtDiag, ui::rectLt, ui::rectSh, ui::tboxClr, ui::divClr, ui::slidePanelColor;
SDL_Color ui::transparent = {0x00, 0x00, 0x00, 0x00};
SDL_Color ui::transparent = {0x00, 0x00, 0x00, 0x00}, ui::loadGlyphClr = {0x00, 0xFF, 0xC5, 0xFF};
//textbox pieces
//I was going to flip them when I draw them, but then laziness kicked in.
@ -52,9 +52,16 @@ static int settPos, extPos;
//Vector of pointers to slideOutPanels. Is looped and drawn last so they are always on top
std::vector<ui::slideOutPanel *> panels;
static unsigned int panelCount = 0;
static ui::popMessageMngr *popMessages;
static ui::threadProcMngr *threadMngr;
//8
const std::string ui::loadGlyphArray[] =
{
"\ue020", "\ue021", "\ue022", "\ue023",
"\ue024", "\ue025", "\ue026", "\ue027"
};
void ui::initTheme()
{
@ -158,6 +165,7 @@ void ui::init()
ui::settInit();
popMessages = new ui::popMessageMngr;
threadMngr = new ui::threadProcMngr;
//Need these from user/main menu
settPos = ui::usrMenu->getOptPos("Settings");
@ -171,6 +179,7 @@ void ui::exit()
ui::settExit();
delete popMessages;
delete threadMngr;
SDL_DestroyTexture(cornerTopLeft);
SDL_DestroyTexture(cornerTopRight);
@ -193,7 +202,13 @@ void ui::exit()
int ui::registerPanel(slideOutPanel *sop)
{
panels.push_back(sop);
return panelCount++;
return panels.size() - 1;
}
int ui::newThread(ThreadFunc func, void *args)
{
threadMngr->newThread(func, args);
return 0;
}
void ui::showLoadScreen()
@ -237,6 +252,9 @@ void ui::drawUI()
for(slideOutPanel *s : panels)
s->draw(&ui::slidePanelColor);
if(!threadMngr->empty())
threadMngr->draw();
popMessages->draw();
}
@ -244,38 +262,44 @@ static bool debugDisp = false;
bool ui::runApp()
{
ui::updateInput();
uint64_t down = ui::padKeysDown();
if(down & HidNpadButton_StickL && down & HidNpadButton_StickR)
debugDisp = true;
else if(down & HidNpadButton_Plus)
return false;
switch(ui::mstate)
if(threadMngr->empty())
{
case USR_SEL:
usrUpdate();
break;
ui::updateInput();
uint64_t down = ui::padKeysDown();
case TTL_SEL:
ttlUpdate();
break;
if(down & HidNpadButton_StickL && down & HidNpadButton_StickR)
debugDisp = true;
else if(down & HidNpadButton_Plus)
return false;
case OPT_MNU:
settUpdate();
break;
switch(ui::mstate)
{
case USR_SEL:
usrUpdate();
break;
case EX_MNU:
/*extMenu.update();
if(down & HidNpadButton_B)
{
ui::changeState(USR_SEL);
mainMenu.setActive(true);
extMenu.setActive(false);
}*/
break;
case TTL_SEL:
ttlUpdate();
break;
case OPT_MNU:
settUpdate();
break;
case EX_MNU:
/*extMenu.update();
if(down & HidNpadButton_B)
{
ui::changeState(USR_SEL);
mainMenu.setActive(true);
extMenu.setActive(false);
}*/
break;
}
}
else
threadMngr->update();
popMessages->update();
drawUI();

View File

@ -20,13 +20,7 @@ static const SDL_Color fillDark = {0x32, 0x50, 0xF0, 0xFF};
static const SDL_Color menuColorLight = {0x32, 0x50, 0xF0, 0xFF};
static const SDL_Color menuColorDark = {0x00, 0xFF, 0xC5, 0xFF};
//8
static const std::string loadGlyphArray[] =
{
"\ue020", "\ue021", "\ue022", "\ue023",
"\ue024", "\ue025", "\ue026", "\ue027"
};
static const SDL_Color darkenBack = {0x00, 0x00, 0x00, 0xBB};
void ui::menu::setParams(const unsigned& _x, const unsigned& _y, const unsigned& _rW, const unsigned& _fS, const unsigned& _mL)
{
@ -535,6 +529,63 @@ void ui::popMessageMngr::draw()
}
}
ui::threadProcMngr::~threadProcMngr()
{
for(threadInfo *t : threads)
{
threadWaitForExit(t->thrdPtr);
threadClose(t->thrdPtr);
delete t->thrdPtr;
if(t->argPtr)
free(t->argPtr);
delete t;
}
}
void ui::threadProcMngr::newThread(ThreadFunc func, void *args)
{
threadInfo *t = new threadInfo;
t->thrdPtr = new Thread;
t->finished = false;
t->argPtr = args;
threadCreate(t->thrdPtr, func, t, NULL, 0x8000, 0x2B, 1);
threads.push_back(t);
}
void ui::threadProcMngr::update()
{
if(!threads.empty())
{
threadInfo *t = threads[0];
if(t->running == false && t->finished == false)
{
t->running = true;
threadStart(t->thrdPtr);
}
else if(t->running == true && t->finished == true)
{
threadWaitForExit(t->thrdPtr);
threadClose(t->thrdPtr);
delete t->thrdPtr;
delete t;
threads.erase(threads.begin());
}
}
}
void ui::threadProcMngr::draw()
{
if(++frameCount % 4 == 0 && ++lgFrame > 7)
lgFrame = 0;
gfx::drawRect(NULL, &darkenBack, 0, 0, 1280, 720);
gfx::drawTextf(NULL, 128, 576, 296, &ui::loadGlyphClr, loadGlyphArray[lgFrame].c_str());
int y = 424;
int statX = 640 - (gfx::getTextWidth(threads[0]->status.c_str(), 18) / 2);
gfx::drawTextf(NULL, 18, statX, 440, &ui::txtCont, threads[0]->status.c_str());
}
void ui::showMessage(const char *head, const char *fmt, ...)
{
char tmp[1024];
@ -694,7 +745,7 @@ void ui::drawBoundBox(SDL_Texture *target, int x, int y, int w, int h, uint8_t c
gfx::drawRect(target, &rectClr, x + 4, y + 4, w - 8, h - 8);
rectClr = {0x00,(uint8_t)(0x88 + clrSh), (uint8_t)(0xC5 + (clrSh / 2)), 0xFF};
rectClr = {0x00, (uint8_t)(0x88 + clrSh), (uint8_t)(0xC5 + (clrSh / 2)), 0xFF};
SDL_SetTextureColorMod(mnuTopLeft, rectClr.r, rectClr.g, rectClr.b);
SDL_SetTextureColorMod(mnuTopRight, rectClr.r, rectClr.g, rectClr.b);

View File

@ -2,6 +2,7 @@
#include <SDL.h>
#include "ui.h"
#include "file.h"
#include "sett.h"
ui::menu *ui::settMenu;
@ -43,61 +44,71 @@ static void toggleOpt(void *a)
switch(ui::settMenu->getSelected())
{
case 0:
toggleBool(data::config["incDev"]);
fs::delDir(fs::getWorkDir() + "_TRASH_/");
mkdir(std::string(fs::getWorkDir() + "_TRASH_").c_str(), 777);
ui::showPopMessage(POP_FRAME_DEFAULT, "Trash emptied.");
break;
case 1:
toggleBool(data::config["autoBack"]);
toggleBool(data::config["incDev"]);
break;
case 2:
toggleBool(data::config["ovrClk"]);
toggleBool(data::config["autoBack"]);
break;
case 3:
toggleBool(data::config["holdDel"]);
toggleBool(data::config["ovrClk"]);
break;
case 4:
toggleBool(data::config["holdRest"]);
toggleBool(data::config["holdDel"]);
break;
case 5:
toggleBool(data::config["holdOver"]);
toggleBool(data::config["holdRest"]);
break;
case 6:
toggleBool(data::config["forceMount"]);
toggleBool(data::config["holdOver"]);
break;
case 7:
toggleBool(data::config["accSysSave"]);
toggleBool(data::config["forceMount"]);
break;
case 8:
toggleBool(data::config["sysSaveWrite"]);
toggleBool(data::config["accSysSave"]);
break;
case 9:
toggleBool(data::config["directFsCmd"]);
toggleBool(data::config["sysSaveWrite"]);
break;
case 10:
toggleBool(data::config["zip"]);
toggleBool(data::config["directFsCmd"]);
break;
case 11:
toggleBool(data::config["langOverride"]);
toggleBool(data::config["zip"]);
break;
case 12:
toggleBool(data::config["langOverride"]);
break;
case 13:
toggleBool(data::config["trashBin"]);
break;
case 14:
if(++data::sortType > 2)
data::sortType = 0;
data::loadUsersTitles(false);
ui::refreshAllViews();
break;
case 13:
case 15:
ui::animScale += 0.5f;
if(ui::animScale > 8)
ui::animScale = 1;
@ -107,23 +118,24 @@ static void toggleOpt(void *a)
static void updateMenuText()
{
ui::settMenu->editOpt(0, NULL, ui::optMenuStr[0] + getBoolText(data::config["incDev"]));
ui::settMenu->editOpt(1, NULL, ui::optMenuStr[1] + getBoolText(data::config["autoBack"]));
ui::settMenu->editOpt(2, NULL, ui::optMenuStr[2] + getBoolText(data::config["ovrClk"]));
ui::settMenu->editOpt(3, NULL, ui::optMenuStr[3] + getBoolText(data::config["holdDel"]));
ui::settMenu->editOpt(4, NULL, ui::optMenuStr[4] + getBoolText(data::config["holdRest"]));
ui::settMenu->editOpt(5, NULL, ui::optMenuStr[5] + getBoolText(data::config["holdOver"]));
ui::settMenu->editOpt(6, NULL, ui::optMenuStr[6] + getBoolText(data::config["forceMount"]));
ui::settMenu->editOpt(7, NULL, ui::optMenuStr[7] + getBoolText(data::config["accSysSave"]));
ui::settMenu->editOpt(8, NULL, ui::optMenuStr[8] + getBoolText(data::config["sysSaveWrite"]));
ui::settMenu->editOpt(9, NULL, ui::optMenuStr[9] + getBoolText(data::config["directFsCmd"]));
ui::settMenu->editOpt(10, NULL, ui::optMenuStr[10] + getBoolText(data::config["zip"]));
ui::settMenu->editOpt(11, NULL, ui::optMenuStr[11] + getBoolText(data::config["langOverride"]));
ui::settMenu->editOpt(12, NULL, ui::optMenuStr[12] + ui::sortString[data::sortType]);
ui::settMenu->editOpt(1, NULL, ui::optMenuStr[1] + getBoolText(data::config["incDev"]));
ui::settMenu->editOpt(2, NULL, ui::optMenuStr[2] + getBoolText(data::config["autoBack"]));
ui::settMenu->editOpt(3, NULL, ui::optMenuStr[3] + getBoolText(data::config["ovrClk"]));
ui::settMenu->editOpt(4, NULL, ui::optMenuStr[4] + getBoolText(data::config["holdDel"]));
ui::settMenu->editOpt(5, NULL, ui::optMenuStr[5] + getBoolText(data::config["holdRest"]));
ui::settMenu->editOpt(6, NULL, ui::optMenuStr[6] + getBoolText(data::config["holdOver"]));
ui::settMenu->editOpt(7, NULL, ui::optMenuStr[7] + getBoolText(data::config["forceMount"]));
ui::settMenu->editOpt(8, NULL, ui::optMenuStr[8] + getBoolText(data::config["accSysSave"]));
ui::settMenu->editOpt(9, NULL, ui::optMenuStr[9] + getBoolText(data::config["sysSaveWrite"]));
ui::settMenu->editOpt(10, NULL, ui::optMenuStr[10] + getBoolText(data::config["directFsCmd"]));
ui::settMenu->editOpt(11, NULL, ui::optMenuStr[11] + getBoolText(data::config["zip"]));
ui::settMenu->editOpt(12, NULL, ui::optMenuStr[12] + getBoolText(data::config["langOverride"]));
ui::settMenu->editOpt(13, NULL, ui::optMenuStr[13] + getBoolText(data::config["trashBin"]));
ui::settMenu->editOpt(14, NULL, ui::optMenuStr[14] + ui::sortString[data::sortType]);
char tmp[16];
sprintf(tmp, "%.1f", ui::animScale);
ui::settMenu->editOpt(13, NULL, ui::optMenuStr[13] + std::string(tmp));
ui::settMenu->editOpt(15, NULL, ui::optMenuStr[15] + std::string(tmp));
}
void ui::settInit()
@ -135,7 +147,7 @@ void ui::settInit()
optHelpX = 1220 - gfx::getTextWidth(ui::optHelp.c_str(), 18);
for(unsigned i = 0; i < 14; i++)
for(unsigned i = 0; i < 16; i++)
{
ui::settMenu->addOpt(NULL, ui::optMenuStr[i]);
ui::settMenu->optAddButtonEvent(i, HidNpadButton_A, toggleOpt, NULL);

View File

@ -5,7 +5,7 @@
#include "file.h"
#include "util.h"
int ttlHelpX = 0;
int ttlHelpX = 0, fldHelpWidth = 0;
static std::vector<ui::titleview *> ttlViews;
static ui::menu *ttlOpts, *fldMenu;
static ui::slideOutPanel *ttlOptsPanel, *infoPanel, *fldPanel;//There's no reason to have a separate folder section
@ -98,19 +98,6 @@ static void ttlOptsCallback(void *a)
}
}
static void infoPanelCallback(void *a)
{
switch(ui::padKeysDown())
{
case HidNpadButton_B:
infoPanel->closePanel();
ttlOptsPanel->openPanel();
ttlOpts->setActive(true);
ui::updateInput();
break;
}
}
static void ttlOptsPanelDraw(void *a)
{
SDL_Texture *panel = (SDL_Texture *)a;
@ -139,7 +126,7 @@ static void ttlOptsDefinePath(void *a)
{
uint64_t tid = data::curData.saveID;
std::string safeTitle = data::getTitleInfoByTID(tid)->safeTitle;
std::string newSafeTitle = util::getStringInput(safeTitle, "Input New Output Folder", 32, 0, NULL);
std::string newSafeTitle = util::getStringInput(safeTitle, "Input New Output Folder", 0x200, 0, NULL);
if(!newSafeTitle.empty())
data::pathDefAdd(tid, newSafeTitle);
}
@ -156,6 +143,89 @@ static void ttlOptsResetSaveData(void *a)
}
}
static void ttlOptsDeleteSaveData(void *a)
{
std::string title = data::getTitleNameByTID(data::curData.saveID);
if(ui::confirm(data::config["holdDel"], ui::confEraseNand.c_str(), title.c_str()) && R_SUCCEEDED(fsDeleteSaveDataFileSystemBySaveDataSpaceId((FsSaveDataSpaceId)data::curData.saveInfo.save_data_space_id, data::curData.saveInfo.save_data_id)))
{
data::loadUsersTitles(false);
if(data::curUser.titleInfo.size() == 0)
{
//Kick back to user
ttlOptsPanel->closePanel();//JIC
ttlOpts->setActive(false);
ttlViews[data::selUser]->setActive(false, false);
ui::usrMenu->setActive(true);
ui::changeState(USR_SEL);
}
ui::showPopMessage(POP_FRAME_DEFAULT, ui::saveDataDeleteSuccess.c_str(), title.c_str());
ttlViews[data::selUser]->refresh();
}
}
static void ttlOptsExtendSaveData_t(void *a)
{
threadInfo *w = (threadInfo *)a;
std::string expSizeStr = util::getStringInput("", "Enter New Size in MB", 4, 0, NULL);
if(!expSizeStr.empty())
{
data::titleInfo *extend = data::getTitleInfoByTID(data::curData.saveID);
w->status = "Expanding save filesystem for " + extend->title;
uint64_t expMB = strtoul(expSizeStr.c_str(), NULL, 10);
FsSaveDataSpaceId space = (FsSaveDataSpaceId)data::curData.saveInfo.save_data_space_id;
uint64_t sid = data::curData.saveInfo.save_data_id;
int64_t expSize = expMB * 1024 * 1024;
int64_t journ = 0;
if(extend->nacp.user_account_save_data_journal_size_max > extend->nacp.user_account_save_data_journal_size)
journ = extend->nacp.user_account_save_data_journal_size_max;
else
journ = extend->nacp.user_account_save_data_journal_size;
Result res = 0;
if(R_SUCCEEDED(res = fsExtendSaveDataFileSystem(space, sid, expSize, journ)))
{
ui::showPopMessage(POP_FRAME_DEFAULT, "Save data expanded for %s!", extend->title.c_str());
fs::logWrite("Extend Succeeded!\n");
}
else
{
int64_t totalSize = 0;
fs::mountSave(data::curData.saveInfo);
fsFsGetTotalSpace(fsdevGetDeviceFileSystem("sv"), "/", &totalSize);
fs::unmountSave();
fs::logWrite("Extend Failed: %uMB to %uMB -> %X\n", totalSize / 1024 / 1024, expSize / 1024 / 1024, res);
ui::showPopMessage(POP_FRAME_DEFAULT, "Failed to expand save data.");
}
}
w->finished = true;
}
static void ttlOptsExtendSaveData(void *a)
{
ui::newThread(ttlOptsExtendSaveData_t, NULL);
}
static void infoPanelDraw(void *a)
{
SDL_Texture *panel = (SDL_Texture *)a;
gfx::texDraw(panel, data::getTitleIconByTID(data::curData.saveID), 77, 32);
gfx::drawTextfWrap(panel, 18, 32, 320, 362, &ui::txtCont, infoPanelString.c_str());
}
static void infoPanelCallback(void *a)
{
switch(ui::padKeysDown())
{
case HidNpadButton_B:
infoPanel->closePanel();
ttlOptsPanel->openPanel();
ttlOpts->setActive(true);
ui::updateInput();
break;
}
}
static void fldMenuCallback(void *a)
{
switch(ui::padKeysDown())
@ -173,80 +243,14 @@ static void fldPanelDraw(void *a)
{
SDL_Texture *target = (SDL_Texture *)a;
fldMenu->draw(target, &ui::txtCont, true);
gfx::drawLine(target, &ui::divClr, 10, 648, 502, 648);
gfx::drawLine(target, &ui::divClr, 10, 648, fldHelpWidth + 54, 648);
gfx::drawTextf(target, 18, 32, 673, &ui::txtCont, ui::folderHelp.c_str());
}
static void ttlOptsDeleteSaveData(void *a)
{
FsSaveDataAttribute attr;
attr.application_id = data::curData.saveID;
attr.uid = data::curData.saveInfo.save_data_type == FsSaveDataType_Account ? data::curUser.getUID() : util::u128ToAccountUID(0);
attr.system_save_data_id = 0;
attr.save_data_type = data::curData.saveInfo.save_data_type;
attr.save_data_rank = data::curData.saveInfo.save_data_rank;
attr.save_data_index = data::curData.saveInfo.save_data_index;
std::string title = data::getTitleNameByTID(data::curData.saveID);
if(ui::confirm(data::config["holdDel"], ui::confEraseNand.c_str(), title.c_str()) && R_SUCCEEDED(fsDeleteSaveDataFileSystemBySaveDataAttribute(FsSaveDataSpaceId_User, &attr)))
{
data::loadUsersTitles(false);
if(data::curUser.titleInfo.size() == 0)
{
//Kick back to user
ttlOptsPanel->closePanel();//JIC
ttlOpts->setActive(false);
ttlViews[data::selUser]->setActive(false, false);
ui::usrMenu->setActive(true);
ui::changeState(USR_SEL);
}
ui::showPopMessage(POP_FRAME_DEFAULT, ui::saveDataDeleteSuccess.c_str(), title.c_str());
ttlViews[data::selUser]->refresh();
}
}
static void ttlOptsExtendSaveData(void *a)
{
std::string expSizeStr = util::getStringInput("", "Enter New Size in MB", 4, 0, NULL);
if(!expSizeStr.empty())
{
uint64_t expMB = strtoul(expSizeStr.c_str(), NULL, 10);
data::titleInfo *extend = data::getTitleInfoByTID(data::curData.saveID);
FsSaveDataSpaceId space = (FsSaveDataSpaceId)data::curData.saveInfo.save_data_space_id;
uint64_t sid = data::curData.saveInfo.save_data_id;
uint64_t expSize = expMB * 1024 * 1024;
uint64_t journ = extend->nacp.user_account_save_data_journal_size;
Result res = 0;
if(R_SUCCEEDED(res = fs::extendSaveDataFileSystem(space, sid, expSize, journ)))
{
ui::showPopMessage(POP_FRAME_DEFAULT, "Save data expanded for %s!", extend->title.c_str());
fs::logWrite("Extend Succeeded!\n");
}
else
{
int64_t totalSize = 0;
fs::mountSave(data::curData.saveInfo);
fsFsGetTotalSpace(fsdevGetDeviceFileSystem("sv"), "/", &totalSize);
fs::unmountSave();
fs::logWrite("Extend Failed: %uMB to %uMB -> %X\n", totalSize / 1024 / 1024, expSize / 1024 / 1024, res);
ui::showPopMessage(POP_FRAME_DEFAULT, "Failed to expand save data.");
}
}
}
static void infoPanelDraw(void *a)
{
SDL_Texture *panel = (SDL_Texture *)a;
gfx::texDraw(panel, data::getTitleIconByTID(data::curData.saveID), 77, 32);
gfx::drawTextfWrap(panel, 18, 32, 320, 362, &ui::txtCont, infoPanelString.c_str());
}
void ui::ttlInit()
{
ttlHelpX = 1220 - gfx::getTextWidth(ui::titleHelp.c_str(), 18);
fldHelpWidth = gfx::getTextWidth(ui::folderHelp.c_str(), 18);
for(data::user& u : data::users)
ttlViews.emplace_back(new ui::titleview(u, 128, 128, 16, 16, 7, ttlViewCallback));
@ -257,7 +261,7 @@ void ui::ttlInit()
ttlOpts->setActive(false);
fldMenu = new ui::menu;
fldMenu->setParams(10, 32, 492, 18, 8);
fldMenu->setParams(10, 32, fldHelpWidth + 44, 18, 8);
fldMenu->setCallback(fldMenuCallback, NULL);
fldMenu->setActive(false);
@ -268,7 +272,7 @@ void ui::ttlInit()
ui::registerPanel(infoPanel);
infoPanel->setCallback(infoPanelCallback, NULL);
fldPanel = new ui::slideOutPanel(512, 720, 0, fldPanelDraw);
fldPanel = new ui::slideOutPanel(fldHelpWidth + 64, 720, 0, fldPanelDraw);
ui::registerPanel(fldPanel);
fldList = new fs::dirList;
@ -320,6 +324,6 @@ void ui::ttlUpdate()
void ui::ttlDraw(SDL_Texture *target)
{
ttlViews[data::selUser]->draw(target);
if(ui::mstate == TTL_SEL)
if(ui::mstate == TTL_SEL && !fldPanel->isOpen())
gfx::drawTextf(NULL, 18, ttlHelpX, 673, &ui::txtCont, ui::titleHelp.c_str());
}

View File

@ -41,7 +41,7 @@ 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::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[14] = { "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: ", "Sort: ", "Animation Scale: "};
std::string ui::optMenuStr[16] = { "Empty Trash Bin", "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" };
@ -49,6 +49,9 @@ std::string ui::titleOptString[6] = {"Information", "Blacklist", "Change Output
void ui::loadTrans()
{
//Disable translation loading until new UI done
return;
bool transFile = fs::fileExists(fs::getWorkDir() + "trans.txt");
if(!transFile && (data::sysLang == SetLanguage_ENUS || data::config["langOverride"]))
return;//Don't bother loading from file. It serves as a translation guide

View File

@ -129,26 +129,25 @@ static void usrOptSaveCreate(void *a)
}
//nsDeleteUserSaveDataAll only works if the user is selected at system level
static void usrOptDeleteAllUserSaves_t(void *a)
{
threadInfo *t = (threadInfo *)a;
data::user *u = &data::users[data::selUser];
for(data::userTitleInfo& tinf : u->titleInfo)
{
t->status = "Deleting " + data::getTitleNameByTID(tinf.saveID);
fsDeleteSaveDataFileSystemBySaveDataSpaceId(FsSaveDataSpaceId_User, tinf.saveInfo.save_data_id);;
}
data::loadUsersTitles(false);
ui::refreshAllViews();
t->finished = true;
}
static void usrOptDeleteAllUserSaves(void *a)
{
data::user *u = &data::users[data::selUser];
if(ui::confirm(true, "*ARE YOU SURE YOU WANT TO DELETE ALL SAVE DATA FOR %s?*", u->getUsername().c_str()))
{
for(data::userTitleInfo& tinf : u->titleInfo)
{
FsSaveDataAttribute attr;
attr.application_id = tinf.saveID;
attr.uid = u->getUID();
attr.system_save_data_id = 0;
attr.save_data_type = tinf.saveInfo.save_data_type;
attr.save_data_rank = tinf.saveInfo.save_data_rank;
attr.save_data_index = tinf.saveInfo.save_data_index;
fsDeleteSaveDataFileSystemBySaveDataAttribute(FsSaveDataSpaceId_User, &attr);
}
data::loadUsersTitles(false);
ui::refreshAllViews();
}
ui::newThread(usrOptDeleteAllUserSaves_t, NULL);
}
static void usrOptPanelDraw(void *a)
@ -181,9 +180,10 @@ static void cacheSavePanelDraw(void *a)
cacheSaveMenu->draw(panel, &ui::txtCont, true);
}
static void createSaveData(void *a)
static void createSaveData_t(void *a)
{
svCreateArgs *in = (svCreateArgs *)a;
threadInfo *t = (threadInfo *)a;
svCreateArgs *in = (svCreateArgs *)t->argPtr;
FsSaveDataType type = in->type;
ui::menu *m = in->m;
@ -211,6 +211,7 @@ static void createSaveData(void *a)
break;
}
data::titleInfo *create = data::getTitleInfoByTID(sid);
t->status = "Creating save data for " + create->title;
FsSaveDataAttribute attr;
memset(&attr, 0, sizeof(FsSaveDataAttribute));
@ -243,7 +244,7 @@ static void createSaveData(void *a)
case FsSaveDataType_Cache:
saveSize = 32 * 1024 * 1024;//Todo: Add target folder/zip selection for size
journalSize = create->nacp.user_account_save_data_journal_size;
journalSize = create->nacp.cache_storage_journal_size;
break;
default:
@ -265,7 +266,6 @@ static void createSaveData(void *a)
Result res = 0;
if(R_SUCCEEDED(res = fsCreateSaveDataFileSystem(&attr, &svCreate, &meta)))
{
ui::showPopMessage(POP_FRAME_DEFAULT, ui::saveCreated.c_str(), create->title.c_str());
data::loadUsersTitles(false);
ui::refreshAllViews();
}
@ -274,6 +274,13 @@ static void createSaveData(void *a)
ui::showPopMessage(POP_FRAME_DEFAULT, ui::saveCreateFailed.c_str());
fs::logWrite("SaveCreate Failed -> %X\n", res);
}
t->finished = true;
}
static void createSaveData(void *a)
{
ui::newThread(createSaveData_t, a);
}
void ui::usrInit()
@ -317,7 +324,7 @@ void ui::usrInit()
ext = util::createIconGeneric("Extras", 40);
pos = usrMenu->addOpt(ext, "Extras");
usrMenu->optAddButtonEvent(pos, HidNpadButton_A, toEXT, NULL);
usrMenu->optAddButtonEvent(pos, HidNpadButton_A, NULL, NULL);
usrMenu->setOnChangeFunc(onMainChange);
usrMenu->editParam(MENU_RECT_WIDTH, 126);

View File

@ -261,9 +261,9 @@ std::string util::getStringInput(const std::string& def, const std::string& head
swkbdConfigSetDictionary(&swkbd, (SwkbdDictWord *)words, dictCnt);
}
char out[maxLength];
memset(out, 0, maxLength);
swkbdShow(&swkbd, out, maxLength);
char out[maxLength + 1];
memset(out, 0, maxLength + 1);
swkbdShow(&swkbd, out, maxLength + 1);
swkbdClose(&swkbd);
return std::string(out);