mirror of
https://github.com/BernardoGiordano/Checkpoint
synced 2024-11-15 06:07:06 +00:00
general updates
This commit is contained in:
parent
4d3b624792
commit
0284cf644f
14 changed files with 96 additions and 31 deletions
|
@ -77,7 +77,7 @@ bool Title::load(u64 _id, FS_MediaType _media, FS_CardType _card)
|
||||||
AM_GetTitleProductCode(mMedia, mId, productCode);
|
AM_GetTitleProductCode(mMedia, mId, productCode);
|
||||||
|
|
||||||
mAccessibleSave = Archive::accessible(mediaType(), lowId(), highId());
|
mAccessibleSave = Archive::accessible(mediaType(), lowId(), highId());
|
||||||
mAccessibleExtdata = Archive::accessible(extdataId());
|
mAccessibleExtdata = mMedia == MEDIATYPE_NAND ? false : Archive::accessible(extdataId());
|
||||||
|
|
||||||
if (mAccessibleSave)
|
if (mAccessibleSave)
|
||||||
{
|
{
|
||||||
|
@ -257,7 +257,7 @@ void Title::refreshDirectories(void)
|
||||||
}
|
}
|
||||||
else
|
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
|
// save backups from configuration
|
||||||
|
@ -302,7 +302,7 @@ void Title::refreshDirectories(void)
|
||||||
}
|
}
|
||||||
else
|
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
|
// extdata backups from configuration
|
||||||
|
|
|
@ -103,6 +103,11 @@ public:
|
||||||
mIndex = i - mPage * mVisibleEntries;
|
mIndex = i - mPage * mVisibleEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t visibleEntries(void)
|
||||||
|
{
|
||||||
|
return mVisibleEntries;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int mx;
|
int mx;
|
||||||
int my;
|
int my;
|
||||||
|
|
|
@ -45,7 +45,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool filter(u64 id);
|
bool filter(u64 id);
|
||||||
bool nandSaves(void);
|
|
||||||
std::vector<std::string> additionalSaveFolders(u64 id);
|
std::vector<std::string> additionalSaveFolders(u64 id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -60,7 +59,6 @@ private:
|
||||||
nlohmann::json mJson;
|
nlohmann::json mJson;
|
||||||
std::unordered_set<u64> mFilterIds;
|
std::unordered_set<u64> mFilterIds;
|
||||||
std::unordered_map<u64, std::vector<std::string>> mAdditionalSaveFolders;
|
std::unordered_map<u64, std::vector<std::string>> mAdditionalSaveFolders;
|
||||||
bool mNandSaves;
|
|
||||||
std::string BASEPATH = "/switch/Checkpoint/config.json";
|
std::string BASEPATH = "/switch/Checkpoint/config.json";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,11 +28,11 @@
|
||||||
#define FILESYSTEM_HPP
|
#define FILESYSTEM_HPP
|
||||||
|
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include "gui.hpp"
|
|
||||||
|
|
||||||
namespace FileSystem
|
namespace FileSystem
|
||||||
{
|
{
|
||||||
Result mount(FsFileSystem* fileSystem, u64 titleID, u128 userID);
|
Result mount(FsFileSystem* fileSystem, u64 titleID, u128 userID);
|
||||||
|
Result mount(FsFileSystem* fileSystem, u64 saveID);
|
||||||
int mount(FsFileSystem fs);
|
int mount(FsFileSystem fs);
|
||||||
void unmount(void);
|
void unmount(void);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "iscrollable.hpp"
|
#include "iscrollable.hpp"
|
||||||
#include "clickable.hpp"
|
#include "clickable.hpp"
|
||||||
|
#include "colors.hpp"
|
||||||
#include "draw.hpp"
|
#include "draw.hpp"
|
||||||
#include "hid.hpp"
|
#include "hid.hpp"
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ extern "C" {
|
||||||
class Title
|
class Title
|
||||||
{
|
{
|
||||||
public:
|
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) { };
|
~Title(void) { };
|
||||||
|
|
||||||
std::string author(void);
|
std::string author(void);
|
||||||
|
@ -54,9 +54,12 @@ public:
|
||||||
u64 id(void);
|
u64 id(void);
|
||||||
std::string name(void);
|
std::string name(void);
|
||||||
std::string path(void);
|
std::string path(void);
|
||||||
|
std::string fullPath(size_t index);
|
||||||
void refreshDirectories(void);
|
void refreshDirectories(void);
|
||||||
std::vector
|
std::vector
|
||||||
<std::string> saves(void);
|
<std::string> saves(void);
|
||||||
|
u8 saveDataType(void);
|
||||||
|
bool systemSave(void);
|
||||||
u128 userId(void);
|
u128 userId(void);
|
||||||
std::string userName(void);
|
std::string userName(void);
|
||||||
|
|
||||||
|
@ -70,6 +73,9 @@ private:
|
||||||
std::string mPath;
|
std::string mPath;
|
||||||
std::vector
|
std::vector
|
||||||
<std::string> mSaves;
|
<std::string> mSaves;
|
||||||
|
std::vector
|
||||||
|
<std::string> mFullSavePaths;
|
||||||
|
u8 mSaveDataType;
|
||||||
};
|
};
|
||||||
|
|
||||||
void getTitle(Title &dst, u128 uid, size_t i);
|
void getTitle(Title &dst, u128 uid, size_t i);
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
"additional_save_folders": {
|
"additional_save_folders": {
|
||||||
|
|
||||||
},
|
},
|
||||||
"nand_saves": false,
|
|
||||||
"version_major": 3,
|
"version_major": 3,
|
||||||
"version_minor": 3,
|
"version_minor": 3,
|
||||||
"version_micro": 1
|
"version_micro": 1
|
||||||
|
|
|
@ -54,9 +54,6 @@ Configuration::Configuration(void)
|
||||||
mFilterIds.emplace(strtoull(id.c_str(), NULL, 16));
|
mFilterIds.emplace(strtoull(id.c_str(), NULL, 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse nand saves
|
|
||||||
mNandSaves = mJson["nand_saves"];
|
|
||||||
|
|
||||||
// parse additional save folders
|
// parse additional save folders
|
||||||
auto js = mJson["additional_save_folders"];
|
auto js = mJson["additional_save_folders"];
|
||||||
for (auto it = js.begin(); it != js.end(); ++it)
|
for (auto it = js.begin(); it != js.end(); ++it)
|
||||||
|
@ -85,11 +82,6 @@ bool Configuration::filter(u64 id)
|
||||||
return mFilterIds.find(id) != mFilterIds.end();
|
return mFilterIds.find(id) != mFilterIds.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Configuration::nandSaves(void)
|
|
||||||
{
|
|
||||||
return mNandSaves;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> Configuration::additionalSaveFolders(u64 id)
|
std::vector<std::string> Configuration::additionalSaveFolders(u64 id)
|
||||||
{
|
{
|
||||||
std::vector<std::string> emptyvec;
|
std::vector<std::string> emptyvec;
|
||||||
|
|
|
@ -31,6 +31,11 @@ Result FileSystem::mount(FsFileSystem* fileSystem, u64 titleID, u128 userID)
|
||||||
return fsMount_SaveData(fileSystem, titleID, userID);
|
return fsMount_SaveData(fileSystem, titleID, userID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result FileSystem::mount(FsFileSystem* fileSystem, u64 saveID)
|
||||||
|
{
|
||||||
|
return fsMount_SystemSaveData(fileSystem, saveID);
|
||||||
|
}
|
||||||
|
|
||||||
int FileSystem::mount(FsFileSystem fs)
|
int FileSystem::mount(FsFileSystem fs)
|
||||||
{
|
{
|
||||||
return fsdevMountDevice("save", fs);
|
return fsdevMountDevice("save", fs);
|
||||||
|
|
|
@ -208,8 +208,8 @@ void Gui::drawCopy(const std::string& src, u64 offset, u64 size)
|
||||||
bool Gui::askForConfirmation(const std::string& text)
|
bool Gui::askForConfirmation(const std::string& text)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
Clickable* buttonYes = new Clickable(293, 540, 200, 80, COLOR_WHITE, COLOR_BLACK, "Yes", 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", 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);
|
MessageBox* message = new MessageBox(COLOR_GREY_DARK, COLOR_WHITE);
|
||||||
message->push_message(text);
|
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);
|
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
|
// title icons
|
||||||
|
@ -319,7 +323,7 @@ void Gui::draw(u128 uid)
|
||||||
}
|
}
|
||||||
else
|
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())
|
if (!selEnt.empty() && std::find(selEnt.begin(), selEnt.end(), k) != selEnt.end())
|
||||||
|
|
|
@ -228,14 +228,24 @@ void io::backup(size_t index, u128 uid)
|
||||||
|
|
||||||
if (Gui::multipleSelectionEnabled())
|
if (Gui::multipleSelectionEnabled())
|
||||||
{
|
{
|
||||||
customPath = isNewFolder ? suggestion : Gui::nameFromCell(cellIndex);
|
customPath = isNewFolder ? suggestion : "";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
customPath = isNewFolder ? StringUtils::removeForbiddenCharacters(KeyboardManager::get().keyboard(suggestion)) : Gui::nameFromCell(cellIndex);
|
customPath = isNewFolder ? StringUtils::removeForbiddenCharacters(KeyboardManager::get().keyboard(suggestion)) : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string dstPath;
|
||||||
|
if (!isNewFolder)
|
||||||
|
{
|
||||||
|
// we're overriding an existing folder
|
||||||
|
dstPath = title.fullPath(cellIndex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dstPath = title.path() + "/" + customPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string dstPath = title.path() + "/" + customPath;
|
|
||||||
if (!isNewFolder || io::directoryExists(dstPath))
|
if (!isNewFolder || io::directoryExists(dstPath))
|
||||||
{
|
{
|
||||||
int ret = io::deleteFolderRecursively(dstPath.c_str());
|
int ret = io::deleteFolderRecursively(dstPath.c_str());
|
||||||
|
@ -277,7 +287,7 @@ void io::restore(size_t index, u128 uid)
|
||||||
getTitle(title, uid, index);
|
getTitle(title, uid, index);
|
||||||
|
|
||||||
FsFileSystem fileSystem;
|
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))
|
if (R_SUCCEEDED(res))
|
||||||
{
|
{
|
||||||
int ret = FileSystem::mount(fileSystem);
|
int ret = FileSystem::mount(fileSystem);
|
||||||
|
@ -294,7 +304,7 @@ void io::restore(size_t index, u128 uid)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string srcPath = title.path() + "/" + Gui::nameFromCell(cellIndex) + "/";
|
std::string srcPath = title.fullPath(cellIndex) + "/";
|
||||||
std::string dstPath = "save:/";
|
std::string dstPath = "save:/";
|
||||||
|
|
||||||
res = io::deleteFolderRecursively(dstPath.c_str());
|
res = io::deleteFolderRecursively(dstPath.c_str());
|
||||||
|
|
|
@ -72,7 +72,8 @@ int main(int argc, char** argv)
|
||||||
hidTouchRead(&touch, 0);
|
hidTouchRead(&touch, 0);
|
||||||
for (u8 i = 0; i < userIds.size(); i++)
|
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+1)) &&
|
||||||
touch.px <= u32(1280 - (USER_ICON_SIZE + 4) * i) &&
|
touch.px <= u32(1280 - (USER_ICON_SIZE + 4) * i) &&
|
||||||
touch.py >= 32 && touch.py <= 32 + USER_ICON_SIZE)
|
touch.py >= 32 && touch.py <= 32 + USER_ICON_SIZE)
|
||||||
|
@ -92,6 +93,7 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
if (kdown & KEY_B)
|
if (kdown & KEY_B)
|
||||||
{
|
{
|
||||||
|
Gui::index(CELLS, 0);
|
||||||
Gui::backupScroll(false);
|
Gui::backupScroll(false);
|
||||||
Gui::updateButtonsColor();
|
Gui::updateButtonsColor();
|
||||||
Gui::entryType(TITLES);
|
Gui::entryType(TITLES);
|
||||||
|
@ -107,8 +109,7 @@ int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
Title title;
|
Title title;
|
||||||
getTitle(title, g_currentUId, Gui::index(TITLES));
|
getTitle(title, g_currentUId, Gui::index(TITLES));
|
||||||
std::vector<std::string> list = title.saves();
|
std::string path = title.fullPath(index);
|
||||||
std::string path = title.path() + "/" + list.at(index);
|
|
||||||
io::deleteFolderRecursively(path.c_str());
|
io::deleteFolderRecursively(path.c_str());
|
||||||
refreshDirectories(title.id());
|
refreshDirectories(title.id());
|
||||||
Gui::index(CELLS, index - 1);
|
Gui::index(CELLS, index - 1);
|
||||||
|
|
|
@ -70,4 +70,8 @@ void Scrollable::draw(void)
|
||||||
{
|
{
|
||||||
mCells.at(i)->draw(4);
|
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);
|
||||||
}
|
}
|
|
@ -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;
|
mId = id;
|
||||||
mUserId = userID;
|
mUserId = userID;
|
||||||
|
mSaveDataType = saveDataType;
|
||||||
mUserName = Account::username(userID);
|
mUserName = Account::username(userID);
|
||||||
mAuthor = author;
|
mAuthor = author;
|
||||||
mDisplayName = name;
|
mDisplayName = name;
|
||||||
|
@ -97,6 +98,16 @@ void Title::init(u64 id, u128 userID, const std::string& name, const std::string
|
||||||
refreshDirectories();
|
refreshDirectories();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Title::systemSave(void)
|
||||||
|
{
|
||||||
|
return mSaveDataType != FsSaveDataType_SaveData;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 Title::saveDataType(void)
|
||||||
|
{
|
||||||
|
return mSaveDataType;
|
||||||
|
}
|
||||||
|
|
||||||
u64 Title::id(void)
|
u64 Title::id(void)
|
||||||
{
|
{
|
||||||
return mId;
|
return mId;
|
||||||
|
@ -127,6 +138,11 @@ std::string Title::path(void)
|
||||||
return mPath;
|
return mPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Title::fullPath(size_t index)
|
||||||
|
{
|
||||||
|
return mFullSavePaths.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> Title::saves()
|
std::vector<std::string> Title::saves()
|
||||||
{
|
{
|
||||||
return mSaves;
|
return mSaves;
|
||||||
|
@ -147,6 +163,8 @@ u8* Title::smallIcon(void)
|
||||||
void Title::refreshDirectories(void)
|
void Title::refreshDirectories(void)
|
||||||
{
|
{
|
||||||
mSaves.clear();
|
mSaves.clear();
|
||||||
|
mFullSavePaths.clear();
|
||||||
|
|
||||||
Directory savelist(mPath);
|
Directory savelist(mPath);
|
||||||
if (savelist.good())
|
if (savelist.good())
|
||||||
{
|
{
|
||||||
|
@ -155,16 +173,38 @@ void Title::refreshDirectories(void)
|
||||||
if (savelist.folder(i))
|
if (savelist.folder(i))
|
||||||
{
|
{
|
||||||
mSaves.push_back(savelist.entry(i));
|
mSaves.push_back(savelist.entry(i));
|
||||||
|
mFullSavePaths.push_back(mPath + "/" + savelist.entry(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(mSaves.rbegin(), mSaves.rend());
|
std::sort(mSaves.rbegin(), mSaves.rend());
|
||||||
|
std::sort(mFullSavePaths.rbegin(), mFullSavePaths.rend());
|
||||||
mSaves.insert(mSaves.begin(), "New...");
|
mSaves.insert(mSaves.begin(), "New...");
|
||||||
|
mFullSavePaths.insert(mFullSavePaths.begin(), "New...");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Gui::createError(savelist.error(), "Couldn't retrieve the directory list for the title " + name() + ".");
|
Gui::createError(savelist.error(), "Couldn't retrieve the directory list for the title " + name() + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// save backups from configuration
|
||||||
|
std::vector<std::string> additionalFolders = Configuration::getInstance().additionalSaveFolders(mId);
|
||||||
|
for (std::vector<std::string>::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)
|
void loadTitles(void)
|
||||||
|
@ -211,7 +251,7 @@ void loadTitles(void)
|
||||||
if (R_SUCCEEDED(res) && nle != NULL)
|
if (R_SUCCEEDED(res) && nle != NULL)
|
||||||
{
|
{
|
||||||
Title title;
|
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));
|
loadIcon(tid, nsacd, outsize - sizeof(nsacd->nacp));
|
||||||
|
|
||||||
// check if the vector is already created
|
// check if the vector is already created
|
||||||
|
|
Loading…
Reference in a new issue