Alpha sort save menus, tweak/fix menu code(hopefully), tweak thread proc, fix auto backup, add back a few more extras

This commit is contained in:
J-D-K 2021-08-03 22:19:42 -04:00
parent 1001eeb8de
commit 93e9fade66
13 changed files with 213 additions and 103 deletions

View File

@ -54,11 +54,7 @@ namespace fs
bool pathIsFiltered(const std::string& _path);
void freePathFilters();
inline void wipeSave()
{
fs::delDir("sv:/");
fsdevCommitDevice("sv");
}
void wipeSave();
//Dumps all titles for 'user'. returns false to bail
bool dumpAllUserSaves(const data::user& u);

View File

@ -10,5 +10,6 @@ namespace fs
void copyFileCommit_t(void *a);
void copyDirToZip_t(void *a);
void copyZipToDir_t(void *a);
void wipesave_t(void *a);
void closeZip_t(void *a);
}

View File

@ -30,6 +30,7 @@ typedef struct
{
bool running = false, finished = false;
Thread thrd;
ThreadFunc thrdFunc;
void *argPtr = NULL;
funcPtr drawFunc = NULL;//Draw func is passed threadInfo pointer too
threadStatus *status;

View File

@ -50,16 +50,17 @@ static struct
{
std::string titleA = data::getTitleNameByTID(a.saveID);
std::string titleB = data::getTitleNameByTID(b.saveID);
uint32_t tmpA, tmpB;
for(unsigned i = 0; i < titleA.length(); )
uint32_t pointA, pointB;
for(unsigned i = 0, j = 0; i < titleA.length(); )
{
ssize_t uCnt = decode_utf8(&tmpA, (const uint8_t *)&titleA.data()[i]);
decode_utf8(&tmpB, (const uint8_t *)&titleB.data()[i]);
tmpA = tolower(tmpA), tmpB = tolower(tmpB);
if(tmpA != tmpB)
return tmpA < tmpB;
ssize_t aCnt = decode_utf8(&pointA, (const uint8_t *)&titleA.data()[i]);
ssize_t bCnt = decode_utf8(&pointB, (const uint8_t *)&titleB.data()[j]);
pointA = tolower(pointA), pointB = tolower(pointB);
if(pointA != pointB)
return pointA < pointB;
i += uCnt;
i += aCnt;
j += bCnt;
}
}
break;

View File

@ -484,6 +484,11 @@ void fs::freePathFilters()
pathFilter.clear();
}
void fs::wipeSave()
{
ui::newThread(fs::wipesave_t, NULL, NULL);
}
bool fs::dumpAllUserSaves(const data::user& u)
{
for(unsigned i = 0; i < u.titleInfo.size(); i++)

View File

@ -267,14 +267,6 @@ void fs::copyDirToZip_t(void *a)
t->finished = true;
}
void fs::closeZip_t(void *a)
{
threadInfo *t = (threadInfo *)a;
zipFile z = t->argPtr;
zipClose(z, NULL);
t->finished = true;
}
void fs::copyZipToDir_t(void *a)
{
threadInfo *t = (threadInfo *)a;
@ -360,3 +352,20 @@ void fs::copyZipToDir_t(void *a)
delete[] buff;
t->finished = true;
}
void fs::wipesave_t(void *a)
{
threadInfo *t = (threadInfo *)a;
t->status->setStatus("Resetting current save...");
fs::delDir("sv:/");
fs::commitToDevice("sv");
t->finished = true;
}
void fs::closeZip_t(void *a)
{
threadInfo *t = (threadInfo *)a;
zipFile z = t->argPtr;
zipClose(z, NULL);
t->finished = true;
}

View File

@ -247,10 +247,9 @@ void ui::drawUI()
for(slideOutPanel *s : panels)
s->draw(&ui::slidePanelColor);
popMessages->draw();
threadMngr->draw();
if(!threadMngr->empty())
threadMngr->draw();
popMessages->draw();
}
static bool debugDisp = false;

View File

