mirror of
https://github.com/J-D-K/JKSV.git
synced 2026-04-26 10:15:22 -05:00
Use Free Bird's CPU speed definitions, Fix ZIP headers, Mass Backup in user options
This commit is contained in:
parent
2b6f91e20f
commit
92e780d284
2
Makefile
2
Makefile
|
|
@ -38,7 +38,7 @@ INCLUDES := inc inc/ui
|
||||||
EXEFS_SRC := exefs_src
|
EXEFS_SRC := exefs_src
|
||||||
APP_TITLE := JKSV
|
APP_TITLE := JKSV
|
||||||
APP_AUTHOR := JK
|
APP_AUTHOR := JK
|
||||||
APP_VERSION := 08.16.2021
|
APP_VERSION := 08.17.2021
|
||||||
ROMFS := romfs
|
ROMFS := romfs
|
||||||
ICON := icon.jpg
|
ICON := icon.jpg
|
||||||
|
|
||||||
|
|
|
||||||
14
inc/data.h
14
inc/data.h
|
|
@ -8,7 +8,7 @@
|
||||||
#include "gfx.h"
|
#include "gfx.h"
|
||||||
|
|
||||||
#define BLD_MON 8
|
#define BLD_MON 8
|
||||||
#define BLD_DAY 16
|
#define BLD_DAY 17
|
||||||
#define BLD_YEAR 2021
|
#define BLD_YEAR 2021
|
||||||
|
|
||||||
namespace data
|
namespace data
|
||||||
|
|
@ -37,7 +37,7 @@ namespace data
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
//Makes it easier to grab id
|
//Makes it easier to grab id
|
||||||
uint64_t saveID;
|
uint64_t tid;
|
||||||
FsSaveDataInfo saveInfo;
|
FsSaveDataInfo saveInfo;
|
||||||
PdmPlayStatistics playStats;
|
PdmPlayStatistics playStats;
|
||||||
} userTitleInfo;
|
} userTitleInfo;
|
||||||
|
|
@ -99,14 +99,6 @@ namespace data
|
||||||
std::string getTitleNameByTID(const uint64_t& tid);
|
std::string getTitleNameByTID(const uint64_t& tid);
|
||||||
std::string getTitleSafeNameByTID(const uint64_t& tid);
|
std::string getTitleSafeNameByTID(const uint64_t& tid);
|
||||||
SDL_Texture *getTitleIconByTID(const uint64_t& tid);
|
SDL_Texture *getTitleIconByTID(const uint64_t& tid);
|
||||||
inline int getTitleIndexInUser(const data::user& u, const uint64_t& sid)
|
int getTitleIndexInUser(const data::user *u, const uint64_t& tid);
|
||||||
{
|
|
||||||
for(unsigned i = 0; i < u.titleInfo.size(); i++)
|
|
||||||
{
|
|
||||||
if(u.titleInfo[i].saveID == sid)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
extern SetLanguage sysLang;
|
extern SetLanguage sysLang;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,14 +52,14 @@ namespace fs
|
||||||
void delDir(const std::string& path);
|
void delDir(const std::string& path);
|
||||||
|
|
||||||
//Loads paths to filter from backup/deletion
|
//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);
|
bool pathIsFiltered(const std::string& _path);
|
||||||
void freePathFilters();
|
void freePathFilters();
|
||||||
|
|
||||||
void wipeSave();
|
void wipeSave();
|
||||||
|
|
||||||
//Dumps all titles for 'user'. returns false to bail
|
//Dumps all titles for current user
|
||||||
bool dumpAllUserSaves(const data::user& u);
|
void dumpAllUserSaves();
|
||||||
|
|
||||||
//returns file properties as C++ string
|
//returns file properties as C++ string
|
||||||
std::string getFileProps(const std::string& _path);
|
std::string getFileProps(const std::string& _path);
|
||||||
|
|
|
||||||
|
|
@ -15,4 +15,6 @@ namespace fs
|
||||||
void copyZipToDir_t(void *a);
|
void copyZipToDir_t(void *a);
|
||||||
void wipesave_t(void *a);
|
void wipesave_t(void *a);
|
||||||
void closeZip_t(void *a);
|
void closeZip_t(void *a);
|
||||||
|
|
||||||
|
void backupUserSaves_t(void *a);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
64
inc/gfx.h
64
inc/gfx.h
|
|
@ -18,62 +18,10 @@ namespace gfx
|
||||||
size_t getTextWidth(const char *str, int fontSize);
|
size_t getTextWidth(const char *str, int fontSize);
|
||||||
|
|
||||||
//Shortcuts for drawing
|
//Shortcuts for drawing
|
||||||
inline void texDraw(SDL_Texture *target, SDL_Texture *tex, int x, int y)
|
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);
|
||||||
int tW = 0, tH = 0;
|
void texDrawPart(SDL_Texture *target, SDL_Texture *tex, int srcX, int srcY, int srcW, int srcH, int dstX, int dstY);
|
||||||
if(SDL_QueryTexture(tex, NULL, NULL, &tW, &tH) == 0)
|
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);
|
||||||
SDL_SetRenderTarget(gfx::render, target);
|
void clearTarget(SDL_Texture *target, const SDL_Color *clear);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
20
inc/util.h
20
inc/util.h
|
|
@ -17,6 +17,26 @@ namespace util
|
||||||
DATE_FMT_ASC
|
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
|
//Returns string with date S+ time
|
||||||
std::string getDateTime(int fmt);
|
std::string getDateTime(int fmt);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,12 +38,12 @@ void cfg::addTitleToBlacklist(void *a)
|
||||||
{
|
{
|
||||||
threadInfo *t = (threadInfo *)a;
|
threadInfo *t = (threadInfo *)a;
|
||||||
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
||||||
uint64_t tid = d->saveID;
|
uint64_t tid = d->tid;
|
||||||
blacklist.push_back(tid);
|
blacklist.push_back(tid);
|
||||||
for(data::user& u : data::users)
|
for(data::user& u : data::users)
|
||||||
{
|
{
|
||||||
for(unsigned i = 0; i < u.titleInfo.size(); i++)
|
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();
|
ui::ttlRefresh();
|
||||||
t->finished = true;
|
t->finished = true;
|
||||||
|
|
|
||||||
40
src/data.cpp
40
src/data.cpp
|
|
@ -35,14 +35,14 @@ static struct
|
||||||
bool operator()(const data::userTitleInfo& a, const data::userTitleInfo& b)
|
bool operator()(const data::userTitleInfo& a, const data::userTitleInfo& b)
|
||||||
{
|
{
|
||||||
//Favorites override EVERYTHING
|
//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)
|
switch(cfg::sortType)
|
||||||
{
|
{
|
||||||
case cfg::ALPHA:
|
case cfg::ALPHA:
|
||||||
{
|
{
|
||||||
std::string titleA = data::getTitleNameByTID(a.saveID);
|
std::string titleA = data::getTitleNameByTID(a.tid);
|
||||||
std::string titleB = data::getTitleNameByTID(b.saveID);
|
std::string titleB = data::getTitleNameByTID(b.tid);
|
||||||
uint32_t pointA, pointB;
|
uint32_t pointA, pointB;
|
||||||
for(unsigned i = 0, j = 0; i < titleA.length(); )
|
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)
|
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)
|
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
|
else
|
||||||
saveID = info.application_id;
|
tid = info.application_id;
|
||||||
|
|
||||||
//Don't bother with this stuff
|
//Don't bother with this stuff
|
||||||
if(cfg::isBlacklisted(saveID) || !accountSystemSaveCheck(info) || !testMount(info))
|
if(cfg::isBlacklisted(tid) || !accountSystemSaveCheck(info) || !testMount(info))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch(info.save_data_type)
|
switch(info.save_data_type)
|
||||||
|
|
@ -258,8 +258,8 @@ bool data::loadUsersTitles(bool clearUsers)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!titleIsLoaded(saveID))
|
if(!titleIsLoaded(tid))
|
||||||
addTitleToList(saveID);
|
addTitleToList(tid);
|
||||||
|
|
||||||
int u = getUserIndex(info.uid);
|
int u = getUserIndex(info.uid);
|
||||||
if(u == -1)
|
if(u == -1)
|
||||||
|
|
@ -274,7 +274,7 @@ bool data::loadUsersTitles(bool clearUsers)
|
||||||
else
|
else
|
||||||
memset(&playStats, 0, sizeof(PdmPlayStatistics));
|
memset(&playStats, 0, sizeof(PdmPlayStatistics));
|
||||||
|
|
||||||
users[u].addUserTitleInfo(saveID, &info, &playStats);
|
users[u].addUserTitleInfo(tid, &info, &playStats);
|
||||||
}
|
}
|
||||||
fsSaveDataInfoReaderClose(&it);
|
fsSaveDataInfoReaderClose(&it);
|
||||||
}
|
}
|
||||||
|
|
@ -307,7 +307,7 @@ void data::sortUserTitles()
|
||||||
void data::init()
|
void data::init()
|
||||||
{
|
{
|
||||||
if(cfg::config["ovrClk"])
|
if(cfg::config["ovrClk"])
|
||||||
util::setCPU(1224000000);
|
util::setCPU(util::cpu1224MHz);
|
||||||
|
|
||||||
uint64_t lang;
|
uint64_t lang;
|
||||||
setGetSystemLanguage(&lang);
|
setGetSystemLanguage(&lang);
|
||||||
|
|
@ -325,7 +325,7 @@ void data::exit()
|
||||||
SDL_DestroyTexture(iconMask);
|
SDL_DestroyTexture(iconMask);
|
||||||
|
|
||||||
if(cfg::config["ovrClk"])
|
if(cfg::config["ovrClk"])
|
||||||
util::setCPU(1020000000);
|
util::setCPU(util::cpu1020MHz);
|
||||||
}
|
}
|
||||||
|
|
||||||
void data::setUserIndex(unsigned _sUser)
|
void data::setUserIndex(unsigned _sUser)
|
||||||
|
|
@ -380,6 +380,16 @@ SDL_Texture *data::getTitleIconByTID(const uint64_t& tid)
|
||||||
return titles[tid].icon;
|
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)
|
data::user::user(const AccountUid& _id, const std::string& _backupName)
|
||||||
{
|
{
|
||||||
userID = _id;
|
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)
|
void data::user::addUserTitleInfo(const uint64_t& tid, const FsSaveDataInfo *_saveInfo, const PdmPlayStatistics *_stats)
|
||||||
{
|
{
|
||||||
data::userTitleInfo newInfo;
|
data::userTitleInfo newInfo;
|
||||||
newInfo.saveID = tid;
|
newInfo.tid = tid;
|
||||||
memcpy(&newInfo.saveInfo, _saveInfo, sizeof(FsSaveDataInfo));
|
memcpy(&newInfo.saveInfo, _saveInfo, sizeof(FsSaveDataInfo));
|
||||||
memcpy(&newInfo.playStats, _stats, sizeof(PdmPlayStatistics));
|
memcpy(&newInfo.playStats, _stats, sizeof(PdmPlayStatistics));
|
||||||
titleInfo.push_back(newInfo);
|
titleInfo.push_back(newInfo);
|
||||||
|
|
@ -451,8 +461,8 @@ void data::dispStats()
|
||||||
for(data::user& u : data::users)
|
for(data::user& u : data::users)
|
||||||
stats += u.getUsername() + ": " + std::to_string(u.titleInfo.size()) + "\n";
|
stats += u.getUsername() + ": " + std::to_string(u.titleInfo.size()) + "\n";
|
||||||
stats += "Current User: " + cu->getUsername() + "\n";
|
stats += "Current User: " + cu->getUsername() + "\n";
|
||||||
stats += "Current Title: " + data::getTitleNameByTID(d->saveID) + "\n";
|
stats += "Current Title: " + data::getTitleNameByTID(d->tid) + "\n";
|
||||||
stats += "Safe Title: " + data::getTitleSafeNameByTID(d->saveID) + "\n";
|
stats += "Safe Title: " + data::getTitleSafeNameByTID(d->tid) + "\n";
|
||||||
stats += "Sort Type: " + std::to_string(cfg::sortType) + "\n";
|
stats += "Sort Type: " + std::to_string(cfg::sortType) + "\n";
|
||||||
gfx::drawTextf(NULL, 16, 2, 2, &green, stats.c_str());
|
gfx::drawTextf(NULL, 16, 2, 2, &green, stats.c_str());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
86
src/file.cpp
86
src/file.cpp
|
|
@ -32,7 +32,9 @@ fs::copyArgs *fs::copyArgsCreate(const std::string& from, const std::string& to,
|
||||||
ret->unz = unz;
|
ret->unz = unz;
|
||||||
ret->cleanup = _cleanup;
|
ret->cleanup = _cleanup;
|
||||||
ret->prog = new ui::progBar;
|
ret->prog = new ui::progBar;
|
||||||
ret->offset = 0.0f;
|
ret->prog->setMax(0);
|
||||||
|
ret->prog->update(0);
|
||||||
|
ret->offset = 0;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,7 +99,7 @@ void fs::createSaveData(FsSaveDataType _type, uint64_t _tid, AccountUid _userID)
|
||||||
{
|
{
|
||||||
std::string indexStr;
|
std::string indexStr;
|
||||||
uint16_t index = 0;
|
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);
|
index = strtoul(indexStr.c_str(), NULL, 10);
|
||||||
|
|
||||||
svCreateArgs *send = new svCreateArgs;
|
svCreateArgs *send = new svCreateArgs;
|
||||||
|
|
@ -357,7 +359,7 @@ void fs::copyDirToZip(const std::string& from, zipFile to)
|
||||||
{
|
{
|
||||||
if(cfg::config["ovrClk"])
|
if(cfg::config["ovrClk"])
|
||||||
{
|
{
|
||||||
util::setCPU(1785000000);
|
util::setCPU(util::cpu1785MHz);
|
||||||
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popCPUBoostEnabled", 0));
|
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popCPUBoostEnabled", 0));
|
||||||
}
|
}
|
||||||
copyArgs *send = copyArgsCreate(from, "", "", to, NULL, true);
|
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"])
|
if(cfg::config["ovrClk"])
|
||||||
{
|
{
|
||||||
util::setCPU(1785000000);
|
util::setCPU(util::cpu1785MHz);
|
||||||
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popCPUBoostEnabled", 0));
|
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popCPUBoostEnabled", 0));
|
||||||
}
|
}
|
||||||
copyArgs *send = copyArgsCreate("", to, dev, NULL, unz, true);
|
copyArgs *send = copyArgsCreate("", to, dev, NULL, unz, true);
|
||||||
|
|
@ -425,11 +427,13 @@ void fs::delDir(const std::string& path)
|
||||||
rmdir(path.c_str());
|
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))
|
while(filter.readNextLine(false))
|
||||||
pathFilter.push_back(filter.getLine());
|
pathFilter.push_back(filter.getLine());
|
||||||
}
|
}
|
||||||
|
|
@ -459,45 +463,11 @@ void fs::wipeSave()
|
||||||
ui::newThread(fs::wipesave_t, NULL, NULL);
|
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++)
|
//This is only really used for the progress bar
|
||||||
{
|
fs::copyArgs *send = fs::copyArgsCreate("", "", "", NULL, NULL, true);
|
||||||
ui::updateInput();
|
ui::newThread(fs::backupUserSaves_t, send, _fileDrawFunc);
|
||||||
|
|
||||||
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;//?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string fs::getFileProps(const std::string& _path)
|
std::string fs::getFileProps(const std::string& _path)
|
||||||
|
|
@ -596,7 +566,7 @@ void fs::createNewBackup(void *a)
|
||||||
|
|
||||||
data::user *u = data::getCurrentUser();
|
data::user *u = data::getCurrentUser();
|
||||||
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
||||||
data::titleInfo *t = data::getTitleInfoByTID(d->saveID);
|
data::titleInfo *t = data::getTitleInfoByTID(d->tid);
|
||||||
|
|
||||||
std::string out;
|
std::string out;
|
||||||
|
|
||||||
|
|
@ -617,7 +587,7 @@ void fs::createNewBackup(void *a)
|
||||||
util::getDateTime(util::DATE_FMT_ASC),
|
util::getDateTime(util::DATE_FMT_ASC),
|
||||||
u->getUsernameSafe(),
|
u->getUsernameSafe(),
|
||||||
t->safeTitle,
|
t->safeTitle,
|
||||||
util::generateAbbrev(d->saveID),
|
util::generateAbbrev(d->tid),
|
||||||
".zip"
|
".zip"
|
||||||
};
|
};
|
||||||
std::string defaultText = u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD);
|
std::string defaultText = u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD);
|
||||||
|
|
@ -627,7 +597,7 @@ void fs::createNewBackup(void *a)
|
||||||
if(!out.empty())
|
if(!out.empty())
|
||||||
{
|
{
|
||||||
std::string ext = util::getExtensionFromString(out);
|
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(cfg::config["zip"] || ext == "zip")
|
||||||
{
|
{
|
||||||
if(ext != "zip")//data::zip is on but extension is not 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);
|
std::string itemName = d->getItem(ind);
|
||||||
if(d->isDir(ind))
|
if(d->isDir(ind))
|
||||||
{
|
{
|
||||||
std::string toPath = util::generatePathByTID(cd->saveID) + itemName + "/";
|
std::string toPath = util::generatePathByTID(cd->tid) + itemName + "/";
|
||||||
//Delete and recreate
|
//Delete and recreate
|
||||||
fs::delDir(toPath);
|
fs::delDir(toPath);
|
||||||
mkdir(toPath.c_str(), 777);
|
mkdir(toPath.c_str(), 777);
|
||||||
|
|
@ -669,7 +639,7 @@ void fs::overwriteBackup(void *a)
|
||||||
}
|
}
|
||||||
else if(!d->isDir(ind) && d->getItemExt(ind) == "zip")
|
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);
|
fs::delfile(toPath);
|
||||||
zipFile zip = zipOpen64(toPath.c_str(), 0);
|
zipFile zip = zipOpen64(toPath.c_str(), 0);
|
||||||
fs::copyDirToZip("sv:/", zip);
|
fs::copyDirToZip("sv:/", zip);
|
||||||
|
|
@ -693,20 +663,20 @@ void fs::restoreBackup(void *a)
|
||||||
{
|
{
|
||||||
if(cfg::config["autoBack"] && cfg::config["zip"])
|
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);
|
zipFile zip = zipOpen64(autoZip.c_str(), 0);
|
||||||
fs::copyDirToZip("sv:/", zip);
|
fs::copyDirToZip("sv:/", zip);
|
||||||
}
|
}
|
||||||
else if(cfg::config["autoBack"])
|
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);
|
mkdir(autoFolder.substr(0, autoFolder.length() - 1).c_str(), 777);
|
||||||
fs::copyDirToDir("sv:/", autoFolder);
|
fs::copyDirToDir("sv:/", autoFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(d->isDir(ind))
|
if(d->isDir(ind))
|
||||||
{
|
{
|
||||||
std::string fromPath = util::generatePathByTID(cd->saveID) + itemName + "/";
|
std::string fromPath = util::generatePathByTID(cd->tid) + itemName + "/";
|
||||||
if(fs::dirNotEmpty(fromPath))
|
if(fs::dirNotEmpty(fromPath))
|
||||||
{
|
{
|
||||||
fs::wipeSave();
|
fs::wipeSave();
|
||||||
|
|
@ -717,7 +687,7 @@ void fs::restoreBackup(void *a)
|
||||||
}
|
}
|
||||||
else if(!d->isDir(ind) && d->getItemExt(ind) == "zip")
|
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());
|
unzFile unz = unzOpen64(path.c_str());
|
||||||
if(unz && fs::zipNotEmpty(unz))
|
if(unz && fs::zipNotEmpty(unz))
|
||||||
{
|
{
|
||||||
|
|
@ -730,7 +700,7 @@ void fs::restoreBackup(void *a)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Just copy file over
|
//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;
|
std::string toPath = "sv:/" + itemName;
|
||||||
fs::copyFileCommit(fromPath, toPath, "sv");
|
fs::copyFileCommit(fromPath, toPath, "sv");
|
||||||
}
|
}
|
||||||
|
|
@ -756,20 +726,20 @@ void fs::deleteBackup(void *a)
|
||||||
t->status->setStatus("Deleting...");
|
t->status->setStatus("Deleting...");
|
||||||
if(cfg::config["trashBin"])
|
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;
|
std::string trashPath = wd + "_TRASH_/" + itemName;
|
||||||
rename(oldPath.c_str(), trashPath.c_str());
|
rename(oldPath.c_str(), trashPath.c_str());
|
||||||
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("saveDataBackupMovedToTrash", 0), itemName.c_str());
|
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("saveDataBackupMovedToTrash", 0), itemName.c_str());
|
||||||
}
|
}
|
||||||
else if(d->isDir(ind))
|
else if(d->isDir(ind))
|
||||||
{
|
{
|
||||||
std::string delPath = util::generatePathByTID(cd->saveID) + itemName + "/";
|
std::string delPath = util::generatePathByTID(cd->tid) + itemName + "/";
|
||||||
fs::delDir(delPath);
|
fs::delDir(delPath);
|
||||||
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("saveDataBackupDeleted", 0), itemName.c_str());
|
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("saveDataBackupDeleted", 0), itemName.c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::string delPath = util::generatePathByTID(cd->saveID) + itemName;
|
std::string delPath = util::generatePathByTID(cd->tid) + itemName;
|
||||||
fs::delfile(delPath);
|
fs::delfile(delPath);
|
||||||
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("saveDataBackupDeleted", 0), itemName.c_str());
|
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("saveDataBackupDeleted", 0), itemName.c_str());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -198,7 +198,7 @@ void fs::copyFileCommit_t(void *a)
|
||||||
threadInfo *t = (threadInfo *)a;
|
threadInfo *t = (threadInfo *)a;
|
||||||
copyArgs *args = (copyArgs *)t->argPtr;
|
copyArgs *args = (copyArgs *)t->argPtr;
|
||||||
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
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());
|
t->status->setStatus(ui::getUICString("threadStatusCopyingFile", 0), args->from.c_str());
|
||||||
|
|
||||||
args->prog->setMax(fs::fsize(args->from));
|
args->prog->setMax(fs::fsize(args->from));
|
||||||
|
|
@ -424,7 +424,13 @@ void fs::copyDirToZip_t(void *a)
|
||||||
}
|
}
|
||||||
else
|
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;
|
std::string filename = args->from + itm;
|
||||||
size_t devPos = filename.find_first_of('/') + 1;
|
size_t devPos = filename.find_first_of('/') + 1;
|
||||||
t->status->setStatus(ui::getUICString("threadStatusAddingFileToZip", 0), itm.c_str());
|
t->status->setStatus(ui::getUICString("threadStatusAddingFileToZip", 0), itm.c_str());
|
||||||
|
|
@ -454,7 +460,7 @@ void fs::copyDirToZip_t(void *a)
|
||||||
if(args->cleanup)
|
if(args->cleanup)
|
||||||
{
|
{
|
||||||
if(cfg::config["ovrClk"])
|
if(cfg::config["ovrClk"])
|
||||||
util::setCPU(1224000000);
|
util::setCPU(util::cpu1224MHz);
|
||||||
ui::newThread(closeZip_t, args->z, NULL);
|
ui::newThread(closeZip_t, args->z, NULL);
|
||||||
delete args->prog;
|
delete args->prog;
|
||||||
delete args;
|
delete args;
|
||||||
|
|
@ -468,7 +474,7 @@ void fs::copyZipToDir_t(void *a)
|
||||||
copyArgs *args = (copyArgs *)t->argPtr;
|
copyArgs *args = (copyArgs *)t->argPtr;
|
||||||
|
|
||||||
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
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;
|
uint64_t journalSize = getJournalSize(tinfo), writeCount = 0;
|
||||||
char filename[FS_MAX_PATH];
|
char filename[FS_MAX_PATH];
|
||||||
uint8_t *buff = new uint8_t[BUFF_SIZE];
|
uint8_t *buff = new uint8_t[BUFF_SIZE];
|
||||||
|
|
@ -543,7 +549,7 @@ void fs::copyZipToDir_t(void *a)
|
||||||
unzClose(args->unz);
|
unzClose(args->unz);
|
||||||
copyArgsDestroy(args);
|
copyArgsDestroy(args);
|
||||||
if(cfg::config["ovrClk"])
|
if(cfg::config["ovrClk"])
|
||||||
util::setCPU(1224000000);
|
util::setCPU(util::cpu1224MHz);
|
||||||
}
|
}
|
||||||
delete[] buff;
|
delete[] buff;
|
||||||
t->finished = true;
|
t->finished = true;
|
||||||
|
|
@ -565,3 +571,70 @@ void fs::closeZip_t(void *a)
|
||||||
zipClose(z, NULL);
|
zipClose(z, NULL);
|
||||||
t->finished = true;
|
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;
|
||||||
|
}
|
||||||
|
|
|
||||||
54
src/gfx.cpp
54
src/gfx.cpp
|
|
@ -412,3 +412,57 @@ size_t gfx::getTextWidth(const char *str, int fontSize)
|
||||||
}
|
}
|
||||||
return width;
|
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);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -392,7 +392,7 @@ static void _devMenuAddToPathFilter(void *a)
|
||||||
{
|
{
|
||||||
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
||||||
std::string filterPath = *ma->path + b->d->getItem(sel - 2);
|
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());
|
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popAddedToPathFilter", 0), filterPath.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,14 +66,14 @@ void ui::populateFldMenu()
|
||||||
fldMenu->reset();
|
fldMenu->reset();
|
||||||
|
|
||||||
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
||||||
util::createTitleDirectoryByTID(d->saveID);
|
util::createTitleDirectoryByTID(d->tid);
|
||||||
std::string targetDir = util::generatePathByTID(d->saveID);
|
std::string targetDir = util::generatePathByTID(d->tid);
|
||||||
|
|
||||||
fldList->reassign(targetDir);
|
fldList->reassign(targetDir);
|
||||||
|
|
||||||
char filterPath[128];
|
char filterPath[128];
|
||||||
sprintf(filterPath, "sdmc:/config/JKSV/0x%016lX_filter.txt", d->saveID);
|
sprintf(filterPath, "sdmc:/config/JKSV/0x%016lX_filter.txt", d->tid);
|
||||||
fs::loadPathFilters(filterPath);
|
fs::loadPathFilters(d->tid);
|
||||||
|
|
||||||
*backargs = {fldMenu, fldList};
|
*backargs = {fldMenu, fldList};
|
||||||
|
|
||||||
|
|
@ -113,7 +113,6 @@ static void ttlViewCallback(void *a)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HidNpadButton_X:
|
case HidNpadButton_X:
|
||||||
data::setTitleIndex(ttlViews[curUserIndex]->getSelected());
|
|
||||||
ttlViews[curUserIndex]->setActive(false, true);
|
ttlViews[curUserIndex]->setActive(false, true);
|
||||||
ttlOpts->setActive(true);
|
ttlOpts->setActive(true);
|
||||||
ui::ttlOptsPanel->openPanel();
|
ui::ttlOptsPanel->openPanel();
|
||||||
|
|
@ -121,9 +120,9 @@ static void ttlViewCallback(void *a)
|
||||||
|
|
||||||
case HidNpadButton_Y:
|
case HidNpadButton_Y:
|
||||||
{
|
{
|
||||||
cfg::addTitleToFavorites(d->saveID);
|
cfg::addTitleToFavorites(d->tid);
|
||||||
int newSel = data::getTitleIndexInUser(*data::getCurrentUser(), d->saveID);
|
data::user *u = data::getCurrentUser();
|
||||||
ui::ttlRefresh();
|
int newSel = data::getTitleIndexInUser(u, d->tid);
|
||||||
ttlViews[curUserIndex]->setSelected(newSel);
|
ttlViews[curUserIndex]->setSelected(newSel);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -156,20 +155,20 @@ static void ttlOptsShowInfoPanel(void *a)
|
||||||
{
|
{
|
||||||
ttlOpts->setActive(false);
|
ttlOpts->setActive(false);
|
||||||
ui::ttlOptsPanel->closePanel();
|
ui::ttlOptsPanel->closePanel();
|
||||||
infoPanelString = util::getInfoString(*data::getCurrentUser(), data::getCurrentUserTitleInfo()->saveID);
|
infoPanelString = util::getInfoString(*data::getCurrentUser(), data::getCurrentUserTitleInfo()->tid);
|
||||||
infoPanel->openPanel();
|
infoPanel->openPanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ttlOptsBlacklistTitle(void *a)
|
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::confirmArgs *conf = ui::confirmArgsCreate(false, cfg::addTitleToBlacklist, NULL, true, ui::getUICString("confirmBlacklist", 0), title.c_str());
|
||||||
ui::confirm(conf);
|
ui::confirm(conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ttlOptsDefinePath(void *a)
|
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 safeTitle = data::getTitleInfoByTID(tid)->safeTitle;
|
||||||
std::string newSafeTitle = util::getStringInput(SwkbdType_QWERTY, safeTitle, "Input New Output Folder", 0x200, 0, NULL);
|
std::string newSafeTitle = util::getStringInput(SwkbdType_QWERTY, safeTitle, "Input New Output Folder", 0x200, 0, NULL);
|
||||||
if(!newSafeTitle.empty())
|
if(!newSafeTitle.empty())
|
||||||
|
|
@ -192,7 +191,7 @@ static void ttlOptsResetSaveData_t(void *a)
|
||||||
{
|
{
|
||||||
threadInfo *t = (threadInfo *)a;
|
threadInfo *t = (threadInfo *)a;
|
||||||
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
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());
|
t->status->setStatus(ui::getUICString("threadStatusResettingSaveData", 0), title.c_str());
|
||||||
|
|
||||||
fs::mountSave(d->saveInfo);
|
fs::mountSave(d->saveInfo);
|
||||||
|
|
@ -208,7 +207,7 @@ static void ttlOptsResetSaveData(void *a)
|
||||||
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
||||||
if(d->saveInfo.save_data_type != FsSaveDataType_System)
|
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::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdDel"], ttlOptsResetSaveData_t, NULL, true, ui::getUICString("confirmResetSaveData", 0), title.c_str());
|
||||||
ui::confirm(conf);
|
ui::confirm(conf);
|
||||||
}
|
}
|
||||||
|
|
@ -221,7 +220,7 @@ static void ttlOptsDeleteSaveData_t(void *a)
|
||||||
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
||||||
unsigned userIndex = data::getCurrentUserIndex();
|
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());
|
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)))
|
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();
|
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
||||||
if(d->saveInfo.save_data_type != FsSaveDataType_System)
|
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::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdDel"], ttlOptsDeleteSaveData_t, NULL, true, ui::getUICString("confirmDeleteSaveData", 0), title.c_str());
|
||||||
ui::confirm(conf);
|
ui::confirm(conf);
|
||||||
}
|
}
|
||||||
|
|
@ -261,7 +260,7 @@ static void ttlOptsExtendSaveData_t(void *a)
|
||||||
if(!expSizeStr.empty())
|
if(!expSizeStr.empty())
|
||||||
{
|
{
|
||||||
int64_t journ = 0, expSize;
|
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());
|
t->status->setStatus(ui::getUICString("threadStatusExtendingSaveData", 0), extend->title.c_str());
|
||||||
//Get journal size
|
//Get journal size
|
||||||
switch(d->saveInfo.save_data_type)
|
switch(d->saveInfo.save_data_type)
|
||||||
|
|
@ -328,7 +327,7 @@ static void infoPanelDraw(void *a)
|
||||||
{
|
{
|
||||||
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
||||||
SDL_Texture *panel = (SDL_Texture *)a;
|
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());
|
gfx::drawTextfWrap(panel, 18, 32, 320, 362, &ui::txtCont, infoPanelString.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ ui::titleview::titleview(const data::user& _u, int _iconW, int _iconH, int _horG
|
||||||
u = &_u;
|
u = &_u;
|
||||||
|
|
||||||
for(const data::userTitleInfo& t : u->titleInfo)
|
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()
|
ui::titleview::~titleview()
|
||||||
|
|
@ -55,7 +55,7 @@ void ui::titleview::refresh()
|
||||||
|
|
||||||
tiles.clear();
|
tiles.clear();
|
||||||
for(const data::userTitleInfo& t : u->titleInfo)
|
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)
|
if(selected > (int)tiles.size() - 1 && selected > 0)
|
||||||
selected = tiles.size() - 1;
|
selected = tiles.size() - 1;
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ void ui::initStrings()
|
||||||
addUIString("confirmCopy", 0, "Are you sure you want to copy #%s# to #%s#?");
|
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("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("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
|
//Save Data related strings
|
||||||
addUIString("saveDataNoneFound", 0, "No saves found for #%s#!");
|
addUIString("saveDataNoneFound", 0, "No saves found for #%s#!");
|
||||||
|
|
@ -104,18 +105,20 @@ void ui::initStrings()
|
||||||
addUIString("extrasMenu", 11, "*[DEV]* Output en-US");
|
addUIString("extrasMenu", 11, "*[DEV]* Output en-US");
|
||||||
|
|
||||||
//User Options
|
//User Options
|
||||||
addUIString("userOptions", 0, "Create Save Data");
|
addUIString("userOptions", 0, "Dump All For ");
|
||||||
addUIString("userOptions", 1, "Create All Save Data");
|
addUIString("userOptions", 1, "Create Save Data");
|
||||||
addUIString("userOptions", 2, "Delete All User Saves");
|
addUIString("userOptions", 2, "Create All Save Data");
|
||||||
|
addUIString("userOptions", 3, "Delete All User Saves");
|
||||||
|
|
||||||
//Title Options
|
//Title Options
|
||||||
addUIString("titleOptions", 0, "Information");
|
addUIString("titleOptions", 0, "Information");
|
||||||
addUIString("titleOptions", 1, "Blacklist");
|
addUIString("titleOptions", 1, "Blacklist");
|
||||||
addUIString("titleOptions", 2, "Change Output Folder");
|
addUIString("titleOptions", 2, "Change Output Folder");
|
||||||
addUIString("titleOptions", 3, "Open in File Mode");
|
addUIString("titleOptions", 3, "Export");
|
||||||
addUIString("titleOptions", 4, "Reset Save Data");
|
addUIString("titleOptions", 4, "Open in File Mode");
|
||||||
addUIString("titleOptions", 5, "Delete Save Data");
|
addUIString("titleOptions", 5, "Reset Save Data");
|
||||||
addUIString("titleOptions", 6, "Extend Save Data");
|
addUIString("titleOptions", 6, "Delete Save Data");
|
||||||
|
addUIString("titleOptions", 7, "Extend Save Data");
|
||||||
|
|
||||||
//Thread Status Strings
|
//Thread Status Strings
|
||||||
addUIString("threadStatusCreatingSaveData", 0, "Creating save data for #%s#...");
|
addUIString("threadStatusCreatingSaveData", 0, "Creating save data for #%s#...");
|
||||||
|
|
|
||||||
|
|
@ -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))
|
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);
|
fsDeleteSaveDataFileSystemBySaveDataSpaceId(FsSaveDataSpaceId_User, tinf.saveInfo.save_data_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -216,6 +216,13 @@ static void cacheSavePanelDraw(void *a)
|
||||||
cacheSaveMenu->draw(panel, &ui::txtCont, true);
|
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)
|
static void createSaveData(void *a)
|
||||||
{
|
{
|
||||||
data::user *u = data::getCurrentUser();
|
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();
|
data::user *u = data::getCurrentUser();
|
||||||
int devPos = ui::usrMenu->getOptPos("Device");
|
int devPos = ui::usrMenu->getOptPos("Device");
|
||||||
int bcatPos = ui::usrMenu->getOptPos("BCAT");
|
int bcatPos = ui::usrMenu->getOptPos("BCAT");
|
||||||
|
|
@ -272,6 +280,14 @@ static void usrOptCreateAllSaves(void *a)
|
||||||
for(unsigned i = 0; i < bcatSids.size(); i++)
|
for(unsigned i = 0; i < bcatSids.size(); i++)
|
||||||
fs::createSaveData(FsSaveDataType_Bcat, bcatSids[i], util::u128ToAccountUID(0));
|
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
|
//Sets up save create menus
|
||||||
|
|
@ -385,15 +401,17 @@ void ui::usrInit()
|
||||||
usrOptPanel = new ui::slideOutPanel(410, 720, 0, ui::SLD_RIGHT, usrOptPanelDraw);
|
usrOptPanel = new ui::slideOutPanel(410, 720, 0, ui::SLD_RIGHT, usrOptPanelDraw);
|
||||||
ui::registerPanel(usrOptPanel);
|
ui::registerPanel(usrOptPanel);
|
||||||
|
|
||||||
for(int i = 0; i < 3; i++)
|
for(int i = 0; i < 4; i++)
|
||||||
usrOptMenu->addOpt(NULL, ui::getUIString("userOptions", i));
|
usrOptMenu->addOpt(NULL, ui::getUIString("userOptions", i));
|
||||||
|
|
||||||
|
//Dump All User Saves
|
||||||
|
usrOptMenu->optAddButtonEvent(0, HidNpadButton_A, usrOptDumpAllUserSaves, NULL);
|
||||||
//Create Save Data
|
//Create Save Data
|
||||||
usrOptMenu->optAddButtonEvent(0, HidNpadButton_A, usrOptSaveCreate, usrMenu);
|
usrOptMenu->optAddButtonEvent(1, HidNpadButton_A, usrOptSaveCreate, usrMenu);
|
||||||
//Create All
|
//Create All
|
||||||
usrOptMenu->optAddButtonEvent(1, HidNpadButton_A, usrOptCreateAllSaves, NULL);
|
usrOptMenu->optAddButtonEvent(2, HidNpadButton_A, usrOptCreateAllSaves, NULL);
|
||||||
//Delete All
|
//Delete All
|
||||||
usrOptMenu->optAddButtonEvent(2, HidNpadButton_A, usrOptDeleteAllUserSaves, NULL);
|
usrOptMenu->optAddButtonEvent(3, HidNpadButton_A, usrOptDeleteAllUserSaves, NULL);
|
||||||
usrOptMenu->setActive(false);
|
usrOptMenu->setActive(false);
|
||||||
|
|
||||||
saveCreatePanel = new ui::slideOutPanel(512, 720, 0, ui::SLD_RIGHT, saveCreatePanelDraw);
|
saveCreatePanel = new ui::slideOutPanel(512, 720, 0, ui::SLD_RIGHT, saveCreatePanelDraw);
|
||||||
|
|
@ -449,6 +467,8 @@ void ui::usrUpdate()
|
||||||
int cachePos = usrMenu->getOptPos("Cache");
|
int cachePos = usrMenu->getOptPos("Cache");
|
||||||
if(usrMenu->getSelected() <= cachePos)
|
if(usrMenu->getSelected() <= cachePos)
|
||||||
{
|
{
|
||||||
|
data::user *u = data::getCurrentUser();
|
||||||
|
usrOptMenu->editOpt(0, NULL, ui::getUIString("userOptions", 0) + u->getUsername());
|
||||||
usrOptMenu->setActive(true);
|
usrOptMenu->setActive(true);
|
||||||
usrMenu->setActive(false);
|
usrMenu->setActive(false);
|
||||||
usrOptPanel->openPanel();
|
usrOptPanel->openPanel();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user