diff --git a/Makefile b/Makefile index 9b4b0ab..b9e64ec 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ INCLUDES := inc EXEFS_SRC := exefs_src APP_TITLE := JKSV APP_AUTHOR := JK -APP_VERSION := 07.12.2021 +APP_VERSION := 07.13.2021 ROMFS := romfs ICON := icon.jpg diff --git a/inc/data.h b/inc/data.h index af79149..281bd9a 100644 --- a/inc/data.h +++ b/inc/data.h @@ -11,7 +11,7 @@ #define curData users[data::selUser].titleInfo[data::selData] #define BLD_MON 7 -#define BLD_DAY 12 +#define BLD_DAY 13 #define BLD_YEAR 2021 namespace data diff --git a/inc/file.h b/inc/file.h index 457cd26..68d6cfe 100644 --- a/inc/file.h +++ b/inc/file.h @@ -20,6 +20,7 @@ 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); diff --git a/inc/sett.h b/inc/sett.h new file mode 100644 index 0000000..331d6ff --- /dev/null +++ b/inc/sett.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +namespace ui +{ + void settInit(); + void settExit(); + void settUpdate(); + void settDraw(SDL_Texture *target); +} diff --git a/inc/ui.h b/inc/ui.h index dfd38cb..434afec 100644 --- a/inc/ui.h +++ b/inc/ui.h @@ -12,6 +12,7 @@ #include "uistr.h" #include "usr.h" #include "ttl.h" +#include "sett.h" enum menuState { diff --git a/inc/uistr.h b/inc/uistr.h index 240aa62..076926e 100644 --- a/inc/uistr.h +++ b/inc/uistr.h @@ -22,7 +22,7 @@ namespace ui //Strings for sort type extern std::string sortString[3]; //Strings for user options - extern std::string usrOptString[1]; + extern std::string usrOptString[2]; //Strings for title options - extern std::string titleOptString[4]; + extern std::string titleOptString[5]; } diff --git a/inc/usr.h b/inc/usr.h index 2ee8276..decbd05 100644 --- a/inc/usr.h +++ b/inc/usr.h @@ -4,7 +4,9 @@ namespace ui { void usrInit(); void usrExit(); - void usrMenuSetActive(bool _set); void usrUpdate(); void usrDraw(SDL_Texture *target); + + //A lot of stuff needs access to this + extern ui::menu *usrMenu; } diff --git a/src/data.cpp b/src/data.cpp index 15e6b8f..2916d1a 100644 --- a/src/data.cpp +++ b/src/data.cpp @@ -460,12 +460,12 @@ void data::saveBlackList() void data::blacklistAdd(const uint64_t& tid) { + blacklist.push_back(tid); for(data::user& _u : data::users) { for(unsigned i = 0; i < _u.titleInfo.size(); i++) if(_u.titleInfo[i].saveID == tid) _u.titleInfo.erase(_u.titleInfo.begin() + i); } - blacklist.push_back(tid); } void data::favoriteTitle(const uint64_t& tid) diff --git a/src/file.cpp b/src/file.cpp index 291e332..57ad77a 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -171,6 +171,20 @@ bool fs::mountSave(const FsSaveDataInfo& _m) 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); +} + fs::dirItem::dirItem(const std::string& pathTo, const std::string& sItem) { itm = sItem; diff --git a/src/gfx.cpp b/src/gfx.cpp index 35f2851..359a41f 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -374,7 +374,7 @@ size_t gfx::getTextWidth(const char *str, int fontSize) i += unitCnt; //Ignore these - if(point == '\n') + if(point == '\n' || point == '#' || point == '*' || point == '<' || point == '>') continue; glyphData *g = getGlyph(point, fontSize); diff --git a/src/ui.cpp b/src/ui.cpp index fc7b1aa..704c0bd 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -46,6 +46,7 @@ SDL_Color ui::heartColor = {0xFF, 0x44, 0x44, 0xFF}; //X position of help texts. Calculated to make editing quicker/easier static unsigned userHelpX, titleHelpX, folderHelpX, optHelpX; +static int settPos, extPos; //For shrinking left panel unsigned leftWidth = 410; @@ -153,12 +154,18 @@ void ui::init() //advCopyMenuPrep(); ui::usrInit(); ui::ttlInit(); + ui::settInit(); + + //Need these from user/main menu + settPos = ui::usrMenu->getOptPos("Settings"); + extPos = ui::usrMenu->getOptPos("Extras"); } void ui::exit() { ui::usrExit(); ui::ttlExit(); + ui::settExit(); SDL_DestroyTexture(cornerTopLeft); SDL_DestroyTexture(cornerTopRight); @@ -212,7 +219,14 @@ void ui::drawUI() gfx::texDraw(leftPanel, sideBar, 0, 89); ui::usrDraw(leftPanel); - ui::ttlDraw(rightPanel); + + if(ui::usrMenu->getSelected() == settPos || ui::mstate == OPT_MNU) + ui::settDraw(rightPanel); + else if(usrMenu->getSelected() == extPos || ui::mstate == EX_MNU) + gfx::drawTextf(rightPanel, 24, 32, 32, &ui::txtCont, "PLACE HOLDER SO COMPILER DOESN'T COMPLAIN"); + else + ui::ttlDraw(rightPanel); + gfx::texDraw(NULL, rightPanel, 200, 89); gfx::texDraw(NULL, leftPanel, 0, 89); for(slideOutPanel *s : panels) @@ -242,13 +256,7 @@ bool ui::runApp() break; case OPT_MNU: - /*optMenu.update(); - if(down & HidNpadButton_B) - { - ui::changeState(USR_SEL); - mainMenu.setActive(true); - optMenu.setActive(false); - }*/ + settUpdate(); break; case EX_MNU: @@ -278,7 +286,7 @@ void ui::toTTL(void *a) { ui::changeState(TTL_SEL); ui::ttlSetActive(data::selUser); - ui::usrMenuSetActive(false); + ui::usrMenu->setActive(false); } else ui::showPopup(POP_FRAME_DEFAULT, ui::noSavesFound.c_str(), data::curUser.getUsername().c_str()); diff --git a/src/ui/sett.cpp b/src/ui/sett.cpp new file mode 100644 index 0000000..d42af7e --- /dev/null +++ b/src/ui/sett.cpp @@ -0,0 +1,32 @@ +#include +#include + +#include "ui.h" +#include "sett.h" + +static ui::menu *settMenu; + +void ui::settInit() +{ + settMenu = new ui::menu; + settMenu->setParams(32, 32, 710, 24, 8); + settMenu->setActive(false); + + for(unsigned i = 0; i < 15; i++) + settMenu->addOpt(NULL, ui::optMenuStr[i]); +} + +void ui::settExit() +{ + delete settMenu; +} + +void ui::settUpdate() +{ + settMenu->update(); +} + +void ui::settDraw(SDL_Texture *target) +{ + settMenu->draw(target, &ui::txtCont, true); +} diff --git a/src/ui/ttl.cpp b/src/ui/ttl.cpp index 3b0eea1..1a14a4d 100644 --- a/src/ui/ttl.cpp +++ b/src/ui/ttl.cpp @@ -59,7 +59,7 @@ static void ttlViewCallback(void *a) case HidNpadButton_B: ttlViews[data::selUser]->setActive(false); - ui::usrMenuSetActive(true); + ui::usrMenu->setActive(true); ui::changeState(USR_SEL); break; @@ -77,7 +77,7 @@ static void ttlViewCallback(void *a) uint64_t sid = data::curData.saveID; data::favoriteTitle(sid); int newSel = data::getTitleIndexInUser(data::curUser, sid); - ttlViews[data::selUser]->refresh(); + ui::refreshAllViews(); ttlViews[data::selUser]->setSelected(newSel); } break; @@ -182,7 +182,7 @@ static void ttlOptsDeleteSaveData(void *a) //Kick back to user ttlOptsPanel->closePanel();//JIC ttlViews[data::selUser]->setActive(false); - ui::usrMenuSetActive(true); + ui::usrMenu->setActive(true); ui::changeState(USR_SEL); } ui::showPopup(POP_FRAME_DEFAULT, ui::saveDataDeleteSuccess.c_str(), title.c_str()); @@ -190,6 +190,30 @@ static void ttlOptsDeleteSaveData(void *a) } } +static void ttlOptsExtendSaveData(void *a) +{ + std::string expSizeStr = util::getStringInput("", "Enter Expansion size in MB", 8, 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::showPopup(POP_FRAME_DEFAULT, "Save data expanded for %s!", extend->title.c_str()); + else + { + ui::showPopup(POP_FRAME_DEFAULT, "Failed to expand save data."); + fs::logWrite("Extend Failed: %u -> %X\n", expSize, res); + } + } +} + static void infoPanelDraw(void *a) { SDL_Texture *panel = (SDL_Texture *)a; @@ -236,6 +260,9 @@ void ui::ttlInit() ttlOpts->setOptFunc(2, FUNC_A, ttlOptsResetSaveData, NULL); ttlOpts->addOpt(NULL, ui::titleOptString[3]); ttlOpts->setOptFunc(3, FUNC_A, ttlOptsDeleteSaveData, NULL); + ttlOpts->addOpt(NULL, ui::titleOptString[4]); + ttlOpts->setOptFunc(4, FUNC_A, ttlOptsExtendSaveData, NULL); + } void ui::ttlExit() diff --git a/src/ui/uistr.cpp b/src/ui/uistr.cpp index 6fe2d58..1ea8017 100644 --- a/src/ui/uistr.cpp +++ b/src/ui/uistr.cpp @@ -44,8 +44,8 @@ std::string ui::exMenuStr[11] = { "SD to SD Browser", "BIS: PRODINFOF", "BIS: SA std::string ui::optMenuStr[15] = { "Include Device Saves: ", "AutoBackup: ", "Overclock: ", "Hold to Delete: ", "Hold to Restore: ", "Hold to Overwrite: ", "Force Mount: ", "Account Sys. Saves: ", "Write to Sys. Saves: ", "Text UI Mode: ", "Direct FS Cmd: ", "Skip User Select: ", "Export to ZIP: ", "Language Override: ", "Sort: "}; std::string ui::holdingText[3] = { "(Hold) ", "(Keep Holding) ", "(Almost there!) " }; std::string ui::sortString[3] = { "Alphabetical", "Time Played", "Last Played" }; -std::string ui::usrOptString[1] = { "Create Save Data" }; -std::string ui::titleOptString[4] = {"Information", "Blacklist", "Reset Save Data", "Delete Save Filesystem"}; +std::string ui::usrOptString[2] = { "Create Save Data", "Delete All User Saves" }; +std::string ui::titleOptString[5] = {"Information", "Blacklist", "Reset Save Data", "Delete Save Filesystem", "Extend Save Filesystem"}; void ui::loadTrans() { diff --git a/src/ui/usr.cpp b/src/ui/usr.cpp index 1f5d8fa..50508bb 100644 --- a/src/ui/usr.cpp +++ b/src/ui/usr.cpp @@ -12,7 +12,9 @@ #include "ttl.h" //Main menu/Users + options, folder -static ui::menu *usrMenu, *usrOptMenu, *saveCreateMenu, *deviceSaveMenu, *bcatSaveMenu, *cacheSaveMenu; +ui::menu *ui::usrMenu; + +static ui::menu *usrOptMenu, *saveCreateMenu, *deviceSaveMenu, *bcatSaveMenu, *cacheSaveMenu; //All save types have different entries. static ui::slideOutPanel *usrOptPanel, *saveCreatePanel, *deviceSavePanel, *bcatSavePanel, *cacheSavePanel; @@ -36,20 +38,20 @@ static unsigned usrHelpX = 0; static void onMainChange(void *a) { - if(usrMenu->getSelected() < (int)data::users.size()) - data::selUser = usrMenu->getSelected(); + if(ui::usrMenu->getSelected() < (int)data::users.size()) + data::selUser = ui::usrMenu->getSelected(); } static void toOPT(void *a) { ui::changeState(OPT_MNU); - ui::usrMenuSetActive(false); + ui::usrMenu->setActive(false); } static void toEXT(void *a) { ui::changeState(EX_MNU); - ui::usrMenuSetActive(false); + ui::usrMenu->setActive(false); } static void usrOptCallback(void *a) @@ -58,7 +60,7 @@ static void usrOptCallback(void *a) { case HidNpadButton_B: usrOptPanel->closePanel(); - usrMenu->setActive(true); + ui::usrMenu->setActive(true); usrOptMenu->setActive(false); break; } @@ -125,6 +127,29 @@ static void usrOptSaveCreate(void *a) } } +//nsDeleteUserSaveDataAll only works if the user is selected at system level +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(); + } +} + static void usrOptPanelDraw(void *a) { SDL_Texture *panel = (SDL_Texture *)a; @@ -212,7 +237,7 @@ static void createSaveData(void *a) case FsSaveDataType_Bcat: saveSize = create->nacp.bcat_delivery_cache_storage_size; - journalSize = create->nacp.user_account_save_data_journal_size; + journalSize = create->nacp.bcat_delivery_cache_storage_size;//This needs to be fixed break; case FsSaveDataType_Cache: @@ -300,6 +325,8 @@ void ui::usrInit() ui::registerPanel(usrOptPanel); usrOptMenu->addOpt(NULL, ui::usrOptString[0]); usrOptMenu->setOptFunc(0, FUNC_A, usrOptSaveCreate, usrMenu); + usrOptMenu->addOpt(NULL, ui::usrOptString[1]); + usrOptMenu->setOptFunc(1, FUNC_A, usrOptDeleteAllUserSaves, NULL); usrOptMenu->setActive(false); saveCreatePanel = new ui::slideOutPanel(410, 720, 0, saveCreatePanelDraw); @@ -372,11 +399,6 @@ void ui::usrExit() SDL_DestroyTexture(ext); } -void ui::usrMenuSetActive(bool _set) -{ - usrMenu->setActive(_set); -} - void ui::usrUpdate() { usrMenu->update(); @@ -386,14 +408,21 @@ void ui::usrUpdate() bcatSaveMenu->update(); cacheSaveMenu->update(); + //Todo: Not this if(!usrOptMenu->getActive() && !saveCreateMenu->getActive() && !deviceSaveMenu->getActive() && !bcatSaveMenu->getActive() && !cacheSaveMenu->getActive()) { switch(ui::padKeysDown()) { case HidNpadButton_X: - usrOptMenu->setActive(true); - usrMenu->setActive(false); - usrOptPanel->openPanel(); + { + int cachePos = usrMenu->getOptPos("Cache"); + if(usrMenu->getSelected() <= cachePos) + { + usrOptMenu->setActive(true); + usrMenu->setActive(false); + usrOptPanel->openPanel(); + } + } break; } }