@ -3,6 +3,7 @@
#include "ui.h"
#include "file.h"
#include "util.h"
ui::menu *ui::extMenu;
@ -88,10 +89,53 @@ static void extMenuOptRemoveUpdate(void *a)
ui::newThread(_delUpdate, NULL, NULL);
}
static void extMenuTerminateProcess(void *a)
{
std::string idStr = util::getStringInput(SwkbdType_QWERTY, "0100000000000000", "Enter Process ID", 18, 0, NULL);
if(!idStr.empty())
{
uint64_t termID = std::strtoull(idStr.c_str(), NULL, 16);
if(R_SUCCEEDED(pmshellTerminateProgram(termID)))
ui::showPopMessage(POP_FRAME_DEFAULT, "Process %s successfully shutdown.", idStr.c_str());
}
}
static void extMenuMountSysSave(void *a)
{
FsFileSystem sys;
std::string idStr = util::getStringInput(SwkbdType_QWERTY, "8000000000000000", "Enter Sys Save ID", 18, 0, NULL);
uint64_t mountID = std::strtoull(idStr.c_str(), NULL, 16);
if(R_SUCCEEDED(fsOpen_SystemSaveData(&sys, FsSaveDataSpaceId_System, mountID, (AccountUid) {0})))
{
fsdevMountDevice("sv", sys);
ui::fmPrep(FsSaveDataType_System, "sv:/", true);
ui::usrSelPanel->closePanel();
ui::changeState(FIL_MDE);
}
}
//Todo: Not so simple now.
static void extMenuReloadTitles(void *a)
{
}
static void extMenuMountRomFS(void *a)
{
FsFileSystem tromfs;
if(R_SUCCEEDED(fsOpenDataFileSystemByCurrentProcess(&tromfs)))
{
fsdevMountDevice("tromfs", tromfs);
ui::fmPrep(FsSaveDataType_System, "tromfs:/", false);
ui::usrSelPanel->closePanel();
ui::changeState(FIL_MDE);
}
}
void ui::extInit()
{
ui::extMenu = new ui::menu;
ui::extMenu->setParams(200, 32, 1016, 24, 5);
ui::extMenu->setParams(200, 24, 1002, 24, 4);
ui::extMenu->setCallback(extMenuCallback, NULL);
ui::extMenu->setActive(false);
for(unsigned i = 0; i < 11; i++)
@ -109,6 +153,14 @@ void ui::extInit()
ui::extMenu->optAddButtonEvent(4, HidNpadButton_A, toFMUser, NULL);
//Del update
ui::extMenu->optAddButtonEvent(5, HidNpadButton_A, extMenuOptRemoveUpdate, NULL);
//Terminate Process
ui::extMenu->optAddButtonEvent(6, HidNpadButton_A, extMenuTerminateProcess, NULL);
//Mount system save
ui::extMenu->optAddButtonEvent(7, HidNpadButton_A, extMenuMountSysSave, NULL);
//Rescan
ui::extMenu->optAddButtonEvent(8, HidNpadButton_A, extMenuReloadTitles, NULL);
//RomFS
ui::extMenu->optAddButtonEvent(9, HidNpadButton_A, extMenuMountRomFS, NULL);
}
void ui::extExit()

View File

@ -383,7 +383,7 @@ void ui::fmInit()
devMenu = new ui::menu;
devMenu->setCallback(_devMenuCallback, devArgs);
devMenu->setParams(10, 8, 590, 18, 6);
devMenu->setParams(10, 8, 590, 18, 5);
devMenu->setActive(true);
devArgs->b->m = devMenu;
@ -404,7 +404,7 @@ void ui::fmInit()
sdMenu = new ui::menu;
sdMenu->setCallback(_sdMenuCallback, sdmcArgs);
sdMenu->setParams(620, 8, 590, 18, 6);
sdMenu->setParams(620, 8, 590, 18, 5);
sdMenu->setActive(false);
sdmcArgs->b->m = sdMenu;

View File

