mirror of
https://github.com/J-D-K/JKSV.git
synced 2026-03-21 17:24:37 -05:00
Fix up readme, add spaces to traditional chinese for line breaking, fix up some other stuff
This commit is contained in:
parent
4e6fa82e47
commit
657b41111f
|
|
@ -27,21 +27,22 @@ JKSV on Switch started as a small project/port to test some things and get famil
|
|||
* A opens the selected user's save files.
|
||||
* Y Dumps __all__ save data from __all users__, device save data, and BCAT save data. System save data is not included in this.
|
||||
* X Changes the UI mode to a text menu based one for people that prefer 3DS JKSM style text menus instead.
|
||||
* ZR Opens the Options menu.
|
||||
* Minus opens a small menu of extras.
|
||||
* Minus Opens the Options menu.
|
||||
* ZR opens a small menu of extras.
|
||||
|
||||
2. Title Select
|
||||
* A Opens the title for backup and restore.
|
||||
* L and R change the current user.
|
||||
* Y Dumps all saves for the currently selected user.
|
||||
* X Adds the selected title to a list of ignored titles.
|
||||
* Minus adds the selected title to a list of favorites that are pushed to the top of the title list/icons.
|
||||
* X adds the selected title to a list of favorites that are pushed to the top of the title list/icons.
|
||||
* Minus adds the selected title to a list of ignored titles.
|
||||
* ZR __ERASES__ The selected title's save from the system. This is the same as going into settings and deleting via data management. __THIS DOES NOT DELETE JKSV's SAVE FOLDERS__.
|
||||
|
||||
3. Backup/Folder Menu
|
||||
* Minus opens file mode. File mode is a basic file browser for moving individual files and folders. This also adds the ability to restore saves from any location on your SD card.
|
||||
* Holding L or R while selecting new with A will automatically name the backup for you without opening the keyboard.
|
||||
* A creates a new backup
|
||||
* JKSV adds some suggestions to the keyboard's dictionary such as: date strings, the current user's name **if it's safe**, and the current title or a generated abbreviation.
|
||||
* Y Restores save data from the selected folder.
|
||||
* X Deletes the selected folder.
|
||||
* ZR __ERASES__ the current save data for the title from __your system__, but leaves the archive on NAND.
|
||||
|
|
|
|||
34
inc/data.h
34
inc/data.h
|
|
@ -44,7 +44,7 @@ namespace data
|
|||
void drawHalf(unsigned x, unsigned y) { texDrawSkipNoAlpha(iconTex, frameBuffer, x, y); }
|
||||
void drawFavHalf(unsigned x, unsigned y) { texDrawSkipNoAlpha(iconFav, frameBuffer, x, y); }
|
||||
|
||||
uint64_t getTitleID() { return titleID; }
|
||||
uint64_t getTitleID() const { return titleID; }
|
||||
tex *getTex() { return iconTex; }
|
||||
|
||||
void deleteData() { texDestroy(iconTex); texDestroy(iconFav); }
|
||||
|
|
@ -66,26 +66,26 @@ namespace data
|
|||
bool isMountable(const AccountUid& uid);
|
||||
|
||||
//Returns title + title without forbidden chars
|
||||
std::string getTitle() { return title;}
|
||||
std::string getTitleSafe() { return titleSafe; }
|
||||
std::string getAuthor() { return author; }
|
||||
std::string getTitle() const { return title;}
|
||||
std::string getTitleSafe() const { return titleSafe; }
|
||||
std::string getAuthor() const { return author; }
|
||||
|
||||
//Creates title folder
|
||||
void createDir();
|
||||
void createDir() const;
|
||||
//Returns folder path
|
||||
std::string getPath() { return path; }
|
||||
std::string getPath() const { return path; }
|
||||
|
||||
//returns save_data_id string. only used for helping identify nand files
|
||||
std::string getTIDStr() { return tidStr; }
|
||||
std::string getSaveIDStr() { return saveIDStr; }
|
||||
std::string getTIDStr() const { return tidStr; }
|
||||
std::string getSaveIDStr() const { return saveIDStr; }
|
||||
|
||||
uint64_t getID() { return id; }
|
||||
uint64_t getSaveID() { return saveID; }
|
||||
uint16_t getSaveIndex() { return saveIndex; }
|
||||
FsSaveDataType getType() { return (FsSaveDataType)saveDataType; }
|
||||
uint64_t getID() const { return id; }
|
||||
uint64_t getSaveID() const { return saveID; }
|
||||
uint16_t getSaveIndex() const { return saveIndex; }
|
||||
FsSaveDataType getType() const { return (FsSaveDataType)saveDataType; }
|
||||
void setType(FsSaveDataType type) { saveDataType = type; }
|
||||
void setFav(bool setFav) { favorite = setFav; }
|
||||
bool getFav() { return favorite; }
|
||||
bool getFav() const { return favorite; }
|
||||
|
||||
//Game icon
|
||||
icn icon;
|
||||
|
|
@ -113,12 +113,12 @@ namespace data
|
|||
void assignIcon(tex *_icn) { userIcon = _icn; }
|
||||
|
||||
//Returns user ID
|
||||
AccountUid getUID() { return userID; }
|
||||
u128 getUID128() { return uID128; }
|
||||
AccountUid getUID() const { return userID; }
|
||||
u128 getUID128() const { return uID128; }
|
||||
|
||||
//Returns username
|
||||
std::string getUsername() { return username; }
|
||||
std::string getUsernameSafe() { return userSafe; }
|
||||
std::string getUsername() const { return username; }
|
||||
std::string getUsernameSafe() const { return userSafe; }
|
||||
|
||||
//Vector for storing save data info for user
|
||||
std::vector<titledata> titles;
|
||||
|
|
|
|||
20
inc/file.h
20
inc/file.h
|
|
@ -16,7 +16,7 @@ namespace fs
|
|||
void exit();
|
||||
|
||||
//Mounts usr's save data for open. Returns false it fails
|
||||
bool mountSave(data::user& usr, data::titledata& open);
|
||||
bool mountSave(const data::user& usr, const data::titledata& open);
|
||||
inline bool unmountSave(){ return fsdevUnmountDevice("sv") == 0; }
|
||||
|
||||
void copyFile(const std::string& from, const std::string& to);
|
||||
|
|
@ -34,7 +34,7 @@ namespace fs
|
|||
void delDir(const std::string& path);
|
||||
|
||||
//Dumps all titles for 'user'. returns false to bail
|
||||
bool dumpAllUserSaves(data::user& u);
|
||||
bool dumpAllUserSaves(const data::user& u);
|
||||
|
||||
//returns file properties as C++ string
|
||||
std::string getFileProps(const std::string& _path);
|
||||
|
|
@ -55,8 +55,8 @@ namespace fs
|
|||
{
|
||||
public:
|
||||
dirItem(const std::string& pathTo, const std::string& sItem);
|
||||
std::string getItm() { return itm; }
|
||||
bool isDir() { return dir; }
|
||||
std::string getItm() const { return itm; }
|
||||
bool isDir() const { return dir; }
|
||||
|
||||
private:
|
||||
std::string itm;
|
||||
|
|
@ -72,9 +72,9 @@ namespace fs
|
|||
void reassign(const std::string& _path);
|
||||
void rescan();
|
||||
|
||||
std::string getItem(int index) { return item[index].getItm(); }
|
||||
bool isDir(int index) { return item[index].isDir(); }
|
||||
unsigned getCount() { return item.size(); }
|
||||
std::string getItem(int index) const { return item[index].getItm(); }
|
||||
bool isDir(int index) const { return item[index].isDir(); }
|
||||
unsigned getCount() const { return item.size(); }
|
||||
|
||||
private:
|
||||
DIR *d;
|
||||
|
|
@ -89,13 +89,13 @@ namespace fs
|
|||
dataFile(const std::string& _path);
|
||||
~dataFile();
|
||||
|
||||
bool isOpen() { return opened; }
|
||||
bool isOpen() const { return opened; }
|
||||
|
||||
bool readNextLine(bool proc);
|
||||
//Finds where variable name ends. When a '(' or '=' is hit. Strips spaces
|
||||
void procLine();
|
||||
std::string getLine() { return line; }
|
||||
std::string getName() { return name; }
|
||||
std::string getLine() const { return line; }
|
||||
std::string getName() const { return name; }
|
||||
//Reads until ';', ',', or '\n' is hit and returns as string.
|
||||
std::string getNextValueStr();
|
||||
int getNextValueInt();
|
||||
|
|
|
|||
|
|
@ -21,18 +21,18 @@ namespace util
|
|||
std::string getDateTime(int fmt);
|
||||
|
||||
//Copys dir list to a menu with 'D: ' + 'F: '
|
||||
void copyDirListToMenu(fs::dirList& d, ui::menu& m);
|
||||
void copyDirListToMenu(const fs::dirList& d, ui::menu& m);
|
||||
|
||||
//Removes last folder from '_path'
|
||||
void removeLastFolderFromString(std::string& _path);
|
||||
|
||||
std::string safeString(const std::string& s);
|
||||
|
||||
std::string getInfoString(data::user& u, data::titledata& d);
|
||||
std::string getInfoString(const data::user& u, const data::titledata& d);
|
||||
|
||||
std::string getStringInput(const std::string& def, const std::string& head, size_t maxLength, unsigned dictCnt, const std::string dictWords[]);
|
||||
|
||||
std::string generateAbbrev(data::titledata& dat);
|
||||
std::string generateAbbrev(const data::titledata& dat);
|
||||
|
||||
//removes char from C++ string
|
||||
void stripChar(char _c, std::string& _s);
|
||||
|
|
|
|||
|
|
@ -30,25 +30,25 @@ off = "關"
|
|||
confirmHead = "再次確認"
|
||||
|
||||
#Confirm blacklist.
|
||||
confirmBlacklist = "是否確定要將#%s#加入黑名單?"
|
||||
confirmBlacklist = "是否確定要將 #%s# 加入黑名單?"
|
||||
|
||||
#Confirm overwriting folder
|
||||
confirmOverwrite = "是否確定要覆寫#%s#?"
|
||||
confirmOverwrite = "是否確定要覆寫 #%s#?"
|
||||
|
||||
#Confirm restoring save
|
||||
confirmRestore = "是否確定要還原#%s#?"
|
||||
confirmRestore = "是否確定要還原 #%s#?"
|
||||
|
||||
#Confirm deleting.
|
||||
confirmDelete = "是否確定要刪除#%s#? *此為永久性刪除*!"
|
||||
confirmDelete = "是否確定要刪除 #%s#? *此為永久性刪除*!"
|
||||
|
||||
#Confirm file copy in file mode
|
||||
confirmCopy = "是否確定要將#%s#複製到#%s#?"
|
||||
confirmCopy = "是否確定要將 #%s# 複製到 #%s#?"
|
||||
|
||||
#Warning for erasing save data from system in title menu
|
||||
confirmEraseNand = "*警告*: 此操作將把#%s#檔案從你的主機系統內*徹底抹除*! 如同從#檔案管理器#內將進度檔案刪除! 是否確定要繼續執行抹除?"
|
||||
confirmEraseNand = "*警告*: 此操作將把 #%s# 檔案從你的主機系統內*徹底抹除*! 如同從#檔案管理器#內將進度檔案刪除! 是否確定要繼續執行抹除?"
|
||||
|
||||
#Warning for deleting save data in folder menu
|
||||
confirmEraseFolder = "*警告*: 此操作*將把*目前的進度#%s#檔案*從主機系統內刪除*! 是否確定要繼續執行刪除?"
|
||||
confirmEraseFolder = "*警告*: 此操作*將把*目前的進度 #%s# 檔案*從主機系統內刪除*! 是否確定要繼續執行刪除?"
|
||||
|
||||
#Text displayed when holding is required. Should have a trailing space
|
||||
holdingText = 0, "(請按住) "
|
||||
|
|
|
|||
18
src/data.cpp
18
src/data.cpp
|
|
@ -32,7 +32,7 @@ static std::vector<uint64_t> favorites;
|
|||
//Sorts titles sort-of alphabetically
|
||||
static struct
|
||||
{
|
||||
bool operator()(data::titledata& a, data::titledata& b)
|
||||
bool operator()(const data::titledata& a, const data::titledata& b)
|
||||
{
|
||||
if(a.getFav() != b.getFav()) return a.getFav();
|
||||
|
||||
|
|
@ -338,7 +338,7 @@ bool data::titledata::isMountable(const AccountUid& uid)
|
|||
return false;
|
||||
}
|
||||
|
||||
void data::titledata::createDir()
|
||||
void data::titledata::createDir() const
|
||||
{
|
||||
mkdir(std::string(fs::getWorkDir() + titleSafe).c_str(), 777);
|
||||
}
|
||||
|
|
@ -403,7 +403,8 @@ void data::loadBlacklist()
|
|||
|
||||
void data::saveBlackList()
|
||||
{
|
||||
FILE *bl = fopen(std::string(fs::getWorkDir() + "blacklist.txt").c_str(), "w");
|
||||
std::string blPath = fs::getWorkDir() + "blacklist.txt";
|
||||
FILE *bl = fopen(blPath.c_str(), "w");
|
||||
for(uint64_t& id : blacklist)
|
||||
fprintf(bl, "0x%016lX\n", id);
|
||||
|
||||
|
|
@ -451,9 +452,10 @@ void data::favoriteTitle(titledata& t)
|
|||
|
||||
void data::loadCfg()
|
||||
{
|
||||
if(fs::fileExists(fs::getWorkDir() + "cfg.bin"))
|
||||
std::string cfgPath = fs::getWorkDir() + "cfg.bin";
|
||||
if(fs::fileExists(cfgPath))
|
||||
{
|
||||
FILE *cfg = fopen(std::string(fs::getWorkDir() + "cfg.bin").c_str(), "rb");
|
||||
FILE *cfg = fopen(cfgPath.c_str(), "rb");
|
||||
|
||||
uint64_t cfgIn = 0;
|
||||
fread(&cfgIn, sizeof(uint64_t), 1, cfg);
|
||||
|
|
@ -476,7 +478,8 @@ void data::loadCfg()
|
|||
|
||||
void data::saveCfg()
|
||||
{
|
||||
FILE *cfg = fopen(std::string(fs::getWorkDir() + "cfg.bin").c_str(), "wb");
|
||||
std::string cfgPath = fs::getWorkDir() + "cfg.bin";
|
||||
FILE *cfg = fopen(cfgPath.c_str(), "wb");
|
||||
|
||||
//Use 64bit int for space future stuff. Like this for readability.
|
||||
uint64_t cfgOut = 0;
|
||||
|
|
@ -525,7 +528,8 @@ void data::loadFav()
|
|||
|
||||
void data::saveFav()
|
||||
{
|
||||
FILE *fav = fopen(std::string(fs::getWorkDir() + "favorites.txt").c_str(), "w");
|
||||
std::string favPath = fs::getWorkDir() + "favorites.txt";
|
||||
FILE *fav = fopen(favPath.c_str(), "w");
|
||||
for(uint64_t& fid : favorites)
|
||||
fprintf(fav, "0x%016lX\n", fid);
|
||||
|
||||
|
|
|
|||
11
src/file.cpp
11
src/file.cpp
|
|
@ -23,7 +23,7 @@ static FsFileSystem sv;
|
|||
|
||||
static struct
|
||||
{
|
||||
bool operator()(fs::dirItem& a, fs::dirItem& b)
|
||||
bool operator()(const fs::dirItem& a, const fs::dirItem& b)
|
||||
{
|
||||
if(a.isDir() != b.isDir())
|
||||
return a.isDir();
|
||||
|
|
@ -213,7 +213,7 @@ void fs::exit()
|
|||
fs::logClose();
|
||||
}
|
||||
|
||||
bool fs::mountSave(data::user& usr, data::titledata& open)
|
||||
bool fs::mountSave(const data::user& usr, const data::titledata& open)
|
||||
{
|
||||
Result svOpen;
|
||||
switch(open.getType())
|
||||
|
|
@ -510,7 +510,7 @@ void fs::delDir(const std::string& path)
|
|||
rmdir(path.c_str());
|
||||
}
|
||||
|
||||
bool fs::dumpAllUserSaves(data::user& u)
|
||||
bool fs::dumpAllUserSaves(const data::user& u)
|
||||
{
|
||||
for(unsigned i = 0; i < u.titles.size(); i++)
|
||||
{
|
||||
|
|
@ -527,10 +527,7 @@ bool fs::dumpAllUserSaves(data::user& u)
|
|||
std::string outPath = u.titles[i].getPath() + u.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_ASC);
|
||||
mkdir(outPath.c_str(), 777);
|
||||
outPath += "/";
|
||||
|
||||
std::string root = "sv:/";
|
||||
|
||||
fs::copyDirToDir(root, outPath);
|
||||
fs::copyDirToDir("sv:/", outPath);
|
||||
|
||||
fsdevUnmountDevice("sv");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,9 +43,10 @@ void ui::createNewBackup(const uint64_t& held)
|
|||
util::getDateTime(util::DATE_FMT_JHK),
|
||||
util::getDateTime(util::DATE_FMT_ASC),
|
||||
data::curUser.getUsernameSafe(),
|
||||
data::curData.getTitleSafe().length() < 24 ? data::curData.getTitleSafe() : util::generateAbbrev(data::curData)
|
||||
data::curData.getTitleSafe(),
|
||||
util::generateAbbrev(data::curData)
|
||||
};
|
||||
folder = util::getStringInput("", "Enter a folder name", 64, 7, dict);
|
||||
folder = util::getStringInput("", "Enter a folder name", 64, 8, dict);
|
||||
}
|
||||
|
||||
if(!folder.empty())
|
||||
|
|
|
|||
20
src/util.cpp
20
src/util.cpp
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
static const char verboten[] = { ',', '/', '\\', '<', '>', ':', '"', '|', '?', '*', '™', '©', '®'};
|
||||
|
||||
static bool isVerboten(uint32_t t)
|
||||
static bool isVerboten(const uint32_t& t)
|
||||
{
|
||||
for(unsigned i = 0; i < 13; i++)
|
||||
{
|
||||
|
|
@ -22,6 +22,11 @@ static bool isVerboten(uint32_t t)
|
|||
return false;
|
||||
}
|
||||
|
||||
static inline bool isASCII(const uint32_t& t)
|
||||
{
|
||||
return t > 30 && t < 127;
|
||||
}
|
||||
|
||||
//Missing swkbd config funcs for now
|
||||
typedef enum
|
||||
{
|
||||
|
|
@ -79,7 +84,6 @@ static inline void replaceCharCStr(char *_s, char _find, char _rep)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
std::string util::getDateTime(int fmt)
|
||||
{
|
||||
char ret[128];
|
||||
|
|
@ -116,7 +120,7 @@ std::string util::getDateTime(int fmt)
|
|||
return std::string(ret);
|
||||
}
|
||||
|
||||
void util::copyDirListToMenu(fs::dirList& d, ui::menu& m)
|
||||
void util::copyDirListToMenu(const fs::dirList& d, ui::menu& m)
|
||||
{
|
||||
m.reset();
|
||||
m.addOpt(".");
|
||||
|
|
@ -152,7 +156,7 @@ std::string util::safeString(const std::string& s)
|
|||
|
||||
if(isVerboten(tmpChr))
|
||||
ret += ' ';
|
||||
else if(tmpChr < 31 || tmpChr > 126)
|
||||
else if(!isASCII(tmpChr))
|
||||
return ""; //return empty string so titledata::init defaults to titleID
|
||||
else
|
||||
ret += (char)tmpChr;
|
||||
|
|
@ -165,7 +169,7 @@ std::string util::safeString(const std::string& s)
|
|||
return ret;
|
||||
}
|
||||
|
||||
std::string util::getInfoString(data::user& u, data::titledata& d)
|
||||
std::string util::getInfoString(const data::user& u, const data::titledata& d)
|
||||
{
|
||||
std::string ret = d.getTitle() + "\n\n";
|
||||
|
||||
|
|
@ -239,7 +243,7 @@ std::string util::getStringInput(const std::string& def, const std::string& head
|
|||
return std::string(out);
|
||||
}
|
||||
|
||||
std::string util::generateAbbrev(data::titledata& dat)
|
||||
std::string util::generateAbbrev(const data::titledata& dat)
|
||||
{
|
||||
size_t titleLength = dat.getTitle().length();
|
||||
|
||||
|
|
@ -251,10 +255,10 @@ std::string util::generateAbbrev(data::titledata& dat)
|
|||
char *tok = strtok(temp, " ");
|
||||
while(tok)
|
||||
{
|
||||
ret += tok[0];
|
||||
if(isASCII(tok[0]))
|
||||
ret += tok[0];
|
||||
tok = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user