From 0284cf644f4ab9bb06872703e9ebd91abf35b848 Mon Sep 17 00:00:00 2001 From: BernardoGiordano Date: Tue, 17 Jul 2018 18:25:07 +0200 Subject: [PATCH] general updates --- 3ds/source/title.cpp | 8 +++--- common/iscrollable.hpp | 5 ++++ switch/include/configuration.hpp | 2 -- switch/include/filesystem.hpp | 2 +- switch/include/scrollable.hpp | 1 + switch/include/title.hpp | 8 +++++- switch/romfs/config.json | 1 - switch/source/configuration.cpp | 8 ------ switch/source/filesystem.cpp | 5 ++++ switch/source/gui.cpp | 10 +++++--- switch/source/io.cpp | 22 +++++++++++----- switch/source/main.cpp | 7 ++--- switch/source/scrollable.cpp | 4 +++ switch/source/title.cpp | 44 ++++++++++++++++++++++++++++++-- 14 files changed, 96 insertions(+), 31 deletions(-) diff --git a/3ds/source/title.cpp b/3ds/source/title.cpp index 6334a06..ec9aa77 100644 --- a/3ds/source/title.cpp +++ b/3ds/source/title.cpp @@ -77,7 +77,7 @@ bool Title::load(u64 _id, FS_MediaType _media, FS_CardType _card) AM_GetTitleProductCode(mMedia, mId, productCode); mAccessibleSave = Archive::accessible(mediaType(), lowId(), highId()); - mAccessibleExtdata = Archive::accessible(extdataId()); + mAccessibleExtdata = mMedia == MEDIATYPE_NAND ? false : Archive::accessible(extdataId()); if (mAccessibleSave) { @@ -89,7 +89,7 @@ bool Title::load(u64 _id, FS_MediaType _media, FS_CardType _card) { Gui::createError(res, "Failed to create backup directory."); } - } + } } if (mAccessibleExtdata) @@ -257,7 +257,7 @@ void Title::refreshDirectories(void) } else { - Gui::createError(savelist.error(), "Couldn't retrieve the directory list for the title " + shortDescription()); + Gui::createError(savelist.error(), "Couldn't retrieve the directory list\nfor the title " + shortDescription()); } // save backups from configuration @@ -302,7 +302,7 @@ void Title::refreshDirectories(void) } else { - Gui::createError(extlist.error(), "Couldn't retrieve the extdata list for the title " + shortDescription()); + Gui::createError(extlist.error(), "Couldn't retrieve the extdata list\nfor the title " + shortDescription()); } // extdata backups from configuration diff --git a/common/iscrollable.hpp b/common/iscrollable.hpp index c9b8246..7ad2e73 100644 --- a/common/iscrollable.hpp +++ b/common/iscrollable.hpp @@ -103,6 +103,11 @@ public: mIndex = i - mPage * mVisibleEntries; } + size_t visibleEntries(void) + { + return mVisibleEntries; + } + protected: int mx; int my; diff --git a/switch/include/configuration.hpp b/switch/include/configuration.hpp index 0f97bd3..20f9a17 100644 --- a/switch/include/configuration.hpp +++ b/switch/include/configuration.hpp @@ -45,7 +45,6 @@ public: } bool filter(u64 id); - bool nandSaves(void); std::vector additionalSaveFolders(u64 id); private: @@ -60,7 +59,6 @@ private: nlohmann::json mJson; std::unordered_set mFilterIds; std::unordered_map> mAdditionalSaveFolders; - bool mNandSaves; std::string BASEPATH = "/switch/Checkpoint/config.json"; }; diff --git a/switch/include/filesystem.hpp b/switch/include/filesystem.hpp index 38e26b8..394e733 100644 --- a/switch/include/filesystem.hpp +++ b/switch/include/filesystem.hpp @@ -28,11 +28,11 @@ #define FILESYSTEM_HPP #include -#include "gui.hpp" namespace FileSystem { Result mount(FsFileSystem* fileSystem, u64 titleID, u128 userID); + Result mount(FsFileSystem* fileSystem, u64 saveID); int mount(FsFileSystem fs); void unmount(void); } diff --git a/switch/include/scrollable.hpp b/switch/include/scrollable.hpp index f9fa245..24aa19c 100644 --- a/switch/include/scrollable.hpp +++ b/switch/include/scrollable.hpp @@ -31,6 +31,7 @@ #include #include "iscrollable.hpp" #include "clickable.hpp" +#include "colors.hpp" #include "draw.hpp" #include "hid.hpp" diff --git a/switch/include/title.hpp b/switch/include/title.hpp index 5f98908..a5655d3 100644 --- a/switch/include/title.hpp +++ b/switch/include/title.hpp @@ -45,7 +45,7 @@ extern "C" { class Title { public: - void init(u64 titleid, u128 userID, const std::string& name, const std::string& author); + void init(u8 saveDataType, u64 titleid, u128 userID, const std::string& name, const std::string& author); ~Title(void) { }; std::string author(void); @@ -54,9 +54,12 @@ public: u64 id(void); std::string name(void); std::string path(void); + std::string fullPath(size_t index); void refreshDirectories(void); std::vector saves(void); + u8 saveDataType(void); + bool systemSave(void); u128 userId(void); std::string userName(void); @@ -70,6 +73,9 @@ private: std::string mPath; std::vector mSaves; + std::vector + mFullSavePaths; + u8 mSaveDataType; }; void getTitle(Title &dst, u128 uid, size_t i); diff --git a/switch/romfs/config.json b/switch/romfs/config.json index f51e910..8b58653 100644 --- a/switch/romfs/config.json +++ b/switch/romfs/config.json @@ -5,7 +5,6 @@ "additional_save_folders": { }, - "nand_saves": false, "version_major": 3, "version_minor": 3, "version_micro": 1 diff --git a/switch/source/configuration.cpp b/switch/source/configuration.cpp index d27c336..47034cb 100644 --- a/switch/source/configuration.cpp +++ b/switch/source/configuration.cpp @@ -54,9 +54,6 @@ Configuration::Configuration(void) mFilterIds.emplace(strtoull(id.c_str(), NULL, 16)); } - // parse nand saves - mNandSaves = mJson["nand_saves"]; - // parse additional save folders auto js = mJson["additional_save_folders"]; for (auto it = js.begin(); it != js.end(); ++it) @@ -85,11 +82,6 @@ bool Configuration::filter(u64 id) return mFilterIds.find(id) != mFilterIds.end(); } -bool Configuration::nandSaves(void) -{ - return mNandSaves; -} - std::vector Configuration::additionalSaveFolders(u64 id) { std::vector emptyvec; diff --git a/switch/source/filesystem.cpp b/switch/source/filesystem.cpp index e50bfad..ea33180 100644 --- a/switch/source/filesystem.cpp +++ b/switch/source/filesystem.cpp @@ -31,6 +31,11 @@ Result FileSystem::mount(FsFileSystem* fileSystem, u64 titleID, u128 userID) return fsMount_SaveData(fileSystem, titleID, userID); } +Result FileSystem::mount(FsFileSystem* fileSystem, u64 saveID) +{ + return fsMount_SystemSaveData(fileSystem, saveID); +} + int FileSystem::mount(FsFileSystem fs) { return fsdevMountDevice("save", fs); diff --git a/switch/source/gui.cpp b/switch/source/gui.cpp index bbaef3c..96f80ce 100644 --- a/switch/source/gui.cpp +++ b/switch/source/gui.cpp @@ -208,8 +208,8 @@ void Gui::drawCopy(const std::string& src, u64 offset, u64 size) bool Gui::askForConfirmation(const std::string& text) { bool ret = false; - Clickable* buttonYes = new Clickable(293, 540, 200, 80, COLOR_WHITE, COLOR_BLACK, "Yes", true); - Clickable* buttonNo = new Clickable(786, 540, 200, 80, COLOR_WHITE, COLOR_BLACK, "No", true); + Clickable* buttonYes = new Clickable(293, 540, 200, 80, COLOR_WHITE, COLOR_BLACK, "Yes (A)", true); + Clickable* buttonNo = new Clickable(786, 540, 200, 80, COLOR_WHITE, COLOR_BLACK, "No (B)", true); MessageBox* message = new MessageBox(COLOR_GREY_DARK, COLOR_WHITE); message->push_message(text); @@ -306,6 +306,10 @@ void Gui::draw(u128 uid) { DrawImage(x, y, USER_ICON_SIZE, USER_ICON_SIZE, Account::icon(userIds.at(i)), IMAGE_MODE_RGB24); } + else + { + rectangle(x, y, USER_ICON_SIZE, USER_ICON_SIZE, COLOR_BLACK); + } } // title icons @@ -319,7 +323,7 @@ void Gui::draw(u128 uid) } else { - rectangle(selectorx, selectory, 128, 128, COLOR_WHITE); + rectangle(selectorx, selectory, 128, 128, COLOR_BLACK); } if (!selEnt.empty() && std::find(selEnt.begin(), selEnt.end(), k) != selEnt.end()) diff --git a/switch/source/io.cpp b/switch/source/io.cpp index 1d4f77c..ffee64f 100644 --- a/switch/source/io.cpp +++ b/switch/source/io.cpp @@ -220,7 +220,7 @@ void io::backup(size_t index, u128 uid) else { Gui::createError(res, "Failed to mount save."); - return; + return; } std::string suggestion = DateTime::dateTimeStr() + " " + StringUtils::removeNotAscii(StringUtils::removeAccents(Account::username(title.userId()))); @@ -228,14 +228,24 @@ void io::backup(size_t index, u128 uid) if (Gui::multipleSelectionEnabled()) { - customPath = isNewFolder ? suggestion : Gui::nameFromCell(cellIndex); + customPath = isNewFolder ? suggestion : ""; } else { - customPath = isNewFolder ? StringUtils::removeForbiddenCharacters(KeyboardManager::get().keyboard(suggestion)) : Gui::nameFromCell(cellIndex); + customPath = isNewFolder ? StringUtils::removeForbiddenCharacters(KeyboardManager::get().keyboard(suggestion)) : ""; } - std::string dstPath = title.path() + "/" + customPath; + std::string dstPath; + if (!isNewFolder) + { + // we're overriding an existing folder + dstPath = title.fullPath(cellIndex); + } + else + { + dstPath = title.path() + "/" + customPath; + } + if (!isNewFolder || io::directoryExists(dstPath)) { int ret = io::deleteFolderRecursively(dstPath.c_str()); @@ -277,7 +287,7 @@ void io::restore(size_t index, u128 uid) getTitle(title, uid, index); FsFileSystem fileSystem; - res = FileSystem::mount(&fileSystem, title.id(), title.userId()); + res = title.systemSave() ? FileSystem::mount(&fileSystem, title.id()) : FileSystem::mount(&fileSystem, title.id(), title.userId()); if (R_SUCCEEDED(res)) { int ret = FileSystem::mount(fileSystem); @@ -294,7 +304,7 @@ void io::restore(size_t index, u128 uid) return; } - std::string srcPath = title.path() + "/" + Gui::nameFromCell(cellIndex) + "/"; + std::string srcPath = title.fullPath(cellIndex) + "/"; std::string dstPath = "save:/"; res = io::deleteFolderRecursively(dstPath.c_str()); diff --git a/switch/source/main.cpp b/switch/source/main.cpp index c6a1a80..dcef880 100644 --- a/switch/source/main.cpp +++ b/switch/source/main.cpp @@ -72,7 +72,8 @@ int main(int argc, char** argv) hidTouchRead(&touch, 0); for (u8 i = 0; i < userIds.size(); i++) { - if (hidKeysHeld(CONTROLLER_P1_AUTO) & KEY_TOUCH && + if (!Gui::backupScroll() && + hidKeysHeld(CONTROLLER_P1_AUTO) & KEY_TOUCH && touch.px >= u32(1280 - (USER_ICON_SIZE + 4) * (i+1)) && touch.px <= u32(1280 - (USER_ICON_SIZE + 4) * i) && touch.py >= 32 && touch.py <= 32 + USER_ICON_SIZE) @@ -92,6 +93,7 @@ int main(int argc, char** argv) if (kdown & KEY_B) { + Gui::index(CELLS, 0); Gui::backupScroll(false); Gui::updateButtonsColor(); Gui::entryType(TITLES); @@ -107,8 +109,7 @@ int main(int argc, char** argv) { Title title; getTitle(title, g_currentUId, Gui::index(TITLES)); - std::vector list = title.saves(); - std::string path = title.path() + "/" + list.at(index); + std::string path = title.fullPath(index); io::deleteFolderRecursively(path.c_str()); refreshDirectories(title.id()); Gui::index(CELLS, index - 1); diff --git a/switch/source/scrollable.cpp b/switch/source/scrollable.cpp index 9063d83..017c8f2 100644 --- a/switch/source/scrollable.cpp +++ b/switch/source/scrollable.cpp @@ -70,4 +70,8 @@ void Scrollable::draw(void) { mCells.at(i)->draw(4); } + + size_t blankRows = mVisibleEntries - sz; + size_t rowHeight = mh / mVisibleEntries; + rectangled(mx, my + (baseIndex + sz) * rowHeight, mw, rowHeight * blankRows, COLOR_GREY_DARKER); } \ No newline at end of file diff --git a/switch/source/title.cpp b/switch/source/title.cpp index 4e01d3c..1574a10 100644 --- a/switch/source/title.cpp +++ b/switch/source/title.cpp @@ -79,10 +79,11 @@ static void loadIcon(u64 id, NsApplicationControlData* nsacd, size_t iconsize) } } -void Title::init(u64 id, u128 userID, const std::string& name, const std::string& author) +void Title::init(u8 saveDataType, u64 id, u128 userID, const std::string& name, const std::string& author) { mId = id; mUserId = userID; + mSaveDataType = saveDataType; mUserName = Account::username(userID); mAuthor = author; mDisplayName = name; @@ -97,6 +98,16 @@ void Title::init(u64 id, u128 userID, const std::string& name, const std::string refreshDirectories(); } +bool Title::systemSave(void) +{ + return mSaveDataType != FsSaveDataType_SaveData; +} + +u8 Title::saveDataType(void) +{ + return mSaveDataType; +} + u64 Title::id(void) { return mId; @@ -127,6 +138,11 @@ std::string Title::path(void) return mPath; } +std::string Title::fullPath(size_t index) +{ + return mFullSavePaths.at(index); +} + std::vector Title::saves() { return mSaves; @@ -147,6 +163,8 @@ u8* Title::smallIcon(void) void Title::refreshDirectories(void) { mSaves.clear(); + mFullSavePaths.clear(); + Directory savelist(mPath); if (savelist.good()) { @@ -155,16 +173,38 @@ void Title::refreshDirectories(void) if (savelist.folder(i)) { mSaves.push_back(savelist.entry(i)); + mFullSavePaths.push_back(mPath + "/" + savelist.entry(i)); } } std::sort(mSaves.rbegin(), mSaves.rend()); + std::sort(mFullSavePaths.rbegin(), mFullSavePaths.rend()); mSaves.insert(mSaves.begin(), "New..."); + mFullSavePaths.insert(mFullSavePaths.begin(), "New..."); } else { Gui::createError(savelist.error(), "Couldn't retrieve the directory list for the title " + name() + "."); } + + // save backups from configuration + std::vector additionalFolders = Configuration::getInstance().additionalSaveFolders(mId); + for (std::vector::const_iterator it = additionalFolders.begin(); it != additionalFolders.end(); it++) + { + // we have other folders to parse + Directory list(*it); + if (list.good()) + { + for (size_t i = 0, sz = list.size(); i < sz; i++) + { + if (list.folder(i)) + { + mSaves.push_back(list.entry(i)); + mFullSavePaths.push_back(*it + "/" + list.entry(i)); + } + } + } + } } void loadTitles(void) @@ -211,7 +251,7 @@ void loadTitles(void) if (R_SUCCEEDED(res) && nle != NULL) { Title title; - title.init(tid, uid, std::string(nle->name), std::string(nle->author)); + title.init(info.SaveDataType, tid, uid, std::string(nle->name), std::string(nle->author)); loadIcon(tid, nsacd, outsize - sizeof(nsacd->nacp)); // check if the vector is already created