@ -29,7 +29,7 @@ void ui::menu::setParams(const unsigned& _x, const unsigned& _y, const unsigned&
rY = _y;
fSize = _fS;
mL = _mL;
rH = _fS + 24;
rH = _fS + 32;
}
void ui::menu::editParam(int _param, unsigned newVal)
@ -73,7 +73,7 @@ int ui::menu::addOpt(SDL_Texture *_icn, const std::string& add)
tmp += add.substr(i, untCnt);
i += untCnt;
if((int)gfx::getTextWidth(tmp.c_str(), fSize) >= rW - 48)
if((int)gfx::getTextWidth(tmp.c_str(), fSize) >= rW - 56)
{
newOpt.txt = tmp;
break;
@ -136,35 +136,26 @@ void ui::menu::update()
if( (down & HidNpadButton_AnyUp) || ((held & HidNpadButton_AnyUp) && fc == 10) )
{
if(selected > 0)
{
--selected;
if(selected - mL >= 0 && selected <= mSize - mL)
tY += rH;
}
}
else if( (down & HidNpadButton_AnyDown) || ((held & HidNpadButton_AnyDown) && fc == 10))
{
if(selected < mSize)
{
++selected;
if(selected - mL > 0 && selected + mL <= mSize + 1)
tY -= rH;
}
}
else if(down & HidNpadButton_AnyLeft)
{
selected -= scrL / 2;
selected -= mL;
if(selected < 0)
selected = 0;
}
else if(down & HidNpadButton_AnyRight)
{
selected += scrL / 2;
selected += mL;
if(selected > mSize)
selected = mSize;
}
if(down)
if(down && !opt[selected].events.empty())
{
for(ui::menuOptEvent& e : opt[selected].events)
{
@ -173,6 +164,13 @@ void ui::menu::update()
}
}
if(selected <= mL)
tY = mY;
else if(selected >= (mSize - mL) && mSize > mL * 2)
tY = mY + -(rH * (mSize - (mL * 2)));
else if(selected > mL && selected < (mSize - mL))
tY = -(rH * (selected - mL));
if(selected != oldSel && onChange)
(*onChange)(NULL);
@ -209,6 +207,9 @@ void ui::menu::draw(SDL_Texture *target, const SDL_Color *textClr, bool drawText
for(int i = 0, tY = y; i < (int)opt.size(); i++, tY += rH)
{
if(tY < -rH || tY > tH)
continue;
if(i == selected)
{
if(isActive)
@ -220,7 +221,7 @@ void ui::menu::draw(SDL_Texture *target, const SDL_Color *textClr, bool drawText
}
else
{
if(drawText && (tY > -rH || tY < tH))
if(drawText)
gfx::drawTextf(target, fSize, x + 20, (y + (rH / 2 - fSize / 2)) + (i * rH), textClr, opt[i].txt.c_str());
}

View File

@ -146,7 +146,7 @@ static void updateMenuText()
void ui::settInit()
{
ui::settMenu = new ui::menu;
ui::settMenu->setParams(200, 32, 1016, 24, 5);
ui::settMenu->setParams(200, 24, 1002, 24, 4);
ui::settMenu->setCallback(settMenuCallback, NULL);
ui::settMenu->setActive(false);

View File

@ -4,7 +4,9 @@
#include "ui.h"
#include "gfx.h"
//Thread status screen always using white
#include "file.h"
//Thread status screen always uses white
static const SDL_Color white = {0xFF, 0xFF, 0xFF, 0xFF};
static const SDL_Color darkenBack = {0x00, 0x00, 0x00, 0xBB};
@ -23,36 +25,32 @@ threadInfo *ui::threadProcMngr::newThread(ThreadFunc func, void *args, funcPtr _
{
threadInfo *t = new threadInfo;
t->status = new threadStatus;
t->running = false;
t->finished = false;
t->thrdFunc = func;
t->drawFunc = _drawfunc;
t->argPtr = args;
if(R_SUCCEEDED(threadCreate(&t->thrd, func, t, NULL, 0x20000, 0x2B, 1)))
{
mutexLock(&threadLock);
threads.push_back(t);
mutexUnlock(&threadLock);
return threads[threads.size() - 1];
}
else
{
delete t->status;
delete t;
}
return NULL;
mutexLock(&threadLock);
threads.push_back(t);
mutexUnlock(&threadLock);
return threads[threads.size() - 1];
}
void ui::threadProcMngr::update()
{
if(!threads.empty())
{
Result res = 0;
threadInfo *t = threads[0];
if(t->running == false && t->finished == false)
if(!t->running && R_SUCCEEDED((res = threadCreate(&t->thrd, t->thrdFunc, t, NULL, 0x20000, 0x2B, 1))))
{
t->running = true;
threadStart(&t->thrd);
t->running = true;
}
else if(t->running == true && t->finished == true)
else if(!t->running && R_FAILED(res))//Should kill the thread that failed.
t->finished = true;
else if(t->finished)
{
threadWaitForExit(&t->thrd);
threadClose(&t->thrd);
@ -67,27 +65,32 @@ void ui::threadProcMngr::update()
void ui::threadProcMngr::draw()
{
if(++frameCount % 4 == 0 && ++lgFrame > 7)
lgFrame = 0;
if(clrAdd && (clrShft += 6) >= 0x72)
clrAdd = false;
else if(!clrAdd && (clrShft -= 3) <= 0x00)
clrAdd = true;
SDL_Color glyphCol = {0x00, (uint8_t)(0x88 + clrShft), (uint8_t)(0xC5 + (clrShft / 2)), 0xFF};
gfx::drawRect(NULL, &darkenBack, 0, 0, 1280, 720);
gfx::drawTextf(NULL, 32, 56, 673, &glyphCol, loadGlyphArray[lgFrame].c_str());
if(threads[0]->drawFunc)
(*(threads[0]->drawFunc))(threads[0]);
else
if(!threads.empty())
{
std::string gStatus;
threads[0]->status->getStatus(gStatus);
if(++frameCount % 4 == 0 && ++lgFrame > 7)
lgFrame = 0;
int statX = 640 - (gfx::getTextWidth(gStatus.c_str(), 18) / 2);
gfx::drawTextf(NULL, 18, statX, 387, &white, gStatus.c_str());
if(clrAdd && (clrShft += 6) >= 0x72)
clrAdd = false;
else if(!clrAdd && (clrShft -= 3) <= 0x00)
clrAdd = true;
SDL_Color glyphCol = {0x00, (uint8_t)(0x88 + clrShft), (uint8_t)(0xC5 + (clrShft / 2)), 0xFF};
gfx::drawRect(NULL, &darkenBack, 0, 0, 1280, 720);
gfx::drawTextf(NULL, 32, 56, 673, &glyphCol, loadGlyphArray[lgFrame].c_str());
threadInfo *t = threads[0];
if(t->drawFunc)
(*(t->drawFunc))(t);
else
{
std::string gStatus;
t->status->getStatus(gStatus);
int statX = 640 - (gfx::getTextWidth(gStatus.c_str(), 18) / 2);
gfx::drawTextf(NULL, 18, statX, 387, &white, gStatus.c_str());
}
}
}

View File

@ -1,5 +1,6 @@
#include <string>
#include <vector>
#include <algorithm>
#include <switch.h>
#include "file.h"
@ -37,6 +38,30 @@ static std::vector<uint64_t> accSids, devSids, bcatSids, cacheSids;
static unsigned usrHelpX = 0;
//Sort save create tids alphabetically by title from data
static struct
{
bool operator()(const uint64_t& tid1, const uint64_t& tid2)
{
std::string tid1Title = data::getTitleNameByTID(tid1);
std::string tid2Title = data::getTitleNameByTID(tid2);
uint32_t pointA = 0, pointB = 0;
for(unsigned i = 0, j = 0; i < tid1Title.length(); )
{
ssize_t tid1Cnt = decode_utf8(&pointA, (const uint8_t *)&tid1Title.c_str()[i]);
ssize_t tid2Cnt = decode_utf8(&pointB, (const uint8_t *)&tid2Title.c_str()[j]);
pointA = tolower(pointA), pointB = tolower(pointB);
if(pointA != pointB)
return pointA < pointB;
i += tid1Cnt, j += tid2Cnt;
}
return false;
}
} sortCreateTIDs;
static void onMainChange(void *a)
{
if(ui::usrMenu->getSelected() < (int)data::users.size())
@ -317,23 +342,23 @@ void ui::usrInit()
bcatSaveMenu = new ui::menu;
cacheSaveMenu = new ui::menu;
usrMenu->setParams(64, 16, 0, 96, 2);
usrOptMenu->setParams(8, 32, 390, 20, 7);
usrMenu->setParams(54, 16, 0, 106, 1);
usrOptMenu->setParams(8, 32, 390, 20, 6);
usrOptMenu->setCallback(usrOptCallback, NULL);
saveCreateMenu->setParams(8, 32, 492, 20, 7);
saveCreateMenu->setParams(8, 32, 492, 20, 6);
saveCreateMenu->setActive(false);
saveCreateMenu->setCallback(saveCreateCallback, NULL);
deviceSaveMenu->setParams(8, 32, 492, 20, 7);
deviceSaveMenu->setParams(8, 32, 492, 20, 6);
deviceSaveMenu->setActive(false);
deviceSaveMenu->setCallback(saveCreateCallback, NULL);
bcatSaveMenu->setParams(8, 32, 492, 20, 7);
bcatSaveMenu->setParams(8, 32, 492, 20, 6);
bcatSaveMenu->setActive(false);
bcatSaveMenu->setCallback(saveCreateCallback, NULL);
cacheSaveMenu->setParams(8, 32, 492, 20, 7);
cacheSaveMenu->setParams(8, 32, 492, 20, 6);
cacheSaveMenu->setActive(false);
cacheSaveMenu->setCallback(saveCreateCallback, NULL);
@ -352,7 +377,7 @@ void ui::usrInit()
usrMenu->optAddButtonEvent(pos, HidNpadButton_A, toEXT, NULL);
usrMenu->setOnChangeFunc(onMainChange);
usrMenu->editParam(MENU_RECT_WIDTH, 126);
usrMenu->editParam(MENU_RECT_WIDTH, 136);
usrSelPanel = new ui::slideOutPanel(200, 559, 89, ui::SLD_LEFT, _usrSelPanelDraw);
usrSelPanel->setX(0);
@ -384,38 +409,55 @@ void ui::usrInit()
devCreate = {FsSaveDataType_Device, deviceSaveMenu};
bcatCreate = {FsSaveDataType_Bcat, bcatSaveMenu};
cacheCreate = {FsSaveDataType_Cache, cacheSaveMenu};
//Group into vectors to match
for(auto& t : data::titles)
{
NacpStruct *nacp = &t.second.nacp;
if(nacp->user_account_save_data_size > 0)
{
int optPos = saveCreateMenu->addOpt(NULL, t.second.title);
saveCreateMenu->optAddButtonEvent(optPos, HidNpadButton_A, createSaveData, &accCreate);
accSids.push_back(t.first);
}
if(nacp->device_save_data_size > 0)
{
int optPos = deviceSaveMenu->addOpt(NULL, t.second.title);
deviceSaveMenu->optAddButtonEvent(optPos, HidNpadButton_A, createSaveData, &devCreate);
devSids.push_back(t.first);
}
if(nacp->bcat_delivery_cache_storage_size > 0)
{
int optPos = bcatSaveMenu->addOpt(NULL, t.second.title);
bcatSaveMenu->optAddButtonEvent(optPos, HidNpadButton_A, createSaveData, &bcatCreate);
bcatSids.push_back(t.first);
}
if(nacp->cache_storage_size > 0 || nacp->cache_storage_journal_size > 0 || nacp->cache_storage_data_and_journal_size_max > 0)
{
int optPos = cacheSaveMenu->addOpt(NULL, t.second.title);
cacheSaveMenu->optAddButtonEvent(optPos, HidNpadButton_A, createSaveData, &cacheCreate);
cacheSids.push_back(t.first);
}
}
//Sort them alphabetically
std::sort(accSids.begin(), accSids.end(), sortCreateTIDs);
std::sort(devSids.begin(), devSids.end(), sortCreateTIDs);
std::sort(bcatSids.begin(), bcatSids.end(), sortCreateTIDs);
std::sort(cacheSids.begin(), cacheSids.end(), sortCreateTIDs);
for(unsigned i = 0; i < accSids.size(); i++)
{
saveCreateMenu->addOpt(NULL, data::getTitleNameByTID(accSids[i]));
saveCreateMenu->optAddButtonEvent(i, HidNpadButton_A, createSaveData, &accCreate);
}
for(unsigned i = 0; i < devSids.size(); i++)
{
deviceSaveMenu->addOpt(NULL, data::getTitleNameByTID(devSids[i]));
deviceSaveMenu->optAddButtonEvent(i, HidNpadButton_A, createSaveData, &devCreate);
}
for(unsigned i = 0; i < bcatSids.size(); i++)
{
bcatSaveMenu->addOpt(NULL, data::getTitleNameByTID(bcatSids[i]));
bcatSaveMenu->optAddButtonEvent(i, HidNpadButton_A, createSaveData, &bcatCreate);
}
for(unsigned i = 0; i < cacheSids.size(); i++)
{
cacheSaveMenu->addOpt(NULL, data::getTitleNameByTID(cacheSids[i]));
cacheSaveMenu->optAddButtonEvent(i, HidNpadButton_A, createSaveData, &cacheCreate);
}
usrHelpX = 1220 - gfx::getTextWidth(ui::userHelp.c_str(), 18);
}